uimaj-2.4.0/0000755000175000017500000000000011665472404012527 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/0000755000175000017500000000000011665472022017614 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/pom.xml0000644000175000017500000000615311665471546021150 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-document-annotation jar 2.4.0 Apache UIMA Base: ${project.artifactId} A common, but not built-in, type in the type system, specifying the language of a document ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-document-annotation scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-document-annotation http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-document-annotation ${project.artifactId} ${ibmNoticeText} org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-test-util ${project.parent.version} test uima-document-annotation uimaj-2.4.0/uimaj-document-annotation/src/0000755000175000017500000000000011665471044020406 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/0000755000175000017500000000000011665471046021334 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/resources/0000755000175000017500000000000011665471046023346 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/0000755000175000017500000000000011665471044022253 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/0000755000175000017500000000000011665471044023042 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/0000755000175000017500000000000011665471044024263 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/0000755000175000017500000000000011665471044025216 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/0000755000175000017500000000000011665471044026136 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/tcas/0000755000175000017500000000000011665471046027072 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/tcas/DocumentAnnotation.javauimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/tcas/DocumentAnnotation.jav0000644000175000017500000000551311665471046033411 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.tcas; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.impl.JCasImpl; /** * The JCas class definition for the CAS DocumentAnnotation type. When text CASs are * created, one instance of this type is created and made accessable via a call to the * {@link JCasImpl#getDocumentAnnotationFs()} method. It is also a subtype of {@link Annotation} and * therefore would appear as one of the annotations that an iterator over all the annotations would * return. */ public class DocumentAnnotation extends Annotation { public final static int typeIndexID = JCasRegistry.register(DocumentAnnotation.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected DocumentAnnotation() { } /** Internal - Constructor used by generator */ public DocumentAnnotation(int addr, TOP_Type type) { super(addr, type); } public DocumentAnnotation(JCas jcas) { super(jcas); } // *------------------* // * Feature: language /** * getter for language */ public String getLanguage() { if (DocumentAnnotation_Type.featOkTst && ((DocumentAnnotation_Type) jcasType).casFeat_language == null) this.jcasType.jcas.throwFeatMissing("language", "uima.tcas.DocumentAnnotation"); return jcasType.ll_cas.ll_getStringValue(addr, ((DocumentAnnotation_Type) jcasType).casFeatCode_language); } /** * setter for language */ public void setLanguage(String v) { if (DocumentAnnotation_Type.featOkTst && ((DocumentAnnotation_Type) jcasType).casFeat_language == null) this.jcasType.jcas.throwFeatMissing("language", "uima.tcas.DocumentAnnotation"); jcasType.ll_cas.ll_setStringValue(addr, ((DocumentAnnotation_Type) jcasType).casFeatCode_language, v); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/tcas/DocumentAnnotation_Type.javauimaj-2.4.0/uimaj-document-annotation/src/main/java/org/apache/uima/jcas/tcas/DocumentAnnotation_Typ0000644000175000017500000000673711665471046033477 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.tcas; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; public class DocumentAnnotation_Type extends Annotation_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (DocumentAnnotation_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = DocumentAnnotation_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new DocumentAnnotation(addr, DocumentAnnotation_Type.this); DocumentAnnotation_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new DocumentAnnotation(addr, DocumentAnnotation_Type.this); } }; public final static int typeIndexID = DocumentAnnotation.typeIndexID; public final static boolean featOkTst = JCasRegistry.getFeatOkTst("uima.tcas.DocumentAnnotation"); final Feature casFeat_language; final int casFeatCode_language; public String getLanguage(int addr) { if (featOkTst && casFeat_language == null) this.jcas.throwFeatMissing("language", "uima.tcas.DocumentAnnotation"); return ll_cas.ll_getStringValue(addr, casFeatCode_language); } public void setLanguage(int addr, String v) { if (featOkTst && casFeat_language == null) this.jcas.throwFeatMissing("language", "uima.tcas.DocumentAnnotation"); ll_cas.ll_setStringValue(addr, casFeatCode_language, v); } // * initialize variables to correspond with Cas Type and Features public DocumentAnnotation_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_language = jcas.getRequiredFeatureDE(casType, "language", "uima.cas.String", featOkTst); casFeatCode_language = (null == casFeat_language) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_language).getCode(); } protected DocumentAnnotation_Type() { // block default new operator casFeat_language = null; casFeatCode_language = JCas.INVALID_FEATURE_CODE; throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-document-annotation/src/test/0000755000175000017500000000000011665471044021365 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/0000755000175000017500000000000011665471044022306 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/0000755000175000017500000000000011665471044023075 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/0000755000175000017500000000000011665471044024316 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/uima/0000755000175000017500000000000011665471044025251 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/uima/jcas/0000755000175000017500000000000011665471044026171 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/uima/jcas/tcas/0000755000175000017500000000000011665471044027123 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/uima/jcas/tcas/DocumentAnnotationTest.javauimaj-2.4.0/uimaj-document-annotation/src/test/java/org/apache/uima/jcas/tcas/DocumentAnnotationTest0000644000175000017500000000406011665471044033517 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.tcas; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.jcas.JCas; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; /** * */ public class DocumentAnnotationTest extends TestCase { JCas jcas; public void setUp() throws Exception { try { CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); this.jcas = cas.getJCas(); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetDocumentAnnotation() throws Exception { try { assertTrue(jcas.getDocumentAnnotationFs() instanceof DocumentAnnotation); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateDocumentAnnot() throws Exception { try { DocumentAnnotation b = (DocumentAnnotation) jcas.getDocumentAnnotationFs(); jcas.reset(); DocumentAnnotation a = (DocumentAnnotation) jcas.getDocumentAnnotationFs(); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-component-test-util/0000755000175000017500000000000011665472070017563 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/pom.xml0000644000175000017500000000614311665471546021113 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-component-test-util jar 2.4.0 Apache UIMA Base: ${project.artifactId}: for JUnit Supporting utilities used in various JUnit tests ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-component-test-util scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-component-test-util http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-component-test-util ${project.artifactId} junit junit 3.8.1 compile org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-test-util ${project.parent.version} compile uimaj-2.4.0/uimaj-component-test-util/src/0000755000175000017500000000000011665471262020354 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/0000755000175000017500000000000011665471264021302 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/resources/0000755000175000017500000000000011665471264023314 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/resources/AnnotationWriter.xml0000644000175000017500000000253411665471264027351 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.test.junit_extension.AnnotationWriter Annotation Writer Writes annotations to a file 1.0 Apache uimaj-2.4.0/uimaj-component-test-util/src/main/java/0000755000175000017500000000000011665471262022221 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/0000755000175000017500000000000011665471262023010 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/0000755000175000017500000000000011665471262024231 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/0000755000175000017500000000000011665471262025164 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/0000755000175000017500000000000011665471262026143 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/0000755000175000017500000000000011665471262031370 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotatorPerformanceTester.javauimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotatorPe0000644000175000017500000002372611665471262033557 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.FileFilter; import java.util.HashMap; import java.util.logging.LogManager; import junit.framework.Assert; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.internal.util.Timer; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.util.FileUtils; import org.apache.uima.util.Level; import org.apache.uima.util.Logger; import org.apache.uima.util.XMLInputSource; /** * AnnotatorPerfTester is a helper class to execute annotator performance tests. The performance * test results are returned as {@link PerformanceTestResultImpl} object. * */ public class AnnotatorPerformanceTester { private static class FileFileFilter implements FileFilter { private FileFileFilter() { super(); } public boolean accept(File arg0) { return arg0.isFile(); } } private static HashMap logLevels = new HashMap(9); static { logLevels.put("OFF", Level.OFF); logLevels.put("SEVERE", Level.SEVERE); logLevels.put("WARNING", Level.WARNING); logLevels.put("INFO", Level.INFO); logLevels.put("CONFIG", Level.CONFIG); logLevels.put("FINE", Level.FINE); logLevels.put("FINER", Level.FINER); logLevels.put("FINEST", Level.FINEST); logLevels.put("ALL", Level.ALL); } /** * runs an annotator performance test * * @param repeatSingle * if true, every document is process "numsToRun" times before the next document is * processed. If false, all documents are processed and this is repeated "numsToRun" * times. * * @param numsToRun * repeat count for the input documents * @param taeDescFilePath * ae descriptor - absolute file path * @param testFileDir * test file directory * @param dataPath * ae datapath * @param doWarmup * do warum for analysis engine - runs an short english sample document * @return PerformanceTestResult - returns the performance test results * * @throws Exception */ public static PerformanceTestResult runPerformanceTest(boolean repeatSingle, int numsToRun, File taeDescFilePath, File testFileDir, String dataPath, boolean doWarmup) throws Exception { // create performance result object PerformanceTestResultImpl result = new PerformanceTestResultImpl(); // check mandetory settings Assert.assertNotNull(taeDescFilePath); Assert.assertNotNull(testFileDir); // save settings result.setRepeatSingleMode(repeatSingle); result.setDoWarmup(doWarmup); result.setNumsToRun(numsToRun); result.setAeDescFilePath(taeDescFilePath); result.setTestFileDir(testFileDir); result.setDatapath(dataPath); // set and check test file directory if (testFileDir == null || !testFileDir.isDirectory() || !testFileDir.canRead()) { throw new Exception("test file directory not valid"); } // get current log level setting Level defaultLogLevel = (Level) logLevels.get(LogManager.getLogManager() .getProperty(".level")); if (defaultLogLevel == null) { // no log level was specified, use default log level settings "INFO" that is also // used by the Java logging framework. defaultLogLevel = Level.INFO; } // turn of logging for the performance test Logger logger = UIMAFramework.getLogger(); logger.setLevel(Level.OFF); //create timer Timer globalTimer = new Timer(); Timer initTimer = new Timer(); Timer warmupTimer = new Timer(); Timer ioTimer = new Timer(); Timer processResetTimer = new Timer(); Timer cleanupTimer = new Timer(); Timer documentPreparationTimer = new Timer(); //start timer for global time globalTimer.start(); // init analysis engine try { // start initialization timer initTimer.start(); // set datapath ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); if (dataPath != null) { resMgr.setDataPath(dataPath); } AnalysisEngine ae = null; CAS cas = null; // get resource specifier from XML file XMLInputSource in = new XMLInputSource(taeDescFilePath); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // create analysis engine with resource manager ae = UIMAFramework.produceAnalysisEngine(specifier, resMgr, null); // check ae Assert.assertNotNull(ae); // create new cas cas = ae.newCAS(); // check cas Assert.assertNotNull(cas); // access cas type system cas.getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_LANGUAGE); // stop initalization timer initTimer.stop(); result.setInitTime(initTimer.getTimeSpan()); if (doWarmup) { // start warmup timer warmupTimer.start(); // process dummy document cas.setDocumentLanguage("en"); cas.setDocumentText("This is a test sentence."); ae.process(cas); cas.reset(); // stop warmup timer warmupTimer.stop(); result.setWarmupTime(warmupTimer.getTimeSpan()); } // start io timer ioTimer.start(); // read all files in the test file directory File[] inputFiles = testFileDir.listFiles(new FileFileFilter()); // create string array for the file content and language String[] fileTexts = new String[inputFiles.length]; String[] languages = new String[inputFiles.length]; int numChars = 0; long fileSize = 0; // iterate of all input files and extract content and language for (int i = 0; i < inputFiles.length; i++) { // get file language languages[i] = inputFiles[i].getName().substring(0, 2); // get file content fileTexts[i] = FileUtils.file2String(inputFiles[i], "UTF-8"); fileSize += inputFiles[i].length(); // count characters numChars += fileTexts[i].length(); } // stop io timer ioTimer.stop(); // save results result.setNumberOfFiles(inputFiles.length); result.setNumberOfCharacters(numChars); result.setTotalFileSize(fileSize); result.setIoTime(ioTimer.getTimeSpan()); // start real processing int numAnnot = 0; // check repeat single mode setting // repeatSingle=true: iterates of all files and repeat each file "numsToRun" times // repeatSingle=false: iterates of all files and repeat the collection "numsToRun" times if (repeatSingle) { // iterate over all text files (over the cached content) for (int i = 0; i < fileTexts.length; i++) { // file repeat mode // iterate over the current document "numsToRun" times for (int j = 0; j < numsToRun; j++) { documentPreparationTimer.start(); // set cas data cas.setDocumentLanguage(languages[i]); cas.setDocumentText(fileTexts[i]); documentPreparationTimer.stop(); processResetTimer.start(); ae.process(cas); processResetTimer.stop(); documentPreparationTimer.start(); numAnnot += cas.getAnnotationIndex().size(); cas.reset(); documentPreparationTimer.stop(); } } } // use collection repeat mode else { // process the file collection "numsToRun" times for (int j = 0; j < numsToRun; j++) { // iterate over all text files (over the cached content) for (int i = 0; i < fileTexts.length; i++) { documentPreparationTimer.start(); // set cas data cas.setDocumentLanguage(languages[i]); cas.setDocumentText(fileTexts[i]); documentPreparationTimer.stop(); processResetTimer.start(); ae.process(cas); processResetTimer.stop(); documentPreparationTimer.start(); numAnnot += cas.getAnnotationIndex().size(); cas.reset(); documentPreparationTimer.stop(); } } } // cleanup ae and stop global timer cleanupTimer.start(); ae.destroy(); ae = null; cleanupTimer.stop(); globalTimer.stop(); // save results result.setNumberOfCreatedAnnotations(numAnnot); result.setOverallTime(globalTimer.getTimeSpan()); result.setProcessingTime(processResetTimer.getTimeSpan()); result.setCleanupTime(cleanupTimer.getTimeSpan()); result.setDocumentPreparationTime(documentPreparationTimer.getTimeSpan()); // turn on logging as it was before logger.setLevel(defaultLogLevel); // return result object return result; } catch (Exception e) { // Bail out. throw e; } } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/PerformanceTestResult.javauimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/Performance0000644000175000017500000000656011665471262033563 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import org.apache.uima.internal.util.TimeSpan; /** * PerformanceTestResult interfance contains all the methods to access the performance test results. * */ public interface PerformanceTestResult { /** * @return Returns the number of processed characters. */ public int getNumberOfProcessedCharacters(); /** * @return Returns the number of processed files. */ public int getNumberOfProcessedFiles(); /** * @return Returns the UIMA datapath setting used for the performance test. */ public String getUIMADatapath(); /** * @return Returns the analysis engine initialization time. */ public TimeSpan getAeInitTime(); /** * @return Returns the file I/O time. */ public TimeSpan getFileIoTime(); /** * @return Returns the number of created annotations. */ public int getNumberOfCreatedAnnotations(); /** * @return Returns the setting for the number of repeated runs. */ public int getNumberOfRepeatedRuns(); /** * @return Returns the overall time of the performance run */ public TimeSpan getOverallTime(); /** * @return Returns the analysis engine processing time. */ public TimeSpan getAeProcessingTime(); /** * @return Returns the setting of the repeat mode mode. */ public boolean isRepeatSingleMode(); /** * @return Returns the analysis engine descriptor file path. */ public String getAeDescFilePath(); /** * @return Returns the test file directory used for the performance run. */ public String getTestFileDirectoryPath(); /** * @return Returns the analysis engine warmup time. */ public TimeSpan getAeWarmupTime(); /** * @return Returns the setting the the analysis engine warmup. */ public boolean isDoAeWarmup(); /** * write performance results as colum. * * @param level * Test level name of the performance test * @param file * Output file where the results are written to * * @throws Exception */ public void writePerfResultsAsColumn(String level, File file) throws Exception; /** * @return Returns the analysis engine cleanup time. */ public TimeSpan getAeCleanupTime(); /** * @return Returns the document preparation time. */ public TimeSpan getDocumentPreparationTime(); /** * @return Returns the processed file collection size. */ public long getProcessedFileSize(); } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/PerformanceTestResultImpl.javauimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/Performance0000644000175000017500000003363611665471262033567 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.FileWriter; import java.util.Calendar; import java.util.GregorianCalendar; import org.apache.uima.internal.util.TimeSpan; /** * PerformanceTestResultImpl implements the PerformanceTestResult interface and provides the results of a performance * test run. * */ public class PerformanceTestResultImpl implements PerformanceTestResult { private static String NEWLINE = System.getProperty("line.separator"); private boolean repeatSingleMode = false; private boolean doWarmup = false; private int numsToRun = 1; private File aeDescFile = null; private File testFileDir = null; private int numberOfFiles = 0; private long collectionFileSize = 0; private int numberOfCharacters = 0; private String datapath = null; private int numberOfCreatedAnnotations = 0; private TimeSpan initTime = null; private TimeSpan warmupTime = null; private TimeSpan overallTime = null; private TimeSpan ioTime = null; private TimeSpan processingTime = null; private TimeSpan cleanupTime = null; private TimeSpan documentPreparationTime = null; /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getNumberOfProcessedCharacters() */ public int getNumberOfProcessedCharacters() { return this.numberOfCharacters * this.numsToRun; } /** * @param numberOfCharacters * The number of characters. */ public void setNumberOfCharacters(int numberOfCharacters) { this.numberOfCharacters = numberOfCharacters; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getNumberOfProcessedFiles() */ public int getNumberOfProcessedFiles() { return this.numberOfFiles * this.numsToRun; } /** * @param numberOfFiles * The number of files. */ public void setNumberOfFiles(int numberOfFiles) { this.numberOfFiles = numberOfFiles; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getUIMADatapath() */ public String getUIMADatapath() { return this.datapath; } /** * @param datapath * The UIMA datapath. */ public void setDatapath(String datapath) { this.datapath = datapath; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getAeInitTime() */ public TimeSpan getAeInitTime() { return this.initTime; } /** * @param initTime * The analysis engine init time. */ public void setInitTime(TimeSpan initTime) { this.initTime = initTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getFileIoTime() */ public TimeSpan getFileIoTime() { return this.ioTime; } /** * @param ioTime * The file io time to set. */ public void setIoTime(TimeSpan ioTime) { this.ioTime = ioTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getNumberOfCreatedAnnotations() */ public int getNumberOfCreatedAnnotations() { return this.numberOfCreatedAnnotations; } /** * @param numberOfCreatedAnnotations * The number of created annotations to set. */ public void setNumberOfCreatedAnnotations(int numberOfCreatedAnnotations) { this.numberOfCreatedAnnotations = numberOfCreatedAnnotations; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getNumberOfRepeatedRuns() */ public int getNumberOfRepeatedRuns() { return this.numsToRun; } /** * @param numsToRun * The number of repeated runs. */ public void setNumsToRun(int numsToRun) { this.numsToRun = numsToRun; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getOverallTime() */ public TimeSpan getOverallTime() { return this.overallTime; } /** * @param overallTime * The overall processing time. */ public void setOverallTime(TimeSpan overallTime) { this.overallTime = overallTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getAeProcessingTime() */ public TimeSpan getAeProcessingTime() { return this.processingTime; } /** * @param processingTime * The analysis engine processing time. */ public void setProcessingTime(TimeSpan processingTime) { this.processingTime = processingTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#isRepeatSingleMode() */ public boolean isRepeatSingleMode() { return this.repeatSingleMode; } /** * @param repeatSingleMode * The repeat single mode setting */ public void setRepeatSingleMode(boolean repeatSingleMode) { this.repeatSingleMode = repeatSingleMode; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getAeDescFilePath() */ public String getAeDescFilePath() { return this.aeDescFile.getAbsolutePath(); } /** * @param aeDescFile * The analysis engine descriptor file. */ public void setAeDescFilePath(File aeDescFile) { this.aeDescFile = aeDescFile; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getTestFileDirectoryPath() */ public String getTestFileDirectoryPath() { return this.testFileDir.getAbsolutePath(); } /** * @param testFileDir * The test file directory. */ public void setTestFileDir(File testFileDir) { this.testFileDir = testFileDir; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getAeWarmupTime() */ public TimeSpan getAeWarmupTime() { return this.warmupTime; } /** * @param warmupTime * The analysis engine warmup time. */ public void setWarmupTime(TimeSpan warmupTime) { this.warmupTime = warmupTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#isDoAeWarmup() */ public boolean isDoAeWarmup() { return this.doWarmup; } /** * @param doWarmup * the doWarmup setting */ public void setDoWarmup(boolean doWarmup) { this.doWarmup = doWarmup; } /** * returns a performance report with the current performance results. * * @see java.lang.Object#toString() */ public String toString() { StringBuffer resultString = new StringBuffer(); resultString.append(NEWLINE + "Performance Test run results " + NEWLINE); resultString.append("-----------------------------" + NEWLINE + NEWLINE); resultString.append("ConfigParameters: " + NEWLINE); resultString.append("repeat-single mode is: " + this.repeatSingleMode + NEWLINE); resultString.append("doWarump is: " + this.doWarmup + NEWLINE); resultString.append("Run test " + this.numsToRun + " times" + NEWLINE); resultString.append("Use " + this.aeDescFile.getAbsolutePath() + " descriptor" + NEWLINE); resultString.append("Fileset " + this.testFileDir + " is used" + NEWLINE); resultString.append("Datapath setting is: " + this.datapath + NEWLINE); resultString.append("Number of documents (overall): " + this.getNumberOfProcessedFiles() + NEWLINE); resultString .append("Number of characters (overall): " + this.getNumberOfProcessedCharacters() + NEWLINE); resultString.append("Total document size (overall): " + (float) (this.getProcessedFileSize() / 1024) + " KB" + NEWLINE); resultString.append(NEWLINE + "Initialize: " + NEWLINE); resultString.append("AE initialize time: " + this.initTime + NEWLINE); if (this.doWarmup) { resultString.append("AE warmup time: " + this.warmupTime + NEWLINE); } resultString.append("IO time for reading files: " + this.ioTime + NEWLINE); resultString.append(NEWLINE + "Processing: " + NEWLINE); resultString.append("Created annotations: " + this.numberOfCreatedAnnotations + NEWLINE); resultString.append("Document preparation time: " + this.documentPreparationTime + NEWLINE); resultString.append("Analysis Engine processing time: " + this.processingTime + NEWLINE); if (this.processingTime.getFullMilliseconds() > 0 && this.getProcessedFileSize() > 0) { resultString.append("Processing throughput: " + (long) ((this.getProcessedFileSize() / 1024) / ((float) this.processingTime .getFullMilliseconds() / 1000)) + " KB/s" + NEWLINE); long mbPerSecond = (long) ((this.getProcessedFileSize() / 1024 / 1024) / ((float) this.processingTime .getFullMilliseconds() / 1000 / 60 / 60)); resultString.append("Processing throughput: " + mbPerSecond + " MB/h" + NEWLINE); } resultString.append(NEWLINE + "Cleanup: " + NEWLINE); resultString.append("Cleanup time: " + this.cleanupTime + NEWLINE); resultString.append(NEWLINE + "Overall: " + NEWLINE); resultString.append("Overall time: " + this.overallTime + NEWLINE); return resultString.toString(); } /** * write performance results as colum. * * @param level * Test level name of the performance test * @param file * Output file where the results are written to * * @throws Exception */ public void writePerfResultsAsColumn(String level, File file) throws Exception { // set level name to "none" if it is not available if (level == null) { level = "none"; } // create current time stamp GregorianCalendar cal = new GregorianCalendar(); StringBuffer timestamp = new StringBuffer(); timestamp.append(cal.get(Calendar.DATE)); timestamp.append("."); timestamp.append(cal.get(Calendar.MONTH) + 1); timestamp.append("."); timestamp.append(cal.get(Calendar.YEAR)); timestamp.append(" "); timestamp.append(cal.get(Calendar.HOUR_OF_DAY)); timestamp.append(":"); timestamp.append(cal.get(Calendar.MINUTE)); timestamp.append(":"); timestamp.append(cal.get(Calendar.SECOND)); // create result line StringBuffer resultLine = new StringBuffer(); resultLine.append(timestamp.toString()); // add timestamp resultLine.append(" ; "); resultLine.append(level); // add level name resultLine.append(" ; "); resultLine.append(this.repeatSingleMode); // repeate single mode resultLine.append(" ; "); resultLine.append(this.doWarmup); // doWarmup resultLine.append(" ; "); resultLine.append(this.numberOfFiles * this.numsToRun); // number of docs overall resultLine.append(" ; "); resultLine.append(this.numberOfCreatedAnnotations); // number of created annots resultLine.append(" ; "); resultLine.append(this.processingTime); // processing time resultLine.append(" ; "); resultLine.append(this.initTime); // init time resultLine.append(" ; "); resultLine.append(this.ioTime); // io time resultLine.append(System.getProperty("line.separator")); boolean writeHeader = false; // check if file does not exist, write file header if (!file.exists()) { writeHeader = true; } // create outputStream in appending mode FileWriter fileWriter = new FileWriter(file, true); if (writeHeader) { fileWriter .write("Timestamp ; Levelname ; singleMode ; warmup; Docs ; Annotations ; Processing time ; init time ; io time"); fileWriter.write(System.getProperty("line.separator")); } // write result fileWriter.write(resultLine.toString()); // flush and close writer fileWriter.flush(); fileWriter.close(); } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getAeCleanupTime() */ public TimeSpan getAeCleanupTime() { return this.cleanupTime; } /** * @param cleanupTime * the analysis engine cleanup time */ public void setCleanupTime(TimeSpan cleanupTime) { this.cleanupTime = cleanupTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getDocumentPreparationTime() */ public TimeSpan getDocumentPreparationTime() { return this.documentPreparationTime; } /** * @param documentPreparationTime * the document preparation time */ public void setDocumentPreparationTime(TimeSpan documentPreparationTime) { this.documentPreparationTime = documentPreparationTime; } /* (non-Javadoc) * @see org.apache.uima.test.junit_extension.PerformanceTestResult#getProcessedFileSize() */ public long getProcessedFileSize() { return this.collectionFileSize * this.numsToRun; } /** * @param collectionFileSize * the collection file size */ public void setTotalFileSize(long collectionFileSize) { this.collectionFileSize = collectionFileSize; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotationWriter.javauimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotationW0000644000175000017500000002505511665471262033563 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.LowLevelTypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.collection.CasConsumer; import org.apache.uima.collection.CasConsumer_ImplBase; import org.apache.uima.resource.ResourceConfigurationException; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceProcessException; import org.apache.uima.util.ProcessTrace; /** * The AnnotationWriter class writes specified annotations to an output file. * The encoding of the output file is UTF-8 */ public class AnnotationWriter extends CasConsumer_ImplBase implements CasConsumer { //output file private File outFile; //output file writer private OutputStreamWriter fileWriter; //respected annotations private String[] tofs; //check if reconfigure must be called private boolean reconfig = false; private final static String featureOnlyKey = "feature"; /** * Initializes this CAS Consumer with the parameters specified in the * descriptor. * * @throws ResourceInitializationException if there is error in * initializing the resources */ public void initialize() throws ResourceInitializationException { // extract configuration parameter settings String oPath = (String) getUimaContext().getConfigParameterValue("outputFile"); //Output file should be specified in the descriptor if (oPath == null) { //set reconfiguration - reconfig() must be called this.reconfig = true; } else { // If specified output directory does not exist, try to create it this.outFile = new File(oPath); if (this.outFile.getParentFile() != null && !this.outFile.getParentFile().exists()) { if (!this.outFile.getParentFile().mkdirs()) throw new ResourceInitializationException( ResourceInitializationException.RESOURCE_DATA_NOT_VALID, new Object[] { oPath, "outputFile" }); } try { this.fileWriter = new OutputStreamWriter(new FileOutputStream(this.outFile, false), "UTF-8"); } catch (IOException e) { throw new ResourceInitializationException(e); } } //extract annotation types this.tofs = (String[]) getUimaContext().getConfigParameterValue("AnnotationTypes"); //sort array if (this.tofs != null) Arrays.sort(this.tofs); } /** * processTofs() writes als specified types an features to a HashMap. * * @param aCAS a CAS with a TypeSystem * @param tofs respected tofs * @return HashMap - Map with all types an features. */ private HashMap processTofs(CAS aCAS, String[] someTofs) { HashMap types = new HashMap(10); for (int i = 0; i < someTofs.length; i++) { Type type = aCAS.getTypeSystem().getType(someTofs[i]); if (type == null) //maybe a feature { int index = someTofs[i].indexOf(":"); if (index != -1) { String typename = someTofs[i].substring(0, index); Type typeKey = aCAS.getTypeSystem().getType(typename); //get feature object (Vector) for the current type Object obj = types.get(typeKey); //if type is not included in the typelist create type and add feature if (obj == null) { ArrayList list = new ArrayList(10); Feature fs = aCAS.getTypeSystem().getFeatureByFullName(someTofs[i]); list.add(0, featureOnlyKey); list.add(fs); types.put(typeKey, list); } else //add feature to type { //cast feature vector for the current type ArrayList vec = (ArrayList) obj; Feature fs = aCAS.getTypeSystem().getFeatureByFullName(someTofs[i]); vec.add(fs); } } } else { //add type as key and a Vector as Feature container if(types.containsKey(type)){ ArrayList featureList = (ArrayList) types.get(type); if(featureList.size() >0 && featureList.get(0).equals(featureOnlyKey)){ featureList.remove(0); } // type is already in the list do not overwrite it! }else{ types.put(type, new ArrayList(10)); } } } return types; } public synchronized void processCas(CAS aCAS) throws ResourceProcessException { if (this.reconfig == true) { throw new ResourceProcessException( ResourceInitializationException.CONFIG_SETTING_ABSENT, new Object[] { "outputFile" }); } //get low level CAS LowLevelCAS ll_cas = aCAS.getLowLevelCAS(); //get low level TypeSystem LowLevelTypeSystem ll_typeSystem = ll_cas.ll_getTypeSystem(); //get types and feature interessted in HashMap types = processTofs(aCAS, this.tofs); try { //iterate and print annotations FSIterator typeIterator = aCAS.getAnnotationIndex().iterator(); for (typeIterator.moveToFirst(); typeIterator.isValid(); typeIterator.moveToNext()) { Iterator it = types.keySet().iterator(); while (it.hasNext()) { //get current type and features Type currentType = (Type) it.next(); boolean isFeatureOnly = false; ArrayList featureList = (ArrayList) types.get(currentType); if(featureList.size() >0 && featureList.get(0).equals(featureOnlyKey)){ featureList.remove(0); isFeatureOnly = true; } Feature[] features = (Feature[]) featureList.toArray(new Feature[] { }); AnnotationFS annot = (AnnotationFS) typeIterator.get(); if (annot.getType().getName() == currentType.getName()) { //only for formatting necessary boolean firstFeature = true; String span = annot.getCoveredText(); if(!isFeatureOnly){ this.fileWriter.write( annot.getType().getShortName() + "(" + annot.getBegin() + "," + annot.getEnd() + "): " + span); }else{ this.fileWriter.write( annot.getType().getShortName() + ": "); } for (int f = 0; f < features.length; f++) { if (firstFeature) { this.fileWriter.write(" { "); firstFeature = false; } else { this.fileWriter.write(", "); } Feature fs = features[f]; int typeClass = ll_cas.ll_getTypeClass(ll_typeSystem.ll_getCodeForType(fs.getRange())); this.fileWriter.write(fs.getShortName() + "="); switch (typeClass) { case LowLevelCAS.TYPE_CLASS_FLOAT : this.fileWriter.write(Float.toString(annot.getFloatValue(fs))); break; case LowLevelCAS.TYPE_CLASS_INT : this.fileWriter.write(Integer.toString(annot.getIntValue(fs))); break; case LowLevelCAS.TYPE_CLASS_STRING : String value = annot.getStringValue(fs); if(value != null) { this.fileWriter.write(value); } else { this.fileWriter.write("null"); } break; case LowLevelCAS.TYPE_CLASS_FS: FeatureStructure fStruct = annot.getFeatureValue(fs); if(fStruct != null) { this.fileWriter.write(fStruct.toString()); } else { this.fileWriter.write("null"); } break; } } if (firstFeature == false) { this.fileWriter.write(" }"); } this.fileWriter.write(System.getProperty("line.separator")); } } } this.fileWriter.flush(); } catch (Exception ex) { throw new ResourceProcessException(ex); } } public void batchProcessComplete(ProcessTrace aTrace) throws ResourceProcessException, IOException { // nothing to do here } public void collectionProcessComplete(ProcessTrace aTrace) throws ResourceProcessException, IOException { if (this.fileWriter != null) { this.fileWriter.close(); } } public void reconfigure() throws ResourceConfigurationException { //reset reconfiguration - is done this.reconfig = false; super.reconfigure(); // extract configuration parameter settings String oPath = (String) getUimaContext().getConfigParameterValue("outputFile"); File oFile = new File(oPath); //if output file has changed, close exiting file and open new if (!oFile.equals(this.outFile)) { this.outFile = oFile; try { if (this.fileWriter != null) this.fileWriter.close(); // If specified output directory does not exist, try to create it if (oFile.getParentFile() != null && !oFile.getParentFile().exists()) { if (!oFile.getParentFile().mkdirs()) throw new ResourceConfigurationException( ResourceInitializationException.RESOURCE_DATA_NOT_VALID, new Object[] { oPath, "outputFile" }); } //write result specification to the output file this.fileWriter = new OutputStreamWriter(new FileOutputStream(oFile, false), "UTF-8"); } catch (IOException e) { throw new ResourceConfigurationException(); } } //extract annotation types this.tofs = (String[]) getUimaContext().getConfigParameterValue("AnnotationTypes"); //sort array if (this.tofs != null) Arrays.sort(this.tofs); } public void destroy() { if (this.fileWriter != null) { try { this.fileWriter.close(); } catch (IOException e) { // ignore IOException on destroy } } } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotatorTester.javauimaj-2.4.0/uimaj-component-test-util/src/main/java/org/apache/uima/test/junit_extension/AnnotatorTe0000644000175000017500000003453411665471262033562 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.IOException; import java.util.Map; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.Assert; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.collection.CasConsumer; import org.apache.uima.resource.ResourceConfigurationException; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.FileCompare; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.FileUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; /** * AnnotatorTester is the helper class to test annotators. */ public class AnnotatorTester { // annotator descriptor private File descFile; // analysis engine instance private AnalysisEngine ae; // Resource Manager private ResourceManager mgr; /** * Constructor save the specified descriptor file path and initialize the * analysis engine. * * @param descFilePath * descriptor file path * @throws Exception * if an analysis engine initialize error occurs. */ public AnnotatorTester(String descFilePath) throws Exception { this.descFile = new File(descFilePath); this.mgr = UIMAFramework.newDefaultResourceManager(); setup(); } /** * Constructor save the specified descriptor file path and initialize the * analysis engine. * * @param descFile * descriptor file * @throws Exception * if an analysis engine initialize error occurs. */ public AnnotatorTester(File descFile) throws Exception { this.descFile = descFile; this.mgr = UIMAFramework.newDefaultResourceManager(); setup(); } /** * Constructor save the specified descriptor file path and initialize the * analysis engine. * * @param descFilePath * descriptor file path * @param mgr * a ResourceManager * @throws Exception * if an analysis engine initialize error occurs. */ public AnnotatorTester(String descFilePath, ResourceManager mgr) throws Exception { this.descFile = new File(descFilePath); this.mgr = mgr; setup(); } /** * initialize the analysis engine with the specified specifier. * * @throws Exception */ private void setup() throws Exception { try { this.ae = null; // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(this.descFile); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); // Create the Text Analysis Engine. this.ae = UIMAFramework.produceAnalysisEngine(specifier, this.mgr, null); } catch (Exception ex) { JUnitExtension.handleException(ex); } } /** * change the parameter name for the given analysis engine * * @param groupName * group name, if no group is available, pass null * @param paramName * parameter name * @param paramValue * parameter value * * @throws ResourceConfigurationException */ public void changeParameterSetting(String groupName, String paramName, Object paramValue) throws ResourceConfigurationException { if (groupName == null) { this.ae.setConfigParameterValue(paramName, paramValue); } else { this.ae.setConfigParameterValue(groupName, paramName, paramValue); } // call reconfigure to activate the change this.ae.reconfigure(); } /** * change the parameter name for the given delegate analysis engine key * * @param delegeteKey * analysis engine key * @param groupName * group name * @param paramName * parameter name * @param paramValue * parameter value * * @throws InvalidXMLException * @throws ResourceInitializationException * @throws IOException */ public void changeDelegateParameterSetting(String delegeteKey, String groupName, String paramName, Object paramValue) throws InvalidXMLException, ResourceInitializationException, IOException { // create CasConsumer description AnalysisEngineDescription aeSpecifier = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(this.descFile)); // get delegates Map delegates = aeSpecifier.getDelegateAnalysisEngineSpecifiers(); // check if delegeteKey is available if (delegates.containsKey(delegeteKey)) { // create new import AnalysisEngineDescription delegate = (AnalysisEngineDescription) delegates .get(delegeteKey); if (groupName == null) { delegate.getMetaData().getConfigurationParameterSettings() .setParameterValue(paramName, paramValue); } else { delegate.getMetaData().getConfigurationParameterSettings() .setParameterValue(groupName, paramName, paramValue); } } // produce new AE this.ae = UIMAFramework .produceAnalysisEngine(aeSpecifier, this.mgr, null); } /** * does configuration parameter test * * @param configDescFilePath * @return AnalysisEngine * * @throws Exception */ public static AnalysisEngine doConfigurationTest(String configDescFilePath) throws Exception { try { AnalysisEngine ae = null; // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(configDescFilePath); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Set the document text on the CAS. cas .setDocumentText("This is a simple text to check if the configuration works"); cas.setDocumentLanguage("en"); // Process the sample document. ae.process(cas); return ae; } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * Creates a new fresh CAS instance which can be used for testing. * @return * @throws Exception */ public CAS createCAS() throws Exception { try { return ae.newCAS(); } catch (Exception ex) { JUnitExtension.handleException(ex); return null; } } /** * performs a test on the initialized annotator. The specified document is * processed with the given language. * * @param text * a document text * @param language * the document text language * @return CAS - results of the analysis * @throws Exception */ public CAS performTest(String text, String language) throws Exception { try { // Create a new CAS. CAS cas = this.ae.newCAS(); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage(language); // Process the sample document. this.ae.process(cas); return cas; } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * performs a test on the initialized annotator. The specified CAS is * processed and the results are returned. * * @param cas * a CAS for processing * @return CAS - results of the analysis * @throws Exception */ public CAS performTest(CAS cas) throws Exception { try { // Process the sample document. this.ae.process(cas); return cas; } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * performs a test with a special annotator configuration. For this a new AE * is created and used to process the specified document for the specified * language. * * @param descFilePath * Descriptor file path * @param text * a document text * @param language * the document text language * @return CAS - results of the analysis * @throws Exception */ public static CAS performTest(String descFilePath, String text, String language) throws Exception { try { AnalysisEngine ae = null; // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(descFilePath); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage(language); // Process the sample document. ae.process(cas); return cas; } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * create a CAS object from the given XCAS and typesystem files * * @param tsFile - * a typesystem file * @param xcasFile - * a xcas file * * @return CAS - CAS object created from the given input data * @throws Exception */ public static CAS getCASfromXCAS(File tsFile, File xcasFile) throws Exception { try { Object tsDescriptor = UIMAFramework.getXMLParser().parse( new XMLInputSource(tsFile)); TypeSystemDescription tsDesc = (TypeSystemDescription) tsDescriptor; CAS cas = CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[0]); SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); XCASDeserializer xcasDeserializer = new XCASDeserializer(cas .getTypeSystem()); parser.parse(xcasFile, xcasDeserializer.getXCASHandler(cas)); return cas; } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * Reads the content form a file to a String with respect to the file * encoding. * * @param file * a file with the source * @param encoding * file encoding * @return String - file content * @throws Exception */ public static String readFileContent(File file, String encoding) throws Exception { try { return FileUtils.file2String(file, encoding); } catch (Exception ex) { JUnitExtension.handleException(ex); } return null; } /** * checkResult compares the analyzed document with the reference output. * * @param cas * a cas with the analyzed data * @param AnnotationTypes * respected annotation types * @param refFile * reference output * @param testFile * test file for the current output * @throws Exception */ public static void checkResult(CAS cas, String[] AnnotationTypes, File refFile, File testFile) throws Exception { try { testFile.delete(); // delete file if exist testFile.createNewFile(); // create new file // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getURL("AnnotationWriter.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); CasConsumer consumer = UIMAFramework.produceCasConsumer(specifier); consumer.setConfigParameterValue("AnnotationTypes", AnnotationTypes); consumer.setConfigParameterValue("outputFile", testFile .getAbsolutePath()); consumer.reconfigure(); consumer.processCas(cas); consumer.destroy(); // check file output boolean isIdentical = FileCompare.compare(refFile, testFile); if (isIdentical) { testFile.delete(); } Assert.assertTrue(isIdentical); } catch (Exception ex) { JUnitExtension.handleException(ex); } } } uimaj-2.4.0/uimaj-adapter-soap/0000755000175000017500000000000011665472064016214 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/pom.xml0000644000175000017500000000737011665471546017544 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-adapter-soap jar 2.4.0 Apache UIMA Base: ${project.artifactId}: SOAP Adapter Provides the capability to connect to a remote component, using the SOAP protocol ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-adapter-soap scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-adapter-soap http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-adapter-soap ${project.artifactId} ${ibmNoticeText} org.apache.uima uimaj-core ${project.parent.version} compile axis axis 1.3 compile axis axis-jaxrpc 1.3 compile org.apache.geronimo.specs geronimo-activation_1.0.2_spec 1.2 compile uima-adapter-soap uimaj-2.4.0/uimaj-adapter-soap/src/0000755000175000017500000000000011665471034016777 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/0000755000175000017500000000000011665471036017725 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/resources/0000755000175000017500000000000011665471036021737 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/0000755000175000017500000000000011665471034020644 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/0000755000175000017500000000000011665471034021433 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/0000755000175000017500000000000011665471034022654 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/0000755000175000017500000000000011665471034023607 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/0000755000175000017500000000000011665471034025227 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/0000755000175000017500000000000011665471034026171 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/XmlDeserializerFactory.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/XmlDeserializerFactory.jav0000644000175000017500000000427711665471034033340 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.util.Iterator; import java.util.Vector; import org.apache.axis.Constants; import org.apache.axis.Version; import org.apache.axis.encoding.DeserializerFactory; import org.apache.uima.adapter.soap.axis11.XmlDeserializer_Axis11; /** * An Axis deserializer factory that constructs instances of {@link XmlDeserializer}. * * */ public class XmlDeserializerFactory implements DeserializerFactory { private static final long serialVersionUID = -414711394032045305L; private Vector mechanisms; public javax.xml.rpc.encoding.Deserializer getDeserializerAs(String mechanismType) { // There is a binary incompatibility between Axis v1.1 and // Axis v1.2 in the serializer/deserializer libraries. // So that UIMA can support both Axis versions, we have different // versions of each of our serializer classes. Here we check the // Axis version number and return an insance of the correct class. String ver = Version.getVersion(); if (ver.startsWith("Apache Axis version: 1.1")) { return new XmlDeserializer_Axis11(); } else { return new XmlDeserializer(); } } public Iterator getSupportedMechanismTypes() { if (mechanisms == null) { mechanisms = new Vector(); mechanisms.add(Constants.AXIS_SAX); } return mechanisms.iterator(); } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinaryDeserializer.java0000644000175000017500000001373711665471034032636 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.Serializable; import javax.activation.DataHandler; import javax.xml.namespace.QName; import org.apache.axis.AxisFault; import org.apache.axis.attachments.AttachmentUtils; import org.apache.axis.encoding.Base64; import org.apache.axis.encoding.DeserializationContext; import org.apache.axis.encoding.DeserializerImpl; import org.apache.axis.message.SOAPBodyElement; import org.apache.axis.soap.SOAPConstants; import org.apache.axis.utils.Messages; import org.apache.uima.internal.util.SerializationUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; /** * An Axis deserializer for {@link Serializable} objects. The serialized bytes are Base-64 encoded * for transport via SOAP. * * */ public class BinaryDeserializer extends DeserializerImpl { private static final long serialVersionUID = 1351090281481173811L; private StringBuffer buf = new StringBuffer(); public void startElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { // System.out.println("startElement(" + namespace + "," + localName + "," + prefix + ")"); if (!context.isDoneParsing()) { if (myElement == null) { try { myElement = makeNewElement(namespace, localName, prefix, attributes, context); } catch (AxisFault axisFault) { throw new SAXException(axisFault); } context.pushNewElement(myElement); } } SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); QName type = context.getTypeFromAttributes(namespace, localName, attributes); if (log.isDebugEnabled()) { log.debug(Messages.getMessage("gotType00", "Deser", "" + type)); } String href = attributes.getValue(soapConstants.getAttrHref()); // System.out.println(soapConstants.getAttrHref() + " = " + href); if (href != null) { Object ref = context.getObjectByRef(href); // System.out.println(ref.getClass().getName()); // System.out.println(ref); if (ref instanceof SOAPBodyElement) // multiref, deref. again { SOAPBodyElement bodyElem = (SOAPBodyElement) ref; href = bodyElem.getAttributeValue(soapConstants.getAttrHref()); ref = context.getObjectByRef(href); // System.out.println(ref.getClass().getName()); // System.out.println(ref); } if (ref instanceof org.apache.axis.Part) { try { DataHandler dataHandler = AttachmentUtils .getActivationDataHandler((org.apache.axis.Part) ref); Object content = dataHandler.getContent(); // System.out.println(content.getClass().getName()); ObjectInputStream objStream = new ObjectInputStream((InputStream) content); try { setValue(objStream.readObject()); } finally { objStream.close(); } } catch (org.apache.axis.AxisFault e) { throw new SAXException(e.getMessage()); } catch (java.io.IOException e) { throw new SAXException(e.getMessage()); } catch (ClassNotFoundException e) { throw new SAXException(e.getMessage()); } } } // if we didn't set a value, call default implementation if (getValue() == null) { super.startElement(namespace, localName, prefix, attributes, context); } // buf.setLength(0); } /** * @see org.apache.axis.message.SOAPHandler#onStartElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes, org.apache.axis.encoding.DeserializationContext) */ public void onStartElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { buf.setLength(0); } /** * @see org.apache.axis.encoding.Deserializer#onEndElement(java.lang.String, java.lang.String, * org.apache.axis.encoding.DeserializationContext) */ public void onEndElement(String arg0, String arg1, DeserializationContext arg2) throws SAXException { try { // System.out.println("onEndElement(" + arg0 + "," + arg1 + ")"); // deserialize (if not done already via attachments) if (this.getValue() == null) { // System.out.println("deserializing - no attachments found"); //DEBUG String base64str = buf.toString(); // System.out.println("Base64str: " + base64str); if (base64str.length() > 0) { byte[] bytes = Base64.decode(base64str); setValue(SerializationUtils.deserialize(bytes)); } } } catch (Exception e) { e.printStackTrace(); throw new SAXException(e); } } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // System.out.println("characters(" + new String(ch,start,length) + ")"); buf.append(ch, start, length); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisResourceServiceManager.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisResourceServiceManager0000644000175000017500000001621111665471034033345 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.util.HashMap; import java.util.Map; import org.apache.axis.AxisFault; import org.apache.axis.Handler; import org.apache.axis.MessageContext; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.service.impl.AnalysisEngineService_impl; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.service.impl.ResourceService_impl; import org.apache.uima.util.Level; import org.apache.uima.util.Logger; import org.apache.uima.util.XMLInputSource; /** * Utility class for deploying Resources as Axis (SOAP) services. This class mantains a map between * Axis service names and the {@link ResourceService_impl} classes that provide the implementation * for those service names. This map is maintained as static data on this class so that it persists * between invocations of the Axis services. *

* SOAP service implementation classes call the static {@link #getServiceImpl(Class)} method from * their constructors. The service's name and configuration parameters will be read from the Axis * MessageContext. If a {@link ResourceService_impl} instance has already been registered under this * service's name, that instance will be returned. Otherwise, a new * ResourceService_impl will be created. */ public class AxisResourceServiceManager { /** * The name of the deployment parameter whose value is the path to an XML resource specifier. This * resource specifier is used to constuct Resource instances that process the requests received by * this service. A value for this option must be speciifed in the deployment descriptor for this * service. */ public static final String PARAM_RESOURCE_SPECIFIER_PATH = "resourceSpecifierPath"; /** * The name of the deployment parameter whose value is the number of instances of the Resource * (specified by {@link #PARAM_RESOURCE_SPECIFIER_PATH}) to be created. The Resources are kept in * a pool and used to service requests. A value for this option must be speciifed in the * deployment descriptor for this service. */ public static final String PARAM_NUM_INSTANCES = "numInstances"; /** * The name of the deployment parameter whose value is a boolean indicating whether to write log * messages during each service invocation. This currently applies only to Analysis Engine * services. */ public static final String PARAM_ENABLE_LOGGING = "enableLogging"; /** * Map from service names to ResourceService_impl objects. */ private static Map mResourceServiceImplMap = new HashMap(); /** * Gets a {@link ResourceService_impl} class to be used to process an request.This method * retrieves the service name and configuration parameters from the Axis MessageContext. If a * {@link ResourceService_impl} object already exists for that service name, that object will be * returned. Otherwise, a new ResourceService_impl object will be created from the * information in the MessageContext. * * @param aResourceImplClass * the class that will be instantiated when a new ResourceService_impl is * to be created. This must be a subclass of ResourceService_impl. * @throws AxisFault * if the configuration information could not be read */ public static ResourceService_impl getServiceImpl(Class aServiceImplClass) throws AxisFault { try { MessageContext ctx = MessageContext.getCurrentContext(); if (ctx == null) { throw new Exception("MessageContext = NULL"); } Handler self = ctx.getService(); if (self == null) { throw new Exception("Handler = NULL"); } // Get service name String serviceName = self.getName(); // see if we have a ResourceService_impl registered for that name ResourceService_impl serviceImpl = (ResourceService_impl) mResourceServiceImplMap .get(serviceName); if (serviceImpl != null) { return serviceImpl; } // No service impl registered for this service name, attempt to // create a new one // Get the Resource Specifier Path String resourceSpecifierPath = (String) self.getOption(PARAM_RESOURCE_SPECIFIER_PATH); if (resourceSpecifierPath == null || resourceSpecifierPath.trim().length() == 0) { throw new Exception("Invalid Configuration - " + PARAM_RESOURCE_SPECIFIER_PATH + " not Defined. Check your deployment descriptor file (WSDD)"); } // parse ResourceSpecifier ResourceSpecifier resourceSpecifier = UIMAFramework.getXMLParser().parseResourceSpecifier( new XMLInputSource(resourceSpecifierPath)); // Get the number of instances to create String numInstancesStr = (String) self.getOption(PARAM_NUM_INSTANCES); int numInstances; try { numInstances = Integer.parseInt(numInstancesStr); } catch (NumberFormatException e) { throw new Exception("Invalid Configuration - " + PARAM_NUM_INSTANCES + " not valid. Check your deployment descriptor file (WSDD)"); } // Get whether to enable logging String enableLogStr = (String) self.getOption(PARAM_ENABLE_LOGGING); boolean enableLog = "true".equalsIgnoreCase(enableLogStr); // create and initialize the service implementation serviceImpl = (ResourceService_impl) aServiceImplClass.newInstance(); HashMap initParams = new HashMap(); initParams.put(AnalysisEngine.PARAM_NUM_SIMULTANEOUS_REQUESTS, new Integer(numInstances)); serviceImpl.initialize(resourceSpecifier, initParams); // disable logging for Analysis Engines if deployer so indicated if (!enableLog && serviceImpl instanceof AnalysisEngineService_impl) { Logger nullLogger = UIMAFramework.newLogger(); nullLogger.setOutputStream(null); ((AnalysisEngineService_impl) serviceImpl).getAnalysisEngine().setLogger(nullLogger); } mResourceServiceImplMap.put(serviceName, serviceImpl); return serviceImpl; } catch (Exception e) { UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e); throw AxisFault.makeFault(e); } } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/0000755000175000017500000000000011665471034027277 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/XmlDeserializer_Axis11.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/XmlDeserializer_Axi0000644000175000017500000001167611665471034033141 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap.axis11; import java.io.File; import org.apache.axis.encoding.DeserializationContext; import org.apache.axis.encoding.DeserializerImpl; import org.apache.axis.message.SOAPHandler; import org.apache.uima.UIMAFramework; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLParser; import org.apache.uima.util.XMLizable; import org.apache.uima.util.impl.SaxDeserializer_impl; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.LocatorImpl; /** * An Axis deserializer for any {@link XMLizable} object. *

* This class works only under Axis v1.1. */ public class XmlDeserializer_Axis11 extends DeserializerImpl { private static final long serialVersionUID = 6687245569965318456L; private SaxDeserializer_impl mDeser; private int mNesting; public XmlDeserializer_Axis11() { try { mNesting = 0; mDeser = new SaxDeserializer_impl(UIMAFramework.getXMLParser(), null, null, new XMLParser.ParsingOptions(false)); LocatorImpl loc = new LocatorImpl(); loc.setSystemId(new File(System.getProperty("user.dir")).toURL().toString()); mDeser.setDocumentLocator(loc); mDeser.startDocument(); } catch (Exception e) { e.printStackTrace(); } } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::characters(" + new // String(ch,start,length) + ")"); mDeser.characters(ch, start, length); } /** * @see org.apache.axis.encoding.Deserializer#onEndElement(java.lang.String, java.lang.String, * org.apache.axis.encoding.DeserializationContext) */ public void onEndElement(String arg0, String arg1, DeserializationContext arg2) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::onEndElement(" + arg0 + "," + arg1); mNesting--; if (mNesting > 0) { mDeser.endElement(arg0, arg1, arg1); } } /** * This method is invoked when an element start tag is encountered. * * @param namespace * is the namespace of the element * @param localName * is the name of the element * @param prefix * is the element's prefix * @param attributes * are the attributes on the element...used to get the type * @param context * is the DeserializationContext */ public SOAPHandler onStartChild(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { return this; } /** * @see org.apache.axis.message.SOAPHandler#onStartElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes, org.apache.axis.encoding.DeserializationContext) */ public void onStartElement(String arg0, String arg1, String arg2, Attributes arg3, DeserializationContext arg4) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::onStartElement(" + arg0 + "," + arg1 + // "," + arg2 + ")"); // don't process the topmost element - it is a SOAP "multiRef" element and // we don't care about that if (mNesting > 0) { mDeser.startElement(arg0, arg1, arg1, arg3); } mNesting++; } /** * @see org.apache.axis.encoding.Deserializer#valueComplete() */ public void valueComplete() throws SAXException { // System.out.println("AxisResourceServiceDeserializer::valueComplete"); if (mNesting == 0) { // System.out.println("Building value"); mDeser.endDocument(); try { Object val = mDeser.getObject(); // System.out.println("Value is: " + val); // value = val; setValue(val); } catch (InvalidXMLException e) { e.printStackTrace(); setValue(null); } // call superclass to register the deserialized object super.valueComplete(); } } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/BinaryDeserializer_Axis11.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/BinaryDeserializer_0000644000175000017500000001402611665471034033153 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap.axis11; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.Serializable; import javax.activation.DataHandler; import javax.xml.namespace.QName; import org.apache.axis.AxisFault; import org.apache.axis.attachments.AttachmentUtils; import org.apache.axis.encoding.Base64; import org.apache.axis.encoding.DeserializationContext; import org.apache.axis.encoding.DeserializerImpl; import org.apache.axis.message.SOAPBodyElement; import org.apache.axis.soap.SOAPConstants; import org.apache.axis.utils.Messages; import org.apache.uima.internal.util.SerializationUtils; import org.xml.sax.Attributes; import org.xml.sax.SAXException; /** * An Axis deserializer for {@link Serializable} objects. The serialized bytes are Base-64 encoded * for transport via SOAP. *

* This class works only under Axis v1.1. */ public class BinaryDeserializer_Axis11 extends DeserializerImpl { private static final long serialVersionUID = -591743087907058514L; private StringBuffer buf = new StringBuffer(); public void startElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { // System.out.println("startElement(" + namespace + "," + localName + "," + prefix + ")"); if (!context.isDoneParsing()) { if (myElement == null) { try { myElement = makeNewElement(namespace, localName, prefix, attributes, context); } catch (AxisFault axisFault) { throw new SAXException(axisFault); } context.pushNewElement(myElement); } } SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); QName type = context.getTypeFromAttributes(namespace, localName, attributes); if (log.isDebugEnabled()) { log.debug(Messages.getMessage("gotType00", "Deser", "" + type)); } String href = attributes.getValue(soapConstants.getAttrHref()); // System.out.println(soapConstants.getAttrHref() + " = " + href); if (href != null) { Object ref = context.getObjectByRef(href); // System.out.println(ref.getClass().getName()); // System.out.println(ref); if (ref instanceof SOAPBodyElement) // multiref, deref. again { SOAPBodyElement bodyElem = (SOAPBodyElement) ref; href = bodyElem.getAttributeValue(soapConstants.getAttrHref()); ref = context.getObjectByRef(href); // System.out.println(ref.getClass().getName()); // System.out.println(ref); } if (ref instanceof org.apache.axis.Part) { try { DataHandler dataHandler = AttachmentUtils .getActivationDataHandler((org.apache.axis.Part) ref); Object content = dataHandler.getContent(); // System.out.println(content.getClass().getName()); ObjectInputStream objStream = new ObjectInputStream((InputStream) content); try { setValue(objStream.readObject()); } finally { objStream.close(); } } catch (org.apache.axis.AxisFault e) { throw new SAXException(e.getMessage()); } catch (java.io.IOException e) { throw new SAXException(e.getMessage()); } catch (ClassNotFoundException e) { throw new SAXException(e.getMessage()); } } } // if we didn't set a value, call default implementation if (getValue() == null) { super.startElement(namespace, localName, prefix, attributes, context); } // buf.setLength(0); } /** * @see org.apache.axis.message.SOAPHandler#onStartElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes, org.apache.axis.encoding.DeserializationContext) */ public void onStartElement(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { buf.setLength(0); } /** * @see org.apache.axis.encoding.Deserializer#onEndElement(java.lang.String, java.lang.String, * org.apache.axis.encoding.DeserializationContext) */ public void onEndElement(String arg0, String arg1, DeserializationContext arg2) throws SAXException { try { // System.out.println("onEndElement(" + arg0 + "," + arg1 + ")"); // deserialize (if not done already via attachments) if (this.getValue() == null) { // System.out.println("deserializing - no attachments found"); //DEBUG String base64str = buf.toString(); // System.out.println("Base64str: " + base64str); if (base64str.length() > 0) { byte[] bytes = Base64.decode(base64str); setValue(SerializationUtils.deserialize(bytes)); } } } catch (Exception e) { e.printStackTrace(); throw new SAXException(e); } } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // System.out.println("characters(" + new String(ch,start,length) + ")"); buf.append(ch, start, length); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/XmlSerializer_Axis11.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/XmlSerializer_Axis10000644000175000017500000001137311665471034033066 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap.axis11; import java.io.IOException; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.encoding.Serializer; import org.apache.axis.wsdl.fromJava.Types; import org.apache.uima.util.XMLizable; import org.w3c.dom.Element; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * An Axis serializer for any {@link XMLizable} object. *

* This class works only under Axis v1.1. */ public class XmlSerializer_Axis11 implements Serializer { private static final long serialVersionUID = -1528534494294634599L; /** * Serialize an element named name, with the indicated attributes and value. * * @param name * is the element name * @param attributes * are the attributes...serializer is free to add more. * @param value * is the value * @param context * is the SerializationContext */ public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException { if (value instanceof XMLizable) { try { // System.out.println("AxisResourceServiceSerializer::serialize(" + name + ")"); context.startElement(name, attributes); SerializerContentHandler contentHandler = new SerializerContentHandler(context); ((XMLizable) value).toXML(contentHandler); context.endElement(); } catch (SAXException e) { throw new IOException("SAXException: " + e.getMessage()); } } else { throw new IOException("Can't serialize a " + value.getClass().getName() + " with an XmlSerializer."); } } public String getMechanismType() { return Constants.AXIS_SAX; } /** * @see org.apache.axis.encoding.Serializer#writeSchema(java.lang.Class, * org.apache.axis.wsdl.fromJava.Types) */ public Element writeSchema(Class javaType, Types types) throws Exception { return null; } /** * Inner class that implements SAX ContentHandler and writes events through to the Axis * SerializationContext. * * */ static class SerializerContentHandler extends DefaultHandler { private SerializationContext mContext; SerializerContentHandler(SerializationContext aContext) { mContext = aContext; } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { try { // System.out.println("Calling SerializationContext.writeChars"); mContext.writeChars(ch, start, length); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } /** * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, * java.lang.String) */ public void endElement(String uri, String localName, String qName) throws SAXException { try { // System.out.println("Calling SerializationContext.endElement(" + qName + ")"); mContext.endElement(); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } /** * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { try { // System.out.println("Calling SerializationContext.startElement(" + qName + ")"); mContext.startElement(new QName(uri, localName), attributes); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/BinarySerializer_Axis11.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/axis11/BinarySerializer_Ax0000644000175000017500000001250611665471034033134 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap.axis11; import java.io.IOException; import java.io.Serializable; import javax.activation.DataHandler; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.Message; import org.apache.axis.Part; import org.apache.axis.attachments.Attachments; import org.apache.axis.attachments.OctetStream; import org.apache.axis.attachments.OctetStreamDataSource; import org.apache.axis.encoding.Base64; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.encoding.Serializer; import org.apache.axis.soap.SOAPConstants; import org.apache.axis.wsdl.fromJava.Types; import org.apache.uima.internal.util.SerializationUtils; import org.w3c.dom.Element; import org.xml.sax.Attributes; import org.xml.sax.helpers.AttributesImpl; /** * An Axis serializer for {@link Serializable} objects. The serialized bytes are Base-64 encoded for * transport via SOAP. *

* This class works only under Axis v1.1. */ public class BinarySerializer_Axis11 implements Serializer { private static final long serialVersionUID = -1968145589342023832L; /** * * Whether attachments should be used to send binary-serialized data */ private boolean mUseAttachments; public BinarySerializer_Axis11() { this(true); } public BinarySerializer_Axis11(boolean aUseAttachments) { mUseAttachments = aUseAttachments; } /** * Serialize an element named name, with the indicated attributes and value. * * @param name * is the element name * @param attributes * are the attributes...serializer is free to add more. * @param value * is the value * @param context * is the SerializationContext */ public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException { if (value instanceof Serializable) { byte[] bytes = SerializationUtils.serialize((Serializable) value); // Should we use an attachment? Do so if: // (a) attachment support exists and mUseAttachments == true and // (b) if we are the server, the client sent us an attachment // (so we know client wants attachment support as well)] Message msg = context.getCurrentMessage(); Attachments attachments = msg.getAttachmentsImpl(); boolean useAttachments = (attachments != null) && mUseAttachments; if (useAttachments) { useAttachments = !context.getMessageContext().getPastPivot() || context.getMessageContext().getRequestMessage().getAttachments().hasNext(); } // if we have attachment support, do this as an attachment if (useAttachments) { // System.out.println("Creating attachment"); //DEBUG SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); DataHandler dataHandler = new DataHandler(new OctetStreamDataSource("test", new OctetStream(bytes))); Part attachmentPart = attachments.createAttachmentPart(dataHandler); AttributesImpl attrs = new AttributesImpl(); if (attributes != null && 0 < attributes.getLength()) attrs.setAttributes(attributes); // copy the existing ones. int typeIndex = -1; if ((typeIndex = attrs.getIndex(Constants.URI_DEFAULT_SCHEMA_XSI, "type")) != -1) { // Found a xsi:type which should not be there for attachments. attrs.removeAttribute(typeIndex); } attrs.addAttribute("", soapConstants.getAttrHref(), soapConstants.getAttrHref(), "CDATA", attachmentPart.getContentIdRef()); context.startElement(name, attrs); context.endElement(); } else { // no attachment support - Base64 encode // System.out.println("No attachment support"); //DEBUG context.startElement(name, attributes); String base64str = Base64.encode(bytes); context.writeChars(base64str.toCharArray(), 0, base64str.length()); context.endElement(); } } else { throw new IOException(value.getClass().getName() + " is not serializable."); } } public String getMechanismType() { return Constants.AXIS_SAX; } /** * @see org.apache.axis.encoding.Serializer#writeSchema(java.lang.Class, * org.apache.axis.wsdl.fromJava.Types) */ public Element writeSchema(Class javaType, Types types) throws Exception { return null; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/SoapAnalysisEngineServiceAdapter.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/SoapAnalysisEngineServiceA0000644000175000017500000000645511665471034033304 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.net.MalformedURLException; import java.util.Map; import org.apache.uima.Constants; import org.apache.uima.analysis_engine.AnalysisEngineServiceStub; import org.apache.uima.analysis_engine.service.impl.AnalysisEngineServiceAdapter; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.URISpecifier; /** * Reference implementation of {@link AnalysisEngineServiceAdapter} for SOAP. * * */ public class SoapAnalysisEngineServiceAdapter extends AnalysisEngineServiceAdapter { /** * @see org.apache.uima.resource.Resource#initialize(ResourceSpecifier, Map) */ public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams) throws ResourceInitializationException { // aSpecifier must be a URISpecifier using the SOAP protocol if (!(aSpecifier instanceof URISpecifier)) { return false; } URISpecifier uriSpec = (URISpecifier) aSpecifier; if (!uriSpec.getProtocol().equals(Constants.PROTOCOL_SOAP) && !uriSpec.getProtocol().equals(Constants.PROTOCOL_SOAP_WITH_ATTACHMENTS)) { return false; } // resource type must be null or AnalysisEngine if (uriSpec.getResourceType() != null && !uriSpec.getResourceType().equals(URISpecifier.RESOURCE_TYPE_ANALYSIS_ENGINE)) { return false; } try { // create proxy to service AnalysisEngineServiceStub stub = new AxisAnalysisEngineServiceStub(uriSpec.getUri(), uriSpec .getTimeout(), uriSpec.getProtocol().equals(Constants.PROTOCOL_SOAP_WITH_ATTACHMENTS)); setStub(stub); // finish initialization. This requires access to metadata, so must be called // after we create the stub super.initialize(aSpecifier, aAdditionalParams); } catch (MalformedURLException e) { throw new ResourceInitializationException(ResourceInitializationException.MALFORMED_URL, new Object[] { uriSpec.getUri(), uriSpec.getSourceUrlString() }, e); } // Sofa mappings are currently not implemented for remote AEs. Catch this // and report an error. if (getUimaContextAdmin().getSofaMap().size() > 0) { throw new ResourceInitializationException(ResourceInitializationException.SOFA_MAPPING_NOT_SUPPORTED_FOR_REMOTE, new Object[]{getMetaData().getName()}); } return true; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisAnalysisEngineService_impl.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisAnalysisEngineService_0000644000175000017500000000602111665471034033331 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import org.apache.axis.AxisFault; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.service.impl.AnalysisEngineService_impl; import org.apache.uima.analysis_engine.service.impl.ServiceDataCargo; import org.apache.uima.resource.ResourceServiceException; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.util.Level; /** * A class used to deploy a {@link AnalysisEngineService} as an Axis (SOAP) service. */ public class AxisAnalysisEngineService_impl { /** * Class that will actually implement functionality for this service. */ private AnalysisEngineService_impl mServiceImpl; /** * Constructor, responsible for initializing the service. */ public AxisAnalysisEngineService_impl() throws AxisFault { mServiceImpl = (AnalysisEngineService_impl) AxisResourceServiceManager .getServiceImpl(AnalysisEngineService_impl.class); } /** * Gets metadata for this Resource service. * * @param metadata */ public ResourceMetaData getMetaData() throws ResourceServiceException { try { return mServiceImpl.getMetaData(); } catch (ResourceServiceException e) { UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e); throw e; } catch (RuntimeException e) { UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e); throw e; } } /** * Processes an entity. * * @param aData * data to be processed * @param aResultSpec * specifies which results the Analysis Engine should produce * * @return the results of analysis */ public ServiceDataCargo process(ServiceDataCargo aData, ResultSpecification aResultSpec) throws ResourceServiceException { try { return mServiceImpl.process(aData, aResultSpec); } catch (ResourceServiceException e) { UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e); throw e; } catch (RuntimeException e) { UIMAFramework.getLogger().log(Level.SEVERE, e.getMessage(), e); throw e; } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinaryDeserializerFactory.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinaryDeserializerFactory.0000644000175000017500000000431611665471034033315 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.util.Iterator; import java.util.Vector; import org.apache.axis.Constants; import org.apache.axis.Version; import org.apache.axis.encoding.DeserializerFactory; import org.apache.uima.adapter.soap.axis11.BinaryDeserializer_Axis11; /** * An Axis deserializer factory that constructs instances of {@link BinaryDeserializer}. * * */ public class BinaryDeserializerFactory implements DeserializerFactory { private static final long serialVersionUID = 9029965561439924991L; private Vector mechanisms; public javax.xml.rpc.encoding.Deserializer getDeserializerAs(String mechanismType) { // There is a binary incompatibility between Axis v1.1 and // Axis v1.2 in the serializer/deserializer libraries. // So that UIMA can support both Axis versions, we have different // versions of each of our serializer classes. Here we check the // Axis version number and return an insance of the correct class. String ver = Version.getVersion(); if (ver.startsWith("Apache Axis version: 1.1")) { return new BinaryDeserializer_Axis11(); } else { return new BinaryDeserializer(); } } public Iterator getSupportedMechanismTypes() { if (mechanisms == null) { mechanisms = new Vector(); mechanisms.add(Constants.AXIS_SAX); } return mechanisms.iterator(); } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinarySerializer.java0000644000175000017500000001237011665471034032315 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.io.IOException; import java.io.Serializable; import javax.activation.DataHandler; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.Message; import org.apache.axis.Part; import org.apache.axis.attachments.Attachments; import org.apache.axis.attachments.OctetStream; import org.apache.axis.attachments.OctetStreamDataSource; import org.apache.axis.encoding.Base64; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.encoding.Serializer; import org.apache.axis.soap.SOAPConstants; import org.apache.axis.wsdl.fromJava.Types; import org.apache.uima.internal.util.SerializationUtils; import org.w3c.dom.Element; import org.xml.sax.Attributes; import org.xml.sax.helpers.AttributesImpl; /** * An Axis serializer for {@link Serializable} objects. The serialized bytes are Base-64 encoded for * transport via SOAP. * * */ public class BinarySerializer implements Serializer { private static final long serialVersionUID = 939554603678974912L; /** * Whether attachments should be used to send binary-serialized data */ private boolean mUseAttachments; public BinarySerializer() { this(true); } public BinarySerializer(boolean aUseAttachments) { mUseAttachments = aUseAttachments; } /** * Serialize an element named name, with the indicated attributes and value. * * @param name * is the element name * @param attributes * are the attributes...serializer is free to add more. * @param value * is the value * @param context * is the SerializationContext */ public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException { if (value instanceof Serializable) { byte[] bytes = SerializationUtils.serialize((Serializable) value); // Should we use an attachment? Do so if: // (a) attachment support exists and mUseAttachments == true and // (b) if we are the server, the client sent us an attachment // (so we know client wants attachment support as well)] Message msg = context.getCurrentMessage(); Attachments attachments = msg.getAttachmentsImpl(); boolean useAttachments = (attachments != null) && mUseAttachments; if (useAttachments) { useAttachments = !context.getMessageContext().getPastPivot() || context.getMessageContext().getRequestMessage().getAttachments().hasNext(); } // if we have attachment support, do this as an attachment if (useAttachments) { // System.out.println("Creating attachment"); //DEBUG SOAPConstants soapConstants = context.getMessageContext().getSOAPConstants(); DataHandler dataHandler = new DataHandler(new OctetStreamDataSource("test", new OctetStream(bytes))); Part attachmentPart = attachments.createAttachmentPart(dataHandler); AttributesImpl attrs = new AttributesImpl(); if (attributes != null && 0 < attributes.getLength()) attrs.setAttributes(attributes); // copy the existing ones. int typeIndex = -1; if ((typeIndex = attrs.getIndex(Constants.URI_DEFAULT_SCHEMA_XSI, "type")) != -1) { // Found a xsi:type which should not be there for attachments. attrs.removeAttribute(typeIndex); } attrs.addAttribute("", soapConstants.getAttrHref(), soapConstants.getAttrHref(), "CDATA", attachmentPart.getContentIdRef()); context.startElement(name, attrs); context.endElement(); } else { // no attachment support - Base64 encode // System.out.println("No attachment support"); //DEBUG context.startElement(name, attributes); String base64str = Base64.encode(bytes); context.writeChars(base64str.toCharArray(), 0, base64str.length()); context.endElement(); } } else { throw new IOException(value.getClass().getName() + " is not serializable."); } } public String getMechanismType() { return Constants.AXIS_SAX; } /** * @see org.apache.axis.encoding.Serializer#writeSchema(java.lang.Class, * org.apache.axis.wsdl.fromJava.Types) */ public Element writeSchema(Class javaType, Types types) throws Exception { return null; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisResourceServiceStub.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisResourceServiceStub.ja0000644000175000017500000000704011665471034033301 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.net.MalformedURLException; import java.net.URL; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.uima.resource.ResourceServiceException; import org.apache.uima.resource.ResourceServiceStub; import org.apache.uima.resource.metadata.ResourceMetaData; /** * Proxy to a {@link ResourceService} that uses Axis SOAP to communicate with the service. * * */ public abstract class AxisResourceServiceStub implements ResourceServiceStub { /** * The service endpoint URL. */ private URL mEndpoint; /** * Timeout in milliseconds; null to use Axis's default value. */ private Integer mTimeout; /** * Sets the endpoint of the service with which this proxy communicates. * * @param aEndpoint * the service endpoint URI * @param aTimeout * timeout period in milliseconds, or null to use Axis's default value * * @throws MalformedURLException * if aEndpoint is not a valid URL */ public AxisResourceServiceStub(String aEndpoint, Integer aTimeout) throws MalformedURLException { mEndpoint = new URL(aEndpoint); mTimeout = aTimeout; } /** * @see org.apache.uima.resource.service.ResourceService#getMetaData() */ public ResourceMetaData callGetMetaData() throws ResourceServiceException { final QName operationQName = new QName("http://uima.apache.org/resource", "getMetaData"); final QName resourceMetaDataTypeQName = new QName("http://uima.apache.org/resourceSpecifier", "resourceMetaData"); try { Service service = new Service(); Call call = (Call) service.createCall(); call.setTimeout(getTimeout()); call.setTargetEndpointAddress(mEndpoint); call.setOperationName(operationQName); call.registerTypeMapping(ResourceMetaData.class, resourceMetaDataTypeQName, new XmlSerializerFactory(), new XmlDeserializerFactory()); return (ResourceMetaData) call.invoke(new Object[0]); } catch (ServiceException e) { throw new ResourceServiceException(e); } catch (java.rmi.RemoteException e) { throw new ResourceServiceException(e); } } /** * Gets the service endpoint URL. * * @return the service endpoint URL */ public URL getServiceEndpoint() { return mEndpoint; } /** * Gets the timeout period. * * @return the timeout period in milliseconds. Null indicates that Axis's default value will be * used. */ public Integer getTimeout() { return mTimeout; } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/XmlDeserializer.java0000644000175000017500000001160111665471034032136 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.io.File; import org.apache.axis.encoding.DeserializationContext; import org.apache.axis.encoding.DeserializerImpl; import org.apache.axis.message.SOAPHandler; import org.apache.uima.UIMAFramework; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLParser; import org.apache.uima.util.XMLizable; import org.apache.uima.util.impl.SaxDeserializer_impl; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.LocatorImpl; /** * An Axis deserializer for any {@link XMLizable} object. * * */ public class XmlDeserializer extends DeserializerImpl { private static final long serialVersionUID = -2178663551643071383L; private SaxDeserializer_impl mDeser; private int mNesting; public XmlDeserializer() { try { mNesting = 0; mDeser = new SaxDeserializer_impl(UIMAFramework.getXMLParser(), null, null, new XMLParser.ParsingOptions(false)); LocatorImpl loc = new LocatorImpl(); loc.setSystemId(new File(System.getProperty("user.dir")).toURL().toString()); mDeser.setDocumentLocator(loc); mDeser.startDocument(); } catch (Exception e) { e.printStackTrace(); } } /** * This method is invoked when an element start tag is encountered. * * @param namespace * is the namespace of the element * @param localName * is the name of the element * @param prefix * is the element's prefix * @param attributes * are the attributes on the element...used to get the type * @param context * is the DeserializationContext */ public SOAPHandler onStartChild(String namespace, String localName, String prefix, Attributes attributes, DeserializationContext context) throws SAXException { return this; } /** * @see org.apache.axis.message.SOAPHandler#onStartElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes, org.apache.axis.encoding.DeserializationContext) */ public void onStartElement(String arg0, String arg1, String arg2, Attributes arg3, DeserializationContext arg4) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::onStartElement(" + arg0 + "," + arg1 + // "," + arg2 + ")"); // don't process the topmost element - it is a SOAP "multiRef" element and // we don't care about that if (mNesting > 0) { mDeser.startElement(arg0, arg1, arg1, arg3); } mNesting++; } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::characters(" + new // String(ch,start,length) + ")"); mDeser.characters(ch, start, length); } /** * @see org.apache.axis.encoding.Deserializer#onEndElement(java.lang.String, java.lang.String, * org.apache.axis.encoding.DeserializationContext) */ public void onEndElement(String arg0, String arg1, DeserializationContext arg2) throws SAXException { // System.out.println("AxisResourceServiceDeserializer::onEndElement(" + arg0 + "," + arg1); mNesting--; if (mNesting > 0) { mDeser.endElement(arg0, arg1, arg1); } } /** * @see org.apache.axis.encoding.Deserializer#valueComplete() */ public void valueComplete() throws SAXException { // System.out.println("AxisResourceServiceDeserializer::valueComplete"); if (mNesting == 0) { // System.out.println("Building value"); mDeser.endDocument(); try { Object val = mDeser.getObject(); // System.out.println("Value is: " + val); // value = val; setValue(val); } catch (InvalidXMLException e) { e.printStackTrace(); setValue(null); } // call superclass to register the deserialized object super.valueComplete(); } } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/XmlSerializer.java0000644000175000017500000001130311665471034031624 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.io.IOException; import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.encoding.SerializationContext; import org.apache.axis.encoding.Serializer; import org.apache.axis.wsdl.fromJava.Types; import org.apache.uima.util.XMLizable; import org.w3c.dom.Element; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * An Axis serializer for any {@link XMLizable} object. * * */ public class XmlSerializer implements Serializer { private static final long serialVersionUID = 1674801848276745835L; /** * Serialize an element named name, with the indicated attributes and value. * * @param name * is the element name * @param attributes * are the attributes...serializer is free to add more. * @param value * is the value * @param context * is the SerializationContext */ public void serialize(QName name, Attributes attributes, Object value, SerializationContext context) throws IOException { if (value instanceof XMLizable) { try { // System.out.println("AxisResourceServiceSerializer::serialize(" + name + ")"); context.startElement(name, attributes); SerializerContentHandler contentHandler = new SerializerContentHandler(context); ((XMLizable) value).toXML(contentHandler); context.endElement(); } catch (SAXException e) { throw new IOException("SAXException: " + e.getMessage()); } } else { throw new IOException("Can't serialize a " + value.getClass().getName() + " with an XmlSerializer."); } } public String getMechanismType() { return Constants.AXIS_SAX; } /** * @see org.apache.axis.encoding.Serializer#writeSchema(java.lang.Class, * org.apache.axis.wsdl.fromJava.Types) */ public Element writeSchema(Class javaType, Types types) throws Exception { return null; } /** * Inner class that implements SAX ContentHandler and writes events through to the Axis * SerializationContext. * * */ static class SerializerContentHandler extends DefaultHandler { private SerializationContext mContext; SerializerContentHandler(SerializationContext aContext) { mContext = aContext; } /** * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { try { // System.out.println("Calling SerializationContext.writeChars"); mContext.writeChars(ch, start, length); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } /** * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, * java.lang.String) */ public void endElement(String uri, String localName, String qName) throws SAXException { try { // System.out.println("Calling SerializationContext.endElement(" + qName + ")"); mContext.endElement(); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } /** * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { try { // System.out.println("Calling SerializationContext.startElement(" + qName + ")"); mContext.startElement(new QName(uri, localName), attributes); } catch (IOException e) { throw new SAXException("IOException:" + e.getMessage()); } } } } uimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/XmlSerializerFactory.java0000644000175000017500000000430111665471034033154 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.util.Iterator; import java.util.Vector; import javax.xml.rpc.encoding.Serializer; import org.apache.axis.Constants; import org.apache.axis.Version; import org.apache.axis.encoding.SerializerFactory; import org.apache.uima.adapter.soap.axis11.XmlSerializer_Axis11; /** * An AxisSerializer factory that constructs instances of {@link XmlSerializer}. * * */ public class XmlSerializerFactory implements SerializerFactory { private static final long serialVersionUID = -6341240975976459158L; private Vector mechanisms; public Serializer getSerializerAs(String mechanismType) { // There is a binary incompatibility between Axis v1.1 and // Axis v1.2 in the serializer/deserializer libraries. // So that UIMA can support both Axis versions, we have different // versions of each of our serializer classes. Here we check the // Axis version number and return an insance of the correct class. String ver = Version.getVersion(); if (ver.startsWith("Apache Axis version: 1.1")) { return new XmlSerializer_Axis11(); } else { return new XmlSerializer(); } } public Iterator getSupportedMechanismTypes() { if (mechanisms == null) { mechanisms = new Vector(); mechanisms.add(Constants.AXIS_SAX); } return mechanisms.iterator(); } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisAnalysisEngineServiceStub.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/AxisAnalysisEngineServiceS0000644000175000017500000001620011665471034033315 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.MalformedURLException; import javax.activation.DataHandler; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceException; import org.apache.axis.attachments.AttachmentPart; import org.apache.axis.attachments.AttachmentUtils; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.uima.analysis_engine.AnalysisEngineServiceStub; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.service.impl.ServiceDataCargo; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.resource.ResourceServiceException; import org.apache.uima.resource.metadata.ResourceMetaData; /** * Proxy to an {@link AnalysisEngineService} that makes use of Axis SOAP to communicate with the * service. * * */ public class AxisAnalysisEngineServiceStub extends AxisResourceServiceStub implements AnalysisEngineServiceStub { /** * Whether attachments should be used to send binary-serialized data */ private boolean mUseAttachments; /** * Sets the endpoint of the service with which this proxy communicates. * * @param aEndpoint * the service endpoint URI * @param aTimeout * the timeout period in millseconds, or null to use Axis's default value * * @throws MalformedURLException * if aEndpoint is not a valid URL */ public AxisAnalysisEngineServiceStub(String aEndpoint, Integer aTimeout) throws MalformedURLException { this(aEndpoint, aTimeout, false); } /** * Sets the endpoint of the service with which this proxy communicates. * * @param aEndpoint * the service endpoint URI * @param aTimeout * the timeout period in millseconds, or null to use Axis's default value * @param aUseAttachments * whether attachments should be used to send binary-serialized data * * @throws MalformedURLException * if aEndpoint is not a valid URL */ public AxisAnalysisEngineServiceStub(String aEndpoint, Integer aTimeout, boolean aUseAttachments) throws MalformedURLException { super(aEndpoint, aTimeout); mUseAttachments = aUseAttachments; } /** * @see org.apache.uima.reference_impl.analysis_engine.service.AnalysisEngineServiceStub#callProcess(CAS) */ public void callProcess(CAS aCAS) throws ResourceServiceException { final QName operationQName = new QName("http://uima.apache.org/analysis_engine", "process"); final QName resultSpecTypeQName = new QName("http://uima.apache.org/analysis_engine", "resultSpecification"); final QName serviceDataCargoTypeQName = new QName("http://uima.apache.org/analysis_engine", "serviceDataCargo"); try { Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(getServiceEndpoint()); call.setTimeout(getTimeout()); call.setOperationName(operationQName); call.registerTypeMapping(ResultSpecification.class, resultSpecTypeQName, new XmlSerializerFactory(), new XmlDeserializerFactory()); call.registerTypeMapping(ServiceDataCargo.class, serviceDataCargoTypeQName, new BinarySerializerFactory(mUseAttachments), new BinaryDeserializerFactory()); // extract data from CAS to prepare for binary serialization // (do not send process trace) ServiceDataCargo dataCargo = new ServiceDataCargo(aCAS, null); // call service Object result = call.invoke(new Object[] { dataCargo, null }); // System.out.println("Got return value of class: " + result.getClass().getName()); //DEBUG ServiceDataCargo resultCargo = null; // if result was attachment, extract data and deserialize if (result instanceof AttachmentPart) { ObjectInputStream objStream = null; try { DataHandler dataHandler = AttachmentUtils .getActivationDataHandler((AttachmentPart) result); Object content = dataHandler.getContent(); // System.out.println(content.getClass().getName()); objStream = new ObjectInputStream((InputStream) content); resultCargo = (ServiceDataCargo) objStream.readObject(); } catch (IOException e) { throw new ResourceServiceException(e); } catch (ClassNotFoundException e) { throw new ResourceServiceException(e); } finally { if (objStream != null) { try { objStream.close(); } catch (IOException e) { throw new ResourceServiceException(e); } } } } else if (result instanceof ServiceDataCargo) // direct return { resultCargo = (ServiceDataCargo) result; } else { throw new ResourceServiceException( ResourceServiceException.UNEXPECTED_SERVICE_RETURN_VALUE_TYPE, new Object[] { ServiceDataCargo.class.getName(), resultCargo == null ? "null" : resultCargo.getClass().getName() }); } // unmarshal analysis results into the original AnalysisProcessData object // (do not replace CAS type system, as it should not have been changed // by the service) resultCargo.unmarshalCas(aCAS, false); } catch (ServiceException e) { throw new ResourceServiceException(e); } catch (java.rmi.RemoteException e) { throw new ResourceServiceException(e); } catch (CASException e) { throw new ResourceServiceException(e); } } /** * @see org.apache.uima.reference_impl.resource.service.ResourceServiceStub#destroy() */ public void destroy() { // no resources to clean up } public void callBatchProcessComplete() throws ResourceServiceException { // currently not implemented for SOAP services } public void callCollectionProcessComplete() throws ResourceServiceException { // currently not implemented for SOAP services } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinarySerializerFactory.javauimaj-2.4.0/uimaj-adapter-soap/src/main/java/org/apache/uima/adapter/soap/BinarySerializerFactory.ja0000644000175000017500000000457011665471034033321 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.adapter.soap; import java.util.Iterator; import java.util.Vector; import javax.xml.rpc.encoding.Serializer; import org.apache.axis.Constants; import org.apache.axis.Version; import org.apache.axis.encoding.SerializerFactory; import org.apache.uima.adapter.soap.axis11.BinarySerializer_Axis11; /** * An Axis serializer factory that constructs instances of {@link BinarySerializer}. * * */ public class BinarySerializerFactory implements SerializerFactory { private static final long serialVersionUID = 2914831356701203129L; private Vector mechanisms; public BinarySerializerFactory() { this(true); } public BinarySerializerFactory(boolean aUseAttachments) { // TODO: attachments never used? } public Serializer getSerializerAs(String mechanismType) { // There is a binary incompatibility between Axis v1.1 and // Axis v1.2 in the serializer/deserializer libraries. // So that UIMA can support both Axis versions, we have different // versions of each of our serializer classes. Here we check the // Axis version number and return an insance of the correct class. String ver = Version.getVersion(); if (ver.startsWith("Apache Axis version: 1.1")) { return new BinarySerializer_Axis11(); } else { return new BinarySerializer(); } } public Iterator getSupportedMechanismTypes() { if (mechanisms == null) { mechanisms = new Vector(); mechanisms.add(Constants.AXIS_SAX); } return mechanisms.iterator(); } } uimaj-2.4.0/uimaj-adapter-soap/src/test/0000755000175000017500000000000011665471034017756 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/test/resources/0000755000175000017500000000000011665471034021770 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-adapter-soap/src/test/java/0000755000175000017500000000000011665471034020677 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/0000755000175000017500000000000011665472100015313 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/META-INF/0000755000175000017500000000000011665472104016457 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/META-INF/MANIFEST.MF0000644000175000017500000000241711665472104020115 0ustar drazzibdrazzibManifest-Version: 1.0 Implementation-Vendor: The Apache Software Foundation Built-By: schor Bundle-Activator: org.apache.uima.ep_debug.DebugPlugin Ignore-Package: org.eclipse.core.runtime Bundle-Version: 2.4.0 Eclipse-AutoStart: true Build-Jdk: 1.6.0 Implementation-Url: http://uima.apache.org Tool: Bnd-1.15.0 Created-By: Apache Maven Bundle Plugin Import-Package: org.eclipse.jdt.internal.debug.ui,org.eclipse.jface.pr eference,org.eclipse.ui,org.eclipse.ui.plugin,org.osgi.framework;vers ion="[1.3,2)" Bundle-DocURL: http://www.apache.org/ Project-Title: Apache UIMA Implementation-Vendor-Id: org.apache.uima Implementation-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.uima.debug;singleton:=true Require-Bundle: org.eclipse.core.runtime Build-Date: 111130_1918 Export-Package: org.apache.uima.ep_debug Bundle-Description: Adds structure knowledge for commonUIMA data struc tures to the Eclipse Debug displays Bundle-Vendor: The Apache Software Foundation Bnd-LastModified: 1322698914122 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Name: Apache UIMA Eclipse: uimaj-ep-debug Implementation-Title: Apache UIMA Eclipse: uimaj-ep-debug Implementation-Version: 2.4.0 Bundle-ManifestVersion: 2 uimaj-2.4.0/uimaj-ep-debug/pom.xml0000644000175000017500000002102611665471546016646 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-ep-debug 2.4.0 jar Apache UIMA Eclipse: ${project.artifactId} Adds structure knowledge for common UIMA data structures to the Eclipse Debug displays ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-debug scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-debug http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-debug ${project.artifactId} org.apache.uima uimaj-core ${project.parent.version} compile org.eclipse.jdt org.eclipse.jdt.debug.ui 3.2.0 provided org.eclipse.core org.eclipse.core.filesystem 1.0.0 provided org.eclipse.core org.eclipse.core.resources 3.2.1 provided org.eclipse.core org.eclipse.core.runtime 3.2.0 provided org.eclipse.equinox org.eclipse.equinox.common 3.2.0 provided org.eclipse.osgi org.eclipse.osgi 3.2.1 provided org.eclipse.core org.eclipse.core.expressions 3.2.1 provided org.eclipse.core org.eclipse.core.variables 3.1.100 provided org.eclipse.ant org.eclipse.ant.core 3.1.100 provided org.eclipse.equinox org.eclipse.equinox.registry 3.2.1 provided org.eclipse.core org.eclipse.core.jobs 3.2.0 provided org.eclipse.equinox org.eclipse.equinox.preferences 3.2.1 provided org.eclipse.core org.eclipse.core.contenttype 3.2.0 provided org.eclipse.core org.eclipse.core.runtime.compatibility.auth 3.2.0 provided org.apache.uima.debug_${parsedVersion.osgiVersion} org.apache.felix maven-bundle-plugin <_nouses>true org.apache.uima.ep_debug org.apache.uima.ep_debug.DebugPlugin org.apache.uima.debug;singleton:=true org.eclipse.core.runtime !org.eclipse.core.runtime, *, org.eclipse.ui.plugin true uimaj-2.4.0/uimaj-ep-debug/plugin.xml0000644000175000017500000001147511665471052017350 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-ep-debug/marker-file-identifying-eclipse-plugin0000644000175000017500000000000011665471052024654 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/0000755000175000017500000000000011665471050016105 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/0000755000175000017500000000000011665471052017033 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/resources/0000755000175000017500000000000011665471052021045 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/0000755000175000017500000000000011665471052017754 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/org/0000755000175000017500000000000011665471052020543 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/org/apache/0000755000175000017500000000000011665471052021764 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/org/apache/uima/0000755000175000017500000000000011665471052022717 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/org/apache/uima/ep_debug/0000755000175000017500000000000011665471052024471 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-debug/src/main/java/org/apache/uima/ep_debug/DebugPlugin.java0000644000175000017500000000654011665471052027546 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.ep_debug; import org.eclipse.core.runtime.Plugin; import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants; import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; import org.eclipse.ui.IStartup; import org.osgi.framework.BundleContext; /** * The main plugin class to be used in the desktop. */ public class DebugPlugin extends Plugin implements IStartup { public static final String PREF_ALREADY_SET_PREF_SHOW_DETAILS = "org.apache.uima.ep_debug.already_set_pref_show_details"; public static final String ALREADY_SET_PREF_SHOW_DETAILS = "already_set_pref_show_details"; // The shared instance. private static DebugPlugin plugin; /** * The constructor. */ public DebugPlugin() { plugin = this; } /** * This method is called upon plug-in activation */ public void start(BundleContext context) throws Exception { super.start(context); // Intent of next code // For users installing this plugin for the first time, set the pref-show-details preference, // but only once (per fresh workspace) - to allow it to be set to the value which makes // debugging // display work, initially, but allowing the user to set it to something else without having // this // be overridden every time the pluging starts. String doneOnce = JDIDebugUIPlugin.getDefault().getPreferenceStore().getString( PREF_ALREADY_SET_PREF_SHOW_DETAILS); if (ALREADY_SET_PREF_SHOW_DETAILS.equals(doneOnce)) return; JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue(PREF_ALREADY_SET_PREF_SHOW_DETAILS, ALREADY_SET_PREF_SHOW_DETAILS); String preference = JDIDebugUIPlugin.getDefault().getPreferenceStore().getString( IJDIPreferencesConstants.PREF_SHOW_DETAILS); if (IJDIPreferencesConstants.INLINE_ALL.equals(preference)) return; JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue( IJDIPreferencesConstants.PREF_SHOW_DETAILS, IJDIPreferencesConstants.INLINE_ALL); } /** * This method is called when the plug-in is stopped */ public void stop(BundleContext context) throws Exception { super.stop(context); plugin = null; } /** * Returns the shared instance. */ public static DebugPlugin getDefault() { return plugin; } // this method is required by the Startup extension, which, in turn, is required // to get the plugin started (no other event gets it started) public void earlyStartup() { } } uimaj-2.4.0/uimaj-ep-cas-editor-ide/0000755000175000017500000000000011665472204017023 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/META-INF/0000755000175000017500000000000011665472204020163 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/META-INF/MANIFEST.MF0000644000175000017500000000753411665472204021626 0ustar drazzibdrazzibManifest-Version: 1.0 Implementation-Vendor: The Apache Software Foundation Bundle-RequiredExecutionEnvironment: J2SE-1.5 Built-By: schor Bundle-Activator: org.apache.uima.caseditor.ide.CasEditorIdePlugin Ignore-Package: org.eclipse.ui.model,org.eclipse.ui.dialogs,org.eclips e.ui,org.eclipse.core.runtime,org.eclipse.ui.part Bundle-Version: 2.4.0 Build-Jdk: 1.6.0 Implementation-Url: http://uima.apache.org Tool: Bnd-1.15.0 Created-By: Apache Maven Bundle Plugin Import-Package: javax.swing.text,javax.swing.text.rtf,org.apache.uima, org.apache.uima.cas,org.apache.uima.cas.impl,org.apache.uima.casedito r,org.apache.uima.caseditor.core,org.apache.uima.caseditor.core.model ,org.apache.uima.caseditor.core.model.dotcorpus,org.apache.uima.cased itor.editor,org.apache.uima.caseditor.editor.editview,org.apache.uima .caseditor.editor.fsview,org.apache.uima.caseditor.editor.styleview,o rg.apache.uima.internal.util,org.apache.uima.resource,org.apache.uima .resource.metadata,org.apache.uima.util,org.eclipse.core.resources,or g.eclipse.core.runtime.preferences,org.eclipse.jface.dialogs,org.ecli pse.jface.layout,org.eclipse.jface.operation,org.eclipse.jface.prefer ence,org.eclipse.jface.util,org.eclipse.jface.viewers,org.eclipse.jfa ce.wizard,org.eclipse.swt.events,org.eclipse.swt.graphics,org.eclipse .swt.layout,org.eclipse.swt.widgets,org.eclipse.ui.plugin,org.eclipse .ui.views.navigator,org.eclipse.ui.wizards.datatransfer,org.osgi.fram ework;version="[1.4,2)",org.xml.sax Bundle-DocURL: http://www.apache.org/ Project-Title: Apache UIMA Implementation-Vendor-Id: org.apache.uima Implementation-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.uima.caseditor.ide;singleton:=true Require-Bundle: org.eclipse.jface.text,org.eclipse.text,org.eclipse.ui .editors,org.eclipse.ui.workbench.texteditor,org.eclipse.ui.ide,org.e clipse.ui,org.eclipse.ui.workbench,org.eclipse.core.runtime,org.eclip se.core.resources,org.junit4;bundle-version="4.5.0";resolution:=optio nal Build-Date: 111130_1918 Export-Package: org.apache.uima.caseditor.ide.wizards;uses:="org.eclip se.core.resources,org.eclipse.jface.viewers,org.apache.uima.internal. util,org.eclipse.ui.wizards.datatransfer,org.apache.uima.cas,org.apac he.uima.cas.impl,org.xml.sax,org.apache.uima.caseditor.editor,javax.s wing.text.rtf,org.apache.uima.util,javax.swing.text,org.apache.uima.c aseditor.core,org.apache.uima.resource,org.apache.uima,org.apache.uim a.resource.metadata,org.eclipse.swt.widgets,org.eclipse.jface.wizard, org.apache.uima.caseditor.ide,org.eclipse.jface.operation,org.apache. uima.caseditor,org.eclipse.jface.dialogs,org.eclipse.jface.preference ,org.eclipse.swt.events,org.eclipse.jface.layout,org.eclipse.swt.layo ut,org.eclipse.swt.graphics",org.apache.uima.caseditor.ide.searchstra tegy;uses:="org.eclipse.core.resources,org.apache.uima.caseditor",org .apache.uima.caseditor.ide;uses:="org.osgi.framework,org.apache.uima. caseditor,org.eclipse.core.resources,org.apache.uima.caseditor.core.m odel.dotcorpus,org.eclipse.ui.plugin,org.eclipse.jface.preference,org .eclipse.core.runtime.preferences,org.eclipse.swt.widgets,org.eclipse .swt.events,org.apache.uima.caseditor.editor,org.eclipse.jface.util,o rg.apache.uima.cas,org.apache.uima.caseditor.core.model,org.eclipse.s wt.layout,org.apache.uima.caseditor.ide.searchstrategy,org.eclipse.jf ace.viewers,org.eclipse.ui.views.navigator" Bundle-Description: Allows editing the contents of a saved CAS Bundle-ActivationPolicy: lazy Bundle-Vendor: The Apache Software Foundation Bnd-LastModified: 1322698979486 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Name: Apache UIMA Eclipse: uimaj-ep-cas-editor-ide Implementation-Title: Apache UIMA Eclipse: uimaj-ep-cas-editor-ide Implementation-Version: 2.4.0 Bundle-ManifestVersion: 2 uimaj-2.4.0/uimaj-ep-cas-editor-ide/pom.xml0000644000175000017500000002116011665471546020350 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-ep-cas-editor-ide 2.4.0 jar Apache UIMA Eclipse: ${project.artifactId} Allows editing the contents of a saved CAS ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-cas-editor-ide scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-cas-editor-ide http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-cas-editor-ide ${project.artifactId} junit junit 4.5 test org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-tools ${project.parent.version} compile org.apache.uima uimaj-ep-cas-editor ${project.parent.version} compile org.eclipse.core runtime [3.3.0.0,4.0.0) provided org.eclipse.core resources [3.3.0.0,4.0.0) provided org.eclipse ui [3.3.0.0,4.0.0) provided org.eclipse.swt org.eclipse.swt.win32.win32.x86 [3.2.0.0,4.0.0) provided org.eclipse.ui ide [3.3.0.0,4.0.0) provided org.eclipse.ui views [3.2.0.0,4.0.0) provided org.eclipse.ui.workbench texteditor [3.3.0.0,4.0.0) provided org.eclipse.jface text [3.3.0.0,4.0.0) provided org.apache.uima.caseditor.ide_${parsedVersion.osgiVersion} . plugin.xml icons/**/*.* src\main\resources org.apache.rat apache-rat-plugin default-cli release.properties src/test/resources/ManualTests/* marker-file-identifying-* org.apache.felix maven-bundle-plugin uima-bundle org.apache.uima.caseditor.ide;singleton:=true org.apache.uima.caseditor.ide.CasEditorIdePlugin J2SE-1.5 lazy org.apache.uima.caseditor.ide.* org.eclipse.jface.text, org.eclipse.text, org.eclipse.ui.editors, org.eclipse.ui.workbench.texteditor, org.eclipse.ui.ide, org.eclipse.ui, org.eclipse.ui.workbench, org.eclipse.core.runtime, org.eclipse.core.resources, org.junit4;bundle-version="4.5.0";resolution:=optional !org.eclipse.jface.text, !org.eclipse.jface.text.link, !org.eclipse.jface.text.source, !org.eclipse.jface.text.templates, !org.eclipse.ui.texteditor, !org.eclipse.ui, !org.eclipse.ui.actions, !org.eclipse.ui.dialogs, !org.eclipse.ui.model, !org.eclipse.ui.part, !org.eclipse.core.runtime, org.apache.uima.caseditor.editor.editview, org.apache.uima.caseditor.editor.fsview, org.apache.uima.caseditor.editor.styleview, * uimaj-2.4.0/uimaj-ep-cas-editor-ide/plugin.xml0000644000175000017500000001013611665471266021053 0ustar drazzibdrazzib Create a Document uimaj-2.4.0/uimaj-ep-cas-editor-ide/marker-file-identifying-eclipse-plugin0000644000175000017500000000000011665471266026366 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/icons/0000755000175000017500000000000011665471266020145 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/icons/svgicons/0000755000175000017500000000000011665471266022000 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/icons/svgicons/corpus.png0000644000175000017500000000114711665471266024024 0ustar drazzibdrazzibPNG  IHDRVΎWgAMA abKGD pHYs  #utIME"lIDATxԽkA̺rIM4^ɟ`h2RKpǁv:l6V*xw̄hٝV> DI@;p5`5@&F%\ hE5?uOo($λT☞1Z*Z.֤ZRLzxT☩jJOFDR"@o ,@\|Y&R!Xp1lzeKB3ȊS re9`3NZCa:Zg!+r|& fm9=QcC _P/^#I|aY\Yv:͹ ㇰC.D$^S@5T&ap8 \1, %p8*,'/F%M6t@mWbGȏ2 \ ~_**{? IENDB`uimaj-2.4.0/uimaj-ep-cas-editor-ide/icons/svgicons/document.png0000644000175000017500000000053211665471266024324 0ustar drazzibdrazzibPNG  IHDRasBIT|dIDATxSK@-53˄\“$w F0p#d*;w$.PV7a^~ ?!(x7axβ수$B2MSql&,n׺@mN&`Yu5(,8N|0 !\>O3ru Vu=eV\*@pK* <[# !" ]AYf 52  ,~4Mo|+8BUU$IwI{LhMIENDB`uimaj-2.4.0/uimaj-ep-cas-editor-ide/icons/svgicons/fsview.png0000644000175000017500000000043011665471266024006 0ustar drazzibdrazzibPNG  IHDRRgAMA a!PLTE@@@@tRNS@6:bKGDH pHYs  d_tIME 7z `IDATxe Nb#0e/LkABoq8mI[eV#_ߴ;$ۗϬcyo-reOn+Lvٯ]251%4R(L&\.p ܩM,-<ttugQ7²,('m]He Bvaލ擧鳲87ր$w(@FKQP\Z%Ub5"(e-pY C= er8|Ԇ0&DgeKg# CYA*FDGBj;]c."qw)zZ X1INOP# IZ05 dB+ Ţ3#_FIQ!d[`TqqkϐaMTq4壕`]RX \,;L02טuX s9x'G5;g*0Ӥ1j^^.f(,A_AIod[4W XH8%E0eFjM{ j{iU#۳_aio\_Gk#"G)ʗ)ĴzF0 *(aAeFM--k#-ehOw1&#mfectw ވZ=}fIENDB`uimaj-2.4.0/uimaj-ep-cas-editor-ide/schema/0000755000175000017500000000000011665471264020270 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/schema/org.apache.uima.caseditor.ide.searchstrategy.exsd0000644000175000017500000001070411665471264031663 0ustar drazzibdrazzib the qualified name of the document provider class the unique id of this provider Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/0000755000175000017500000000000011665471264017617 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/0000755000175000017500000000000011665471266020545 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/0000755000175000017500000000000011665471266022557 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/0000755000175000017500000000000011665471266023346 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/0000755000175000017500000000000011665471266024567 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/uima/0000755000175000017500000000000011665471266025522 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/uima/caseditor/0000755000175000017500000000000011665471266027477 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/uima/caseditor/ide/0000755000175000017500000000000011665471266030240 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/uima/caseditor/ide/wizards/0000755000175000017500000000000011665471266031723 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/resources/org/apache/uima/caseditor/ide/wizards/ts.xml0000644000175000017500000000205511665471266033075 0ustar drazzibdrazzib DummyTypeSystem 1.0 uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/0000755000175000017500000000000011665471264021464 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/0000755000175000017500000000000011665471264022253 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/0000755000175000017500000000000011665471264023474 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/0000755000175000017500000000000011665471264024427 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/0000755000175000017500000000000011665471264026404 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/0000755000175000017500000000000011665471264027145 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferenceInitializer.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferen0000644000175000017500000000313611665471264033061 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import java.nio.charset.Charset; import org.apache.uima.cas.CAS; import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; import org.eclipse.jface.preference.IPreferenceStore; public class CasEditorIdePreferenceInitializer extends AbstractPreferenceInitializer { public void initializeDefaultPreferences() { IPreferenceStore store = CasEditorIdePlugin.getDefault().getPreferenceStore(); store.setDefault(CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_LANG, CAS.DEFAULT_LANGUAGE_NAME); store.setDefault(CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_ENCODINGS, Charset.defaultCharset().displayName()); store.setDefault(CasEditorIdePreferenceConstants.CAS_EDITOR_REMEMBER_TYPESYSTEM, true); } } uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/NlpProject.java0000644000175000017500000000246111665471264032073 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.runtime.CoreException; public final class NlpProject implements IProjectNature { private IProject project; public void configure() throws CoreException { } public void deconfigure() throws CoreException { } public IProject getProject() { return project; } public void setProject(IProject project) { this.project = project; } }././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferencePage.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferen0000644000175000017500000000361411665471264033062 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; /** * Preference page to manage preferences for the ide plugin. */ public class CasEditorIdePreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { private BooleanFieldEditor mEditorRememberTypesystem; public CasEditorIdePreferencePage() { setPreferenceStore(CasEditorIdePlugin.getDefault().getPreferenceStore()); setDescription("Cas Editor Ide Preferences."); } @Override protected void createFieldEditors() { // should the editor use the last selected type system to open the cas? mEditorRememberTypesystem = new BooleanFieldEditor(CasEditorIdePreferenceConstants.CAS_EDITOR_REMEMBER_TYPESYSTEM, "Use the previously selected type system to open a CAS", getFieldEditorParent()); addField(mEditorRememberTypesystem); } public void init(IWorkbench workbench) { } } uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/searchstrategy/0000755000175000017500000000000011665471264032175 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/searchstrategy/TypeSystemSearchStrategyFactory.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/searchstrategy/TypeS0000644000175000017500000000532711665471264033173 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.searchstrategy; import java.util.Map; import java.util.TreeMap; import org.apache.uima.caseditor.CasEditorPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.Platform; public class TypeSystemSearchStrategyFactory { private static final String SEARCH_STRATEGY_EXTENSION = "org.apache.uima.caseditor.ide.searchstrategy"; private static TypeSystemSearchStrategyFactory instance; private Map searchStrategies = new TreeMap(); private TypeSystemSearchStrategyFactory() { IConfigurationElement[] config = Platform.getExtensionRegistry().getConfigurationElementsFor( SEARCH_STRATEGY_EXTENSION); for (IConfigurationElement element : config) { if ("searchStrategy".equals(element.getName())) { // extract id element String id = element.getAttribute("id"); String priority = element.getAttribute("priority"); Object searchStrategyObject; try { searchStrategyObject = element.createExecutableExtension("class"); } catch (CoreException e) { CasEditorPlugin.log("Failed to load search strategy with id: " + id, e); searchStrategyObject = null; } if (searchStrategyObject instanceof ITypeSystemSearchStrategy) { searchStrategies.put(Integer.parseInt(priority), (ITypeSystemSearchStrategy) searchStrategyObject); } } } } public static TypeSystemSearchStrategyFactory instance() { if (instance == null) { instance = new TypeSystemSearchStrategyFactory(); } return instance; } public Map getSearchStrategies() { return searchStrategies; } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/searchstrategy/ITypeSystemSearchStrategy.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/searchstrategy/IType0000644000175000017500000000177611665471264033165 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.searchstrategy; import org.eclipse.core.resources.IFile; public interface ITypeSystemSearchStrategy { IFile findTypeSystem(IFile casFile); } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/TypeSystemLocationPropertyPage.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/TypeSystemLocationPr0000644000175000017500000001542411665471264033217 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.apache.uima.caseditor.CasEditorPlugin; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * Type System Property Page to set the default type system location * of a project. */ public class TypeSystemLocationPropertyPage extends PropertyPage { public final static String TYPE_SYSTEM_PROPERTY = "UimaCasEditorTypeSystemPath"; private static final String DEFAULT_TYPE_SYSTEM_PATH = "TypeSystem.xml"; private Text typeSystemText; IProject getProject() { return (IProject) getElement().getAdapter(IProject.class); } String getDefaultTypeSystemLocation() { IProject project = getProject(); if (project != null) return project.getFile(DEFAULT_TYPE_SYSTEM_PATH).getFullPath().toString(); else return ""; } protected Control createContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 2; composite.setLayout(layout); GridData data = new GridData(); data.verticalAlignment = GridData.FILL; data.horizontalAlignment = GridData.FILL; composite.setLayoutData(data); Label instructions = new Label(composite, SWT.WRAP); instructions.setText("Select the default type system which is used to open CASes:"); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; gd.grabExcessHorizontalSpace = true; instructions.setLayoutData(gd); typeSystemText = new Text(composite,SWT.BORDER); gd = new GridData(GridData.FILL_HORIZONTAL); typeSystemText.setLayoutData(gd); typeSystemText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { updateApplyButton(); } }); try { String typeSystemPath = ((IResource) getElement()).getPersistentProperty(new QualifiedName("", TYPE_SYSTEM_PROPERTY)); typeSystemText.setText((typeSystemPath != null) ? typeSystemPath : getDefaultTypeSystemLocation()); } catch (CoreException e) { typeSystemText.setText(DEFAULT_TYPE_SYSTEM_PATH); } Button browseButton = new Button(composite, SWT.PUSH); browseButton.setText("Browse ..."); browseButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), new WorkbenchLabelProvider(), new WorkbenchContentProvider()); dialog.setTitle("Select descriptor"); dialog.setMessage("Select descriptor"); dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); dialog.setInitialSelection(ResourcesPlugin.getWorkspace().getRoot(). findMember(typeSystemText.getText())); if (dialog.open() == IDialogConstants.OK_ID) { IResource resource = (IResource) dialog.getFirstResult(); if (resource != null) { String fileLoc = resource.getFullPath().toString(); typeSystemText.setText(fileLoc); } } } }); return composite; } protected void performDefaults() { typeSystemText.setText(getDefaultTypeSystemLocation()); } public boolean performOk() { // have check, so performOk is only done when ts file is a valid file string // store the value in the owner text field try { ((IResource) getElement()).setPersistentProperty( new QualifiedName("", TYPE_SYSTEM_PROPERTY), typeSystemText.getText()); } catch (CoreException e) { return false; } return true; } /** * Retrieves the type system or null if its not set. * * @param project * @return */ public static IFile getTypeSystemLocation(IProject project) { IFile defaultTypeSystemFile = project.getFile(DEFAULT_TYPE_SYSTEM_PATH); String typeSystemLocation; try { typeSystemLocation = project.getPersistentProperty(new QualifiedName("", TYPE_SYSTEM_PROPERTY)); } catch (CoreException e) { typeSystemLocation = null; } IFile typeSystemFile = null; // Type system location is null when it was never set it anyway, if (typeSystemLocation != null) { if (typeSystemLocation.length() > 0) { IResource potentialTypeSystemResource = ResourcesPlugin.getWorkspace().getRoot().findMember(typeSystemLocation); if (potentialTypeSystemResource instanceof IFile) typeSystemFile = (IFile) potentialTypeSystemResource; } // Empty string means user does not want a type system to be set else { return null; } } if (typeSystemFile == null) { typeSystemFile = defaultTypeSystemFile; } return typeSystemFile; } public static void setTypeSystemLocation(IProject project, String typeSystemLocation) { try { project.setPersistentProperty(new QualifiedName("", TYPE_SYSTEM_PROPERTY), typeSystemLocation); } catch (CoreException e) { CasEditorPlugin.log(e); } } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorPerspectiveFactory.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorPerspective0000644000175000017500000000641411665471264033164 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.apache.uima.caseditor.editor.editview.EditView; import org.apache.uima.caseditor.editor.fsview.FeatureStructureBrowserView; import org.apache.uima.caseditor.editor.styleview.AnnotationStyleView; import org.eclipse.ui.IFolderLayout; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; /** * This PerspectiveFactory generates the initial layout * for the NLP perspective. */ public class CasEditorPerspectiveFactory implements IPerspectiveFactory { /** * ID of the perspective factory. Use this ID for example in the plugin.xml * file. * * Note: This id should also be changed, but that will break existing * perspectives, and might confuse users. */ public static String ID = "org.apache.uima.caseditor.perspective.NLP"; /** * Define the initial layout of the Cas Editor Perspective */ public void createInitialLayout(IPageLayout layout) { defineActions(layout); defineLayout(layout); } private void defineActions(IPageLayout layout) { // add "show views" layout.addShowViewShortcut("org.eclipse.ui.navigator.ProjectExplorer"); layout.addShowViewShortcut(IPageLayout.ID_OUTLINE); layout.addShowViewShortcut(AnnotationStyleView.ID); // add "open perspective" layout.addPerspectiveShortcut(CasEditorPerspectiveFactory.ID); } private void defineLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); // left views IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.19f, editorArea); left.addView("org.eclipse.ui.navigator.ProjectExplorer"); // right views IFolderLayout right = layout.createFolder("right", IPageLayout.RIGHT, 0.70f, editorArea); right.addView(IPageLayout.ID_OUTLINE); right.addView(FeatureStructureBrowserView.ID); IFolderLayout rightBottomCorner = layout.createFolder("rightBottomCorner", IPageLayout.BOTTOM, 0.75f, "right"); rightBottomCorner.addView(AnnotationStyleView.ID); // bottom views IFolderLayout rightBottom = layout.createFolder("rightBottom", IPageLayout.BOTTOM, 0.75f, editorArea); rightBottom.addView(EditView.ID); IFolderLayout leftBottom = layout.createFolder("leftBottom", IPageLayout.RIGHT, 0.5f, EditView.ID); leftBottom.addView(EditView.ID_2); } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/WorkspaceResourceDialog.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/WorkspaceResourceDia0000644000175000017500000000727011665471264033162 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.ui.views.navigator.ResourceSorter; /** * * */ public class WorkspaceResourceDialog { public static IResource getWorkspaceResourceElement (Shell shell, IResource root, String dialogTitle, String dialogMessage) { IResource resource = null; ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider()); dialog.setTitle(dialogTitle); dialog.setMessage(dialogMessage); dialog.setInput(root); dialog.setSorter(new ResourceSorter(ResourceSorter.NAME)); int buttonId = dialog.open(); if (buttonId == IDialogConstants.OK_ID) { resource = (IResource) dialog.getFirstResult(); if (!resource.isAccessible()) { return null; } if (resource instanceof IContainer) { } String arg = resource.getFullPath().toString(); // String fileLoc = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", arg); //$NON-NLS-1$ // Trace.trace("resource.getFullPath().toString():" + arg); // Trace.trace(fileLoc); // selectedElement = resource.getLocation().toOSString(); } return resource; } public static IResource getWorkspaceResourceElement (Shell shell) { IResource resource = null; ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider()); dialog.setTitle("Select Cpe descriptor"); dialog.setMessage("Select Cpe Xml descriptor file"); dialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); dialog.setSorter(new ResourceSorter(ResourceSorter.NAME)); int buttonId = dialog.open(); if (buttonId == IDialogConstants.OK_ID) { resource = (IResource) dialog.getFirstResult(); if (!resource.isAccessible()) { return null; } String arg = resource.getFullPath().toString(); // String fileLoc = VariablesPlugin.getDefault().getStringVariableManager().generateVariableExpression("workspace_loc", arg); //$NON-NLS-1$ // Trace.trace(fileLoc); // selectedElement = resource.getLocation().toOSString(); } return resource; } }././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorPreferencePage.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorPreferenceP0000644000175000017500000000273511665471264033073 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; public class CasEditorPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { public CasEditorPreferencePage() { // TODO uncomment, if you really want to use this page // setPreferenceStore(CasEditorPlugin.getDefault().getPreferenceStore()); setDescription("General Cas Editor Preferences."); } public void init(IWorkbench arg0) { } @Override protected void createFieldEditors() { } } uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/0000755000175000017500000000000011665471264030630 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ImportDocumentWizardPage.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ImportDocume0000644000175000017500000004054311665471264033170 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.wizards; import java.io.File; import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.uima.caseditor.CasEditorPlugin; import org.apache.uima.caseditor.editor.DocumentFormat; import org.apache.uima.caseditor.ide.CasEditorIdePlugin; import org.apache.uima.caseditor.ide.CasEditorIdePreferenceConstants; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.DecoratingLabelProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.dialogs.ElementTreeSelectionDialog; import org.eclipse.ui.dialogs.ISelectionStatusValidator; import org.eclipse.ui.model.BaseWorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; /** * The main page of the ImportDocumentWizard. */ final class ImportDocumentWizardPage extends WizardPage { private static final Set defaultEncodings; static { Set encodings = new HashSet(); encodings.add("US-ASCII"); encodings.add("ISO-8859-1"); encodings.add("UTF-8"); encodings.add("UTF-16BE"); encodings.add("UTF-16LE"); encodings.add("UTF-16"); encodings.add(Charset.defaultCharset().displayName()); defaultEncodings = Collections.unmodifiableSet(encodings); } private IPath importDestinationPath; private String importEncoding; private String language; private DocumentFormat documentFormat; private TableViewer fileTable; private IContainer containerElement; protected ImportDocumentWizardPage(String pageName, IStructuredSelection currentResourceSelection) { super(pageName); setTitle("Import Text Files"); // TODO: Pre select the selected foler .. // if (!currentResourceSelection.isEmpty()) { // if (currentResourceSelection.getFirstElement() instanceof CorpusElement) { // containerElement = (IContainer) currentResourceSelection.getFirstElement(); // importDestinationPath = containerElement.getFullPath(); // } // } setPageComplete(false); } private void updatePageState() { boolean isEncodingSupported = false; try { isEncodingSupported = Charset.isSupported(importEncoding); } catch (IllegalCharsetNameException e) { // Name of the Charset is incorrect, that means // it cannot exist } String errorMessage = null; if (!isEncodingSupported) errorMessage ="Invalid text import encoding!"; // error message is always displayed instead of status message // if both are set setErrorMessage(errorMessage); setMessage("Please select the documents to import."); setPageComplete(importDestinationPath != null && fileTable.getTable().getItemCount() > 0 && isEncodingSupported); } public void createControl(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(3, false)); fileTable = new TableViewer(composite); GridDataFactory.fillDefaults().grab(true, true).span(2, 4).applyTo(fileTable.getControl()); Button addButton = new Button(composite, SWT.PUSH); addButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING)); addButton.setText("Add"); addButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { // never called } /** * Opens a file dialog and adds the selected files to the file table viewer. */ public void widgetSelected(SelectionEvent e) { // open a file dialog FileDialog fd = new FileDialog(Display.getCurrent().getActiveShell(), SWT.MULTI); fd.setText("Choose text files"); fd.setFilterExtensions(new String[] { "*.txt;*.rtf", "*.*"}); fd.setFilterNames(new String[] {"Text Files", "All Files (*)"}); if (fd.open() != null) { for (String fileItem : fd.getFileNames()) { fileTable.add(new File(fd.getFilterPath() + File.separator + fileItem)); } updatePageState(); } } }); Button removeButton = new Button(composite, SWT.PUSH); removeButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING)); removeButton.setText("Remove"); removeButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { // never called } /** * Removes selected elements from the file table viewer. */ @SuppressWarnings("rawtypes") public void widgetSelected(SelectionEvent e) { IStructuredSelection selection = (IStructuredSelection) fileTable.getSelection(); Iterator seletionIterator = selection.iterator(); Object selectedElements[] = new Object[selection.size()]; for (int i = 0; i < selection.size(); i++) { selectedElements[i] = seletionIterator.next(); } fileTable.remove(selectedElements); updatePageState(); } }); Button selectAllButton = new Button(composite, SWT.PUSH); selectAllButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING)); selectAllButton.setText("Select All"); selectAllButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { // never called } /** * Selects all elements in the file table viewer. */ public void widgetSelected(SelectionEvent e) { fileTable.getTable().selectAll(); fileTable.setSelection(fileTable.getSelection()); } }); Button deselectAllButton = new Button(composite, SWT.PUSH); deselectAllButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING)); deselectAllButton.setText("Deselect All"); deselectAllButton.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { // never called } /** * Deselects all elements in the file table viewer. */ public void widgetSelected(SelectionEvent e) { fileTable.getTable().deselectAll(); fileTable.setSelection(fileTable.getSelection()); } }); // Into Corpus folder Label intoFolderLabel = new Label(composite, SWT.NONE); intoFolderLabel.setText("Into folder:"); final Text corpusText = new Text(composite, SWT.READ_ONLY | SWT.BORDER); corpusText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); if (importDestinationPath != null) { corpusText.setText(importDestinationPath.toString()); } Button browseForFolder = new Button(composite, SWT.NONE); browseForFolder.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_BEGINNING)); browseForFolder.setText("Browse"); browseForFolder.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { // never called } /** * Opens the corpus folder chooser dialog and shows the chosen dialog in the corpus folder * text field. */ public void widgetSelected(SelectionEvent e) { final ElementTreeSelectionDialog folderSelectionDialog = new ElementTreeSelectionDialog( getShell(), new DecoratingLabelProvider(new WorkbenchLabelProvider(), PlatformUI .getWorkbench().getDecoratorManager().getLabelDecorator()), new BaseWorkbenchContentProvider()); folderSelectionDialog.addFilter(new ContainerElementFilter()); if (containerElement != null) { folderSelectionDialog.setInitialSelection(containerElement); } folderSelectionDialog.setInput(ResourcesPlugin.getWorkspace().getRoot()); folderSelectionDialog.setTitle("Choose folder"); folderSelectionDialog.setMessage("Please choose a folder."); folderSelectionDialog.setValidator(new ISelectionStatusValidator() { public IStatus validate(Object[] selection) { if (selection.length == 1) { Object selectedElement = selection[0]; if (selectedElement instanceof IAdaptable) { Object resourceElement = ((IAdaptable) selectedElement).getAdapter(IResource.class); if (resourceElement != null) selectedElement = resourceElement; } if (selectedElement instanceof IContainer) return new Status(IStatus.OK, CasEditorPlugin.ID, 0, "", null); } return new Status(IStatus.ERROR, CasEditorPlugin.ID, 0, "Please select a folder!", null); } }); folderSelectionDialog.open(); Object[] results = folderSelectionDialog.getResult(); if (results != null && results.length > 0) { // validator makes sure that an IContainer or an IAdaptable // element which can provide an IContainer is selected if (results[0] instanceof IContainer) { containerElement = (IContainer) results[0]; } else if (results[0] instanceof IAdaptable) { IAdaptable adaptableElement = (IAdaptable) results[0]; containerElement = (IContainer) adaptableElement.getAdapter(IResource.class); } else { throw new IllegalStateException("Unexpected selection!"); } importDestinationPath = containerElement.getFullPath(); corpusText.setText(importDestinationPath.toString()); updatePageState(); } } }); Group importOptions = new Group(composite, SWT.NONE); importOptions.setText("Options"); GridLayout importOptionsGridLayout = new GridLayout(); importOptionsGridLayout.numColumns = 2; importOptions.setLayout(importOptionsGridLayout); GridData importOptionsGridData = new GridData(GridData.FILL, GridData.CENTER, true, false); importOptionsGridData.horizontalSpan = 3; importOptions.setLayoutData(importOptionsGridData); Label languageLabel = new Label(importOptions, SWT.NONE); languageLabel.setText("Language:"); final IPreferenceStore store = CasEditorIdePlugin.getDefault().getPreferenceStore(); final Text languageText = new Text(importOptions, SWT.BORDER); languageText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); language = store.getString( CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_LANG); languageText.setText(language); languageText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { language = languageText.getText(); store.setValue(CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_LANG, language); } }); // Text file encoding Label encodingLabel = new Label(importOptions, SWT.NONE); encodingLabel.setText("Text Encoding:"); // combo box ... final Combo encodingCombo = new Combo(importOptions, SWT.NONE); encodingCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Set charsets = new HashSet(); charsets.addAll(defaultEncodings); String lastUsedEncodingsString = store.getString(CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_ENCODINGS); String lastUsedEncodings[] = lastUsedEncodingsString.split(CasEditorIdePreferenceConstants.STRING_DELIMITER); charsets.addAll(Arrays.asList(lastUsedEncodings)); if (lastUsedEncodings.length > 0) { importEncoding = lastUsedEncodings[0]; } else { importEncoding = Charset.defaultCharset().displayName(); } encodingCombo.setItems(charsets.toArray(new String[charsets.size()])); encodingCombo.setText(importEncoding); encodingCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { importEncoding = encodingCombo.getText(); updatePageState(); } public void widgetDefaultSelected(SelectionEvent e) { } }); encodingCombo.addKeyListener(new KeyListener() { public void keyReleased(KeyEvent e) { importEncoding = encodingCombo.getText(); updatePageState(); } public void keyPressed(KeyEvent e) { } }); Label casFormatLabel = new Label(importOptions, SWT.NONE); casFormatLabel.setText("Cas Format:"); final Combo casFormatCombo = new Combo(importOptions, SWT.READ_ONLY); casFormatCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); casFormatCombo.setItems(new String[]{DocumentFormat.XMI.toString(), DocumentFormat.XCAS.toString()}); documentFormat = DocumentFormat.XMI; casFormatCombo.select(0); casFormatCombo.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { documentFormat = DocumentFormat.valueOf(casFormatCombo.getText()); } public void widgetDefaultSelected(SelectionEvent e) { } }); updatePageState(); setControl(composite); } /** * Retrieves the import destination path. * * @return the path or null if none */ IPath getImportDestinationPath() { return importDestinationPath; } List getFilesToImport() { List files = new ArrayList(fileTable.getTable().getItemCount()); for (int i = 0; i < fileTable.getTable().getItemCount(); i++) { files.add((File) fileTable.getElementAt(i)); } return files; } String getTextEncoding() { return importEncoding; } String getLanguage() { return language; } DocumentFormat getCasFormat() { return documentFormat; } } uimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/package.html0000644000175000017500000000246111665471264033114 0ustar drazzibdrazzib org.apache.uima.caseditor.corpusview

This package contains the wizards classes.

././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/OverwriteQuery.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/OverwriteQue0000644000175000017500000000442011665471264033214 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.wizards; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.dialogs.IOverwriteQuery; /** * Overwrite Query to ask user how to deal with fields that need * to be overwritten. */ class OverwriteQuery implements IOverwriteQuery { private final Shell shell; private String result = CANCEL; OverwriteQuery(Shell shell) { this.shell = shell; } public String queryOverwrite(final String pathString) { if (ALL.equals(result)) { return ALL; } final String[] options = { IDialogConstants.YES_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL }; // Must executed synchronously, otherwise the result is not available // when the return statement is executed Display.getDefault().syncExec(new Runnable() { public void run() { MessageDialog dialog = new MessageDialog(shell, "CAS target file already exists" , null, "The CAS target file already exists: \n" + pathString + "\n\nPlease choose an action.", MessageDialog.QUESTION, options, 0); dialog.open(); String codes[] = { YES, ALL, NO, CANCEL }; result = codes[dialog.getReturnCode()]; } }); return result; } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ContainerElementFilter.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ContainerEle0000644000175000017500000000301211665471264033117 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.wizards; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; public class ContainerElementFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IAdaptable) { IResource resourceElement = (IResource) ((IAdaptable) element).getAdapter(IResource.class); if (resourceElement != null) element = resourceElement; } return element instanceof IContainer; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/DocumentImportStructureProvider.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/DocumentImpo0000644000175000017500000002107311665471264033161 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.wizards; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.List; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.StyledDocument; import javax.swing.text.rtf.RTFEditorKit; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.impl.XCASSerializer; import org.apache.uima.cas.impl.XmiCasSerializer; import org.apache.uima.caseditor.core.TaeError; import org.apache.uima.caseditor.editor.DocumentFormat; import org.apache.uima.internal.util.XMLUtils; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; import org.xml.sax.SAXException; /** */ final class DocumentImportStructureProvider implements IImportStructureProvider { private final String language; private final String importEncoding; // https://issues.apache.org/jira/browse/UIMA-1808 private final DocumentFormat casFormat; /** * Constructs a new DocumentImportStructureProvider object. * * @param containerFullPath */ public DocumentImportStructureProvider(String language, String importEncoding, DocumentFormat casFormat) { this.language = language; this.importEncoding = importEncoding; // https://issues.apache.org/jira/browse/UIMA-1808 this.casFormat = casFormat; } private static String removeNonXmlChars(String input) { char inputChars[] = input.toCharArray(); StringBuilder cleanedString = new StringBuilder(inputChars.length); int startIndex = 0; int offendingCharOsset; while ((offendingCharOsset = XMLUtils.checkForNonXmlCharacters( inputChars, startIndex, inputChars.length - startIndex, false)) != -1) { cleanedString.append(inputChars, startIndex, offendingCharOsset - startIndex); startIndex = offendingCharOsset + 1; } cleanedString.append(inputChars, startIndex, inputChars.length - startIndex); return cleanedString.toString(); } public List getChildren(Object element) { return null; } private static CAS createEmtpyCAS() { XMLInputSource xmlTypeSystemSource = new XMLInputSource(DocumentImportStructureProvider.class .getResourceAsStream("ts.xml"), new File("")); XMLParser xmlParser = UIMAFramework.getXMLParser(); TypeSystemDescription typeSystemDesciptor; try { typeSystemDesciptor = (TypeSystemDescription) xmlParser .parse(xmlTypeSystemSource); } catch (InvalidXMLException e1) { throw new TaeError("Integrated ts.xml typesystem descriptor is not valid!"); } try { return CasCreationUtils.createCas(typeSystemDesciptor, null, null); } catch (ResourceInitializationException e) { // should not happen throw new TaeError("Unexpected exception!"); } } private InputStream getDocument(String fileName, String text, String language, DocumentFormat format) { String failedToImportLine = "Failed to import: " + fileName + "\n\n"; CAS cas = createEmtpyCAS(); cas.setDocumentText(removeNonXmlChars(text)); cas.setDocumentLanguage(language); ByteArrayOutputStream out = new ByteArrayOutputStream(40000); if (DocumentFormat.XCAS.equals(format)) { try { XCASSerializer.serialize(cas, out); } catch (SAXException e) { // should not happen throw new TaeError(failedToImportLine + e.getMessage(), e); } catch (IOException e) { // will not happen, writing to memory throw new TaeError(failedToImportLine + e.getMessage(), e); } } else if (DocumentFormat.XMI.equals(format)) { try { XmiCasSerializer.serialize(cas, out); } catch (SAXException e) { // should not happen throw new TaeError(failedToImportLine + e.getMessage(), e); } } else { throw new TaeError(failedToImportLine + "Unkown document type!", null); } return new ByteArrayInputStream(out.toByteArray()); } public InputStream getContents(Object element) { File fileToImport = (File) element; String fileName = fileToImport.getName(); if (fileName.endsWith(".rtf")) { InputStream in = null; try { in = new FileInputStream((File) element); String text = convert(in); return getDocument(fileToImport.getAbsolutePath(), text, language, casFormat); } catch (FileNotFoundException e) { return null; } catch (IOException e) { return null; } finally { try { if (in != null) { in.close(); } } catch (IOException e) { // sorry that this can happen } } } else if (fileName.endsWith(".txt")) { InputStream in = null; try { in = new FileInputStream((File) element); StringBuilder textStringBuffer = new StringBuilder(); byte[] readBuffer = new byte[2048]; while (in.available() > 0) { int length = in.read(readBuffer); textStringBuffer.append(new String(readBuffer, 0, length, importEncoding)); } return getDocument(fileToImport.getAbsolutePath(), textStringBuffer.toString(), language, casFormat); } catch (FileNotFoundException e) { return null; } catch (IOException e) { return null; } finally { if (in != null) { try { in.close(); } catch (IOException e) { // sorry that this can fail } } } } else { try { return new FileInputStream((File) element); } catch (FileNotFoundException e) { return null; } } } private String convert(InputStream rtfDocumentInputStream) throws IOException { RTFEditorKit aRtfEditorkit = new RTFEditorKit(); StyledDocument styledDoc = new DefaultStyledDocument(); String textDocument; try { aRtfEditorkit.read(rtfDocumentInputStream, styledDoc, 0); textDocument = styledDoc.getText(0, styledDoc.getLength()); } catch (BadLocationException e) { throw new IOException("Error during parsing"); } return textDocument; } public String getFullPath(Object element) { return ""; } public String getLabel(Object element) { File fileToImport = (File) element; String fileName = fileToImport.getName(); if (fileName.endsWith(".rtf") || fileName.endsWith(".txt")) { int nameWithouEndingLength = fileName.lastIndexOf("."); String nameWithouEnding = fileName.substring(0, nameWithouEndingLength); String ending; if (DocumentFormat.XMI.equals(casFormat)) { ending = "xmi"; } else if (DocumentFormat.XCAS.equals(casFormat)) { ending = "xcas"; } else { throw new IllegalStateException("Unkown DocumentFormat!"); } return nameWithouEnding + "." + ending; } else { return fileName; } } public boolean isFolder(Object element) { return ((File) element).isDirectory(); } }././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ImportDocumentWizard.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/wizards/ImportDocume0000644000175000017500000001156611665471264033173 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide.wizards; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.uima.caseditor.CasEditorPlugin; import org.apache.uima.caseditor.ide.CasEditorIdePlugin; import org.apache.uima.caseditor.ide.CasEditorIdePreferenceConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.IImportWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; /** * This import dialog can import text files into a corpus. Currently plain text and rich text format * is supported. */ public final class ImportDocumentWizard extends Wizard implements IImportWizard { private ImportDocumentWizardPage mMainPage; private IStructuredSelection mCurrentResourceSelection; public void init(IWorkbench workbench, IStructuredSelection selection) { mCurrentResourceSelection = selection; // if corpus set as import corpus // Did not find a way to retrieve the "Import" string // from an eclipse message file setWindowTitle("Import"); } @Override public void addPages() { mMainPage = new ImportDocumentWizardPage("ImportDocuments", mCurrentResourceSelection); addPage(mMainPage); } @Override public boolean performFinish() { String usedEncoding = mMainPage.getTextEncoding(); IPreferenceStore store = CasEditorIdePlugin.getDefault().getPreferenceStore(); String lastUsedEncodingsString = store.getString( CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_ENCODINGS); List lastUsedEncodings = new ArrayList(Arrays.asList(lastUsedEncodingsString.split( CasEditorIdePreferenceConstants.STRING_DELIMITER))); int usedEncodingIndex = lastUsedEncodings.indexOf(usedEncoding); if (usedEncodingIndex != -1) { lastUsedEncodings.remove(usedEncodingIndex); } lastUsedEncodings.add(0, usedEncoding); int maxUserItemCount = 10; if (lastUsedEncodings.size() > maxUserItemCount) { lastUsedEncodings = lastUsedEncodings.subList(0, maxUserItemCount - 1); } StringBuilder updatedLastUsedEncodingsString = new StringBuilder(); for (String encoding : lastUsedEncodings) { updatedLastUsedEncodingsString.append(encoding); updatedLastUsedEncodingsString.append( CasEditorIdePreferenceConstants.STRING_DELIMITER); } store.setValue(CasEditorIdePreferenceConstants.CAS_IMPORT_WIZARD_LAST_USED_ENCODINGS, updatedLastUsedEncodingsString.toString()); IImportStructureProvider importProvider = new DocumentImportStructureProvider(mMainPage.getLanguage(), mMainPage.getTextEncoding(), mMainPage.getCasFormat()); // BUG: We cannot pass null here for the overwrite query ImportOperation operation = new ImportOperation(mMainPage.getImportDestinationPath(), importProvider, new OverwriteQuery(getShell()), mMainPage.getFilesToImport()); operation.setContext(getShell()); operation.setOverwriteResources(false); try { getContainer().run(true, true, operation); } catch (InvocationTargetException e) { CasEditorPlugin.log(e); String message = "Unkown error during import, see the log file for details"; Throwable cause = e.getCause(); if (cause != null) { String causeMessage = cause.getMessage(); if (causeMessage != null) message = causeMessage; } MessageDialog.openError(getContainer().getShell(), "Import failed", message); return false; } catch (InterruptedException e) { return false; } return true; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferenceConstants.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePreferen0000644000175000017500000000236611665471264033065 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; public class CasEditorIdePreferenceConstants { public static final String STRING_DELIMITER = ";"; public static final String CAS_IMPORT_WIZARD_LAST_USED_LANG = "CAS_IMPORT_WIZARD_LAST_USED_LANG"; public static final String CAS_IMPORT_WIZARD_LAST_USED_ENCODINGS = "CAS_IMPORT_WIZARD_ENCODINGS"; public static final String CAS_EDITOR_REMEMBER_TYPESYSTEM = "CAS_EDITOR_REMEMBER_TYPESYSTEM"; } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePlugin.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/CasEditorIdePlugin.j0000644000175000017500000001305111665471264032776 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import java.io.IOException; import java.io.InputStream; import java.util.ResourceBundle; import org.apache.uima.caseditor.CasEditorPlugin; import org.apache.uima.caseditor.core.model.dotcorpus.DotCorpus; import org.apache.uima.caseditor.core.model.dotcorpus.DotCorpusSerializer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; /** * TODO: add javadoc here */ public class CasEditorIdePlugin extends AbstractUIPlugin { public static final String ID = "org.apache.uima.caseditor.ide"; /** * The shared instance. */ private static CasEditorIdePlugin sPlugin; /** * Resource bundle. */ private ResourceBundle mResourceBundle; /** * The constructor. */ public CasEditorIdePlugin() { super(); sPlugin = this; } /** * This method is called upon plug-in activation * * @param context * @throws Exception */ @Override public void start(BundleContext context) throws Exception { super.start(context); // Backward compatibility: Migrate old Cas Editor Projects // Scan for all Nlp nature projects IProject projects[] = ResourcesPlugin.getWorkspace().getRoot().getProjects(); for (IProject project : projects) { // if nlp nature project if (project.isOpen() && project.hasNature("org.apache.uima.caseditor.NLPProject")) { // if ts property is not set ... String typeSystemLocation; try { typeSystemLocation = project.getPersistentProperty(new QualifiedName("", TypeSystemLocationPropertyPage.TYPE_SYSTEM_PROPERTY)); } catch (CoreException e) { typeSystemLocation = null; } if (typeSystemLocation == null) { // 1. Read dotCorpus IFile dotCorpusFile = project.getFile(".corpus"); if (dotCorpusFile.exists()) { InputStream dotCorpusIn = null; try { dotCorpusIn = dotCorpusFile.getContents(); } catch (CoreException e) { log(e); } IFile typeSystemFile = null; if (dotCorpusIn != null) { try { DotCorpus dotCorpus = DotCorpusSerializer.parseDotCorpus(dotCorpusIn); if (dotCorpus.getTypeSystemFileName() != null) typeSystemFile = project.getFile(dotCorpus.getTypeSystemFileName()); } finally { try { dotCorpusIn.close(); } catch (IOException e) { log(e); } } } if (typeSystemFile != null && typeSystemFile.exists()) { // 2. Set type system file accordingly TypeSystemLocationPropertyPage.setTypeSystemLocation(project, typeSystemFile.getFullPath().toString()); // 3. Try to copy dotCorpus file to type system location try { dotCorpusFile.copy(project.getFile(typeSystemFile.getParent().getProjectRelativePath() + "/" + ".style-" + typeSystemFile.getName()).getFullPath(), true, null); CasEditorPlugin.getDefault().setShowMigrationDialog(); } catch (CoreException e) { log(e); } } } } } } } /** * This method is called when the plug-in is stopped. * * @param context * @throws Exception */ @Override public void stop(BundleContext context) throws Exception { super.stop(context); sPlugin = null; mResourceBundle = null; } /** * Returns the shared instance. * * @return the TaePlugin */ public static CasEditorIdePlugin getDefault() { return sPlugin; } /** * Log the throwable. * * @param t */ public static void log(Throwable t) { getDefault().getLog().log(new Status(IStatus.ERROR, ID, IStatus.OK, t.getMessage(), t)); } public static void logError(String message) { getDefault().getLog().log(new Status(IStatus.ERROR, ID, message)); } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/DefaultCasDocumentProvider.javauimaj-2.4.0/uimaj-ep-cas-editor-ide/src/main/java/org/apache/uima/caseditor/ide/DefaultCasDocumentPr0000644000175000017500000005427211665471264033116 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.caseditor.ide; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.caseditor.CasEditorPlugin; import org.apache.uima.caseditor.core.model.DefaultColors; import org.apache.uima.caseditor.core.model.dotcorpus.DotCorpus; import org.apache.uima.caseditor.core.model.dotcorpus.DotCorpusSerializer; import org.apache.uima.caseditor.editor.AnnotationStyle; import org.apache.uima.caseditor.editor.CasDocumentProvider; import org.apache.uima.caseditor.editor.DocumentFormat; import org.apache.uima.caseditor.editor.DocumentUimaImpl; import org.apache.uima.caseditor.editor.ICasDocument; import org.apache.uima.caseditor.editor.ICasEditor; import org.apache.uima.caseditor.ide.searchstrategy.ITypeSystemSearchStrategy; import org.apache.uima.caseditor.ide.searchstrategy.TypeSystemSearchStrategyFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.Status; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceStore; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.part.FileEditorInput; public class DefaultCasDocumentProvider extends org.apache.uima.caseditor.editor.CasDocumentProvider { /** * Listens for resource events: If the input file for the editor is removed the editor will be * closed and if the input file is modified, then the CAS needs to be updated and all views needs * to be notified. */ private class ModifyElementListener implements IResourceChangeListener { private FileEditorInput fileInput; public ModifyElementListener(FileEditorInput fileInput) { this.fileInput = fileInput; } public void resourceChanged(IResourceChangeEvent event) { IResourceDelta delta = event.getDelta(); try { IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta) throws CoreException { if (delta.getFlags() != IResourceDelta.MARKERS && delta.getResource().getType() == IResource.FILE) { IResource resource = delta.getResource(); if (resource.equals(fileInput.getFile())) { if (delta.getKind() == IResourceDelta.REMOVED) { handleElementDeleted(fileInput); } else if (delta.getKind() == IResourceDelta.CHANGED) { if (isFileChangeTrackingEnabled) handleElementChanged(fileInput); } } } return true; } }; delta.accept(visitor); } catch (CoreException e) { CasEditorPlugin.log(e); } } } private static class FileElementInfo extends ElementInfo { private ModifyElementListener deleteListener; FileElementInfo(ElementInfo info) { super(info.element); } } private class SaveSessionPreferencesTrigger implements IPropertyChangeListener { private Object element; SaveSessionPreferencesTrigger(Object element) { this.element = element; } public void propertyChange(PropertyChangeEvent event) { IResource tsFile = ResourcesPlugin.getWorkspace().getRoot() .findMember((getTypesystemId(element))); PreferenceStore prefStore = (PreferenceStore) getSessionPreferenceStore(element); ByteArrayOutputStream prefBytes = new ByteArrayOutputStream(); try { prefStore.save(prefBytes, ""); } catch (IOException e) { CasEditorIdePlugin.log(e); } try { tsFile.setPersistentProperty(new QualifiedName("", CAS_EDITOR_SESSION_PROPERTIES), new String(prefBytes.toByteArray(), "UTF-8")); } catch (CoreException e) { CasEditorIdePlugin.log(e); } catch (IOException e) { CasEditorIdePlugin.log(e); } } } private static final String CAS_EDITOR_SESSION_PROPERTIES = "CAS_EDITOR_SESSION_PROPERTIES"; /** * This map resolved an opened document to its associated style object id. * * The tracking is done in the provider because the document element itself does not has any link * to the style object. */ private Map documentToTypeSystemMap = new HashMap(); private Map sessionPreferenceStores = new HashMap(); /** * This map resolves a type system to a style. It is used to cache type system preference instance * while the editor is open. */ private Map typeSystemPreferences = new HashMap(); private boolean isFileChangeTrackingEnabled = true; // UIMA-2245 Remove this method together with the migration code below one day private String getStyleFileForTypeSystem(String typeSystemFile) { int lastSlashIndex = typeSystemFile.lastIndexOf("/"); String styleId = typeSystemFile.substring(0, lastSlashIndex + 1); styleId = styleId + ".style-" + typeSystemFile.substring(lastSlashIndex + 1); return styleId; } private String getPreferenceFileForTypeSystem(String typeSystemFile) { int lastSlashIndex = typeSystemFile.lastIndexOf("/"); String styleId = typeSystemFile.substring(0, lastSlashIndex + 1); styleId = styleId + ".pref-" + typeSystemFile.substring(lastSlashIndex + 1); return styleId; } private Collection getConfiguredAnnotationStyles(IPreferenceStore store, TypeSystem types) { Collection styles = new HashSet(); // TODO: for each annotation type, try to retrieve annotation styles return styles; } @Override protected ICasDocument createDocument(Object element) throws CoreException { if (element instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) element; IFile casFile = fileInput.getFile(); // Try to find a type system for the CAS file // TODO: Change to only use full path IFile typeSystemFile = null; // First check if a type system is already known or was // set by the editor for this specific CAS. // apply that type system only if the setting is active in the preferences String typeSystemFileString = null; IPreferenceStore prefStore = CasEditorIdePlugin.getDefault().getPreferenceStore(); boolean useLastTypesystem = prefStore .getBoolean(CasEditorIdePreferenceConstants.CAS_EDITOR_REMEMBER_TYPESYSTEM); if (useLastTypesystem) { typeSystemFileString = documentToTypeSystemMap .get(casFile.getFullPath().toPortableString()); } if (typeSystemFileString != null) typeSystemFile = ResourcesPlugin.getWorkspace().getRoot() .getFile(new Path(typeSystemFileString)); // use search strategies for finding the type system if (typeSystemFile == null || !typeSystemFile.exists()) { Map searchStrategies = TypeSystemSearchStrategyFactory .instance().getSearchStrategies(); // TODO sort again for user preference settings Collection values = searchStrategies.values(); for (ITypeSystemSearchStrategy eachStrategy : values) { IFile findTypeSystem = eachStrategy.findTypeSystem(casFile); if (findTypeSystem != null && findTypeSystem.exists()) { typeSystemFile = findTypeSystem; break; } } } // If non was found get it from project if (typeSystemFile == null) typeSystemFile = TypeSystemLocationPropertyPage.getTypeSystemLocation(casFile.getProject()); if (typeSystemFile != null && typeSystemFile.exists()) { if (!typeSystemFile.isSynchronized(IResource.DEPTH_ZERO)) { typeSystemFile.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()); } // TODO: Update this comment! // Try to load a style file for the type system // Should be named: ts file name, prefixed with .style- // If it does not exist, create it when it is changed // Creating it after the default is changed means that // colors could change completely when the a type is // added or removed to the type system IFile prefFile = ResourcesPlugin .getWorkspace() .getRoot() .getFile( new Path(getPreferenceFileForTypeSystem(typeSystemFile.getFullPath() .toPortableString()))); PreferenceStore tsPrefStore = typeSystemPreferences.get(prefFile.getFullPath() .toPortableString()); // If lookup for store failed ... if (tsPrefStore == null) { if (prefFile.exists()) { tsPrefStore = new PreferenceStore(prefFile.getName()); try { tsPrefStore.load(prefFile.getContents()); // TODO: Close stream! } catch (IOException e) { e.printStackTrace(); // TODO: Handle this correctly! } } else { // UIMA-2245 // DotCorpus to Eclipse PreferenceStore migration code. // If there is DotCorpus style file and not yet a preference store file // the settings from the DotCorpus style file should be written into a preference store // file. IFile styleFile = ResourcesPlugin .getWorkspace() .getRoot() .getFile( new Path(getStyleFileForTypeSystem(typeSystemFile.getFullPath() .toPortableString()))); if (styleFile.exists()) { InputStream styleFileIn = null; ; DotCorpus dotCorpus = null; try { styleFileIn = styleFile.getContents(); dotCorpus = DotCorpusSerializer.parseDotCorpus(styleFileIn); } finally { if (styleFileIn != null) try { styleFileIn.close(); } catch (IOException e) { CasEditorPlugin.log(e); } } if (dotCorpus != null) { tsPrefStore = new PreferenceStore(prefFile.getName()); for (AnnotationStyle style : dotCorpus.getAnnotationStyles()) { AnnotationStyle.putAnnotatationStyleToStore(tsPrefStore, style); } for (String shownType : dotCorpus.getShownTypes()) { tsPrefStore.putValue(shownType + ".isShown", "true"); } ByteArrayOutputStream prefOut = new ByteArrayOutputStream(); try { tsPrefStore.save(prefOut, ""); } catch (IOException e) { // Should never happen! CasEditorPlugin.log(e); } // TODO: Do we need to handle exceptions here? prefFile.create(new ByteArrayInputStream(prefOut.toByteArray()), IFile.FORCE, null); } } } // No preference defined, lets use defaults if (tsPrefStore == null) { tsPrefStore = new PreferenceStore(prefFile.getName()); CAS cas = DocumentUimaImpl.getVirginCAS(typeSystemFile); TypeSystem ts = cas.getTypeSystem(); Collection defaultStyles = getConfiguredAnnotationStyles(tsPrefStore, ts); Collection newStyles = DefaultColors.assignColors(ts, defaultStyles); // TODO: Settings defaults must be moved to the AnnotationEditor for (AnnotationStyle style : newStyles) { AnnotationStyle.putAnnotatationStyleToStore(tsPrefStore, style); } } typeSystemPreferences.put(prefFile.getFullPath().toPortableString(), tsPrefStore); } documentToTypeSystemMap.put(casFile.getFullPath().toPortableString(), typeSystemFile .getFullPath().toPortableString()); IPreferenceStore store = sessionPreferenceStores.get(getTypesystemId(element)); if (store == null) { PreferenceStore newStore = new PreferenceStore(); sessionPreferenceStores.put(getTypesystemId(element), newStore); newStore.addPropertyChangeListener(new SaveSessionPreferencesTrigger(element)); String sessionPreferenceString = typeSystemFile.getPersistentProperty(new QualifiedName( "", CAS_EDITOR_SESSION_PROPERTIES)); if (sessionPreferenceString != null) { try { newStore.load(new ByteArrayInputStream(sessionPreferenceString.getBytes("UTF-8"))); } catch (IOException e) { CasEditorPlugin.log(e); } } } // TODO: // Preferences are bound to the type system // Changed in one place, then it should change in all places CAS cas = DocumentUimaImpl.getVirginCAS(typeSystemFile); DocumentFormat documentFormat; // Which file format to use ? if (casFile.getName().endsWith("xmi")) { documentFormat = DocumentFormat.XMI; } else if (casFile.getName().endsWith("xcas")) { documentFormat = DocumentFormat.XCAS; } else { throw new CoreException(new Status(IStatus.ERROR, "org.apache.uima.dev", "Unkown file format!")); } InputStream casIn = casFile.getContents(); org.apache.uima.caseditor.editor.ICasDocument doc; try { doc = new DocumentUimaImpl(cas, casIn, documentFormat); } finally { try { casIn.close(); } catch (IOException e) { // Unable to close file after loading it // // In the current implementation the user // does not notice the error and can just // edit the file, tough saving it might fail // if the io error persists CasEditorPlugin.log(e); } } elementErrorStatus.remove(element); return doc; } else { String message = null; if (typeSystemFile != null) { message = "Cannot find type system!\nPlease place a valid type system in this path:\n" + typeSystemFile.getFullPath().toString(); } else message = "Type system is not set, please choose a type system to open the CAS."; IStatus status = new Status(IStatus.ERROR, "org.apache.uima.dev", CasDocumentProvider.TYPE_SYSTEM_NOT_AVAILABLE_STATUS_CODE, message, null); elementErrorStatus.put(element, status); } } return null; } @Override protected void doSaveDocument(IProgressMonitor monitor, Object element, ICasDocument document, boolean overwrite) throws CoreException { if (element instanceof FileEditorInput) { FileEditorInput fileInput = (FileEditorInput) element; IFile file = fileInput.getFile(); if (document instanceof DocumentUimaImpl) { DocumentUimaImpl documentImpl = (DocumentUimaImpl) document; ByteArrayOutputStream outStream = new ByteArrayOutputStream(40000); documentImpl.serialize(outStream); InputStream stream = new ByteArrayInputStream(outStream.toByteArray()); isFileChangeTrackingEnabled = false; try { file.setContents(stream, true, false, null); } finally { isFileChangeTrackingEnabled = true; } } } // tell everyone that the element changed and is not dirty any longer fireElementDirtyStateChanged(element, false); } private String getTypesystemId(Object element) { if (element instanceof FileEditorInput) { FileEditorInput editorInput = (FileEditorInput) element; return documentToTypeSystemMap.get(editorInput.getFile().getFullPath().toPortableString()); } return null; } @Override public void saveTypeSystemPreferenceStore(Object element) { String prefereceFileId = getPreferenceFileForTypeSystem(getTypesystemId(element)); PreferenceStore preferences = typeSystemPreferences.get(prefereceFileId); // serialize ... IFile preferenceFile = ResourcesPlugin.getWorkspace().getRoot() .getFile(Path.fromPortableString(prefereceFileId)); ByteArrayOutputStream preferenceBytes = new ByteArrayOutputStream(); try { preferences.save(preferenceBytes, ""); } catch (IOException e) { // will not fail, writing to memory CasEditorPlugin.log(e); } try { if (preferenceFile.exists()) { preferenceFile.setContents(new ByteArrayInputStream(preferenceBytes.toByteArray()), true, false, null); } else { preferenceFile.create(new ByteArrayInputStream(preferenceBytes.toByteArray()), true, null); } } catch (CoreException e) { // might fail if writing is not possible // for some reason CasEditorPlugin.log(e); } } @Override public IPreferenceStore getTypeSystemPreferenceStore(Object element) { String tsId = getTypesystemId(element); if (tsId != null) return typeSystemPreferences.get(getPreferenceFileForTypeSystem(tsId)); else return null; } @Override public IPreferenceStore getSessionPreferenceStore(Object element) { return sessionPreferenceStores.get(getTypesystemId(element)); } void setTypeSystem(String document, String typeSystem) { documentToTypeSystemMap.put(document, typeSystem); } @Override public Composite createTypeSystemSelectorForm(final ICasEditor editor, Composite parent, IStatus status) { // Note: // If the editor is not active and the user clicks on the button // the editor gets activated and an exception is logged // on the second click the button is selected // How to fix the exception ?! // Only tested on OS X Snow Leopard Composite provideTypeSystemForm = new Composite(parent, SWT.NONE); provideTypeSystemForm.setLayout(new GridLayout(1, false)); Label infoLabel = new Label(provideTypeSystemForm, SWT.NONE); infoLabel.setText(status.getMessage()); Button retryButton = new Button(provideTypeSystemForm, SWT.NONE); retryButton.setText("Choose Type System ..."); retryButton.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { // Open a dialog to let the user choose a type system IResource resource = WorkspaceResourceDialog.getWorkspaceResourceElement(Display .getCurrent().getActiveShell(), ResourcesPlugin.getWorkspace().getRoot(), "Select a Type System", "Please select a Type System:"); if (resource != null) { FileEditorInput editorInput = (FileEditorInput) editor.getEditorInput(); setTypeSystem(editorInput.getFile().getFullPath().toPortableString(), resource .getFullPath().toString()); // Now set the input again to open the editor with the // specified type system editor.reopenEditorWithNewTypeSystem(); } } public void widgetDefaultSelected(SelectionEvent e) { throw new IllegalStateException("Never be called!"); } }); return provideTypeSystemForm; } @Override protected ElementInfo createElementInfo(Object element) { FileElementInfo info = new FileElementInfo(super.createElementInfo(element)); // Register listener to listens for deletion events, // if the file opened in this editor is deleted, the editor should be closed! info.deleteListener = new ModifyElementListener((FileEditorInput) element); ResourcesPlugin.getWorkspace().addResourceChangeListener(info.deleteListener, IResourceChangeEvent.POST_CHANGE); return info; } @Override protected void disposeElementInfo(Object element, ElementInfo info) { FileElementInfo fileInfo = (FileElementInfo) info; ResourcesPlugin.getWorkspace().removeResourceChangeListener(fileInfo.deleteListener); super.disposeElementInfo(element, info); } private void handleElementDeleted(Object element) { fireElementDeleted(element); } private void handleElementChanged(Object element) { fireElementChanged(element); } } uimaj-2.4.0/uimaj-ep-jcasgen/0000755000175000017500000000000011665472110015640 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/META-INF/0000755000175000017500000000000011665472112017002 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/META-INF/MANIFEST.MF0000644000175000017500000000264111665472112020437 0ustar drazzibdrazzibManifest-Version: 1.0 Implementation-Vendor: The Apache Software Foundation Built-By: schor Bundle-Activator: org.eclipse.core.internal.compatibility.PluginActiva tor Ignore-Package: org.eclipse.core.runtime Bundle-Version: 2.4.0 Eclipse-AutoStart: true Build-Jdk: 1.6.0 Implementation-Url: http://uima.apache.org Tool: Bnd-1.15.0 Created-By: Apache Maven Bundle Plugin Plugin-Class: org.apache.uima.jcas.jcasgenp.JgPlugin Import-Package: org.apache.uima.tools.jcasgen,org.eclipse.core.interna l.compatibility,org.eclipse.core.resources,org.eclipse.emf.codegen.jm erge,org.eclipse.jdt.core.jdom,org.osgi.framework;version="[1.3,2)" Bundle-DocURL: http://www.apache.org/ Project-Title: Apache UIMA Implementation-Vendor-Id: org.apache.uima Implementation-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.uima.jcas.jcasgenp;singleton:=true Require-Bundle: org.eclipse.core.runtime Build-Date: 111130_1918 Export-Package: org.apache.uima.jcas.jcasgenp Bundle-Description: Provides a connection to the JCasGen tooling, for the Component Descriptor Editor Bundle-Vendor: The Apache Software Foundation Bnd-LastModified: 1322698920159 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Name: Apache UIMA Eclipse: uimaj-ep-jcasgen Implementation-Title: Apache UIMA Eclipse: uimaj-ep-jcasgen Implementation-Version: 2.4.0 Bundle-ManifestVersion: 2 uimaj-2.4.0/uimaj-ep-jcasgen/pom.xml0000644000175000017500000002201411665471546017170 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-ep-jcasgen jar 2.4.0 Apache UIMA Eclipse: ${project.artifactId} Provides a connection to the JCasGen tooling, for the Component Descriptor Editor ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-jcasgen scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-jcasgen http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-jcasgen ${project.artifactId} ${ibmNoticeText} org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-tools ${project.parent.version} compile org.eclipse.core org.eclipse.core.runtime 3.2.0 provided org.eclipse.core org.eclipse.core.runtime.compatibility 3.1.100 provided org.eclipse.jdt org.eclipse.jdt.core 3.2.0 provided org.eclipse.emf codegen 2.1.0 provided org.eclipse.emf common 2.1.0 org.eclipse.equinox org.eclipse.equinox.registry 3.2.1 provided org.eclipse.core org.eclipse.core.jobs 3.2.0 provided org.eclipse.core org.eclipse.core.contenttype 3.2.0 provided org.eclipse.equinox org.eclipse.equinox.preferences 3.2.1 provided org.eclipse.core org.eclipse.core.runtime.compatibility.auth 3.2.0 provided org.eclipse.osgi org.eclipse.osgi 3.2.1 provided org.eclipse.core org.eclipse.core.filesystem 1.0.0 provided org.eclipse.equinox org.eclipse.equinox.common 3.2.0 provided org.eclipse.core org.eclipse.core.resources 3.2.1 provided org.eclipse.ant org.eclipse.ant.core 3.1.100 provided org.eclipse.core org.eclipse.core.expressions 3.2.1 provided org.eclipse.core org.eclipse.core.variables 3.1.100 provided org.apache.uima.jcas.jcasgenp_${parsedVersion.osgiVersion} org.apache.felix maven-bundle-plugin <_nouses>true org.apache.uima.jcas.jcasgenp org.eclipse.core.internal.compatibility.PluginActivator org.eclipse.core.runtime !org.eclipse.core.runtime, *, org.osgi.framework, org.eclipse.jdt.core.jdom org.apache.uima.jcas.jcasgenp;singleton:=true true org.apache.uima.jcas.jcasgenp.JgPlugin uimaj-2.4.0/uimaj-ep-jcasgen/plugin.xml0000644000175000017500000000246511665471016017673 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-ep-jcasgen/marker-file-identifying-eclipse-plugin0000644000175000017500000000000011665471016025200 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/0000755000175000017500000000000011665471016016433 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/0000755000175000017500000000000011665471016017357 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/resources/0000755000175000017500000000000011665471016021371 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/0000755000175000017500000000000011665471016020300 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/0000755000175000017500000000000011665471016021067 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/0000755000175000017500000000000011665471016022310 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/0000755000175000017500000000000011665471016023243 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/0000755000175000017500000000000011665471016024163 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/0000755000175000017500000000000011665471016025755 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/JgPluginRunner.java0000644000175000017500000000414511665471016031535 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.jcasgenp; import org.apache.uima.tools.jcasgen.Jg; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPlatformRunnable; import org.eclipse.core.runtime.IProgressMonitor; /** * Class holds type plugin-wide collections and static methods. Also implements the runnable that is * called to do the processing */ public class JgPluginRunner implements IPlatformRunnable { public JgPluginRunner() { } public Object run(Object object) { try { final String[] arguments = (String[]) object; final IWorkspace workspace = ResourcesPlugin.getWorkspace(); final Jg jg = new Jg(); IWorkspaceRunnable runnable = new IWorkspaceRunnable() { public void run(IProgressMonitor progressMonitor) throws CoreException { jg.main0(arguments, new MergerImpl(), null, // no progressMonitor, new EP_LogThrowErrorImpl()); } }; workspace.run(runnable, null); return new Integer(0); } catch (Exception exception) { exception.printStackTrace(); } return new Integer(1); } } uimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/EP_LogThrowErrorImpl.java0000644000175000017500000000330511665471016032606 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.jcasgenp; import org.apache.uima.tools.jcasgen.IError; import org.apache.uima.tools.jcasgen.Jg.ErrorExit; import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; public class EP_LogThrowErrorImpl implements IError { private static int logLevels[] = { IStatus.INFO, IStatus.WARNING, IStatus.ERROR }; /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IError#newError(int, java.lang.String) */ public void newError(int severity, String message, Exception exception) { String pluginId = JgPlugin.getDefault().getDescriptor().getUniqueIdentifier(); ILog log = JgPlugin.getDefault().getLog(); log.log(new Status(logLevels[severity], pluginId, IStatus.OK, message, exception)); if (IError.WARN < severity) throw new ErrorExit(); } } uimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/JgPlugin.java0000644000175000017500000000355411665471016030346 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.jcasgenp; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPluginDescriptor; import org.eclipse.core.runtime.Plugin; /** * The main plugin class to be used in the desktop. */ public class JgPlugin extends Plugin { // The shared instance. private static JgPlugin plugin; public static final String JCASGEN_ID = "org.apache.uima.jcas.jcasgenp"; //$NON-NLS-1$ /** * The constructor. */ public JgPlugin(IPluginDescriptor descriptor) { super(descriptor); plugin = this; } /** * Returns the shared instance. */ public static JgPlugin getDefault() { return plugin; } /** * Returns the workspace instance. */ public static IWorkspace getWorkspace() { return ResourcesPlugin.getWorkspace(); } /** * Convenience method which returns the unique identifier of this plugin. */ public static String getUniqueIdentifier() { return JCASGEN_ID; } } uimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/MergerImpl.java0000644000175000017500000000675411665471016030677 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.jcasgenp; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.apache.uima.tools.jcasgen.IError; import org.apache.uima.tools.jcasgen.IProgressMonitor; import org.apache.uima.tools.jcasgen.Jg; import org.eclipse.emf.codegen.jmerge.JControlModel; import org.eclipse.emf.codegen.jmerge.JMerger; import org.eclipse.jdt.core.jdom.IDOMCompilationUnit; public class MergerImpl implements org.apache.uima.tools.jcasgen.IMerge { static final String jControlModel = "jMergeCtl.xml"; static JControlModel jControlModelInstance = null; public void doMerge(Jg jg, IProgressMonitor progressMonitor, String sourceContents, String targetContainer, String targetPath, String targetClassName, File targetFile) throws IOException { JMerger jMerger = new JMerger(); IDOMCompilationUnit sourceCompilationUnit = jMerger .createCompilationUnitForContents(sourceContents); if (targetFile.exists()) { progressMonitor.subTask(jg.getString("updatingTarget", new Object[] { targetClassName })); synchronized (this) { if (null == jControlModelInstance) { String controlModelPath = jg.getClass().getResource(jControlModel).toString(); jControlModelInstance = (new JControlModel(controlModelPath)); } } jMerger.setControlModel(jControlModelInstance); // jMerger.setControlModel( // new JControlModel( // jg.getClass().getResource(jControlModel).toString())); try { jMerger.setSourceCompilationUnit(sourceCompilationUnit); jMerger.setTargetCompilationUnit(jMerger.createCompilationUnitForURI(targetPath)); } catch (NullPointerException e) { jg.error.newError(IError.ERROR, jg.getString("nullPtr", new Object[] { targetClassName }), e); } // jMerger.getTargetPatternDictionary().dump(); jMerger.merge(); FileWriter fw = new FileWriter(targetPath); fw.write(jMerger.getTargetCompilationUnit().getContents()); fw.close(); // targetFile.setContents( // mergedContents, // true, // true, // new SubProgressMonitor(progressMonitor, 1)); } else { progressMonitor.subTask(jg.getString("creatingTarget", new Object[] { targetClassName })); (new File(targetContainer)).mkdirs(); FileWriter fw = new FileWriter(targetPath); fw.write(sourceContents); fw.close(); // targetFile.setContents( // new ByteArrayInputStream(sourceContents.getBytes()), // true, // true, // new SubProgressMonitor(progressMonitor, 1)); } } } uimaj-2.4.0/uimaj-ep-jcasgen/src/main/java/org/apache/uima/jcas/jcasgenp/ProgressMonitorImpl.java0000644000175000017500000000403711665471016032622 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.jcasgenp; import org.eclipse.core.runtime.IProgressMonitor; public class ProgressMonitorImpl implements org.apache.uima.tools.jcasgen.IProgressMonitor { private IProgressMonitor fwd; ProgressMonitorImpl(IProgressMonitor pm) { fwd = pm; } public void done() { fwd.done(); } public void beginTask(String name, int totalWorked) { fwd.beginTask(name, totalWorked); } public void subTask(String name) { fwd.subTask(name); } public void worked(int work) { fwd.worked(work); } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double) */ public void internalWorked(double work) { } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled() */ public boolean isCanceled() { return false; } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean) */ public void setCanceled(boolean value) { } /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String) */ public void setTaskName(String name) { } } uimaj-2.4.0/uimaj-ep-runtime/0000755000175000017500000000000011665472210015712 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-runtime/META-INF/0000755000175000017500000000000011665472230017054 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-runtime/META-INF/MANIFEST.MF0000644000175000017500000001146011665472230020510 0ustar drazzibdrazzibManifest-Version: 1.0 Implementation-Vendor: The Apache Software Foundation Bundle-RequiredExecutionEnvironment: J2SE-1.5 Built-By: schor Bundle-Version: 2.4.0 Build-Jdk: 1.6.0 Implementation-Url: http://uima.apache.org Tool: Bnd-1.15.0 Created-By: Apache Maven Bundle Plugin Import-Package: javax.imageio,javax.naming,javax.swing,javax.swing.bor der,javax.swing.event,javax.swing.filechooser,javax.swing.plaf,javax. swing.table,javax.swing.text,javax.swing.text.html,javax.swing.tree,j avax.swing.undo,javax.xml.parsers,javax.xml.transform,javax.xml.trans form.dom,javax.xml.transform.sax,javax.xml.transform.stream,org.apach e.log4j;resolution:=optional,org.apache.uima,org.apache.uima.analysis _component,org.apache.uima.analysis_engine,org.apache.uima.cas,org.ap ache.uima.cas.impl,org.apache.uima.cas.text,org.apache.uima.collectio n,org.apache.uima.internal.util,org.apache.uima.jcas,org.apache.uima. jcas.cas,org.apache.uima.jcas.tcas,org.apache.uima.pear.tools,org.apa che.uima.resource,org.apache.uima.resource.metadata,org.apache.uima.u til,org.w3c.dom,org.xml.sax,org.xml.sax.ext,org.xml.sax.helpers Bundle-DocURL: http://www.apache.org/ Project-Title: Apache UIMA Implementation-Vendor-Id: org.apache.uima Implementation-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.uima.runtime;singleton:=true Build-Date: 111130_1918 Export-Package: org.apache.uima,org.apache.uima.adapter.vinci,org.apac he.uima.adapter.vinci.util,org.apache.uima.analysis_component,org.apa che.uima.analysis_engine,org.apache.uima.analysis_engine.annotator,or g.apache.uima.analysis_engine.asb,org.apache.uima.analysis_engine.asb .impl,org.apache.uima.analysis_engine.impl,org.apache.uima.analysis_e ngine.impl.compatibility,org.apache.uima.analysis_engine.metadata,org .apache.uima.analysis_engine.metadata.impl,org.apache.uima.analysis_e ngine.service.impl,org.apache.uima.cas,org.apache.uima.cas.admin,org. apache.uima.cas.impl,org.apache.uima.cas.text,org.apache.uima.cas_dat a,org.apache.uima.cas_data.impl,org.apache.uima.cas_data.impl.vinci,o rg.apache.uima.collection,org.apache.uima.collection.base_cpm,org.apa che.uima.collection.impl,org.apache.uima.collection.impl.base_cpm.con tainer,org.apache.uima.collection.impl.base_cpm.container.deployer,or g.apache.uima.collection.impl.cpm,org.apache.uima.collection.impl.cpm .container,org.apache.uima.collection.impl.cpm.container.deployer,org .apache.uima.collection.impl.cpm.container.deployer.socket,org.apache .uima.collection.impl.cpm.container.deployer.vinci,org.apache.uima.co llection.impl.cpm.container.deployer.vns,org.apache.uima.collection.i mpl.cpm.engine,org.apache.uima.collection.impl.cpm.utils,org.apache.u ima.collection.impl.cpm.vinci,org.apache.uima.collection.impl.cpm.vin ci.cas_data,org.apache.uima.collection.impl.metadata,org.apache.uima. collection.impl.metadata.cpe,org.apache.uima.collection.metadata,org. apache.uima.flow,org.apache.uima.flow.impl,org.apache.uima.impl,org.a pache.uima.internal.util,org.apache.uima.internal.util.rb_trees,org.a pache.uima.internal.util.text,org.apache.uima.jcas,org.apache.uima.jc as.cas,org.apache.uima.jcas.impl,org.apache.uima.jcas.tcas,org.apache .uima.pear.tools,org.apache.uima.pear.util,org.apache.uima.resource,o rg.apache.uima.resource.impl,org.apache.uima.resource.metadata,org.ap ache.uima.resource.metadata.impl,org.apache.uima.resource.service.imp l,org.apache.uima.search,org.apache.uima.search.impl,org.apache.uima. tools,org.apache.uima.tools.annot_view,org.apache.uima.tools.cpm,org. apache.uima.tools.cvd,org.apache.uima.tools.cvd.control,org.apache.ui ma.tools.cvd.tsview,org.apache.uima.tools.docanalyzer,org.apache.uima .tools.images,org.apache.uima.tools.jcasgen,org.apache.uima.tools.pea r.install,org.apache.uima.tools.pear.merger,org.apache.uima.tools.sty lemap,org.apache.uima.tools.util.gui,org.apache.uima.tools.util.htmlv iew,org.apache.uima.tools.viewer,org.apache.uima.uimacpp,org.apache.u ima.util,org.apache.uima.util.impl,org.apache.vinci.debug,org.apache. vinci.transport,org.apache.vinci.transport.context,org.apache.vinci.t ransport.document,org.apache.vinci.transport.util,org.apache.vinci.tr ansport.vns,org.apache.vinci.transport.vns.client,org.apache.vinci.tr ansport.vns.service Bundle-Description: Provides the core UIMA Framework to other Eclipse plugins for their use Eclipse-BuddyPolicy: registered Bundle-Vendor: The Apache Software Foundation Bnd-LastModified: 1322698999891 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Name: Apache UIMA Eclipse: uimaj-ep-runtime Eclipse-ExtensibleAPI: true Implementation-Title: Apache UIMA Eclipse: uimaj-ep-runtime Implementation-Version: 2.4.0 Bundle-ManifestVersion: 2 Embed-Dependency: *;scope=compile;inline=true uimaj-2.4.0/uimaj-ep-runtime/pom.xml0000644000175000017500000002642111665471546017247 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-ep-runtime 2.4.0 jar Apache UIMA Eclipse: ${project.artifactId} Provides the core UIMA Framework to other Eclipse plugins for their use ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-runtime scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-runtime http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-runtime ${project.artifactId} org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-cpe ${project.parent.version} compile org.apache.uima uimaj-tools ${project.parent.version} compile org.apache.uima uimaj-adapter-vinci ${project.parent.version} compile org.apache.uima jVinci ${project.parent.version} compile org.apache.uima.runtime_${parsedVersion.osgiVersion} org.apache.felix maven-bundle-plugin uima-bundle <_nouses>true <_exportcontents> org.apache.uima, org.apache.uima.adapter.vinci, org.apache.uima.adapter.vinci.util, org.apache.uima.analysis_component, org.apache.uima.analysis_engine, org.apache.uima.analysis_engine.annotator, org.apache.uima.analysis_engine.asb, org.apache.uima.analysis_engine.asb.impl, org.apache.uima.analysis_engine.impl, org.apache.uima.analysis_engine.impl.compatibility, org.apache.uima.analysis_engine.metadata, org.apache.uima.analysis_engine.metadata.impl, org.apache.uima.analysis_engine.service.impl, org.apache.uima.cas, org.apache.uima.cas.admin, org.apache.uima.cas.impl, org.apache.uima.cas.text, org.apache.uima.cas_data, org.apache.uima.cas_data.impl, org.apache.uima.cas_data.impl.vinci, org.apache.uima.collection, org.apache.uima.collection.base_cpm, org.apache.uima.collection.impl, org.apache.uima.collection.impl.base_cpm.container, org.apache.uima.collection.impl.base_cpm.container.deployer, org.apache.uima.collection.impl.cpm, org.apache.uima.collection.impl.cpm.container, org.apache.uima.collection.impl.cpm.container.deployer, org.apache.uima.collection.impl.cpm.container.deployer.socket, org.apache.uima.collection.impl.cpm.container.deployer.vinci, org.apache.uima.collection.impl.cpm.container.deployer.vns, org.apache.uima.collection.impl.cpm.engine, org.apache.uima.collection.impl.cpm.utils, org.apache.uima.collection.impl.cpm.vinci, org.apache.uima.collection.impl.cpm.vinci.cas_data, org.apache.uima.collection.impl.metadata, org.apache.uima.collection.impl.metadata.cpe, org.apache.uima.collection.metadata, org.apache.uima.flow, org.apache.uima.flow.impl, org.apache.uima.impl, org.apache.uima.internal.util, org.apache.uima.internal.util.rb_trees, org.apache.uima.internal.util.text, org.apache.uima.jcas, org.apache.uima.jcas.cas, org.apache.uima.jcas.impl, org.apache.uima.jcas.tcas, org.apache.uima.pear.tools, org.apache.uima.pear.util, org.apache.uima.resource, org.apache.uima.resource.impl, org.apache.uima.resource.metadata, org.apache.uima.resource.metadata.impl, org.apache.uima.resource.service.impl, org.apache.uima.search, org.apache.uima.search.impl, org.apache.uima.tools, org.apache.uima.tools.annot_view, org.apache.uima.tools.cpm, org.apache.uima.tools.cvd, org.apache.uima.tools.cvd.control, org.apache.uima.tools.cvd.tsview, org.apache.uima.tools.docanalyzer, org.apache.uima.tools.images, org.apache.uima.tools.jcasgen, org.apache.uima.tools.pear.install, org.apache.uima.tools.pear.merger, org.apache.uima.tools.stylemap, org.apache.uima.tools.util.gui, org.apache.uima.tools.util.htmlview, org.apache.uima.tools.viewer, org.apache.uima.uimacpp, org.apache.uima.util, org.apache.uima.util.impl, org.apache.vinci.debug, org.apache.vinci.transport, org.apache.vinci.transport.context, org.apache.vinci.transport.document, org.apache.vinci.transport.util, org.apache.vinci.transport.vns, org.apache.vinci.transport.vns.client, org.apache.vinci.transport.vns.service org.apache.log4j;resolution:=optional,* *;scope=compile;inline=true org.apache.uima.runtime;singleton:=true J2SE-1.5 true registered maven-dependency-plugin unpackDependentJars unpack-dependencies ${project.build.outputDirectory} uimaj-2.4.0/uimaj-ep-runtime/plugin.xml0000644000175000017500000000203311665471044017734 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-ep-runtime/marker-file-identifying-eclipse-plugin0000644000175000017500000000000011665471044025252 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-runtime/src/0000755000175000017500000000000011665471044016505 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-runtime/src/main/0000755000175000017500000000000011665471044017431 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-runtime/src/main/resources/0000755000175000017500000000000011665471044021443 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/0000755000175000017500000000000011665472250020367 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/feature.properties0000644000175000017500000000241411665471204024137 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** # do not delete this file - it is required for optimized site generation # feature.properties # contains externalized strings for feature.xml # "%foo" in feature.xml corresponds to the key "foo" in this file # java.io.Properties file (ISO 8859-1 with "\" escapes) # This file should be translated.uimaj-2.4.0/uimaj-eclipse-feature-runtime/pom.xml0000644000175000017500000001005111665471546021710 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-eclipse-feature-runtime 2.4.0 Apache UIMA Eclipse: ${project.artifactId} UIMA Eclipse Plugin Feature that has the base UIMA runtime, referred to by other plugins that need UIMA framework code ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-runtime scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-runtime http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-runtime ${project.artifactId} ${project.artifactId}_${parsedVersion.osgiVersion} ${basedir} feature.properties feature.xml true maven-resources-plugin filter feature.xml generate-resources copy-resources ${basedir} src/main/resources feature.xml true uimaj-2.4.0/uimaj-eclipse-feature-runtime/marker-file-identifying-eclipse-feature0000644000175000017500000000000011665471204030056 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/build.properties0000644000175000017500000000177011665471204023607 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** bin.includes = feature.xml uimaj-2.4.0/uimaj-eclipse-feature-runtime/src/0000755000175000017500000000000011665471204021154 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/src/main/0000755000175000017500000000000011665471204022100 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/src/main/resources/0000755000175000017500000000000011665471204024112 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-runtime/src/main/resources/feature.xml0000644000175000017500000000521011665471204026265 0ustar drazzibdrazzib This feature packages the UIMA runtime libraries plugin. Copyright the Apache Software Foundation and others; see License and NOTICE files Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/uimaj-eclipse-feature-runtime/feature.xml0000644000175000017500000000513211665472250022545 0ustar drazzibdrazzib This feature packages the UIMA runtime libraries plugin. Copyright the Apache Software Foundation and others; see License and NOTICE files Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/pom.xml0000644000175000017500000002644011665471546014060 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 uimaj-parent/pom.xml uimaj pom 2.4.0 Apache UIMA Java SDK: ${project.artifactId} The top project for the uimaj SDK ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1 scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1 http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1 ${project.artifactId} 12315996 uimaj-${project.version} ${ibmNoticeText} org.apache.uima uimaj-adapter-vinci ${project.version} org.apache.uima uimaj-adapter-soap ${project.version} org.apache.uima uimaj-bootstrap ${project.version} org.apache.uima uimaj-core ${project.version} org.apache.uima uimaj-cpe ${project.version} org.apache.uima uimaj-examples ${project.version} org.apache.uima uimaj-tools ${project.version} org.apache.uima uimaj-ep-cas-editor ${project.version} org.apache.uima uimaj-ep-configurator ${project.version} org.apache.uima uimaj-ep-debug ${project.version} org.apache.uima uimaj-ep-jcasgen ${project.version} org.apache.uima uimaj-ep-pear-packager ${project.version} org.apache.uima uimaj-ep-runtime ${project.version} org.apache.uima uimaj-ep-cas-editor-ide ${project.version} org.apache.uima uimaj-ep-launcher ${project.version} uimaj-parent aggregate-uimaj maven-javadoc-plugin javadocs-distr prepare-package javadoc api_1.5 http://download.oracle.com/javase/1.5.0/docs/api/ Packages * uimaj-core/src/main/java;uimaj-document-annotation/src/main/java *.internal.*:*.impl.* ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASDeserializer.java ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASParsingException.java ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasDeserializer.java ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiCasSerializer.java ${basedir}/uimaj-core/src/main/java/org/apache/uima/cas/impl/XmiSerializationSharedData.java ${basedir}/uimaj-cpe/src/main/java/org/apache/uima/collection/impl/metadata/cpe/CpeDescriptorFactory.java ${basedir}/uimaj-cpe/src/main/java/org/apache/uima/collection/impl/cpm/engine/CPMChunkTimeoutException.java Apache UIMA Java SDK ${project.version} User-Level API Documentation Apache UIMA Java SDK ${project.version} User-Level API Documentation org.apache.rat apache-rat-plugin default-cli check verify release.properties README* RELEASE_NOTES* issuesFixed/** src/main/resources/docbook-shared/titlepage/*.xsl marker-file-identifying-* DEPENDENCIES aggregate-uimaj*/** jVinci/** PearPackagingMavenPlugin/** uima-docbook-*/** uimaj-adapter-*/** uimaj-component-test-util/** uimaj-core/** uimaj-cpe/** uimaj-document-annotation/** uimaj-eclipse-*/** uimaj-ep-*/** uimaj-examples/** uimaj-test-util/** uimaj-tools/** uimaj-jet-expander/** uimaj-bootstrap/** uimaj-internal-tools/** apache-release maven-changes-plugin default-cli ${jiraVersion} uimaj-2.4.0/aggregate-uimaj-docbooks/0000755000175000017500000000000011665472362017364 5ustar drazzibdrazzibuimaj-2.4.0/aggregate-uimaj-docbooks/pom.xml0000644000175000017500000000550111665471546020705 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml aggregate-uimaj-docbooks pom 2.4.0 Apache UIMA Aggregate POM ${project.artifactId}: UIMA Base ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj-docbooks scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj-docbooks http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj-docbooks ${project.artifactId} ../uima-docbook-overview-and-setup ../uima-docbook-references ../uima-docbook-tools ../uima-docbook-tutorials-and-users-guides uimaj-2.4.0/uimaj-examples/0000755000175000017500000000000011665472052015447 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/pom.xml0000644000175000017500000001152011665471546016772 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-examples jar 2.4.0 Apache UIMA Base: ${project.artifactId}: SDK Examples Examples and sample code ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-examples scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-examples http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-examples ${project.artifactId} ${ibmNoticeText} org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-cpe ${project.parent.version} compile org.apache.uima uimaj-document-annotation ${project.parent.version} compile org.apache.uima uimaj-tools ${project.parent.version} compile org.eclipse.emf common 2.1.0 provided org.eclipse.emf ecore 2.1.0 provided org.eclipse.emf ecore-xmi 2.1.0 provided uima-examples org.apache.rat apache-rat-plugin default-cli release.properties src/main/data/*.txt src/main/run_configuration/*.launch src/main/eclipseProject/*readme.txt src/main/resources/org/apache/uima/tutorial/ex6/*.txt uimaj-2.4.0/uimaj-examples/src/0000755000175000017500000000000011665471020016230 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/0000755000175000017500000000000011665471034017161 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/0000755000175000017500000000000011665471024021521 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/0000755000175000017500000000000011665471022024667 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/SofaExampleAnnotator.xml0000644000175000017500000000537011665471022031510 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.SofaExampleAnnotator English to German translator Creates output SOFA in de CAS 1.0 The Apache Software Foundation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation sofa.test.CrossAnnotation EnglishDocument GermanDocument x-unspecified true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/NamesAndPersonTitles_TAE.xml0000644000175000017500000000537411665471022032155 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Name Recognizer and Person Title Annotator Detects Names and Person Titles NameRecognizer PersonTitleAnnotator example.PersonTitle en example.Name x-unspecified true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/UIMA_Analysis_Example.xml0000644000175000017500000000630211665471022031463 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Tokenizer, Name Recognizer, Person Title and Email Address Annotator Detects Tokens, Sentences, Names, Person Titles and Email Addresses TokenAndSentence NamesAndPersonTitles Email org.apache.uima.examples.tokenizer.Sentence org.apache.uima.examples.tokenizer.Token example.PersonTitle en example.Name example.EmailAddress x-unspecified true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/SimpleTokenAndSentenceAnnotator.xml0000644000175000017500000000546011665471022033646 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.tokenizer.SimpleTokenAndSentenceAnnotator Simple Token and Sentence Annotator Annotates tokens and sentences. 1.0 The Apache Software Foundation org.apache.uima.examples.tokenizer.Token uima.tcas.Annotation org.apache.uima.examples.tokenizer.Sentence uima.tcas.Annotation org.apache.uima.examples.tokenizer.Sentence org.apache.uima.examples.tokenizer.Token en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/SimpleNameRecognizer_RegEx_TAE.xml0000644000175000017500000001077311665471022033266 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.RegExAnnotator Simple Name Recognizer using Regular Expressions Detects Names using a simple regular expression. Patterns Regular expression patterns to match. The language is that supported by Java 1.4. String true false TypeNames Names of CAS Types to create for the patterns found. The indexes of this array correspond to the indexes of the Patterns or PatternFiles arrays. If a match is found for Patterns[i], it will result in an annotation of type TypeNames[i]. String true false ContainingAnnotationTypes Names of CAS Input Types within which annotations should be created. String true false AnnotateEntireContainingAnnotation When the ContainingAnnoationTypes parameter is specified, a value of true for this parameter will cause the entire containing annotation to be used as the span of the new annotation, rather than just the span of the regular expression match. This can be used to "classify" previously created annotations according to whether or not they contain text matching a regular expression. Boolean false false Patterns \p{Upper}\w*(\.?\s\p{Upper}\w*)+ TypeNames example.Name example.Name A proper name. uima.tcas.Annotation example.Name true true false ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/GovernmentOfficialRecognizer_RegEx_TAE.xmluimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/GovernmentOfficialRecognizer_RegEx_T0000644000175000017500000001424111665471022034002 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.RegExAnnotator Government Title Recognizer using Regular Expressions Detects Government Titles using regular expressions. Patterns Regular expression patterns to match. The language is that supported by Java 1.4. String true false TypeNames Names of CAS Types to create for the patterns found. The indexes of this array correspond to the indexes of the Patterns or PatternFiles arrays. If a match is found for Patterns[i], it will result in an annotation of type TypeNames[i]. String true false ContainingAnnotationTypes Names of CAS Input Types within which annotations should be created. String true false AnnotateEntireContainingAnnotation When the ContainingAnnoationTypes parameter is specified, a value of true for this parameter will cause the entire containing annotation to be used as the span of the new annotation, rather than just the span of the regular expression match. This can be used to "classify" previously created annotations according to whether or not they contain text matching a regular expression. Boolean false false ContainingAnnotationTypes example.Name AnnotateEntireContainingAnnotation true example.Name A proper name. uima.tcas.Annotation example.GovernmentOfficial A government official. uima.tcas.Annotation example.Name example.GovernmentOfficial en true true false PatternFile An optional external file containing regular expressions to match. File format is as follows: - Lines starting with # or whitepsace are ignored - Lines starting with % indicate an annotation type. - All other lines are regular expressions. The languages is that supported by Java 1.4. If a regular expression is matched, it will be annotated with the last annotation type declared (the nearest preceding line starting with %). true GovernmentTitlePatterns File containing Regular Expressions for the CAS type example.GovernmentOfficial. file:GovernmentTitlePatterns.dat PatternFile GovernmentTitlePatterns uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/RegExAnnotator.xml0000644000175000017500000001236011665471022030313 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.RegExAnnotator RegEx Annotator Matches regular expressions in document text. Patterns Regular expression patterns to match. The language is that supported by Java 1.4. String true false TypeNames Names of CAS Types to create for the patterns found. The indexes of this array correspond to the indexes of the Patterns or PatternFiles arrays. If a match is found for Patterns[i] or for any pattern in PatternFile[i], it will result in an annotation of type TypeNames[i]. String true true ContainingAnnotationTypes Names of CAS Input Types within which annotations should be created. String true false AnnotateEntireContainingAnnotation When the ContainingAnnoationTypes parameter is specified, a value of true for this parameter will cause the entire containing annotation to be used as the span of the new annotation, rather than just the span of the regular expression match. This can be used to "classify" previously created annotations according to whether or not they contain text matching a regular expression. Boolean false false Patterns President|Governor|Senator|Representative|Gov\.|Sen\.|Rep\. TypeNames GovernmentTitle GovernmentTitle The title of a government official. uima.tcas.Annotation GovernmentTitle true true false PatternFile An optional external file containing regular expressions to match. File format is as follows: - Lines starting with # or whitepsace are ignored - Lines starting with % indicate an annotation type. - All other lines are regular expressions. The language is that supported by Java 1.4. If a regular expression is matched, it will be annotated with the last annotation type declared (the nearest preceding line starting with %). true uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/SimpleEmailRecognizer_RegEx_TAE.xml0000644000175000017500000001103511665471022033425 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.RegExAnnotator Simple Name Recognizer using Regular Expressions Detects Names using a simple regular expression. Patterns Regular expression patterns to match. The language is that supported by Java 1.4. String true false TypeNames Names of CAS Types to create for the patterns found. The indexes of this array correspond to the indexes of the Patterns or PatternFiles arrays. If a match is found for Patterns[i], it will result in an annotation of type TypeNames[i]. String true false ContainingAnnotationTypes Names of CAS Input Types within which annotations should be created. String true false AnnotateEntireContainingAnnotation When the ContainingAnnoationTypes parameter is specified, a value of true for this parameter will cause the entire containing annotation to be used as the span of the new annotation, rather than just the span of the regular expression match. This can be used to "classify" previously created annotations according to whether or not they contain text matching a regular expression. Boolean false false Patterns [a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+[a-zA-Z]{2,4} TypeNames example.EmailAddress example.EmailAddress Email Address uima.tcas.Annotation example.EmailAddress true true false ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/PersonTitleAnnotator_WithinNamesOnly.xmluimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/PersonTitleAnnotator_WithinNamesOnly0000644000175000017500000001521511665471022034124 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.PersonTitleAnnotator Person Title Annotator - Within Names only A configuration of the PersonTitleAnnotator that looks for Person Titles only within existing Name annotations. See also PersonTitleAnnotator.xml. 1.0 The Apache Software Foundation CivilianTitles List of Civilian Titles to be annotated. String true true MilitaryTitles List of Military Titles to be annotated. String true true GovernmentTitles List of Government Titles to be annotated. String true true ContainingAnnotationType Annotation type within which to search for Person Titles. If no value is specified, the entire document will be searched. String false false CivilianTitles Mr. Ms. Mrs. Dr. MilitaryTitles Gen. Col. Maj. Capt. Lt. Gen. Lt Col. Lt. GovernmentTitles Vice President President Vice Pres. Pres. Governor Lt. Governor Gov. Lt. Gov. Senator Sen. ContainingAnnotationType example.Name example.PersonTitle A Personal Title. uima.tcas.Annotation Kind The kind of title - Civilian, Military, or Government. example.PersonTitleKind example.PersonTitleKind A kind of person title - Civilian, Military, or Government. uima.cas.String Civilian Title of a person not in military or government service. Military Title of a person in the military. Government Title of a government official. example.Name A proper name. uima.tcas.Annotation example.Name example.PersonTitle example.PersonTitle:Kind en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/XmlDetagger.xml0000644000175000017500000000565211665471022027624 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.XmlDetagger XML Detagger A multi-sofa annotator that does XML detagging. Reads XML data from the input Sofa (named "xmlDocument"); this data can be stored in the CAS as a string or array, or it can be a URI to a remote file. The XML is parsed using the JVM's default parser, and the plain-text content is written to a new sofa called "plainTextDocument". 1.0 The Apache Software Foundation XmlTagContainingText The name of an XML tag that appears in the files. Only text that falls within this XML tag will be considered part of the "document" that is put into the CAS. If omitted, the entire file will be considered the document. String false false xmlDocument plainTextDocument en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/PersonTitleAnnotator.xml0000644000175000017500000001463011665471022031553 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.PersonTitleAnnotator Person Title Annotator An example annotator that discovers Person Titles in text and classifies them into three categories - Civilian (e.g. Mr.,Ms.), Military (e.g. Lt. Col.) , and Government (e.g. Gov., Sen.). This annotator can be configured to only look for titles within existing annotations of a particular type (for example, Person Name annotations). 1.0 The Apache Software Foundation CivilianTitles List of Civilian Titles to be annotated. String true true MilitaryTitles List of Military Titles to be annotated. String true true GovernmentTitles List of Government Titles to be annotated. String true true ContainingAnnotationType Annotation type within which to search for Person Titles. If no value is specified, the entire document will be searched. String false false CivilianTitles Mr. Ms. Mrs. Dr. MilitaryTitles Gen. Col. Maj. Capt. Lt. Gen. Lt Col. Lt. GovernmentTitles Vice President President Vice Pres. Pres. Governor Lt. Governor Gov. Lt. Gov. Senator Sen. example.PersonTitle A Personal Title. uima.tcas.Annotation Kind The kind of title - Civilian, Military, or Government. example.PersonTitleKind example.PersonTitleKind A kind of person title - Civilian, Military, or Government. uima.cas.String Civilian Title of a person not in military or government service. Military Title of a person in the military. Government Title of a government official. example.PersonTitle example.PersonTitle:Kind en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/analysis_engine/NamesAndGovernmentOfficials_TAE.xml0000644000175000017500000000547311665471022033466 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Name Recognizer and Government Official Recognizer Detects Names and Government Officials NameRecognizer GovernmentOfficialRecognizer example.GovernmentOfficial en example.Name x-unspecified true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/0000755000175000017500000000000011665471022024731 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/MeetingDetectorTAE_AdvancedFixedFlow.xmluimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/MeetingDetectorTAE_AdvancedFixedFlow0000644000175000017500000001111611665471022033665 0ustar drazzibdrazzib org.apache.uima.java false Meeting Detector TAE with Advanced Fixed Flow Controller Detects Room Numbers, Times, and Dates in text, and annotates the combination of all three as a meeting. This example demonstrates how to use the Advanced Fixed Flow Controller. 1.0 The Apache Software Foundation Flow Specifies the flow. This is an array of strings where each string is either a single Analysis Engine key or a comma-separated list of Analysis Engine keys that can be executed in parallel. String true true FlowController/Flow AllowContinueOnFailure Specifies for which AnalysisEngines the Flow should continue when an exception occurs. This parameter takes an array of Strings as its value. Each String is the key of AnalysisEngine for which continuing on failure should be allowed. String true FlowController/AllowContinueOnFailure Flow RoomNumberAnnotator,DateTimeAnnotator MeetingAnnotator AllowContinueOnFailure MeetingAnnotator org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.Meeting uimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/AdvancedFixedFlowController.xml0000644000175000017500000001012611665471022033034 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.flow.AdvancedFixedFlowController Advanced Fixed Flow Controller An extension of the FixedFlowController that can also do ParallelSteps and can continue after errors. It is configured via the "Flow" configuration parameter rather than using the flowConstraints element of the aggregate descriptor. 1.0 The Apache Software Foundation ActionAfterCasMultiplier The action to be taken after a CAS has been input to a CAS Multiplier and the CAS Multiplier has finished processing it. Valid values are: continue - the CAS continues on to the next element in the flow stop - the CAS will no longer continue in the flow, and will be returned from the aggregate if possible. drop - the CAS will no longer continue in the flow, and will be dropped (not returned from the aggregate) if possible. dropIfNewCasProduced (the default) - if the CAS multiplier produced a new CAS as a result of processing this CAS, then this CAS will be dropped. If not, then this CAS will continue. String false false Flow Specifies the flow. This is an array of strings where each string is either a single Analysis Engine key or a comma-separated list of Analysis Engine keys that should be executed in parallel. This parameter must be overridden in the aggregate AE containing this Flow Conroller. String true true AllowContinueOnFailure Specifies for which AnalysisEngines the Flow should continue when an exception occurs. This parameter takes an array of Strings as its value. Each String is the key of AnalysisEngine for which continuing on failure should be allowed. String true false ActionAfterCasMultiplier dropIfNewCasProduced uimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/MeetingDetectorTAE_Whiteboard.xml0000644000175000017500000000547311665471022033250 0ustar drazzibdrazzib org.apache.uima.java false Meeting Detector TAE Detects Room Numbers, Times, and Dates in text, and annotates the combination of all three as a meeting. org.apache.uima.tutorial.Meeting org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.TimeAnnot en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/flow_controller/WhiteboardFlowController.xml0000644000175000017500000000421411665471022032440 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.flow.WhiteboardFlowController Whiteboard Flow Controller FlowController implementing a simple version of the "whiteboard" flow model. Each time a CAS is received, it looks at the pool of available AEs that have not yet run on that CAS, and picks one whose input requirements are satisfied. Limitations: only looks at types, not features. Does not handle multiple Sofas or CasMultipliers. 1.0 The Apache Software Foundation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/collection_reader/0000755000175000017500000000000011665471024025176 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/collection_reader/XmiCollectionReader.xml0000644000175000017500000000556611665471024031630 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.xmi.XmiCollectionReader XMI Collection Reader A simple collection reader that reads CASes in XMI format from a directory in the filesystem. 1.0 The Apache Software Foundation InputDirectory Directory containing input files String false true FailOnUnknownType Boolean false false InputDirectory C:/Program Files/apache-uima/examples/data FailOnUnknownType true true false true uimaj-2.4.0/uimaj-examples/src/main/descriptors/collection_reader/FileSystemCollectionReader.xml0000644000175000017500000001235611665471024033152 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.cpe.FileSystemCollectionReader File System Collection Reader Reads files from the filesystem. This CollectionReader may be used with or without a CAS Initializer. If a CAS Initializer is supplied, it will be passed an InputStream to the file and must populate the CAS from that InputStream. If no CAS Initializer is supplied, this CollectionReader will read the file itself and set treat the entire contents of the file as the document to be inserted into the CAS. 1.0 The Apache Software Foundation InputDirectory Directory containing input files String false true Encoding Character encoding for the documents. If not specified, the default system encoding will be used. Note that this parameter only applies if there is no CAS Initializer provided; otherwise, it is the CAS Initializer's responsibility to deal with character encoding issues. String false false Language ISO language code for the documents String false false BrowseSubdirectories True means include files of subdirectories, recursively, of the input directory. Boolean false false InputDirectory C:/Program Files/apache-uima/examples/data BrowseSubdirectories false Language en org.apache.uima.examples.SourceDocumentInformation true false true uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_multiplier/0000755000175000017500000000000011665471022024533 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextSegmenter.xml0000644000175000017500000000536711665471022031240 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.casMultiplier.SimpleTextSegmenter Simple Text Segmenter Splits a text document into pieces. Approximate size of the segments as determined by the SegmentSize parameter, but the break between segments will always occur at a newline character, so segments will not be exactly that size. 1.0 The Apache Software Foundation SegmentSize Approximate number of characters that should be in each segment. Integer false true SegmentSize 100000 false true true uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_multiplier/SimpleTextMerger.xml0000644000175000017500000000645711665471022030531 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.casMultiplier.SimpleTextMerger Simple Text Merger Merges text documents into larger ones, producing a merged CAS. Also copies selected annotation types to the merged CAS. The input CAS requires an instance of the type org.apache.uima.examples.SourceDocumentInformation (which is produced by the FileSystemCollectionReader and SimpleTextSegmenter examples). Input CASes will be merged until a CAS is encountered whose SourceDocumentInformation FS has its lastSegment feature set to true. At that point a merged CAS will be output which includes the content up to and including that CAS. If additional CASes are then received, a second merged CAS will be built, including all content from that point until the next CAS with lastSegment = true, and so on. 1.0 The Apache Software Foundation AnnotationTypesToCopy Names of annotation types to be copied from source CASes into the merged CAS. String true true AnnotationTypesToCopy org.apache.uima.examples.SourceDocumentInformation false true true uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_multiplier/SegmenterAndTokenizerAE.xml0000644000175000017500000000500711665471022031734 0ustar drazzibdrazzib org.apache.uima.java false Segmenter and Tokenizer Splits a document into pieces and runs tokenization on each piece independently. All segments are output. Segmenter Tokenizer org.apache.uima.examples.tokenizer.Sentence org.apache.uima.examples.tokenizer.Token en true true true uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml0000644000175000017500000001237211665471022032201 0ustar drazzibdrazzib org.apache.uima.java false Segment, Annotate, and Merge Example AE Splits a document into pieces and runs the tokenizer and name recognizer on each piece independently. Then runs the merger to reassemble the document, keeping the name annotations in the merged document but discarding the tokens. By default the intermediate segments are dropped after being processed by the merger, and are not output from the aggregate. This behavior is configurable via the ActionForIntermediateSegments parameter. 1.0 The Apache Software Foundation Segmenter Tokenizer NameRecognizer Merger AnnotationTypesToPreserve Names of annotation types to be preserved in the merged CAS. String true true Merger/AnnotationTypesToCopy ActionForIntermediateSegments Tells the flow controller what to do with intermediate segments after they are input to the merger. Valid values are: continue - the CAS continues on to the next element in the flow stop - the CAS will no longer continue in the flow, and will be returned from the aggregate if possible. drop - the CAS will no longer continue in the flow, and will be dropped (not returned from the aggregate) if possible. dropIfNewCasProduced (the default) - if the CAS multiplier produced a new CAS as a result of processing this CAS, then this CAS will be dropped. If not, then this CAS will continue. String false false FixedFlowController/ActionAfterCasMultiplier AnnotationTypesToPreserve example.Name ActionForIntermediateSegments drop org.apache.uima.examples.tokenizer.Sentence org.apache.uima.examples.tokenizer.Token example.Name en true true true uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/0000755000175000017500000000000011665471020024176 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/AnnotationPrinter.xml0000644000175000017500000000513611665471020030403 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.cpe.AnnotationPrinter Annotation Printer Prints annotations. 1.0 The Apache Software Foundation outputFile File to which annotations will be printed String false false outputFile temp-uima-output/annotprint/annotations.txt org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/XmiWriterCasConsumer.xml0000644000175000017500000000540611665471020031022 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.xmi.XmiWriterCasConsumer Xmi Writer CAS Consumer Writes the CAS to XMI format 1.0 The Apache Software Foundation OutputDirectory Directory where the XMI files will be written String false true OutputDirectory temp-uima-output/xmi_output org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/InlineXmlCasConsumer.xml0000644000175000017500000000613211665471020030764 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.cpe.InlineXmlCasConsumer Inline XML CAS Consumer Generates inline XML for each CAS and writes it to a file 1.0 The Apache Software Foundation OutputDirectory Directory into which to write output files String false true OutputDirectory temp-uima-output/inlinexml org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/XmiWriterWithTutorialTypeSystem.xml0000644000175000017500000000526611665471020033312 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.xmi.XmiWriterCasConsumer Xmi Writer CAS Consumer Writes the CAS to XMI format 1.0 The Apache Software Foundation OutputDirectory Directory where the XMI files will be written String false true OutputDirectory temp-uima-output/xmi_output org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/XmiEcoreCasConsumer.xml0000644000175000017500000000642611665471020030606 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.xmi.XmiEcoreCasConsumer Xmi Writer CAS Consumer Writes the CAS to XMI format 1.0 The Apache Software Foundation OutputDirectory Directory where the XMI files will be written String false true WriteEcoreTypeSystem If true, the type system will be serialized in Ecore format to the output directory, and each of the output XMI files will have a link to it via their schemaLocation attribute. If this option is set to true, EMF libraries are required in the classpath at runtime. Boolean false false OutputDirectory xmi_output WriteEcoreTypeSystem false org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/cas_consumer/XCasWriterCasConsumer.xml0000644000175000017500000000554611665471020031130 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.examples.cpe.XCasWriterCasConsumer XCAS Writer CAS Consumer Writes the CAS to a stand-off XML format (XCAS) 1.0 The Apache Software Foundation OutputDirectory String Directory where the XCAS files will be written false true OutputDirectory temp-uima-output/xcaswriter org.apache.uima.examples.SourceDocumentInformation false true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/vinciService/0000755000175000017500000000000011665471022024150 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/vinciService/MeetingDetectorVinciService.xml0000644000175000017500000000227511665471022032274 0ustar drazzibdrazzib AnalysisEngine uima.tutorial.MeetingDetectorTAE Vinci uimaj-2.4.0/uimaj-examples/src/main/descriptors/vinciService/PersonTitleVinciService.xml0000644000175000017500000000230011665471022031447 0ustar drazzibdrazzib AnalysisEngine uima.annotator.PersonTitleAnnotator Vinci ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-examples/src/main/descriptors/vinciService/XmiWriterVinciServiceWithTutorialTypeSystem.xmluimaj-2.4.0/uimaj-examples/src/main/descriptors/vinciService/XmiWriterVinciServiceWithTutorialTypeSy0000644000175000017500000000230711665471022034077 0ustar drazzibdrazzib CasConsumer uima.consumer.XmiWriterWithTutorialTypeSystem Vinci uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/0000755000175000017500000000000011665471022023362 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex1/0000755000175000017500000000000011665471022024057 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex1/RoomNumberAnnotator.xml0000644000175000017500000000453111665471022030557 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex1.RoomNumberAnnotator Room Number Annotator An example annotator that searches for room numbers in the IBM Watson research buildings. 1.0 The Apache Software Foundation org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.RoomNumber:building true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex1/TutorialTypeSystem.xml0000644000175000017500000000330611665471022030455 0ustar drazzibdrazzib TutorialTypeSystem Type System Definition for the tutorial examples - as of Exercise 1 The Apache Software Foundation 1.0 org.apache.uima.tutorial.RoomNumber uima.tcas.Annotation building Building containing this room uima.cas.String uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex2/0000755000175000017500000000000011665471022024060 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex2/RoomNumberAnnotator.xml0000644000175000017500000000677111665471022030570 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex2.RoomNumberAnnotator Room Number Annotator An example annotator that searches for room numbers in the IBM Watson research buildings. 1.0 The Apache Software Foundation Patterns List of room number regular expression pattterns. String true true Locations List of locations corresponding to the room number expressions specified by the Patterns parameter. String true true Patterns \b[0-4]\d-[0-2]\d\d\b \b[G1-4][NS]-[A-Z]\d\d\b \bJ[12]-[A-Z]\d\d\b Locations Watson - Yorktown Watson - Hawthorne I Watson - Hawthorne II org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.RoomNumber:building true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex5/0000755000175000017500000000000011665471020024061 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex5/RoomNumberAnnotator.xml0000644000175000017500000000747511665471020030573 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex5.RoomNumberAnnotator Room Number Annotator An example annotator that searches for room numbers in the IBM Watson research buildings. 1.0 The Apache Software Foundation Patterns List of room number regular expression pattterns. String true true Locations List of locations corresponding to the room number expressions specified by the Patterns parameter. String true true Patterns \b[0-4]\d-[0-2]\d\d\b \b[G1-4][NS]-[A-Z]\d\d\b \bJ[12]-[A-Z]\d\d\b (foo Locations Watson - Yorktown Watson - Hawthorne I Watson - Hawthorne II org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.RoomNumber:building true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex4/0000755000175000017500000000000011665471020024060 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex4/TutorialTypeSystem.xml0000644000175000017500000000741511665471020030463 0ustar drazzibdrazzib TutorialTypeSystem Type System Definition for the tutorial examples - as of Exercise 4 The Apache Software Foundation 1.0 org.apache.uima.tutorial.RoomNumber uima.tcas.Annotation building Building containing this room uima.cas.String org.apache.uima.tutorial.DateTimeAnnot uima.tcas.Annotation shortDateString uima.cas.String org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.Meeting uima.tcas.Annotation room org.apache.uima.tutorial.RoomNumber date org.apache.uima.tutorial.DateAnnot startTime org.apache.uima.tutorial.TimeAnnot endTime org.apache.uima.tutorial.TimeAnnot org.apache.uima.examples.tokenizer.Token uima.tcas.Annotation org.apache.uima.examples.tokenizer.Sentence uima.tcas.Annotation uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex4/MeetingDetectorTAE.xml0000644000175000017500000000546211665471020030225 0ustar drazzibdrazzib org.apache.uima.java false Meeting Detector TAE Detects Room Numbers, Times, and Dates in text, and annotates the combination of all three as a meeting. RoomNumber DateTime Meeting org.apache.uima.tutorial.Meeting org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.TimeAnnot en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex4/MeetingAnnotator.xml0000644000175000017500000000645011665471020030065 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex4.MeetingAnnotator Meeting Annotator Detects meetings from co-occurrences of room numbers, dates, and times 1.0 The Apache Software Foundation WindowSize Maximum number of characters within which a room number, a date, and two times must occur for a meeting annotation to be created. Integer false true WindowSize 200 org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.Meeting en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex6/0000755000175000017500000000000011665471022024064 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex6/UimaMeetingDetectorTAE.xml0000644000175000017500000000766411665471020031051 0ustar drazzibdrazzib org.apache.uima.java false UIMA Meeting Detector TAE Annotates meeting notices, and also marks those meetings whose topic is likely to be related to UIMA. Also annotates all UIMA acronyms and provides their expanded form. This TAE also demonstrates using the Resource Manager to share data between annotators. Both the UimaMeetingAnnotator and UimaAcronymAnnotator share a common resource file. MeetingDetector UimaMeetingAnnotator UimaAcronymAnnotator org.apache.uima.tutorial.Meeting org.apache.uima.tutorial.UimaMeeting org.apache.uima.tutorial.UimaAcronym en true true false UimaAcronymTableFile A table containing UIMA acronyms and their exanded forms. file:org/apache/uima/tutorial/ex6/uimaAcronyms.txt org.apache.uima.tutorial.ex6.StringMapResource_impl UimaAcronymAnnotator/AcronymTable UimaAcronymTableFile UimaMeetingAnnotator/UimaTermTable UimaAcronymTableFile uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex6/UimaMeetingAnnotator.xml0000644000175000017500000000553111665471022030704 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex6.UimaMeetingAnnotator UIMA Meeting Annotator Iterates over Meeting annotations and annotates a meeting as a UimaMeeting if a UIMA acronym occurs in close proximity to that meeting. 1.0 The Apache Software Foundation org.apache.uima.tutorial.Meeting org.apache.uima.tutorial.UimaMeeting en true true false UimaTermTable Map whose keps are UIMA terms. org.apache.uima.tutorial.ex6.StringMapResource false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex6/TutorialTypeSystem.xml0000644000175000017500000001050611665471020030460 0ustar drazzibdrazzib TutorialTypeSystem Type System Definition for the tutorial examples - as of Exercise 6 1.0 The Apache Software Foundation org.apache.uima.tutorial.RoomNumber uima.tcas.Annotation building Building containing this room uima.cas.String org.apache.uima.tutorial.DateTimeAnnot uima.tcas.Annotation shortDateString uima.cas.String org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.Meeting uima.tcas.Annotation room org.apache.uima.tutorial.RoomNumber date org.apache.uima.tutorial.DateAnnot startTime org.apache.uima.tutorial.TimeAnnot endTime org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.UimaAcronym uima.tcas.Annotation expandedForm uima.cas.String org.apache.uima.tutorial.UimaMeeting org.apache.uima.tutorial.Meeting org.apache.uima.examples.tokenizer.Token uima.tcas.Annotation org.apache.uima.examples.tokenizer.Sentence uima.tcas.Annotation uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex6/UimaAcronymAnnotator.xml0000644000175000017500000000646411665471020030730 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex6.UimaAcronymAnnotator UIMA Acronym Annotator Annotates UIMA Acronyms and provides their expanded form. 1.0 The Apache Software Foundation org.apache.uima.tutorial.UimaAcronym en true true false AcronymTable Table of acronyms and their expanded forms. org.apache.uima.tutorial.ex6.StringMapResource UimaAcronymTableFile A table containing UIMA acronyms and their expanded forms. file:org/apache/uima/tutorial/ex6/uimaAcronyms.txt org.apache.uima.tutorial.ex6.StringMapResource_impl AcronymTable UimaAcronymTableFile uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex3/0000755000175000017500000000000011665471020024057 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex3/RoomNumberAndDateTime.xml0000644000175000017500000000510511665471020030727 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Room Number and DateTime Annotators Detects Room Numbers, Dates, and Times RoomNumber DateTime org.apache.uima.tutorial.RoomNumber org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.TimeAnnot en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex3/TutorialDateTime.xml0000644000175000017500000000534311665471020030026 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.tutorial.ex3.TutorialDateTime TutorialDateTime Annotator Finds dates and times 1.0 The Apache Software Foundation org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.DateAnnot en true true false uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/ex3/TutorialTypeSystem.xml0000644000175000017500000000476011665471020030462 0ustar drazzibdrazzib TutorialTypeSystem Type System Definition for the tutorial examples - as of Exercise 3 The Apache Software Foundation 1.0 org.apache.uima.tutorial.RoomNumber uima.tcas.Annotation building Building containing this room uima.cas.String org.apache.uima.tutorial.DateTimeAnnot uima.tcas.Annotation shortDateString uima.cas.String org.apache.uima.tutorial.TimeAnnot org.apache.uima.tutorial.DateTimeAnnot org.apache.uima.tutorial.DateAnnot org.apache.uima.tutorial.DateTimeAnnot uimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/search/0000755000175000017500000000000011665471022024627 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-examples/src/main/descriptors/tutorial/search/MeetingIndexBuildSpec.xml0000644000175000017500000000424511665471022031531 0ustar drazzibdrazzib org.apache.uima.examples.tokenizer.Token org.apache.uima.tutorial.DateAnnot this.is.another.test bar=42 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/0000755000175000017500000000000011665471102025574 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams6.xml0000644000175000017500000000465411665471102032275 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator1StringParam Annotator1 Annotator2 ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/NestedAggregateSegmenterForErrorTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/NestedAggregateSegmenterForErro0000644000175000017500000000411511665471102033722 0ustar drazzibdrazzib org.apache.uima.java false Nested Aggregate for Error Test An aggregate AE that contains an Aggregate Segmenter, where that Aggregate Semgneter throws an exception. For error testing. AggregateSegmenter true true true ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateSegmenterForDropTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateSegmenterForDropTest.x0000644000175000017500000000414011665471102033660 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including a Segmenter For testing only Segmenter Annotator true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams7.xml0000644000175000017500000000465511665471102032277 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator3/StringParam Annotator1 Annotator2 ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerWithConfigurationGroups.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerWithConfiguration0000644000175000017500000001225611665471102034064 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.SegmentDroppingFlowController FlowController With Configuration Groups For testing parameter overrides on FlowControllers. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 1 2 3 StringArrayParam e n - U S IntegerParam 1776 StringParam de StringArrayParam d e IntegerArrayParam 4 5 6 StringParam zh StringArrayParam z h FloatParam 3.14 StringArrayParam ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidAggregate_UndefinedKeyInFlow.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidAggregate_UndefinedKeyIn0000644000175000017500000000433511665471102033642 0ustar drazzibdrazzib org.apache.uima.java false Invalid Aggregate - Undefined Key in Flow This aggregate descriptor uses key "Annotator3" in its flow, but that key is not defined. This should be caught during validation. 1.0 The Apache Software Foundation Annotator1 Annotator2 Annotator3 true true false uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForErrorTest.xml0000644000175000017500000000455311665471102032534 0ustar drazzibdrazzib org.apache.uima.java false Aggregate for Error Test An aggregate for testing error beahvior. 1.0 The Apache Software Foundation ContinueOnFailure Boolean FlowController/ContinueOnFailure ErrorAnnotator ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForParallelStepCasMultiplierTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForParallelStepCasMult0000644000175000017500000000406311665471102033661 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE for ParallelStep CAS Multiplier Test For testing ParallelStep with CAS Multipliers. 1.0 The Apache Software Foundation true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateThatImportsItself.xml0000644000175000017500000000366111665471102033560 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE that Imports Itself For testing that circular import is detected and an errors is reported. 1.0 The Apache Software Foundation Annotator1 Myself ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides2.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOver0000644000175000017500000000665111665471102033646 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Configuration Parameter Overrides For testing configuration parameters. 1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam StringArrayParam String true AggregateParam2 Integer Annotator1/IntegerParam Annotator2/IntegerParam MyFlowController/IntegerParam AggregateParam override StringArrayParam override AggregateParam2 100 Annotator1 Annotator2 ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorForCollectionProcessCompleteTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorForCollectionProcessCo0000644000175000017500000000340311665471102033770 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.AnnotatorForCollectionProcessCompleteTest Annotator for Collection Process Complete Test For testing only. 1.0 The Apache Software Foundation TestValue String en uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/EmptyAggregate.xml0000644000175000017500000000311711665471102031225 0ustar drazzibdrazzib org.apache.uima.java false Empty Aggregate An aggregate containing no components. For testing empty flow. 1.0 The Apache Software Foundation uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams2.xml0000644000175000017500000000702211665471102032261 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 123 ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWith2SegmentersForErrorTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWith2SegmentersForErro0000644000175000017500000000441211665471102033660 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including 2 Segmenter, for Error Test For error testing only Segmenter1 Segmenter2 Annotator true true true ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithConfigurationParameters.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithConfigurationParam0000644000175000017500000000725011665471102034035 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true RequiredParam String false true StringParam myString StringArrayParam one two IntegerParam 42 IntegerArrayParam 1 2 3 FloatParam 3.14 RequiredParam RequiredValue uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/ParallelFlowController.xml0000644000175000017500000000254011665471102032747 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.ParallelFlowController Parallel Flow Controller For testing only. 1.0 The Apache Software Foundation ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOverrides.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOver0000644000175000017500000000742411665471102033754 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Configuration Parameter Overrides For testing configuration parameters. 1.0 The Apache Software Foundation Param1 String Annotator1/CommonParam Param2 String Annotator1/BCParam Param3 String Annotator1/ABParam Annotator2/BCParam Param1 AggregateParam1a Param1 AggregateParam1b Param2 AggregateParam2b Param3 AggregateParam3b Param1 AggregateParam1c Param2 AggregateParam2c Annotator1 Annotator2 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithSegmenter.xml0000644000175000017500000000377711665471102032730 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including a Segmenter For testing only Segmenter Annotator true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/NewlineResegmenter.xml0000644000175000017500000000465711665471102032134 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.NewlineResegmenter Newline Resegmenter Given a stream of input CASes containing text documents, outputs a different stream of CASes where the CASes are divided at newline characters. For example, if CASes A, B, and C are input, and there are only 2 newline characters, one in the middle of B and one at the end of C, then two new CASes A' and B' will be output, ' where A' contains all of the text from A plus the portion of the text from B before the newline, and B' contains the portion of the text from B after the newline plus all of the text from C. We also record a SourceDocumentInformation annotation for each input CAS (so an output CAS may have multiple SourceDocumentInformation annotations), indicating the source of each piece of text. 1.0 The Apache Software Foundation false true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestPrimitiveTae1.xml0000644000175000017500000000705511665471102031650 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Test Primitive TAE 1 For testing only. 1.0 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure Sentence A sentence. DocumentStructure Paragraph Sentence DocumentStructure begin standard DocumentStructure NamedEntity en uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams4.xml0000644000175000017500000000721011665471102032262 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 123 FloatParam 3.14 ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForCollectionProcessCompleteTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForCollectionProcessCo0000644000175000017500000000676511665471102033727 0ustar drazzibdrazzib org.apache.uima.java false Aggregate for Collection Process Complete Test For testing onlyr. 1.0 The Apache Software Foundation FirstTestValue String a1/TestValue SecondTestValue String a2/TestValue ThirdTestValue String a3/TestValue FirstTestValue One SecondTestValue Two ThirdTestValue Three a3 a2 a1 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/BadSegmenter.xml0000644000175000017500000000332211665471102030656 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.BadSegmenter Bad Segmenter Segmenter that requests three CASes in its next() method. For testing that we can catch segmenters that request too many CASes. 1.0 The Apache Software Foundation false true true ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndIm0000644000175000017500000000453411665471102033611 0ustar drazzibdrazzib org.apache.uima.java false AE with Configuration Parameter Overrides an Import By Name For testing that import by name works during valiation of configuration parameter overrides. 1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam AggregateParam override Annotator1 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams12.xml0000644000175000017500000000450711665471102032347 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator2/FooParam Annotator1 Annotator2 ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateContainingAggregateSegmenter.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateContainingAggregateSeg0000644000175000017500000000363111665471102033670 0ustar drazzibdrazzib org.apache.uima.java false Aggregate AE that contains an Aggregate Segmenter For testing nested aggregate segmenters AggregateSegmenter true true true ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithSegmenterForErrorTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithSegmenterForErrorT0000644000175000017500000000413311665471102033721 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including a Segmenter For testing only Segmenter Annotator true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestUimaCppAe.xml0000644000175000017500000001105011665471102030757 0ustar drazzibdrazzib org.apache.uima.cpp true TestAnnotator Test UIMA C++ Primitive AE For descriptor testing only. The actual annotator code doesn't really exist 1.0 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure Sentence A sentence. DocumentStructure Paragraph Sentence DocumentStructure begin standard DocumentStructure NamedEntity en true true false uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/dataPathDir/0000755000175000017500000000000011665471100027757 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/dataPathDir/AnnotatorWithConfigurationParameters.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/dataPathDir/AnnotatorWithConfig0000644000175000017500000000725011665471100033635 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true RequiredParam String false true StringParam myString StringArrayParam one two IntegerParam 42 IntegerArrayParam 1 2 3 FloatParam 3.14 RequiredParam RequiredValue ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithBadSegmenterForErrorTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithBadSegmenterForErr0000644000175000017500000000462311665471102033647 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including a Segmenter For testing only ContinueOnFailure Boolean FlowController/ContinueOnFailure Segmenter Annotator true true true ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestAggregateContainingCppAnnotator.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestAggregateContainingCppAnnot0000644000175000017500000000410011665471102033715 0ustar drazzibdrazzib org.apache.uima.java false Test Aggregate Containing C++ Annotator For descriptor testing only. 1.0 TestUimaCppAe true true false uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestCasConsumer.xml0000644000175000017500000000252011665471102031377 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.AnnotationWriter Cas Consumer Print Prints annotations. 1.0 The Apache Software Foundation uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams11.xml0000644000175000017500000000451211665471102032342 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator3/StringParam Annotator1 Annotator2 ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerWithConfigurationParameters.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerWithConfiguration0000644000175000017500000000727311665471102034067 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.SegmentDroppingFlowController FlowController With Configuration Parameters For testing parameter overrides on FlowControllers. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true RequiredParam String false true StringParam myString StringArrayParam one two IntegerParam 42 IntegerArrayParam 1 2 3 FloatParam 3.14 RequiredParam RequiredValue uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams8.xml0000644000175000017500000000465211665471102032275 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator2/FooParam Annotator1 Annotator2 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidAggregateSegmenter.xml0000644000175000017500000000442611665471102033373 0ustar drazzibdrazzib org.apache.uima.java false Invalid Aggregate Segmenter This descriptor declares it is a segmenter, but none of its components are segmenters. This should be caught during validation. 1.0 The Apache Software Foundation Annotator1 Annotator2 true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/ErrorAnnotator.xml0000644000175000017500000000265711665471102031307 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.ErrorAnnotator Error Annotator Annotator that throws an exception if the document text is "ERROR". For testing error handling. 1.0 The Apache Software Foundation ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.x0000644000175000017500000001071711665471102033760 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Unsatisfied Resource Test For testing the resource manager. 1.0 The Apache Software Foundation TestFileResource TestFileLanguageResource TestResourceObject org.apache.uima.resource.impl.TestResourceInterface TestLanguageResourceObject org.apache.uima.resource.impl.TestResourceInterface AdditionalResource org.apache.uima.resource.impl.TestResourceInterface MyFileResource file:testDataFile.dat MyFileLanguageResource file:FileLanguageResource_implTest_data_ .dat MyResourceObject file:testDataFile.dat org.apache.uima.resource.impl.TestResourceInterface_impl MyLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl TestFileResource MyFileResource TestFileLanguageResource MyFileLanguageResource TestResourceObject MyResourceObject TestLanguageResourceObject MyLanguageResourceObject uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams10.xml0000644000175000017500000000451111665471102032340 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Invalid Configuration Parameters For testing configuration parameters.1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam Annotator1StringParam Annotator1 Annotator2 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml0000644000175000017500000000402611665471102033127 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE for Merge Test For testing merging of type system, type priorities, and indexes. 1.0 The Apache Software Foundation Annotator1 Annotator2 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams13.xml0000644000175000017500000000416211665471102032345 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String Foo/Bar StringArrayParam String true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams5.xml0000644000175000017500000000706511665471102032273 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float true FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 123 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams3.xml0000644000175000017500000000730211665471102032263 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true StringArrayParam String true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 123 ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOver0000644000175000017500000000751611665471102033647 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE with Configuration Parameter Overrides For testing configuration parameters. 1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam StringArrayParam String true AggregateParam2 Integer Annotator1/IntegerParam Annotator2/IntegerParam MyFlowController/IntegerParam AggregateParam3 String Annotator2/StringParam AggregateParam override StringArrayParam override AggregateParam2 100 Annotator1 Annotator2 ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithUnknownRemoteComponent.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWithUnknownRemoteCompo0000644000175000017500000000751511665471102034003 0ustar drazzibdrazzib org.apache.uima.java false this.does.not.exist.at.least.i.hope.not Vinci Aggregate TAE with Configuration Parameter Overrides For testing configuration parameters. 1.0 The Apache Software Foundation AggregateParam String Annotator1/StringParam StringArrayParam String true AggregateParam2 Integer Annotator1/IntegerParam Annotator2/IntegerParam AggregateParam override StringArrayParam override AggregateParam2 100 Annotator1 Annotator2 Service outputSofa Service serviceSofa outputSofa uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidFsIndexes.xml0000644000175000017500000000427711665471102031527 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator aeDescriptor 1.0 uima.tcas.Annotation sorted end reverse false false uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams9.xml0000644000175000017500000000713311665471102032273 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String Foo/Bar StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 123 uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TestPrimitiveTae2.xml0000644000175000017500000000676311665471102031656 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator2 Test Primitive TAE 2 For testing only. 1.0 The Apache Software Foundation Person A person. uima.tcas.Annotation Gender Gender of person. uima.cas.String Place A place. uima.tcas.Annotation BigPlace Big Place within a Compound Place. uima.cas.String LittlePlace Little Place within a Compound Place. uima.cas.String Org An organization. uima.tcas.Annotation Person Place Org Place BigPlace standard LittlePlace standard begin standard end reverse Person Place Org en uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml0000644000175000017500000000425311665471102033641 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE containing an Annotator and a CAS Consumer For testing mixed aggregate. 1.0 The Apache Software Foundation Annotator CasConsumer NamedEntity DocumentStructure true false ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigurationGroups.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigura0000644000175000017500000000650611665471102034020 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Duplicate Configuration Groups For testing configuration groups. Has multiple definitions of same group name which should be allowed. 1.0 The Apache Software Foundation CommonParam String ABParam String BCParam String CommonParam common-a ABParam ab-a CommonParam common-b ABParam ab-b BCParam bc-b CommonParam common-c BCParam bc-c uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/NewlineSegmenter.xml0000644000175000017500000000321411665471102031571 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.NewlineSegmenter Test Segmenter Segments a test document by breaking at newline characters. 1.0 The Apache Software Foundation false true true ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/SegmentDroppingFlowController.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/SegmentDroppingFlowController.x0000644000175000017500000000314611665471102033772 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.SegmentDroppingFlowController Segment Dropping Flow Controller Simple FlowController that drops any segment whose document text is "DROP", and otherwise uses linear flow. 1.0 The Apache Software Foundation uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerForErrorTest.xml0000644000175000017500000000310611665471102033612 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.FlowControllerForErrorTest Flow Controller for Error Test For testing only. 1.0 The Apache Software Foundation ContinueOnFailure Boolean false uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/TabSegmenter.xml0000644000175000017500000000320411665471102030675 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TabSegmenter Test Segmenter Segments a test document by breaking at tab characters. 1.0 The Apache Software Foundation false true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateWith2Segmenters.xml0000644000175000017500000000425411665471102033164 0ustar drazzibdrazzib org.apache.uima.java false Example Aggregate TAE including 2 Segmenters and a Test Annotator For testing only Segmenter1 Segmenter2 Annotator true true true uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/InvalidConfigParams1.xml0000644000175000017500000000673511665471102032272 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Invalid Configuration Parameters For testing configuration parameters. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 0 ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithConfigurationGroups.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AnnotatorWithConfigurationGroup0000644000175000017500000001222711665471102034071 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Configuration Groups For testing configuration groups. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 1 2 3 StringArrayParam e n - U S IntegerParam 1776 StringParam de StringArrayParam d e IntegerArrayParam 4 5 6 StringParam zh StringArrayParam z h FloatParam 3.14 StringArrayParam ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForParallelStepTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/AggregateForParallelStepTest.xm0000644000175000017500000000353511665471102033656 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE for ParallelStep Test For testing ParallelStep. 1.0 The Apache Software Foundation uimaj-2.4.0/uimaj-core/src/test/resources/TextAnalysisEngineImplTest/FlowControllerForMergeTest.xml0000644000175000017500000000556211665471102033570 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.analysis_engine.impl.SegmentDroppingFlowController Flow Controller for Merge Test For testing only. 1.0 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String test.flowController.Test Test type for merge. uima.tcas.Annotation testFeat uima.cas.String test.flowController.Test NamedEntity test.flowController.Test testFeat standard test.flowController.Test en uimaj-2.4.0/uimaj-core/src/test/resources/ConfigurableResourceImplTest/0000755000175000017500000000000011665471074026136 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ConfigurableResourceImplTest/AnnotatorWithConfigurationGroups.xmluimaj-2.4.0/uimaj-core/src/test/resources/ConfigurableResourceImplTest/AnnotatorWithConfigurationGro0000644000175000017500000001211411665471074034061 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Annotator With Configuration Groups For testing configuration groups. 1.0 The Apache Software Foundation StringParam String true StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam en StringArrayParam e n IntegerParam 42 IntegerArrayParam 1 2 3 StringArrayParam e n - U S IntegerParam 1776 StringParam de StringArrayParam d e IntegerArrayParam 4 5 6 StringParam zh StringArrayParam z h FloatParam 3.14 StringArrayParam uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/0000755000175000017500000000000011665471074021775 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/CASTests/english.txt0000644000175000017500000000165111665471074024172 0ustar drazzibdrazzibSome tokenization "test" to do ! We are checking so-so and so - so and --- also... Especially we are interested in abrs e.g. Ave. which are very special. Single char abrs like John C. Mills. This is zyz. but not known as abbreviation. This is zyz. BUT not known as abbreviation. Another case is . in a sentence??? Or .Net .12 or so. Numbers 9.23 1,23 $12 22% #2 and so on !!! Parentheses (which are important) and [numeric] {expressions} ((*)) like (3 - 5) + 2 * -1 / 12 or 1/2 must work too. Also mark@twain.com and 9.4.124.8 and www.ibm-research.com @are also@ ### $$ @@ -checked. Commas, and semicolons; and colons: are ::: interesting,,, ,too? Apostrophes ''' are' 'interesting as well: L'Oreal Tom's 'don't' 1'2'3 8''. Also 'used' as 'quotations'. Let's go to the internet-cafe and chat with foo-bar. The next lines are paragraph boundary tests: tok1 tok2 tok3 tok4 tok5 - tokX tokY tok6 uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/xcas/0000755000175000017500000000000011665471074022733 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/CASTests/xcas/sample.ts0000644000175000017500000012151311665471074024567 0ustar drazzibdrazzib uima.tcas.Annotation uima.cas.AnnotationBase sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tcas.DocumentAnnotation uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer language uima.cas.String categories uima.cas.FSList languageCandidates uima.cas.FSList id uima.cas.String esDocumentMetaData org.apache.es.tt.DocumentMetaData uima.tt.TTAnnotation uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.DocStructureAnnotation uima.tt.TTAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.ParagraphAnnotation uima.tt.DocStructureAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.SentenceAnnotation uima.tt.DocStructureAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.LexicalAnnotation uima.tt.TTAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.TokenLikeAnnotation uima.tt.LexicalAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer tokenProperties uima.cas.Integer lemma uima.tt.Lemma normalizedCoveredText uima.cas.String uima.tt.TokenAnnotation uima.tt.TokenLikeAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer tokenProperties uima.cas.Integer lemma uima.tt.Lemma normalizedCoveredText uima.cas.String uima.tt.CompPartAnnotation uima.tt.TokenLikeAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer tokenProperties uima.cas.Integer lemma uima.tt.Lemma normalizedCoveredText uima.cas.String uima.tt.KeyStringEntry uima.cas.TOP key uima.cas.String uima.tt.Lemma uima.tt.KeyStringEntry key uima.cas.String uima.tt.CategoryConfidencePair uima.cas.TOP categoryString uima.cas.String categoryConfidence uima.cas.Float mostSpecific uima.cas.Integer taxonomy uima.cas.String uima.tt.LanguageConfidencePair uima.cas.TOP languageConfidence uima.cas.Float language uima.cas.String languageID uima.cas.Integer uima.tt.MultiTokenAnnotation uima.tt.LexicalAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.CompoundAnnotation uima.tt.TokenLikeAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer tokenProperties uima.cas.Integer lemma uima.tt.Lemma normalizedCoveredText uima.cas.String org.apache.es.tt.DocumentMetaData uima.cas.TOP crawlerId uima.cas.String dataSource uima.cas.String dataSourceName uima.cas.String charset uima.cas.String knownCharset uima.cas.String actualCharset uima.cas.String docType uima.cas.String securityTokens uima.cas.StringArray date uima.cas.String staticScore uima.cas.String baseUri uima.cas.String metaDataFields uima.cas.FSArray redirectUrl uima.cas.String knownLanguage uima.cas.String contentLanguage uima.cas.String compressed uima.cas.Integer truncated uima.cas.Integer hasSeparatContent uima.cas.Integer mimeType uima.cas.String metaLanguage uima.cas.String url uima.cas.String documentName uima.cas.String httpcode uima.cas.Integer metalength uima.cas.Integer contentlength uima.cas.Integer rdstype uima.cas.Integer nativeACLS org.apache.es.tt.NativeACLS isCompleted uima.cas.Integer sequenceNumber uima.cas.Integer documentId uima.cas.Integer title uima.cas.String frames uima.cas.StringArray throttleID uima.cas.String org.apache.es.tt.CommonFieldParameters uima.cas.TOP searchable uima.cas.Integer fieldSearchable uima.cas.Integer parametric uima.cas.Integer showInSearchResult uima.cas.Integer resolveConflict uima.cas.String exactMatch uima.cas.Integer name uima.cas.String sortable uima.cas.Integer org.apache.es.tt.ContentField uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer parameters org.apache.es.tt.CommonFieldParameters org.apache.es.tt.Anchor uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uri uima.cas.String org.apache.es.tt.MarkupTag uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer name uima.cas.String depth uima.cas.Integer attributeNames uima.cas.StringArray attributeValues uima.cas.StringArray org.apache.es.tt.MetaDataField uima.cas.TOP parameters org.apache.es.tt.CommonFieldParameters text uima.cas.String org.apache.es.tt.NativeACLS uima.cas.TOP domain uima.cas.String level1allow uima.cas.StringArray level1deny uima.cas.StringArray level2allow uima.cas.StringArray level2deny uima.cas.StringArray impersonate uima.cas.Integer protocol uima.cas.String org.apache.es.tt.Fragment uima.tcas.Annotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer tokenType uima.cas.Integer org.apache.es.tt.BoostTermAnnotation uima.tt.MultiTokenAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer value uima.cas.Integer uima.tt.StopwordAnnotation uima.tt.MultiTokenAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uima.tt.SynonymAnnotation uima.tt.MultiTokenAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer synonyms uima.cas.StringArray uima.tt.SpellCorrectionAnnotation uima.tt.MultiTokenAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer correctionTerms uima.cas.StringArray uima.tt.MultiWordAnnotation uima.tt.MultiTokenAnnotation sofa uima.cas.Sofa begin uima.cas.Integer end uima.cas.Integer uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/xcas/sample1.xcas0000644000175000017500000007477211665471074025176 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/xcas/sample2.xcas0000644000175000017500000016610611665471074025170 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/verjuice.txt0000644000175000017500000000133611665471074024355 0ustar drazzibdrazzibVerjuice, or green juice, which, with vinegar, formed the essential basis of sauces, and is now extracted from a species of green grape, which never ripens, was originally the juice of sorrel; another sort was extracted by pounding the green blades of wheat. Vinegar was originally merely soured wine, as the word vin-aigre denotes. The mode of manufacturing it by artificial means, in order to render the taste more pungent and the quality better, is very ancient. It is needless to state that it was scented by the infusion of herbs or flowers--roses, elder, cloves, &c.; but it was not much before the sixteenth century that it was used for pickling herbs or fruits and vegetables, such as gherkins, onions, cucumber, purslain, &c.uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/CasTypeOrderTestRef.txt0000644000175000017500000000356611665471074026411 0ustar drazzibdrazzibToken: 0 - 1 Token: 0 - 1 Token: 0 - 1 Sentence: 0 - 1 uima.tcas.Annotation: 0 - 1 Token: 2 - 3 Token: 2 - 3 Token: 2 - 3 Sentence: 2 - 3 uima.tcas.Annotation: 2 - 3 Token: 4 - 5 Token: 4 - 5 Token: 4 - 5 Sentence: 4 - 5 uima.tcas.Annotation: 4 - 5 Token: 6 - 7 Token: 6 - 7 Token: 6 - 7 Sentence: 6 - 7 uima.tcas.Annotation: 6 - 7 Token: 8 - 9 Token: 8 - 9 Token: 8 - 9 Sentence: 8 - 9 uima.tcas.Annotation: 8 - 9 Token: 10 - 11 Token: 10 - 11 Token: 10 - 11 Sentence: 10 - 11 uima.tcas.Annotation: 10 - 11 Token: 12 - 13 Token: 12 - 13 Token: 12 - 13 Sentence: 12 - 13 uima.tcas.Annotation: 12 - 13 Token: 14 - 15 Token: 14 - 15 Token: 14 - 15 Sentence: 14 - 15 uima.tcas.Annotation: 14 - 15 Token: 16 - 17 Token: 16 - 17 Token: 16 - 17 Sentence: 16 - 17 uima.tcas.Annotation: 16 - 17 Token: 18 - 19 Token: 18 - 19 Token: 18 - 19 Sentence: 18 - 19 uima.tcas.Annotation: 18 - 19 Token: 20 - 21 Token: 20 - 21 Token: 20 - 21 Sentence: 20 - 21 uima.tcas.Annotation: 20 - 21 Token: 22 - 23 Token: 22 - 23 Token: 22 - 23 Sentence: 22 - 23 uima.tcas.Annotation: 22 - 23 Token: 24 - 25 Token: 24 - 25 Token: 24 - 25 Sentence: 24 - 25 uima.tcas.Annotation: 24 - 25 Token: 26 - 27 Token: 26 - 27 Token: 26 - 27 Sentence: 26 - 27 uima.tcas.Annotation: 26 - 27 Token: 28 - 29 Token: 28 - 29 Token: 28 - 29 Sentence: 28 - 29 uima.tcas.Annotation: 28 - 29 Token: 30 - 31 Token: 30 - 31 Token: 30 - 31 Sentence: 30 - 31 uima.tcas.Annotation: 30 - 31 Token: 32 - 33 Token: 32 - 33 Token: 32 - 33 Sentence: 32 - 33 uima.tcas.Annotation: 32 - 33 Token: 34 - 35 Token: 34 - 35 Token: 34 - 35 Sentence: 34 - 35 uima.tcas.Annotation: 34 - 35 Token: 36 - 37 Token: 36 - 37 Token: 36 - 37 Sentence: 36 - 37 uima.tcas.Annotation: 36 - 37 Token: 38 - 39 Token: 38 - 39 Token: 38 - 39 Sentence: 38 - 39 uima.tcas.Annotation: 38 - 39 uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/0000755000175000017500000000000011665471074022713 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/TokensAndSentencesTS.xml0000644000175000017500000000260611665471074027446 0ustar drazzibdrazzib TypeSystem 1.0 org.apache.uima.cas.test.Token uima.tcas.Annotation org.apache.uima.cas.test.Sentence uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/pathValidationTS.xml0000644000175000017500000000636111665471074026661 0ustar drazzibdrazzib casTestCaseTypesystem Type system description for CAS test cases. 1.0 Apache Software Foundation Type1 uima.cas.TOP f0 uima.tcas.Annotation Type2 Type1 Type22 Type2 f2 uima.cas.FSList Type3 Type1 f1 uima.cas.FSList t1 uima.cas.TOP f1 t2 t2 uima.cas.TOP f2 t3 t3 uima.cas.TOP f3 uima.cas.String uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/arrayValueDescriptor.xml0000644000175000017500000000545211665471074027615 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.TestAnnotator aeDescriptor 1.0 org.apache.uima.test.Test uima.tcas.Annotation fsArray uima.cas.FSArray uima.tcas.Annotation true intArray uima.cas.IntegerArray uima.cas.Integer true true true false uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/TokensAndSentences.xml0000644000175000017500000000366111665471074027201 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.SubiteratorAnnotator TokensAndSentences 1.0 true true false uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/casTestCaseTypesystem.xml0000644000175000017500000001474211665471074027756 0ustar drazzibdrazzib casTestCaseTypesystem Type system description for CAS test cases. 1.0 Apache Software Foundation Token uima.tcas.Annotation type TokenType tokenFloatFeat uima.cas.Float lemma uima.cas.String sentenceLength uima.cas.Integer lemmaList uima.cas.StringArray true TokenType uima.cas.TOP Sentence uima.tcas.Annotation sentenceLength uima.cas.Integer Separator TokenType EndOfSentence TokenType Word TokenType org.apache.lang.Group1 uima.cas.String "Chinese" "Japanese" "Korean" "English" "French" "German" "Italian" "Spanish" "Portuguese" org.apache.lang.Group2 uima.cas.String "Arabic" "Czech" "Danish" "Dutch" "Finnish" "Greek" "Hebrew" "Hungarian" "Norwegian" "Polish" "Portuguese" "Russian" "Turkish" org.apache.lang.LanguagePair uima.cas.TOP lang1 org.apache.lang.Group1 lang2 org.apache.lang.Group2 OtherAnnotation uima.cas.AnnotationBase org.apache.uima.cas.test.types.Word uima.cas.TOP word uima.cas.String uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/StringSubtypeTest.xml0000644000175000017500000000525711665471074027130 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.StringSubtypeTest$Annotator StringSubtypeTest 1.0 The Apache Software Foundation org.apache.uima.cas.test.StringSubtypeAnnotation uima.tcas.Annotation stringSetFeature org.apache.uima.cas.test.StringSubtype org.apache.uima.cas.test.StringSubtype uima.cas.String aa bb cc x-unspecified uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/ArrayIndexTest.xml0000644000175000017500000000563311665471074026352 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.ArrayIndexTest ArrayIndexTest 1.0 The Apache Software Foundation uima.test.Child1Annotation uima.tcas.Annotation uima.test.Child2Annotation uima.tcas.Annotation uima.test.Child2ChildAnnotation uima.test.Child2Annotation uima.test.Type uima.cas.TOP uima.cas.FSArray bag x-unspecified uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/casTestCaseDescriptor.xml0000644000175000017500000000741411665471074027704 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.TestAnnotator aeDescriptor 1.0 uima.tcas.Annotation set begin standard end reverse uima.tcas.Annotation bag begin standard end reverse uima.tcas.Annotation sorted begin standard end reverse org.apache.uima.cas.test.types.Word set word standard true true false uimaj-2.4.0/uimaj-core/src/test/resources/CASTests/desc/typePriorityTestCaseDescriptor.xml0000644000175000017500000000674511665471074031667 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.TestAnnotator aeDescriptor 1.0 Token Sentence uima.tcas.Annotation uima.tcas.Annotation set begin standard end reverse uima.tcas.Annotation bag begin standard end reverse uima.tcas.Annotation sorted begin standard end reverse true true false uimaj-2.4.0/uimaj-core/src/test/resources/data/0000755000175000017500000000000011665471102021245 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/data/moby.txt0000644000175000017500000446152511665471102022775 0ustar drazzibdrazzibPreliminary Matter. This text of Melville's Moby-Dick is based on the Hendricks House edition. It was prepared by Professor Eugene F. Irey at the University of Colorado. Any subsequent copies of this data must include this notice and any publications resulting from analysis of this data must include reference to Professor Irey's work. Etymology (Supplied by a late consumptive usher to a grammar school.) The pale Ushei{rthreadbare} in coat, heart, body, and brain; I see him now. He was ever dusting his old lexicons and grammars, with a queer handkerchief, mockingly embellished with all the gay flags of all the known nations of the world. He loved to dust his old grammars; it somehow mildly reminded him of his mortality. Extracts (supplied by a sub-sub-librarian.) It will be seen that this mere painstaking burrower and grubworm of a poor devil of a Sub-Sub appears to have gone through the long Vaticans and street-stalls of the earth, picking up whatever random allusions to whales he could anyways find in any book whatsoever, sacred or profane. Therefore you must not, in every case at least, take the higgledy-piggledy whale statements, however authentic, in these extracts, for veritable gospel cetology. Far from it. As touching the ancient authors generally, as well as the poets here appearing, these extracts are solely valuable or entertaining, as affording a glancing bird's eye view of what has been promiscuously said, thought, fancied, and sung of Leviathan, by many nations and generations, including our own. So fare thee well, poor devil of a Sub-Sub, whose commentator I am. Thou belongest to that hopeless, sallow tribe which no wine of this world will ever warm; and for whom even Pale Sherry would be too rosy-strong; but with whom one sometimes loves to sit, and feel poor-devilish, too; and grow convivial upon tears; and say to them bluntly, with full eyes and empty glasses, and in not altogether unpleasant sadness i{give} it up, sub-subs! For by how much the more pains ye take to please the world, by so much the more shall ye for ever go thankless! Would that I could clear out Hampton Court and the Tuileries for ye! But gulp down your tears and hie aloft to the royal-mast with your hearts; for your friends who have gone before are clearing out the seven-storied heavens, and making refugees of long-pampered Gabriel, Michael, and Raphael, against your coming. Here ye strike but splintered hearts together i{there}, ye shall strike unsplinterable .. < chapter I 2 LOOMINGS > Call me Ishmael. Some years ago--never mind how long precisely --having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen, and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off--then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me. There now is your insular city of the Manhattoes, belted round by wharves as Indian isles by coral reefs--commerce surrounds it with her surf. Right and left, the streets take you waterward. Its extreme down-town is the battery, where that noble mole is washed by waves, and cooled by breezes, which a few hours previous were out of sight of land. Look at the crowds of water-gazers there. Circumambulate the city of a dreamy Sabbath afternoon. Go from Corlears Hook to Coenties Slip, and from thence, by Whitehall northward. What do you see?--Posted like silent sentinels all around the town, stand thousands upon thousands of mortal men fixed in ocean reveries. Some leaning against the spiles; some seated upon the pier-heads; some looking over the bulwarks glasses! ..

of ships from China; some high aloft in the rigging, as if striving to get a still better seaward peep. But these are all landsmen; of week days pent up in lath and plaster--tied to counters, nailed to benches, clinched to desks. How then is this? Are the green fields gone? What do they here? But look! here come more crowds, pacing straight for the water, and seemingly bound for a dive. Strange! Nothing will content them but the extremest limit of the land; loitering under the shady lee of yonder warehouses will not suffice. No. They must get just as nigh the water as they possibly can without falling in. And there they stand--miles of them--leagues. Inlanders all, they come from lanes and alleys, streets and avenues, --north, east, south, and west. Yet here they all unite. Tell me, does the magnetic virtue of the needles of the compasses of all those ships attract them thither? Once more. Say, you are in the country; in some high land of lakes. Take almost any path you please, and ten to one it carries you down in a dale, and leaves you there by a pool in the stream. There is magic in it. Let the most absent-minded of men be plunged in his deepest reveries--stand that man on his legs, set his feet a-going, and he will infallibly lead you to water, if water there be in all that region. Should you ever be athirst in the great American desert, try this experiment, if your caravan happen to be supplied with a metaphysical professor. Yes, as every one knows, meditation and water are wedded for ever. But here is an artist. He desires to paint you the dreamiest, shadiest, quietest, most enchanting bit of romantic landscape in all the valley of the Saco. What is the chief element he employs? There stand his trees, each with a hollow trunk, as if a hermit and a crucifix were within; and here sleeps his meadow, and there sleep his cattle; and up from yonder cottage goes a sleepy smoke. Deep into distant woodlands winds a mazy way, reaching to overlapping spurs of mountains bathed in their hill-side blue. But though the picture lies thus tranced, and though this pine-tree shakes down its sighs like leaves upon this shepherd's head, yet all were vain, unless the shepherd's eye were fixed upon the magic stream before him. Go visit the Prairies in June, ..

when for scores on scores of miles you wade knee-deep among Tiger-lilies--what is the one charm wanting? --Water --there is not a drop of water there! Were Niagara but a cataract of sand, would you travel your thousand miles to see it? Why did the poor poet of Tennessee, upon suddenly receiving two handfuls of silver, deliberate whether to buy him a coat, which he sadly needed, or invest his money in a pedestrian trip to Rockaway Beach? Why is almost every robust healthy boy with a robust healthy soul in him, at some time or other crazy to go to sea? Why upon your first voyage as a passenger, did you yourself feel such a mystical vibration, when first told that you and your ship were now out of sight of land? Why did the old Persians hold the sea holy? Why did the Greeks give it a separate deity, and own brother of Jove? Surely all this is not without meaning. And still deeper the meaning of that story of Narcissus, who because he could not grasp the tormenting, mild image he saw in the fountain, plunged into it and was drowned. But that same image, we ourselves see in all rivers and oceans. It is the image of the ungraspable phantom of life; and this is the key to it all. Now, when I say that I am in the habit of going to sea whenever I begin to grow hazy about the eyes, and begin to be over conscious of my lungs, I do not mean to have it inferred that I ever go to sea as a passenger. For to go as a passenger you must needs have a purse, and a purse is but a rag unless you have something in it. Besides, passengers get sea-sick --grow quarrelsome --don't sleep of nights --do not enjoy themselves much, as a general thing; --no, I never go as a passenger; nor, though I am something of a salt, do I ever go to sea as a Commodore, or a Captain, or a Cook. I abandon the glory and distinction of such offices to those who like them. For my part, I abominate all honorable respectable toils, trials, and tribulations of every kind whatsoever. It is quite as much as I can do to take care of myself, without taking care of ships, barques, brigs, schooners, and what not. And as for going as cook, -- though I confess there is considerable glory in that, a cook being a sort of officer on ship-board --yet, somehow, I never fancied broiling fowls; --though once broiled, judiciously buttered, and judgmatically salted and peppered, there is no one who will ..

speak more respectfully, not to say reverentially, of a broiled fowl than I will. It is out of the idolatrous dotings of the old Egyptians upon broiled ibis and roasted river horse, that you see the mummies of those creatures in their huge bake-houses the pyramids. No, when I go to sea, I go as a simple sailor, right before the mast, plumb down into the forecastle, aloft there to the royal mast-head. True, they rather order me about some, and make me jump from spar to spar, like a grasshopper in a May meadow. And at first, this sort of thing is unpleasant enough. It touches one's sense of honor, particularly if you come of an old established family in the land, the van Rensselaers, or Randolphs, or Hardicanutes. And more than all, if just previous to putting your hand into the tar-pot, you have been lording it as a country schoolmaster, making the tallest boys stand in awe of you. The transition is a keen one, I assure you, from the schoolmaster to a sailor, and requires a strong decoction of Seneca and the Stoics to enable you to grin and bear it. But even this wears off in time. What of it, if some old hunks of a sea-captain orders me to get a broom and sweep down the decks? What does that indignity amount to, weighed, I mean, in the scales of the New Testament? Do you think the archangel Gabriel thinks anything the less of me, because I promptly and respectfully obey that old hunks in that particular instance? Who aint a slave? Tell me that. Well, then, however the old sea-captains may order me about--however they may thump and punch me about, I have the satisfaction of knowing that it is all right; that everybody else is one way or other served in much the same way -- either in a physical or metaphysical point of view, that is; and so the universal thump is passed round, and all hands should rub each other's shoulder-blades, and be content. Again, I always go to sea as a sailor, because they make a point of paying me for my trouble, whereas they never pay passengers a single penny that I ever heard of. On the contrary, passengers themselves must pay. And there is all the difference in the world between paying and being paid. The act of paying is perhaps the most uncomfortable infliction that the two orchard ..

thieves entailed upon us. But being paid, --what will compare with it? The urbane activity with which a man receives money is really marvellous, considering that we so earnestly believe money to be the root of all earthly ills, and that on no account can a monied man enter heaven. Ah! how cheerfully we consign ourselves to perdition! Finally, I always go to sea as a sailor, because of the wholesome exercise and pure air of the forecastle deck. For as in this world, head winds are far more prevalent than winds from astern (that is, if you never violate the Pythagorean maxim), so for the most part the Commodore on the quarter-deck gets his atmosphere at second hand from the sailors on the forecastle. He thinks he breathes it first; but not so. In much the same way do the commonalty lead their leaders in many other things, at the same time that the leaders little suspect it. But wherefore it was that after having repeatedly smelt the sea as a merchant sailor, I should now take it into my head to go on a whaling voyage; this the invisible police officer of the Fates, who has the constant surveillance of me, and secretly dogs me, and influences me in some unaccountable way --he can better answer than any one else. And, doubtless, my going on this whaling voyage, formed part of the grand programme of Providence that was drawn up a long time ago. It came in as a sort of brief interlude and solo between more extensive performances. I take it that this part of the bill must have run something like this: Grand Contested Election for the Presidency of the United States. Whaling Voyage by one Ishmael. Bloody Battle in Affghanistan. Though I cannot tell why it was exactly that those stage managers, the Fates, put me down for this shabby part of a whaling voyage, when others were set down for magnificent parts in high tragedies, and short and easy parts in genteel comedies, and jolly parts in farces --though I cannot tell why this was exactly; yet, now that I recall all the circumstances, I think I can see a little into the springs and motives which being cunningly presented to me under various disguises, induced me to set about ..

performing the part I did, besides cajoling me into the delusion that it was a choice resulting from my own unbiased freewill and discriminating judgment. chief among these motives was the overwhelming idea of the great whale himself. Such a portentous and mysterious monster roused all my curiosity. Then the wild and distant seas where he rolled his island bulk; the undeliverable, nameless perils of the whale; these, with all the attending marvels of a thousand Patagonian sights and sounds, helped to sway me to my wish. With other men, perhaps, such things would not have been inducements; but as for me, I am tormented with an everlasting itch for things remote. I love to sail forbidden seas, and land on barbarous coasts. Not ignoring what is good, I am quick to perceive a horror, and could still be social with it--would they let me --since it is but well to be on friendly terms with all the inmates of the place one lodges in. By reason of these things, then, the whaling voyage was welcome; the great flood-gates of the wonder-world swung open, and in the wild conceits that swayed me to my purpose, two and two there floated into my inmost soul, endless processions of the whale, and, mid most of them all, one grand hooded phantom, like a snow hill in the air. ..

.. < chapter ii 24 THE CARPET-BAG > I stuffed a shirt or two into my old carpet-bag, tucked it under my arm, and started for Cape Horn and the Pacific. Quitting the good city of old Manhatto, I duly arrived in New Bedford. It was on a Saturday night in December. Much was I disappointed upon learning that the little packet for Nantucket had already sailed, and that no way of reaching that place would offer, till the following Monday. As most young candidates for the pains and penalties of whaling ..

stop at this same New Bedford, thence to embark on their voyage, it may as well be related that I, for one, had no idea of so doing. For my mind was made up to sail in no other than a Nantucket craft, because there was a fine, boisterous something about everything connected with that famous old island, which amazingly pleased me. Besides though New Bedford has of late been gradually monopolizing the business of whaling, and though in this matter poor old Nantucket is now much behind her, yet Nantucket was her great original --the Tyre of this Carthage; --the place where the first dead American whale was stranded. Where else but from Nantucket did those aboriginal whalemen, the Red-Men, first sally out in canoes to give chase to the Leviathan? And where but from Nantucket, too, did that first adventurous little sloop put forth, partly laden with imported cobble-stones --so goes the story --to throw at the whales, in order to discover when they were nigh enough to risk a harpoon from the bowsprit? Now having a night, a day, and still another night following before me in New Bedford, ere I could embark for my destined port, it became a matter of concernment where I was to eat and sleep meanwhile. It was a very dubious-looking, nay, a very dark and dismal night, bitingly cold and cheerless. I knew no one in the place. With anxious grapnels I had sounded my pocket, and only brought up a few pieces of silver, --So, wherever you go, Ishmael, said I to myself, as I stood in the middle of a dreary street shouldering my bag, and comparing the gloom towards the north with the darkness towards the south --wherever in your wisdom you may conclude to lodge for the night, my dear Ishmael, be sure to inquire the price, and don't be too particular. With halting steps I paced the streets, and passed the sign of The Crossed Harpoons --but it looked too expensive and jolly there. Further on, from the bright red windows of the Sword-Fish Inn, there came such fervent rays, that it seemed to have melted the packed snow and ice from before the house, for everywhere else the congealed frost lay ten inches thick in a hard, asphaltic pavement, --rather weary for me, when I struck my foot against the flinty projections, because from hard, remorseless ..

service the soles of my boots were in a most miserable plight. Too expensive and jolly, again thought I, pausing one moment to watch the broad glare in the street, and hear the sounds of the tinkling glasses within. But go on, Ishmael, said I at last; don't you hear? get away from before the door; your patched boots are stopping the way. So on I went. I now by instinct followed the streets that took me waterward, for there, doubtless, were the cheapest, if not the cheeriest inns. Such dreary streets! Blocks of blackness, not houses, on either hand, and here and there a candle, like a candle moving about in a tomb. At this hour of the night, of the last day of the week, that quarter of the town proved all but deserted. But presently I came to a smoky light proceeding from a low, wide building, the door of which stood invitingly open. It had a careless look, as if it were meant for the uses of the public; so, entering, the first thing I did was to stumble over an ash-box in the porch. Ha! thought I, ha, as the flying particles almost choked me, are these ashes from that destroyed city, Gomorrah? But The Crossed Harpoons, and The Sword-Fish? --this, then, must needs be the sign of The Trap. However, I picked myself up and hearing a loud voice within, pushed on and opened a second, interior door. It seemed the great Black Parliament sitting in Tophet. A hundred black faces turned round in their rows to peer; and beyond, a black Angel of Doom was beating a book in a pulpit. It was a negro church; and the preacher's text was about the blackness of darkness, and the weeping and wailing and teeth-gnashing there. Ha, Ishmael, muttered I, backing out, Wretched entertainment at the sign of The Trap! Moving on, I at last came to a dim sort of light not far from the docks, and heard a forlorn creaking in the air; and looking up, saw a swinging sign over the door with a white painting upon it, faintly representing a tall straight jet of misty spray, and these words underneath -- The Spouter-Inn: --Peter Coffin. Coffin? --Spouter? --Rather ominous in that particular connexion, thought I. But it is a common name in Nantucket, they say, and I suppose this Peter here is an emigrant from there. As the light looked so dim, and the place, for the time, looked ..

quiet enough, and the dilapidated little wooden house itself looked as if it might have been carted here from the ruins of some burnt district, and as the swinging sign had a poverty-stricken sort of creak to it, I thought that here was the very spot for cheap lodgings, and the best of pea coffee. It was a queer sort of place --a gable-ended old house, one side palsied as it were, and leaning over sadly. It stood on a sharp bleak corner, where that tempestuous wind Euroclydon kept up a worse howling than ever it did about poor Paul's tossed craft. Euroclydon, nevertheless, is a mighty pleasant zephyr to any one in-doors, with his feet on the hob quietly toasting for bed. In judging of that tempestuous wind called Euroclydon, says an old writer --of whose works I possess the only copy extant -- it maketh a marvellous difference, whether thou lookest out at it from a glass window where the frost is all on the outside, or whether thou observest it from that sashless window, where the frost is on both sides, and of which the wight Death is the only glazier. True enough, thought I, as this passage occurred to my mind --old black-letter, thou reasonest well. Yes, these eyes are windows, and this body of mine is the house. What a pity they didn't stop up the chinks and the crannies though, and thrust in a little lint here and there. But it's too late to make any improvements now. The universe is finished; the copestone is on, and the chips were carted off a million years ago. Poor Lazarus there, chattering his teeth against the curbstone for his pillow, and shaking off his tatters with his shiverings, he might plug up both ears with rags, and put a corn-cob into his mouth, and yet that would not keep out the tempestuous Euroclydon. Euroclydon! says old Dives, in his red silken wrapper --(he had a redder one afterwards) pooh, pooh! What a fine frosty night; how Orion glitters; what northern lights! Let them talk of their oriental summer climes of everlasting conservatories; give me the privilege of making my own summer with my own coals. But what thinks Lazarus? Can he warm his blue hands by holding them up to the grand northern lights? Would not Lazarus rather be in Sumatra than here? Would he not far rather lay him down lengthwise along the line of the equator; yea, ye ..

gods! go down to the fiery pit itself, in order to keep out this frost? Now, that Lazarus should lie stranded there on the curbstone before the door of Dives, this is more wonderful than that an iceberg should be moored to one of the Moluccas. Yet Dives himself, he too lives like a Czar in an ice palace made of frozen sighs, and being a president of a temperance society, he only drinks the tepid tears of orphans. But no more of this blubbering now, we are going a-whaling, and there is plenty of that yet to come. Let us scrape the ice from our frosted feet, and see what sort of a place this Spouter may be. ..

.. < chapter iii 14 THE SPOUTER-INN > Entering that gable-ended Spouter-Inn, you found yourself in a wide, low, straggling entry with old-fashioned wainscots, reminding one of the bulwarks of some condemned old craft. On one side hung a very large oil-painting so thoroughly besmoked, and every way defaced, that in the unequal cross-lights by which you viewed it, it was only by diligent study and a series of systematic visits to it, and careful inquiry of the neighbors, that you could any way arrive at an understanding of its purpose. such unaccountable masses of shades and shadows, that at first you almost thought some ambitious young artist, in the time of the New England hags, had endeavored to delineate chaos bewitched. But by dint of much and earnest contemplation, and oft repeated ponderings, and especially by throwing open the little window towards the back of the entry, you at last come to the conclusion that such an idea, however wild, might not be altogether unwarranted. But what most puzzled and confounded you was a long, limber, portentous, black mass of something hovering in the ..

centre of the picture over three blue, dim, perpendicular lines floating in a nameless yeast. A boggy, soggy, squitchy picture truly, enough to drive a nervous man distracted. Yet was there a sort of indefinite, half-attained, unimaginable sublimity about it that fairly froze you to it, till you involuntarily took an oath with yourself to find out what that marvellous painting meant. Ever and anon a bright, but, alas, deceptive idea would dart you through. --It's the Black Sea in a midnight gale. --It's the unnatural combat of the four primal elements. --It's a blasted heath. --It's a Hyperborean winter scene. --It's the breaking-up of the ice-bound stream of Time. But at last all these fancies yielded to that one portentous something in the picture's midst. That once found out, and all the rest were plain. But stop; does it not bear a faint resemblance to a gigantic fish? even the great leviathan himself? In fact, the artist's design seemed this: a final theory of my own, partly based upon the aggregated opinions of many aged persons with whom I conversed upon the subject. The picture represents a Cape-Horner in a great hurricane; the half-foundered ship weltering there with its three dismantled masts alone visible; and an exasperated whale, purposing to spring clean over the craft, is in the enormous act of impaling himself upon the three mast-heads. The opposite wall of this entry was hung all over with a heathenish array of monstrous clubs and spears. Some were thickly set with glittering teeth resembling ivory saws; others were tufted with knots of human hair; and one was sickle-shaped, with a vast handle sweeping round like the segment made in the new-mown grass by a long-armed mower. You shuddered as you gazed, and wondered what monstrous cannibal and savage could ever have gone a death-harvesting with such a hacking, horrifying implement. Mixed with these were rusty old whaling lances and harpoons all broken and deformed. Some were storied weapons. With this once long lance, now wildly elbowed, fifty years ago did Nathan Swain kill fifteen whales between a sunrise and a sunset. And that harpoon--so like a corkscrew now--was flung in Javan seas, and run away with by a whale, years afterward slain off the Cape of Blanco. The original iron entered ..

nigh the tail, and, like a restless needle sojourning in the body of a man, travelled full forty feet, and at last was found imbedded in the hump. Crossing this dusky entry, and on through yon low-arched way --cut through what in old times must have been a great central chimney with fire-places all round --you enter the public room. A still duskier place is this, with such low ponderous beams above, and such old wrinkled planks beneath, that you would almost fancy you trod some old craft's cockpits, especially of such a howling night, when this corner-anchored old ark rocked so furiously. On one side stood a long, low, shelf-like table covered with cracked glass cases, filled with dusty rarities gathered from this wide world's remotest nooks. Projecting from the further angle of the room stands a dark-looking den --the bar-- a rude attempt at a right whale's head. Be that how it may, there stands the vast arched bone of the whale's jaw, so wide, a coach might almost drive beneath it. within are shabby shelves, ranged round with old decanters, bottles, flasks; and in those jaws of swift destruction, like another cursed Jonah (by which name indeed they called him), bustles a little withered old man, who, for their money, dearly sells the sailors deliriums and death. Abominable are the tumblers into which he pours his poison. Though true cylinders without --within, the villanous green goggling glasses deceitfully tapered downwards to a cheating bottom. Parallel meridians rudely pecked into the glass, surround these footpads' goblets. Fill to this mark, and your charge is but a penny; to this a penny more; and so on to the full glass --the Cape Horn measure, which you may gulp down for a shilling. Upon entering the place I found a number of young seamen gathered about a table, examining by a dim light divers specimens of skrimshander. I sought the landlord, and telling him I desired to be accommodated with a room, received for answer that his house was full --not a bed unoccupied. But avast, he added, tapping his forehead, you haint no objections to sharing a harpooneer's blanket, have ye? I s'pose you are goin' a whalin', so you'd better get used to that sort of thing. ..

I told him that I never liked to sleep two in a bed; that if I should ever do so, it would depend upon who the harpooneer might be, and that if he (the landlord) really had no other place for me, and the harpooneer was not decidedly objectionable, why rather than wander further about a strange town on so bitter a night, I would put up with the half of any decent man's blanket. I thought so. All right; take a seat. Supper? --you want supper? Supper 'll be ready directly. I sat down on an old wooden settle, carved all over like a bench on the Battery. At one end a ruminating tar was still further adorning it with his jack-knife, stooping over and diligently working away at the space between his legs. he was trying his hand at a ship under full sail, but he didn't make much headway, I thought. At last some four or five of us were summoned to our meal in an adjoining room. It was cold as Iceland --no fire at all --the landlord said he couldn't afford it. Nothing but two dismal tallow candles, each in a winding sheet. We were fain to button up our monkey jackets, and hold to our lips cups of scalding tea with our half frozen fingers. But the fare was of the most substantial kind --not only meat and potatoes, but dumplings; good heavens! dumplings for supper! One young fellow in a green box coat, addressed himself to these dumplings in a most direful manner. My boy, said the landlord, you'll have the nightmare to a dead sartainty. Landlord, I whispered, that aint the harpooneer, is it? Oh, no, said he, looking a sort of diabolically funny, the harpooneer is a dark complexioned chap. He never eats dumplings, he don't--he eats nothing but steaks, and likes 'em rare. The devil he does, says I. Where is that harpooneer? Is he here? He'll be here afore long, was the answer. I could not help it, but I began to feel suspicious of this dark complexioned harpooneer. At any rate, I made up my mind that if it so turned out that we should sleep together, he must undress and get into bed before I did. ..

Supper over, the company went back to the bar-room, when, knowing not what else to do with myself, I resolved to spend the rest of the evening as a looker on. Presently a rioting noise was heard without. Starting up, the landlord cried, That's the Grampus's crew. I seed her reported in the offing this morning; a three years' voyage, and a full ship. Hurrah, boys; now we'll have the latest news from the Feegees. A tramping of sea boots was heard in the entry; the door was flung open, and in rolled a wild set of mariners enough. Enveloped in their shaggy watch coats, and with their heads muffled in woollen comforters, all bedarned and ragged, and their beards stiff with icicles, they seemed an eruption of bears from Labrador. They had just landed from their boat, and this was the first house they entered. No wonder, then, that they made a straight wake for the whale's mouth --the bar --when the wrinkled little old Jonah, there officiating, soon poured them out brimmers all round. One complained of a bad cold in his head, upon which Jonah mixed him a pitch-like potion of gin and molasses, which he swore was a sovereign cure for all colds and catarrhs whatsoever, never mind of how long standing, or whether caught off the coast of Labrador, or on the weather side of an ice-island. The liquor soon mounted into their heads, as it generally does even with the arrantest topers newly landed from sea, and they began capering about most obstreperously. I observed, however, that one of them held somewhat aloof, and though he seemed desirous not to spoil the hilarity of his shipmates by his own sober face, yet upon the whole he refrained from making as much noise as the rest. This man interested me at once; and since the sea-gods had ordained that he should soon become my shipmate (though but a sleeping-partner one, so far as this narrative is concerned), I will here venture upon a little description of him. He stood full six feet in height, with noble shoulders, and a chest like a coffer-dam. I have seldom seen such brawn in a man. His face was deeply brown and burnt, making his white teeth dazzling by the contrast; while in the deep shadows of his eyes floated some reminiscences that did not seem to give him much joy. His voice at once announced ..

that he was a Southerner, and from his fine stature, I thought he must be one of those tall mountaineers from the Alleganian Ridge in Virginia. When the revelry of his companions had mounted to its height, this man slipped away unobserved, and I saw no more of him till he became my comrade on the sea. In a few minutes, however, he was missed by his shipmates, and being, it seems, for some reason a huge favorite with them, they raised a cry of Bulkington! Bulkington! where's Bulkington? and darted out of the house in pursuit of him. It was now about nine o'clock, and the room seeming almost supernaturally quiet after these orgies, I began to congratulate myself upon a little plan that had occurred to me just previous to the entrance of the seamen. No man prefers to sleep two in a bed. In fact, you would a good deal rather not sleep with your own brother. I don't know how it is, but people like to be private when they are sleeping. And when it comes to sleeping with an unknown stranger, in a strange inn, in a strange town, and that stranger a harpooneer, then your objections indefinitely multiply. Nor was there any earthly reason why I as a sailor should sleep two in a bed, more than anybody else; for sailors no more sleep two in a bed at sea, than bachelor Kings do ashore. To be sure they all sleep together in one apartment, but you have your own hammock, and cover yourself with your own blanket, and sleep in your own skin. The more I pondered over this harpooneer, the more I abominated the thought of sleeping with him. It was fair to presume that being a harpooneer, his linen or woollen, as the case might be, would not be of the tidiest, certainly none of the finest. I began to twitch all over. Besides, it was getting late, and my decent harpooneer ought to be home and going bedwards. Suppose now, he should tumble in upon me at midnight --how could I tell from what vile hole he had been coming? Landlord! I've changed my mind about that harpooneer. -- I shan't sleep with him. I'll try the bench here. just as you please; i'm sorry i cant spare ye a tablecloth for a mattress, and it's a plaguy rough board here --feeling of the knots and notches. But wait a bit, Skrimshander; I've ..

got a carpenter's plane there in the bar --wait, I say, and I'll make ye snug enough. So saying he procured the plane; and with his old silk handkerchief first dusting the bench, vigorously set to planing away at my bed, the while grinning like an ape. The shavings flew right and left; till at last the plane-iron came bump against an indestructible knot. The landlord was near spraining his wrist, and I told him for heaven's sake to quit -- the bed was soft enough to suit me, and I did not know how all the planing in the world could make eider down of a pine plank. So gathering up the shavings with another grin, and throwing them into the great stove in the middle of the room, he went about his business, and left me in a brown study. I now took the measure of the bench, and found that it was a foot too short; but that could be mended with a chair. But it was a foot too narrow, and the other bench in the room was about four inches higher than the planed one --so there was no yoking them. I then placed the first bench lengthwise along the only clear space against the wall, leaving a little interval between, for my back to settle down in. But I soon found that there came such a draught of cold air over me from under the sill of the window, that this plan would never do at all, especially as another current from the rickety door met the one from the window, and both together formed a series of small whirlwinds in the immediate vicinity of the spot where I had thought to spend the night. The devil fetch that harpooneer, thought I, but stop, couldn't I steal a march on him --bolt his door inside, and jump into his bed, not to be wakened by the most violent knockings? it seemed no bad idea; but upon second thoughts I dismissed it. For who could tell but what the next morning, so soon as I popped out of the room, the harpooneer might be standing in the entry, all ready to knock me down! Still, looking around me again, and seeing no possible chance of spending a sufferable night unless in some other person's bed, I began to think that after all I might be cherishing unwarrantable prejudices against this unknown harpooneer. Thinks I, I'll wait awhile; he must be dropping in before long. I'll have a good look at him then, and perhaps we may become jolly good bedfellows after all --there's no telling. ..

But though the other boarders kept coming in by ones, twos, and threes, and going to bed, yet no sign of my harpooneer. Landlord! said I, what sort of a chap is he --does he always keep such late hours? It was now hard upon twelve o'clock. The landlord chuckled again with his lean chuckle, and seemed to be mightily tickled at something beyond my comprehension. No, he answered, generally he's an early bird -- airley to bed and airley to rise --yes, he's the bird what catches the worm. --But to-night he went out a peddling, you see, and I don't see what on airth keeps him so late, unless, may be, he can't sell his head. Can't sell his head? --What sort of a bamboozingly story is this you are telling me? getting into a towering rage. Do you pretend to say, landlord, that this harpooneer is actually engaged this blessed Saturday night, or rather Sunday morning, in peddling his head around this town? That's precisely it, said the landlord, and I told him he couldn't sell it here, the market's overstocked. With what? shouted I. With heads to be sure; ain't there too many heads in the world? I tell you what it is, landlord, said I, quite calmly, you'd better stop spinning that yarn to me --I'm not green. May be not, taking out a stick and whittling a toothpick, but I rayther guess you'll be done brown if that ere harpooneer hears you a slanderin' his head. I'll break it for him, said I, now flying into a passion again at this unaccountable farrago of the landlord's. It's broke a'ready, said he. Broke, said I -- broke, do you mean? Sartain, and that's the very reason he can't sell it, I guess. Landlord, said I, going up to him as cool as Mt. Hecla in a snow storm, -- landlord, stop whittling. You and I must understand one another, and that too without delay. I come to your house and want a bed; you tell me you can only give me half a one; that the other half belongs to a certain harpooneer. And about this harpooneer, whom I have not yet seen, you persist in telling me the most mystifying and exasperating stories, tending to beget in me an uncomfortable feeling towards the man whom ..

you design for my bedfellow --a sort of connexion, landlord, which is an intimate and confidential one in the highest degree. I now demand of you to speak out and tell me who and what this harpooneer is, and whether I shall be in all respects safe to spend the night with him. And in the first place, you will be so good as to unsay that story about selling his head, which if true I take to be good evidence that this harpooneer is stark mad, and I've no idea of sleeping with a madman; and you, sir, you I mean, landlord, you, sir, by trying to induce me to do so knowingly, would thereby render yourself liable to a criminal prosecution. Wall, said the landlord, fetching a long breath, that's a purty long sarmon for a chap that rips a little now and then. But be easy, be easy, this here harpooneer I have been tellin' you of has just arrived from the south seas, where he bought up a lot of 'balmed New Zealand heads (great curios, you know), and he's sold all on 'em but one, and that one he's trying to sell to-night, cause to-morrow's Sunday, and it would not do to be sellin' human heads about the streets when folks is goin' to churches. He wanted to, last Sunday, but I stopped him just as he was goin' out of the door with four heads strung on a string, for all the airth like a string of inions. This account cleared up the otherwise unaccountable mystery, and showed that the landlord, after all, had had no idea of fooling me --but at the same time what could I think of a harpooneer who stayed out a Saturday night clean into the holy Sabbath, engaged in such a cannibal business as selling the heads of dead idolators? Depend upon it, landlord, that harpooneer is a dangerous man. He pays reg'lar, was the rejoinder. But come, it's getting dreadful late, you had better be turning flukes --it's a nice bed: Sal and me slept in that ere bed the night we were spliced. There's plenty room for two to kick about in that bed; it's an almighty big bed that. Why, afore we give it up, Sal used to put our Sam and little Johnny in the foot of it. But I got a dreaming and sprawling about one night, and somehow, Sam got pitched on the floor, and came near breaking his arm. After ..

that, Sal said it wouldn't do. Come along here, I'll give ye a glim in a jiffy; and so saying he lighted a candle and held it towards me, offering to lead the way. But I stood irresolute; when looking at a clock in the corner, he exclaimed I vum it's Sunday --you won't see that harpooneer to-night; he's come to anchor somewhere --come along then; do come; won't ye come? I considered the matter a moment, and then up stairs we went, and I was ushered into a small room, cold as a clam, and furnished, sure enough, with a prodigious bed, almost big enough indeed for any four harpooneers to sleep abreast. There, said the landlord, placing the candle on a crazy old sea chest that did double duty as a wash-stand and centre table; there, make yourself comfortable now, and good night to ye. I turned round from eyeing the bed, but he had disappeared. Folding back the counterpane, I stooped over the bed. Though none of the most elegant, it yet stood the scrutiny tolerably well. I then glanced round the room; and besides the bedstead and centre table, could see no other furniture belonging to the place, but a rude shelf, the four walls, and a papered fireboard representing a man striking a whale. Of things not properly belonging to the room, there was a hammock lashed up, and thrown upon the floor in one corner; also a large seaman's bag, containing the harpooneer's wardrobe, no doubt in lieu of a land trunk. Likewise, there was a parcel of outlandish bone fish hooks on the shelf over the fire-place, and a tall harpoon standing at the head of the bed. But what is this on the chest? I took it up, and held it close to the light, and felt it, and smelt it, and tried every way possible to arrive at some satisfactory conclusion concerning it. I can compare it to nothing but a large door mat, ornamented at the edges with little tinkling tags something like the stained porcupine quills round an Indian moccasin. There was a hole or slit in the middle of this mat, as you see the same in South American ponchos. But could it be possible that any sober harpooneer would get into a door mat, and parade the streets of any Christian town in that sort of guise? I put it on, to try it, and it weighed me down like a hamper, being uncommonly shaggy and thick, and I thought a little damp, as though this ..

mysterious harpooneer had been wearing it of a rainy day. I went up in it to a bit of glass stuck against the wall, and I never saw such a sight in my life. I tore myself out of it in such a hurry that I gave myself a kink in the neck. I sat down on the side of the bed, and commenced thinking about this head-peddling harpooneer, and his door mat. After thinking some time on the bed-side, I got up and took off my monkey jacket, and then stood in the middle of the room thinking. I then took off my coat, and thought a little more in my shirt sleeves. But beginning to feel very cold now, half undressed as I was, and remembering what the landlord said about the harpooneer's not coming home at all that night, it being so very late, I made no more ado, but jumped out of my pantaloons and boots, and then blowing out the light tumbled into bed, and commended myself to the care of heaven. Whether that mattress was stuffed with corn-cobs or broken crockery, there is no telling, but I rolled about a good deal, and could not sleep for a long time. At last I slid off into a light doze, and had pretty nearly made a good offing towards the land of Nod, when I heard a heavy footfall in the passage, and saw a glimmer of light come into the room from under the door. Lord save me, thinks I, that must be the harpooneer, the infernal head-peddler. But I lay perfectly still, and resolved not to say a word till spoken to. Holding a light in one hand, and that identical New Zealand head in the other, the stranger entered the room, and without looking towards the bed, placed his candle a good way off from me on the floor in one corner, and then began working away at the knotted cords of the large bag I before spoke of as being in the room. I was all eagerness to see his face, but he kept it averted for some time while employed in unlacing the bag's mouth. This accomplished, however, he turned round --when, good heavens! what a sight! Such a face! It was of a dark purplish, yellow color, here and there stuck over with large, blackish looking squares. Yes, it's just as I thought, he's a terrible bedfellow; he's been in a fight, got dreadfully cut, and here he is, just from the surgeon. But at that moment he chanced to turn his face so towards the light, that I plainly saw they could not be sticking-plasters at all, ..

those black squares on his cheeks. they were stains of some sort or other. At first I knew not what to make of this; but soon an inkling of the truth occurred to me. I remembered a story of a white man --a whaleman too--who, falling among the cannibals, had been tattooed by them. I concluded that this harpooneer, in the course of his distant voyages, must have met with a similar adventure. And what is it, thought I, after all! It's only his outside; a man can be honest in any sort of skin. But then, what to make of his unearthly complexion, that part of it, I mean, lying round about, and completely independent of the squares of tattooing. To be sure, it might be nothing but a good coat of tropical tanning; but I never heard of a hot sun's tanning a white man into a purplish yellow one. However, I had never been in the South Seas; and perhaps the sun there produced these extraordinary effects upon the skin. Now, while all these ideas were passing through me like lightning, this harpooneer never noticed me at all. But, after some difficulty having opened his bag, he commenced fumbling in it, and presently pulled out a sort of tomahawk, and a seal-skin wallet with the hair on. Placing these on the old chest in the middle of the room, he then took the New Zealand head --a ghastly thing enough --and crammed it down into the bag. He now took off his hat --a new beaver hat --when I came nigh singing out with fresh surprise. There was no hair on his head --none to speak of at least -- nothing but a small scalp-knot twisted up on his forehead. His bald purplish head now looked for all the world like a mildewed skull. Had not the stranger stood between me and the door, I would have bolted out of it quicker than ever I bolted a dinner. Even as it was, I thought something of slipping out of the window, but it was the second floor back. I am no coward, but what to make of this head-peddling purple rascal altogether passed my comprehension. Ignorance is the parent of fear, and being completely nonplussed and confounded about the stranger, i confess i was now as much afraid of him as if it was the devil himself who had thus broken into my room at the dead of night. In fact, I was so afraid of him that I was not game enough just then to address him, and demand a satisfactory answer concerning what seemed inexplicable in him. ..

Meanwhile, he continued the business of undressing, and at last showed his chest and arms. As I live, these covered parts of him were checkered with the same squares as his face; his back, too, was all over the same dark squares; he seemed to have been in a Thirty Years' War, and just escaped from it with a sticking-plaster shirt. Still more, his very legs were marked, as if a parcel of dark green frogs were running up the trunks of young palms. It was now quite plain that he must be some abominable savage or other shipped aboard of a whaleman in the South Seas, and so landed in this Christian country. I quaked to think of it. A peddler of heads too --perhaps the heads of his own brothers. He might take a fancy to mine --heavens! look at that tomahawk! But there was no time for shuddering, for now the savage went about something that completely fascinated my attention, and convinced me that he must indeed be a heathen. Going to his heavy grego, or wrapall, or dreadnaught, which he had previously hung on a chair, he fumbled in the pockets, and produced at length a curious little deformed image with a hunch on its back, and exactly the color of a three days' old Congo baby. Remembering the embalmed head, at first I almost thought that this black manikin was a real baby preserved in some similar manner. But seeing that it was not at all limber, and that it glistened a good deal like polished ebony, I concluded that it must be nothing but a wooden idol, which indeed it proved to be. For now the savage goes up to the empty fireplace, and removing the papered fire-board, sets up this little hunchbacked image, like a tenpin, between the andirons. the chimney jambs and all the bricks inside were very sooty, so that I thought this fire-place made a very appropriate little shrine or chapel for his Congo idol. I now screwed my eyes hard towards the half hidden image, feeling but ill at ease meantime --to see what was next to follow. First he takes about a double handful of shavings out of his grego pocket, and places them carefully before the idol; then laying a bit of ship biscuit on top and applying the flame from the lamp, he kindled the shavings into a sacrificial blaze. Presently, after many hasty snatches into the fire, and still hastier ..

withdrawals of his fingers (whereby he seemed to be scorching them badly), he at last succeeded in drawing out the biscuit; then blowing off the heat and ashes a little, he made a polite offer of it to the little negro. But the little devil did not seem to fancy such dry sort of fare at all; he never moved his lips. All these strange antics were accompanied by still stranger guttural noises from the devotee, who seemed to be praying in a sing-song or else singing some pagan psalmody or other, during which his face twitched about in the most unnatural manner. At last extinguishing the fire, he took the idol up very unceremoniously, and bagged it again in his grego pocket as carelessly as if he were a sportsman bagging a dead woodcock. All these queer proceedings increased my uncomfortableness, and seeing him now exhibiting strong symptoms of concluding his business operations, and jumping into bed with me, I thought it was high time, now or never, before the light was put out, to break the spell into which I had so long been bound. But the interval I spent in deliberating what to say, was a fatal one. Taking up his tomahawk from the table, he examined the head of it for an instant, and then holding it to the light, with his mouth at the handle, he puffed out great clouds of tobacco smoke. The next moment the light was extinguished, and this wild cannibal, tomahawk between his teeth, sprang into bed with me. I sang out, I could not help it now; and giving a sudden grunt of astonishment he began feeling me. Stammering out something, I knew not what, I rolled away from him against the wall, and then conjured him, whoever or whatever he might be, to keep quiet, and let me get up and light the lamp again. But his guttural responses satisfied me at once that he but ill comprehended my meaning. Who-e debel you? --he at last said -- you no speak-e, dam-me, I kill-e. And so saying the lighted tomahawk began flourishing about me in the dark. Landlord, for God's sake, Peter Coffin! shouted I. Landlord! Watch! Coffin! Angels! save me! Speak-e! tell-ee me who-ee be, or dam-me, I kill-e! again growled the cannibal, while his horrid flourishings of the tomahawk scattered the hot tobacco ashes about me till I thought ..

my linen would get on fire. But thank heaven, at that moment the landlord came into the room light in hand, and leaping from the bed I ran up to him. Don't be afraid now, said he, grinning again. Queequeg here wouldn't harm a hair of your head. Stop your grinning, shouted I, and why didn't you tell me that that infernal harpooneer was a cannibal? I thought ye know'd it; --didn't I tell ye, he was peddlin' heads around town? --but turn flukes again and go to sleep. Queequeg, look here --you sabbee me, I sabbee you --this man sleepe you --you sabbee? Me sabbee plenty --grunted Queequeg, puffing away at his pipe and sitting up in bed. You gettee in, he added, motioning to me with his tomahawk, and throwing the clothes to one side. He really did this in not only a civil but a really kind and charitable way. I stood looking at him a moment. For all his tattooings he was on the whole a clean, comely looking cannibal. What's all this fuss I have been making about, thought i to myself --the man's a human being just as I am: he has just as much reason to fear me, as I have to be afraid of him. Better sleep with a sober cannibal than a drunken Christian. Landlord, said I, tell him to stash his tomahawk there, or pipe, or whatever you call it; tell him to stop smoking, in short, and I will turn in with him. But I don't fancy having a man smoking in bed with me. It's dangerous. Besides, I aint insured. This being told to Queequeg, he at once complied, and again politely motioned me to get into bed --rolling over to one side as much as to say --I wont touch a leg of ye. Good night, landlord, said I, you may go. I turned in, and never slept better in my life. ..

.. < chapter iv 2 THE COUNTERPANE > Upon waking next morning about daylight, I found Queequeg's arm thrown over me in the most loving and affectionate manner. You had almost thought I had been his wife. The counterpane was of patchwork, full of odd little parti-colored squares and triangles; and this arm of his tattooed all over with an interminable Cretan labyrinth of a figure, no two parts of which were of one precise shade --owing I suppose to his keeping his arm at sea unmethodically in sun and shade, his shirt sleeves irregularly rolled up at various times --this same arm of his, I say, looked for all the world like a strip of that same patchwork quilt. Indeed, partly lying on it as the arm did when I first awoke, I could hardly tell it from the quilt, they so blended their hues together; and it was only by the sense of weight and pressure that I could tell that Queequeg was hugging me. My sensations were strange. Let me try to explain them. When I was a child, I well remember a somewhat similar circumstance that befell me; whether it was a reality or a dream, I never could entirely settle. The circumstance was this. I had been cutting up some caper or other --I think it was trying to crawl up the chimney, as i had seen a little sweep do a few days previous; and my stepmother who, somehow or other, was all the time whipping me, or sending me to bed supperless, --my mother dragged me by the legs out of the chimney and packed me off to bed, though it was only two o'clock in the afternoon of the 21st June, the longest day in the year in our hemisphere. I felt dreadfully. But there was no help for it, so up stairs I went to my little room in the third floor, undressed myself as slowly as possible so as to kill time, and with a bitter sigh got between the sheets. I lay there dismally calculating that sixteen entire hours must elapse before I could hope for a resurrection. Sixteen hours in ..

bed! the small of my back ached to think of it. And it was so light too; the sun shining in at the window, and a great rattling of coaches in the streets, and the sound of gay voices all over the house. I felt worse and worse --at last I got up, dressed, and softly going down in my stockinged feet, sought out my stepmother, and suddenly threw myself at her feet, beseeching her as a particular favor to give me a good slippering for my misbehavior; anything indeed but condemning me to lie abed such an unendurable length of time. But she was the best and most conscientious of stepmothers, and back I had to go to my room. For several hours I lay there broad awake, feeling a great deal worse than I have ever done since, even from the greatest subsequent misfortunes. At last I must have fallen into a troubled nightmare of a doze; and slowly waking from it --half steeped in dreams --I opened my eyes, and the before sun-lit room was now wrapped in outer darkness. Instantly I felt a shock running through all my frame; nothing was to be seen, and nothing was to be heard; but a supernatural hand seemed placed in mine. My arm hung over the counterpane, and the nameless, unimaginable, silent form or phantom, to which the hand belonged, seemed closely seated by my bedside. For what seemed ages piled on ages, I lay there, frozen with the most awful fears, not daring to drag away my hand; yet ever thinking that if I could but stir it one single inch, the horrid spell would be broken. I knew not how this consciousness at last glided away from me; but waking in the morning, I shudderingly remembered it all, and for days and weeks and months afterwards I lost myself in confounding attempts to explain the mystery. Nay, to this very hour, I often puzzle myself with it. Now, take away the awful fear, and my sensations at feeling the supernatural hand in mine were very similar, in their strangeness, to those which I experienced on waking up and seeing Queequeg's pagan arm thrown round me. But at length all the past night's events soberly recurred, one by one, in fixed reality, and then I lay only alive to the comical predicament. For though I tried to move his arm --unlock his bridegroom clasp --yet, sleeping as he was, he still hugged me tightly, as though naught but death should part us twain. I now strove to rouse him -- ..

Queequeg! --but his only answer was a snore. I then rolled over, my neck feeling as if it were in a horse-collar; and suddenly felt a slight scratch. Throwing aside the counterpane, there lay the tomahawk sleeping by the savage's side, as if it were a hatchet-faced baby. A pretty pickle, truly, thought I; abed here in a strange house in the broad day, with a cannibal and a tomahawk! Queequeg! --in the name of goodness, Queequeg, wake! At length, by dint of much wriggling, and loud and incessant expostulations upon the unbecomingness of his hugging a fellow male in that matrimonial sort of style, I succeeded in extracting a grunt; and presently, he drew back his arm, shook himself all over like a Newfoundland dog just from the water, and sat up in bed, stiff as a pike-staff, looking at me, and rubbing his eyes as if he did not altogether remember how I came to be there, though a dim consciousness of knowing something about me seemed slowly dawning over him. Meanwhile, I lay quietly eyeing him, having no serious misgivings now, and bent upon narrowly observing so curious a creature. When, at last, his mind seemed made up touching the character of his bedfellow, and he became, as it were, reconciled to the fact; he jumped out upon the floor, and by certain signs and sounds gave me to understand that, if it pleased me, he would dress first and then leave me to dress afterwards, leaving the whole apartment to myself. Thinks I, Queequeg, under the circumstances, this is a very civilized overture; but, the truth is, these savages have an innate sense of delicacy, say what you will; it is marvellous how essentially polite they are. I pay this particular compliment to Queequeg, because he treated me with so much civility and consideration, while I was guilty of great rudeness; staring at him from the bed, and watching all his toilette motions; for the time my curiosity getting the better of my breeding. Nevertheless, a man like Queequeg you don't see every day, he and his ways were well worth unusual regarding. He commenced dressing at top by donning his beaver hat, a very tall one, by the by, and then --still minus his trowsers -- he hunted up his boots. What under the heavens he did it for, I cannot tell, but his next movement was to crush himself --boots in hand, and hat on --under the bed; when, from sundry violent ..

gaspings and strainings, I inferred he was hard at work booting himself; though by no law of propriety that I ever heard of, is any man required to be private when putting on his boots. But Queequeg, do you see, was a creature in the transition state -- neither caterpillar nor butterfly. He was just enough civilized to show off his outlandishness in the strangest possible manner. his education was not yet completed. He was an undergraduate. If he had not been a small degree civilized, he very probably would not have troubled himself with boots at all; but then, if he had not been still a savage, he never would have dreamt of getting under the bed to put them on. At last, he emerged with his hat very much dented and crushed down over his eyes, and began creaking and limping about the room, as if, not being much accustomed to boots, his pair of damp, wrinkled cowhide ones -- probably not made to order either --rather pinched and tormented him at the first go off of a bitter cold morning. Seeing, now, that there were no curtains to the window, and that the street being very narrow, the house opposite commanded a plain view into the room, and observing more and more the indecorous figure that Queequeg made, staving about with little else but his hat and boots on; I begged him as well as I could, to accelerate his toilet somewhat, and particularly to get into his pantaloons as soon as possible. He complied, and then proceeded to wash himself. At that time in the morning any Christian would have washed his face; but Queequeg, to my amazement, contented himself with restricting his ablutions to his chest, arms, and hands. He then donned his waistcoat, and taking up a piece of hard soap on the wash-stand centre-table, dipped it into water and commenced lathering his face. I was watching to see where he kept his razor, when lo and behold, he takes the harpoon from the bed corner, slips out the long wooden stock, unsheathes the head, whets it a little on his boot, and striding up to the bit of mirror against the wall, begins a vigorous scraping, or rather harpooning of his cheeks. Thinks I, Queequeg, this is using Rogers's best cutlery with a vengeance. Afterwards I wondered the less at this operation when I came to know of what fine steel the head of a harpoon is made, and how exceedingly sharp the long straight edges are always kept. ..

the rest of his toilet was soon achieved, and he proudly marched out of the room, wrapped up in his great pilot monkey jacket, and sporting his harpoon like a marshal's baton. ..

.. < chapter v 5 BREAKFAST > I quickly followed suit, and descending into the bar-room accosted the grinning landlord very pleasantly. I cherished no malice towards him, though he had been skylarking with me not a little in the matter of my bedfellow. However, a good laugh is a mighty good thing, and rather too scarce a good thing; the more's the pity. So, if any one man, in his own proper person, afford stuff for a good joke to anybody, let him not be backward, but let him cheerfully allow himself to spend and be spent in that way. And the man that has anything bountifully laughable about him, be sure there is more in that man than you perhaps think for. The bar-room was now full of the boarders who had been dropping in the night previous, and whom I had not as yet had a good look at. They were nearly all whalemen; chief mates, and second mates, and third mates, and sea carpenters, and sea coopers, and sea blacksmiths, and harpooneers, and ship keepers; a brown and brawny company, with bosky beards; an unshorn, shaggy set, all wearing monkey jackets for morning gowns. You could pretty plainly tell how long each one had been ashore. This young fellow's healthy cheek is like a sun-toasted pear in hue, and would seem to smell almost as musky; he cannot have been three days landed from his Indian voyage. That man next him looks a few shades lighter; you might say a touch of satin wood is in him. In the complexion of a third still lingers a tropic tawn, but slightly bleached withal; he doubtless has tarried whole weeks ashore. But who could show a cheek like ..

Queequeg? which, barred with various tints, seemed like the Andes' western slope, to show forth in one array, contrasting climates, zone by zone. Grub, ho! now cried the landlord, flinging open a door, and in we went to breakfast. They say that men who have seen the world, thereby become quite at ease in manner, quite self-possessed in company. Not always, though: Ledyard, the great New England traveller, and Mungo Park, the Scotch one; of all men, they possessed the least assurance in the parlor. But perhaps the mere crossing of Siberia in a sledge drawn by dogs as Ledyard did, or the taking a long solitary walk on an empty stomach, in the negro heart of Africa, which was the sum of poor Mungo's performances -- this kind of travel, I say, may not be the very best mode of attaining a high social polish. Still, for the most part, that sort of thing is to be had anywhere. These reflections just here are occasioned by the circumstance that after we were all seated at the table, and I was preparing to hear some good stories about whaling; to my no small surprise, nearly every man maintained a profound silence. And not only that, but they looked embarrassed. Yes, here were a set of sea-dogs, many of whom without the slightest bashfulness had boarded great whales on the high seas --entire strangers to them --and duelled them dead without winking; and yet, here they sat at a social breakfast table --all of the same calling, all of kindred tastes --looking round as sheepishly at each other as though they had never been out of sight of some sheepfold among the Green Mountains. A curious sight; these bashful bears, these timid warrior whalemen! But as for Queequeg --why, Queequeg sat there among them --at the head of the table, too, it so chanced; as cool as an icicle. To be sure I cannot say much for his breeding. His greatest admirer could not have cordially justified his bringing his harpoon into breakfast with him, and using it there without ceremony; reaching over the table with it, to the imminent jeopardy of many heads, and grappling the beefsteaks towards him. But that was certainly very coolly done by him, and every ..

one knows that in most people's estimation, to do anything coolly is to do it genteelly. We will not speak of all Queequeg's peculiarities here; how he eschewed coffee and hot rolls, and applied his undivided attention to beefsteaks, done rare. Enough, that when breakfast was over he withdrew like the rest into the public room, lighted his tomahawk-pipe, and was sitting there quietly digesting and smoking with his inseparable hat on, when I sallied out for a stroll. ..

.. < chapter vi 11 THE STREET > If I had been astonished at first catching a glimpse of so outlandish an individual as Queequeg circulating among the polite society of a civilized town, that astonishment soon departed upon taking my first daylight stroll through the streets of New Bedford. In thoroughfares nigh the docks, any considerable seaport will frequently offer to view the queerest looking nondescripts from foreign parts. Even in Broadway and Chestnut streets, Mediterranean mariners will sometimes jostle the affrighted ladies. Regent street is not unknown to Lascars and Malays; and at Bombay, in the Apollo Green, live Yankees have often scared the natives. But New Bedford beats all Water street and Wapping. In these last-mentioned haunts you see only sailors; but in New Bedford, actual cannibals stand chatting at street corners; savages outright; many of whom yet carry on their bones unholy flesh. It makes a stranger stare. But, besides the Feegeeans, Tongatabooarrs, Erromanggoans, Pannangians, and Brighggians, and, besides the wild specimens of the whaling-craft which unheeded reel about the streets, you will see other sights still more curious, certainly more comical. ..

There weekly arrive in this town scores of green Vermonters and New Hampshire men, all athirst for gain and glory in the fishery. They are mostly young, of stalwart frames; fellows who have felled forests, and now seek to drop the axe and snatch the whale-lance. Many are as green as the Green Mountains whence they came. In some things you would think them but a few hours old. Look there! that chap strutting round the corner. He wears a beaver hat and swallow-tailed coat, girdled with a sailor-belt and sheath-knife. Here comes another with a sou'-wester and a bombazine cloak. No town-bred dandy will compare with a country-bred one -- I mean a downright bumpkin dandy --a fellow that, in the dog-days, will mow his two acres in buckskin gloves for fear of tanning his hands. Now when a country dandy like this takes it into his head to make a distinguished reputation, and joins the great whale-fishery, you should see the comical things he does upon reaching the seaport. In bespeaking his sea-outfit, he orders bell-buttons to his waistcoats; straps to his canvas trowsers. Ah, poor Hay-Seed! how bitterly will burst those straps in the first howling gale, when thou art driven, straps, buttons, and all, down the throat of the tempest. But think not that this famous town has only harpooneers, cannibals, and bumpkins to show her visitors. Not at all. Still New Bedford is a queer place. Had it not been for us whalemen, that tract of land would this day perhaps have been in as howling condition as the coast of Labrador. As it is, parts of her back country are enough to frighten one, they look so bony. The town itself is perhaps the dearest place to live in, in all New England. It is a land of oil, true enough; but not like Canaan; a land, also, of corn and wine. The streets do not run with milk; nor in the spring-time do they pave them with fresh eggs. Yet, in spite of this, nowhere in all America will you find more patrician-like houses; parks and gardens more opulent, than in New Bedford. Whence came they? how planted upon this once scraggy scoria of a country? Go and gaze upon the iron emblematical harpoons round yonder lofty mansion, and your question will be answered. Yes; all these brave houses and flowery gardens came from the ..

Atlantic, Pacific, and Indian oceans. One and all, they were harpooned and dragged up hither from the bottom of the sea. Can Herr Alexander perform a feat like that? In New Bedford, fathers, they say, give whales for dowers to their daughters, and portion off their nieces with a few porpoises a-piece. You must go to New Bedford to see a brilliant wedding; for, they say, they have reservoirs of oil in every house, and every night recklessly burn their lengths in spermaceti candles. In summer time, the town is sweet to see; full of fine maples --long avenues of green and gold. And in August, high in air, the beautiful and bountiful horse-chestnuts, candelabra-wise, proffer the passer-by their tapering upright cones of congregated blossoms. So omnipotent is art; which in many a district of New Bedford has superinduced bright terraces of flowers upon the barren refuse rocks thrown aside at creation's final day. And the women of New Bedford, they bloom like their own red roses. But roses only bloom in summer; whereas the fine carnation of their cheeks is perennial as sunlight in the seventh heavens. Elsewhere match that bloom of theirs, ye cannot, save in Salem, where they tell me the young girls breathe such musk, their sailor sweethearts smell them miles off shore, as though they were drawing nigh the odorous Moluccas instead of the Puritanic sands. .. < chapter vii 26 THE CHAPEL > In this same New Bedford there stands a Whaleman's Chapel, and few are the moody fishermen, shortly bound for the Indian Ocean or Pacific, who fail to make a Sunday visit to the spot. I am sure that I did not. Returning from my first morning stroll, I again sallied out upon this special errand. The sky had changed from clear, ..

sunny cold, to driving sleet and mist. Wrapping myself in my shaggy jacket of the cloth called bearskin, I fought my way against the stubborn storm. Entering, I found a small scattered congregation of sailors, and sailors' wives and widows. A muffled silence reigned, only broken at times by the shrieks of the storm. Each silent worshipper seemed purposely sitting apart from the other, as if each silent grief were insular and incommunicable. The chaplain had not yet arrived; and there these silent islands of men and women sat steadfastly eyeing several marble tablets, with black borders, masoned into the wall on either side the pulpit. Three of them ran something like the following, but I do not pretend to quote: -- Sacred To the Memory of John Talbot, Who, at the age of eighteen, was lost overboard, Near the Isle of Desolation, off Patagonia, November 1st, . This Tablet Is erected to his Memory By his Sister. Sacred To the Memory of Robert Long, Willis Ellery, Nathan Coleman, Walter Canny, Seth Macy, and Samuel Gleig, Forming one of the boats' crews of the Ship Eliza, Who were towed out of sight by a Whale, On the Off-shore Ground in the Pacific, December 31st, . This Marble Is here placed by their surviving Shipmates. ..

Sacred To the Memory of The late Captain Ezekiel Hardy, Who in the bows of his boat was killed by a Sperm Whale on the coast of Japan, August 3d, This Tablet Is erected to his Memory by His Widow. Shaking off the sleet from my ice-glazed hat and jacket, I seated myself near the door, and turning sideways was surprised to see Queequeg near me. Affected by the solemnity of the scene, there was a wondering gaze of incredulous curiosity in his countenance. This savage was the only person present who seemed to notice my entrance; because he was the only one who could not read, and, therefore, was not reading those frigid inscriptions on the wall. Whether any of the relatives of the seamen whose names appeared there were now among the congregation, I knew not; but so many are the unrecorded accidents in the fishery, and so plainly did several women present wear the countenance if not the trappings of some unceasing grief, that I feel sure that here before me were assembled those, in whose unhealing hearts the sight of those bleak tablets sympathetically caused the old wounds to bleed afresh. Oh! ye whose dead lie buried beneath the green grass; who standing among flowers can say --here, here lies my beloved; ye know not the desolation that broods in bosoms like these. What bitter blanks in those black-bordered marbles which cover no ashes! What despair in those immovable inscriptions! What deadly voids and unbidden infidelities in the lines that seem to gnaw upon all Faith, and refuse resurrections to the beings who have placelessly perished without a grave. As well might those tablets stand in the cave of Elephanta as here. In what census of living creatures, the dead of mankind are included; why it is that a universal proverb says of them, that ..

they tell no tales, though containing more secrets than the Goodwin Sands; how it is that to his name who yesterday departed for the other world, we prefix so significant and infidel a word, and yet do not thus entitle him, if he but embarks for the remotest Indies of this living earth; why the Life Insurance Companies pay death-forfeitures upon immortals; in what eternal, unstirring paralysis, and deadly, hopeless trance, yet lies antique Adam who died sixty round centuries ago; how it is that we still refuse to be comforted for those who we nevertheless maintain are dwelling in unspeakable bliss; why all the living so strive to hush all the dead; wherefore but the rumor of a knocking in a tomb will terrify a whole city. All these things are not without their meanings. But Faith, like a jackal, feeds among the tombs, and even from these dead doubts she gathers her most vital hope. It needs scarcely to be told, with what feelings, on the eve of a Nantucket voyage, I regarded those marble tablets, and by the murky light of that darkened, doleful day read the fate of the whalemen who had gone before me, Yes, Ishmael, the same fate may be thine. But somehow I grew merry again. Delightful inducements to embark, fine chance for promotion, it seems -- aye, a stove boat will make me an immortal by brevet. Yes, there is death in this business of whaling --a speechlessly quick chaotic bundling of a man into Eternity. But what then? Methinks we have hugely mistaken this matter of Life and Death. Methinks that what they call my shadow here on earth is my true substance. Methinks that in looking at things spiritual, we are too much like oysters observing the sun through the water, and thinking that thick water the thinnest of air. Methinks my body is but the lees of my better being. In fact take my body who will, take it I say, it is not me. And therefore three cheers for Nantucket; and come a stove boat and stove body when they will, for stave my soul, Jove himself cannot. ..

.. < chapter viii 2 THE PULPIT > I had not been seated very long ere a man of a certain venerable robustness entered; immediately as the storm-pelted door flew back upon admitting him, a quick regardful eyeing of him by all the congregation, sufficiently attested that this fine old man was the chaplain. Yes, it was the famous Father Mapple, so called by the whalemen, among whom he was a very great favorite. He had been a sailor and a harpooneer in his youth, but for many years past had dedicated his life to the ministry. At the time I now write of, Father Mapple was in the hardy winter of a healthy old age; that sort of old age which seems merging into a second flowering youth, for among all the fissures of his wrinkles, there shone certain mild gleams of a newly developing bloom --the spring verdure peeping forth even beneath February's snow. No one having previously heard his history, could for the first time behold Father Mapple without the utmost interest, because there were certain engrafted clerical peculiarities about him, imputable to that adventurous maritime life he had led. When he entered I observed that he carried no umbrella, and certainly had not come in his carriage, for his tarpaulin hat ran down with melting sleet, and his great pilot cloth jacket seemed almost to drag him to the floor with the weight of the water it had absorbed. However, hat and coat and overshoes were one by one removed, and hung up in a little space in an adjacent corner; when, arrayed in a decent suit, he quietly approached the pulpit. Like most old fashioned pulpits, it was a very lofty one, and since a regular stairs to such a height would, by its long angle with the floor, seriously contract the already small area of the chapel, the architect, it seemed, had acted upon the hint of Father Mapple, and finished the pulpit without a stairs, substituting a perpendicular side ladder, like those used in mounting ..

a ship from a boat at sea. The wife of a whaling captain had provided the chapel with a handsome pair of red worsted man-ropes for this ladder, which, being itself nicely headed, and stained with a mahogany color, the whole contrivance, considering what manner of chapel it was, seemed by no means in bad taste. Halting for an instant at the foot of the ladder, and with both hands grasping the ornamental knobs of the man-ropes, Father Mapple cast a look upwards, and then with a truly sailorlike but still reverential dexterity, hand over hand, mounted the steps as if ascending the main-top of his vessel. the perpendicular parts of this side ladder, as is usually the case with swinging ones, were of cloth-covered rope, only the rounds were of wood, so that at every step there was a joint. At my first glimpse of the pulpit, it had not escaped me that however convenient for a ship, these joints in the present instance seemed unnecessary. For I was not prepared to see Father Mapple after gaining the height, slowly turn round, and stooping over the pulpit, deliberately drag up the ladder step by step, till the whole was deposited within, leaving him impregnable in his little Quebec. I pondered some time without fully comprehending the reason for this. Father Mapple enjoyed such a wide reputation for sincerity and sanctity, that I could not suspect him of courting notoriety by any mere tricks of the stage. No, thought I, there must be some sober reason for this thing; furthermore, it must symbolize something unseen. Can it be, then, that by that act of physical isolation, he signifies his spiritual withdrawal for the time, from all outward worldly ties and connexions? Yes, for replenished with the meat and wine of the word, to the faithful man of God, this pulpit, I see, is a self-containing stronghold --a lofty Ehrenbreitstein, with a perennial well of water within the walls. But the side ladder was not the only strange feature of the place, borrowed from the chaplain's former sea-farings. Between the marble cenotaphs on either hand of the pulpit, the wall which formed its back was adorned with a large painting representing a gallant ship beating against a terrible storm off a lee coast of black rocks and snowy breakers. But high above the ..

flying scud and dark-rolling clouds, there floated a little isle of sunlight, from which beamed forth an angel's face; and this bright face shed a distinct spot of radiance upon the ship's tossed deck, something like that silver plate now inserted into the Victory's plank where Nelson fell. Ah, noble ship, the angel seemed to say, beat on, beat on, thou noble ship, and bear a hardy helm; for lo! the sun is breaking through; the clouds are rolling off --serenest azure is at hand. Nor was the pulpit itself without a trace of the same sea-taste that had achieved the ladder and the picture. Its panelled front was in the likeness of a ship's bluff bows, and the Holy Bible rested on the projecting piece of scroll work, fashioned after a ship's fiddle-headed beak. What could be more full of meaning? --for the pulpit is ever this earth's foremost part; all the rest comes in its rear; the pulpit leads the world. From thence it is the storm of God's quick wrath is first descried, and the bow must bear the earliest brunt. From thence it is the God of breezes fair or foul is first invoked for favorable winds. Yes, the world's a ship on its passage out, and not a voyage complete; and the pulpit is its prow. .. < chapter ix 23 THE SERMON > Father Mapple rose, and in a mild voice of unassuming authority ordered the scattered people to condense. Starboard gangway, there! side away to larboard--larboard gangway to starboard! Midships! midships! There was a low rumbling of heavy sea-boots among the benches, and a still slighter shuffling of women's shoes, and all was quiet again, and every eye on the preacher. He paused a little; then kneeling in the pulpit's bows, folded his large brown hands across his chest, uplifted his closed eyes, ..

and offered a prayer so deeply devout that he seemed kneeling and praying at the bottom of the sea. This ended, in prolonged solemn tones, like the continual tolling of a bell in a ship that is foundering at sea in a fog --in such tones he commenced reading the following hymn; but changing his manner towards the concluding stanzas, burst forth with a pealing exultation and joy -- The ribs and terrors in the whale, Arched over me a dismal gloom, While all God's sun-lit waves rolled by, And lift me deepening down to doom. I saw the opening maw of hell, With endless pains and sorrows there; Which none but they that feel can tell-- Oh, I was plunging to despair. In black distress, I called my God, When I could scarce believe him mine, He bowed his ear to my complaints -- No more the whale did me confine. With speed he flew to my relief, As on a radiant dolphin borne; Awful, yet bright, as lightning shone The face of my Deliverer God. My song for ever shall record That terrible, that joyful hour; I give the glory to my God, His all the mercy and the power. Nearly all joined in singing this hymn, which swelled high above the howling of the storm. A brief pause ensued; the preacher slowly turned over the leaves of the Bible, and at last, folding his hand down upon the proper page, said: Beloved shipmates, clinch the last verse of the first chapter of Jonah -- And God had prepared a great fish to swallow up Jonah. Shipmates, this book, containing only four chapters --four yarns --is one of the smallest strands in the mighty cable of the Scriptures. Yet what depths of the soul does Jonah's deep sealine sound! what a pregnant lesson to us is this prophet! What ..

a noble thing is that canticle in the fish's belly! How billow-like and boisterously grand! We feel the floods surging over us; we sound with him to the kelpy bottom of the waters; sea-weed and all the slime of the sea is about us! But what is this lesson that the book of Jonah teaches? Shipmates, it is a two-stranded lesson; a lesson to us all as sinful men, and a lesson to me as a pilot of the living God. As sinful men, it is a lesson to us all, because it is a story of the sin, hard-heartedness, suddenly awakened fears, the swift punishment, repentance, prayers, and finally the deliverance and joy of Jonah. As with all sinners among men, the sin of this son of Amittai was in his wilful disobedience of the command of God --never mind now what that command was, or how conveyed --which he found a hard command. But all the things that God would have us do are hard for us to do --remember that --and hence, he oftener commands us than endeavors to persuade. And if we obey God, we must disobey ourselves; and it is in this disobeying ourselves, wherein the hardness of obeying God consists. With this sin of disobedience in him, Jonah still further flouts at God, by seeking to flee from Him. He thinks that a ship made by men, will carry him into countries where God does not reign, but only the Captains of this earth. He skulks about the wharves of Joppa, and seeks a ship that's bound for Tarshish. There lurks, perhaps, a hitherto unheeded meaning here. By all accounts Tarshish could have been no other city than the modern Cadiz. That's the opinion of learned men. And where is Cadiz, shipmates? Cadiz is in Spain; as far by water, from Joppa, as Jonah could possibly have sailed in those ancient days, when the Atlantic was an almost unknown sea. Because Joppa, the modern Jaffa, shipmates, is on the most easterly coast of the Mediterranean, the Syrian; and Tarshish or Cadiz more than two thousand miles to the westward from that, just outside the Straits of Gibraltar. See ye not then, shipmates, that Jonah sought to flee world-wide from God? Miserable man! Oh! most contemptible and worthy of all scorn; with slouched hat and guilty eye, skulking from his God; prowling among the shipping like a vile burglar hastening to cross the seas. So disordered, self-condemning is his look, that had there been policemen in ..

those days, jonah, on the mere suspicion of something wrong, had been arrested ere he touched a deck. How plainly he's a fugitive! no baggage, not a hat-box, valise, or carpet-bag, --no friends accompany him to the wharf with their adieux. At last, after much dodging search, he finds the Tarshish ship receiving the last items of her cargo; and as he steps on board to see its Captain in the cabin, all the sailors for the moment desist from hoisting in the goods, to mark the stranger's evil eye. Jonah sees this; but in vain he tries to look all ease and confidence; in vain essays his wretched smile. Strong intuitions of the man assure the mariners he can be no innocent. In their gamesome but still serious way, one whispers to the other --"Jack, he's robbed a widow;" or,"Joe, do you mark him; he's a bigamist;" or,"Harry lad, I guess he's the adulterer that broke jail in old Gomorrah, or belike, one of the missing murderers from Sodom." Another runs to read the bill that's stuck against the spile upon the wharf to which the ship is moored, offering five hundred gold coins for the apprehension of a parricide, and containing a description of his person. He reads, and looks from Jonah to the bill; while all his sympathetic shipmates now crowd round Jonah, prepared to lay their hands upon him. Frighted Jonah trembles, and summoning all his boldness to his face, only looks so much the more a coward. He will not confess himself suspected; but that itself is strong suspicion. So he makes the best of it; and when the sailors find him not to be the man that is advertised, they let him pass, and he descends into the cabin. "Who's there?" cries the Captain at his busy desk, hurriedly making out his papers for the Customs --"who's there?" Oh! how that harmless question mangles Jonah! For the instant he almost turns to flee again. But he rallies. "I seek a passage in this ship to Tarshish; how soon sail ye, sir?" Thus far the busy captain had not looked up to jonah, though the man now stands before him; but no sooner does he hear that hollow voice, than he darts a scrutinizing glance. "We sail with the next coming tide," at last he slowly answered, still intently eyeing him. "No sooner, sir?" --"Soon enough for any honest man that goes a passenger." Ha! Jonah, that's another stab. But he swiftly calls away the Captain from that scent. "I'll sail with ye," --he says, --"the passage ..

money, how much is that, --I'll pay now." For it is particularly written, shipmates, as if it were a thing not to be overlooked in this history,"that he paid the fare thereof" ere the craft did sail. And taken with the context, this is full of meaning. Now Jonah's Captain, shipmates, was one whose discernment detects crime in any, but whose cupidity exposes it only in the penniless. In this world, shipmates, sin that pays its way can travel freely, and without a passport; whereas Virtue, if a pauper, is stopped at all frontiers. So Jonah's Captain prepares to test the length of Jonah's purse, ere he judge him openly. He charges him thrice the usual sum; and it's assented to. Then the Captain knows that Jonah is a fugitive; but at the same time resolves to help a flight that paves its rear with gold. Yet when Jonah fairly takes out his purse, prudent suspicions still molest the Captain. He rings every coin to find a counterfeit. Not a forger, any way, he mutters; and Jonah is put down for his passage. "Point out my state-room, Sir," says Jonah now. "I'm travel-weary; I need sleep." "Thou look'st like it," says the Captain, "there's thy room." Jonah enters, and would lock the door, but the lock contains no key. Hearing him foolishly fumbling there, the Captain laughs lowly to himself, and mutters something about the doors of convicts' cells being never allowed to be locked within. All dressed and dusty as he is, Jonah throws himself into his berth, and finds the little state-room ceiling almost resting on his forehead. The air is close, and jonah gasps. then, in that contracted hole, sunk, too, beneath the ship's water-line, Jonah feels the heralding presentiment of that stifling hour, when the whale shall hold him in the smallest of his bowel's wards. Screwed at its axis against the side, a swinging lamp slightly oscillates in Jonah's room; and the ship, heeling over towards the wharf with the weight of the last bales received, the lamp, flame and all, though in slight motion, still maintains a permanent obliquity with reference to the room; though, in truth, infallibly straight itself, it but made obvious the false, lying levels among which it hung. The lamp alarms and frightens Jonah; as lying in his berth his tormented eyes roll round the place, and this thus far successful fugitive finds no refuge for his restless glance. But that contradiction in the lamp more and ..

more appals him. The floor, the ceiling, and the side, are all awry. "Oh! so my conscience hangs in me!" he groans, "straight upward, so it burns; but the chambers of my soul are all in crookedness!" Like one who after a night of drunken revelry hies to his bed, still reeling, but with conscience yet pricking him, as the plungings of the Roman race-horse but so much the more strike his steel tags into him; as one who in that miserable plight still turns and turns in giddy anguish, praying God for annihilation until the fit be passed; and at last amid the whirl of woe he feels, a deep stupor steals over him, as over the man who bleeds to death, for conscience is the wound, and there's naught to staunch it; so, after sore wrestlings in his berth, Jonah's prodigy of ponderous misery drags him drowning down to sleep. And now the time of tide has come; the ship casts off her cables; and from the deserted wharf the uncheered ship for Tarshish, all careening, glides to sea. That ship, my friends, was the first of recorded smugglers! the contraband was jonah. but the sea rebels; he will not bear the wicked burden. A dreadful storm comes on, the ship is like to break. But now when the boatswain calls all hands to lighten her; when boxes, bales, and jars are clattering overboard; when the wind is shrieking, and the men are yelling, and every plank thunders with trampling feet right over Jonah's head; in all this raging tumult, Jonah sleeps his hideous sleep. He sees no black sky and raging sea, feels not the reeling timbers, and little hears he or heeds he the far rush of the mighty whale, which even now with open mouth is cleaving the seas after him. Aye, shipmates, Jonah was gone down into the sides of the ship --a berth in the cabin as I have taken it, and was fast asleep. But the frightened master comes to him, and shrieks in his dead ear, "What meanest thou, O sleeper! arise!" Startled from his lethargy by that direful cry, Jonah staggers to his feet, and stumbling to the deck, grasps a shroud, to look out upon the sea. But at that moment he is sprung upon by a panther billow leaping over the bulwarks. Wave after wave thus leaps into the ship, and finding no speedy vent runs roaring fore and aft, till the mariners come nigh to drowning while yet afloat. And ever, as the white moon shows ..

her affrighted face from the steep gullies in the blackness overhead, aghast Jonah sees the rearing bowsprit pointing high upward, but soon beat downward again towards the tormented deep. Terrors upon terrors run shouting through his soul. In all his cringing attitudes, the God-fugitive is now too plainly known. The sailors mark him; more and more certain grow their suspicions of him, and at last, fully to test the truth, by referring the whole matter to high Heaven, they fall to casting lots, to see for whose cause this great tempest was upon them. The lot is Jonah's; that discovered, then how furiously they mob him with their questions. "What is thine occupation? whence comest thou? thy country? what people?" but mark now, my shipmates, the behavior of poor Jonah. The eager mariners but ask him who he is, and where from; whereas, they not only receive an answer to those questions, but likewise another answer to a question not put by them, but the unsolicited answer is forced from Jonah by the hard hand of God that is upon him. "I am a Hebrew," he cries --and then --"I fear the Lord the God of Heaven who hath made the sea and the dry land!" Fear him, O Jonah? Aye, well mightest thou fear the Lord God then! Straightway, he now goes on to make a full confession; whereupon the mariners became more and more appalled, but still are pitiful. For when Jonah, not yet supplicating God for mercy, since he but too well knew the darkness of his deserts, --when wretched Jonah cries out to them to take him and cast him forth into the sea, for he knew that for his sake this great tempest was upon them; they mercifully turn from him, and seek by other means to save the ship. But all in vain; the indignant gale howls louder; then, with one hand raised invokingly to God, with the other they not unreluctantly lay hold of Jonah. And now behold Jonah taken up as an anchor and dropped into the sea; when instantly an oily calmness floats out from the east, and the sea is still, as Jonah carries down the gale with him, leaving smooth water behind. He goes down in the whirling heart of such a masterless commotion that he scarce heeds the moment when he drops seething into the yawning jaws ..

awaiting him; and the whale shoots-to all his ivory teeth, like the Lord out of the fish's belly. But observe his prayer, and so many white bolts, upon his prison. Then Jonah prayed unto learn a weighty lesson. For sinful as he is, Jonah does not weep and wail for direct deliverance. He feels that his dreadful punishment is just. He leaves all his deliverance to God, contenting himself with this, that spite of all his pains and pangs, he will still look towards His holy temple. And here, shipmates, is true and faithful repentance; not clamorous for pardon, but grateful for punishment. And how pleasing to God was this conduct in Jonah, is shown in the eventual deliverance of him from the sea and the whale. Shipmates, I do not place Jonah before you to be copied for his sin but I do place him before you as a model for repentance. Sin not; but if you do, take heed to repent of it like Jonah. While he was speaking these words, the howling of the shrieking, slanting storm without seemed to add new power to the preacher, who, when describing Jonah's sea-storm, seemed tossed by a storm himself. His deep chest heaved as with a ground-swell; his tossed arms seemed the warring elements at work; and the thunders that rolled away from off his swarthy brow, and the light leaping from his eye, made all his simple hearers look on him with a quick fear that was strange to them. There now came a lull in his look, as he silently turned over the leaves of the Book once more; and, at last, standing motionless, with closed eyes, for the moment, seemed communing with God and himself. But again he leaned over towards the people, and bowing his head lowly, with an aspect of the deepest yet manliest humility, he spake these words: Shipmates, God has laid but one hand upon you; both his hands press upon me. I have read ye by what murky light may be mine the lesson that Jonah teaches to all sinners; and therefore to ye, and still more to me, for I am a greater sinner than ye. And now how gladly would I come down from this mast-head and sit on the hatches there where you sit, and listen as you listen, while some one of you reads me that other and more awful lesson which Jonah teaches to me as a pilot of ..

the living God. How being an anointed pilot-prophet, or speaker of true things, and bidden by the Lord to sound those unwelcome truths in the ears of a wicked nineveh, jonah, appalled at the hostility he should raise, fled from his mission, and sought to escape his duty and his God by taking ship at Joppa. But God is everywhere; Tarshish he never reached. As we have seen, God came upon him in the whale, and swallowed him down to living gulfs of doom, and with swift slantings tore him along"into the midst of the seas," where the eddying depths sucked him ten thousand fathoms down, and"the weeds were wrapped about his head," and all the watery world of woe bowled over him. Yet even then beyond the reach of any plummet --"out of the belly of hell" --when the whale grounded upon the ocean's utmost bones, even then, God heard the engulphed, repenting prophet when he cried. Then God spake unto the fish; and from the shuddering cold and blackness of the sea, the whale came breeching up towards the warm and pleasant sun, and all the delights of air and earth; and"vomited out Jonah upon the dry land;" when the word of the Lord came a second time; and Jonah, bruised and beaten --his ears, like two sea-shells, still multitudinously murmuring of the ocean --Jonah did the Almighty's bidding. And what was that, shipmates? To preach the Truth to the face of Falsehood! That was it! This, shipmates, this is that other lesson; and woe to that pilot of the living God who slights it. Woe to him whom this world charms from Gospel duty! Woe to him who seeks to pour oil upon the waters when God has brewed them into a gale! Woe to him who seeks to please rather than to appal! Woe to him whose good name is more to him than goodness! Woe to him who, in this world, courts not dishonor! Woe to him who would not be true, even though to be false were salvation! Yea, woe to him who, as the great Pilot Paul has it, while preaching to others is himself a castaway! He drooped and fell away from himself for a moment; then lifting his face to them again, showed a deep joy in his eyes, as he cried out with a heavenly enthusiasm, -- but oh! shipmates! on the starboard hand of every woe, there is a sure delight; and higher the top of that delight, than the bottom of the woe is ..

deep. Is not the main-truck higher than the kelson is low? Delight is to him --a far, far upward, and inward delight --who against the proud gods and commodores of this earth, ever stands forth his own inexorable self. Delight is to him whose strong arms yet support him, when the ship of this base treacherous world has gone down beneath him. Delight is to him, who gives no quarter in the truth, and kills, burns, and destroys all sin though he pluck it out from under the robes of Senators and Judges. Delight, --top-gallant delight is to him, who acknowledges no law or lord, but the Lord his God, and is only a patriot to heaven. Delight is to him, whom all the waves of the billows of the seas of the boisterous mob can never shake from this sure Keel of the Ages. And eternal delight and deliciousness will be his, who coming to lay him down, can say with his final breath --O Father! --chiefly known to me by Thy rod --mortal or immortal, here I die. I have striven to be Thine, more than to be this world's, or mine own. Yet this is nothing; I leave eternity to Thee; for what is man that he should live out the lifetime of his God? He said no more, but slowly waving a benediction, covered his face with his hands, and so remained kneeling, till all the people had departed, and he was left alone in the place. ..

.. < chapter X 24 A BOSOM FRIEND > Returning to the Spouter-Inn from the Chapel, I found Queequeg there quite alone; he having left the Chapel before the benediction some time. He was sitting on a bench before the fire, with his feet on the stove hearth, and in one hand was holding close up to his face that little negro idol of his; peering hard into its face, and with a jack-knife gently whittling away at its nose, meanwhile humming to himself in his heathenish way. But being now interrupted, he put up the image; and pretty ..

soon, going to the table, took up a large book there, and placing it on his lap began counting the pages with deliberate regularity; at every fiftieth page --as I fancied --stopping a moment, looking vacantly around him, and giving utterance to a long-drawn gurgling whistle of astonishment. He would then begin again at the next fifty; seeming to commence at number one each time, as though he could not count more than fifty, and it was only by such a large number of fifties being found together, that his astonishment at the multitude of pages was excited. With much interest I sat watching him. Savage though he was, and hideously marred about the face --at least to my taste -- his countenance yet had a something in it which was by no means disagreeable. You cannot hide the soul. Through all his unearthly tattooings, I thought I saw the traces of a simple honest heart; and in his large, deep eyes, fiery black and bold, there seemed tokens of a spirit that would dare a thousand devils. And besides all this, there was a certain lofty bearing about the Pagan, which even his uncouthness could not altogether maim. He looked like a man who had never cringed and never had had a creditor. Whether it was, too, that his head being shaved, his forehead was drawn out in freer and brighter relief, and looked more expansive than it otherwise would, this I will not venture to decide; but certain it was his head was phrenologically an excellent one. It may seem ridiculous, but it reminded me of General Washington's head, as seen in the popular busts of him. It had the same long regularly graded retreating slope from above the brows, which were likewise very projecting, like two long promontories thickly wooded on top. Queequeg was George Washington cannibalistically developed. Whilst I was thus closely scanning him, half-pretending meanwhile to be looking out at the storm from the casement, he never heeded my presence, never troubled himself with so much as a single glance; but appeared wholly occupied with counting the pages of the marvellous book. Considering how sociably we had been sleeping together the night previous, and especially considering the affectionate arm I had found thrown over me upon waking in the morning, I thought this indifference of his ..

very strange. But savages are strange beings; at times you do not know exactly how to take them. At first they are overawing; their calm self-collectedness of simplicity seems a Socratic wisdom. I had noticed also that Queequeg never consorted at all, or but very little, with the other seamen in the inn. He made no advances whatever; appeared to have no desire to enlarge the circle of his acquaintances. All this struck me as mighty singular; yet, upon second thoughts, there was something almost sublime in it. Here was a man some twenty thousand miles from home, by the way of Cape Horn, that is --which was the only way he could get there --thrown among people as strange to him as though he were in the planet Jupiter; and yet he seemed entirely at his ease; preserving the utmost serenity; content with his own companionship; always equal to himself. Surely this was a touch of fine philosophy; though no doubt he had never heard there was such a thing as that. But, perhaps, to be true philosophers, we mortals should not be conscious of so living or so striving. So soon as I hear that such or such a man gives himself out for a philosopher, I conclude that, like the dyspeptic old woman, he must have broken his digester. As I sat there in that now lonely room; the fire burning low, in that mild stage when, after its first intensity has warmed the air, it then only glows to be looked at; the evening shades and phantoms gathering round the casements, and peering in upon us silent, solitary twain; the storm booming without in solemn swells; I began to be sensible of strange feelings. I felt a melting in me. No more my splintered heart and maddened hand were turned against the wolfish world. This soothing savage had redeemed it. There he sat, his very indifference speaking a nature in which there lurked no civilized hypocrisies and bland deceits. Wild he was; a very sight of sights to see; yet I began to feel myself mysteriously drawn towards him. And those same things that would have repelled most others, they were the very magnets that thus drew me. I'll try a pagan friend, thought I, since Christian kindness has proved but hollow courtesy. I drew my bench near him, and made some friendly signs and hints, doing my best to talk with him meanwhile. At first he little noticed these advances; but presently, upon my referring to his last ..

night's hospitalities, he made out to ask me whether we were again to be bedfellows. I told him yes; whereat I thought he looked pleased, perhaps a little complimented. We then turned over the book together, and I endeavored to explain to him the purpose of the printing, and the meaning of the few pictures that were in it. Thus I soon engaged his interest; and from that we went to jabbering the best we could about the various outer sights to be seen in this famous town. Soon I proposed a social smoke; and, producing his pouch and tomahawk, he quietly offered me a puff. And then we sat exchanging puffs from that wild pipe of his, and keeping it regularly passing between us. If there yet lurked any ice of indifference towards me in the Pagan's breast, this pleasant, genial smoke we had, soon thawed it out, and left us cronies. He seemed to take to me quite as naturally and unbiddenly as I to him; and when our smoke was over, he pressed his forehead against mine, clasped me round the waist, and said that henceforth we were married; meaning, in his country's phrase, that we were bosom friends; he would gladly die for me, if need should be. In a countryman, this sudden flame of friendship would have seemed far too premature, a thing to be much distrusted; but in this simple savage those old rules would not apply. After supper, and another social chat and smoke, we went to our room together. He made me a present of his embalmed head; took out his enormous tobacco wallet, and groping under the tobacco, drew out some thirty dollars in silver; then spreading them on the table, and mechanically dividing them into two equal portions, pushed one of them towards me, and said it was mine. I was going to remonstrate; but he silenced me by pouring them into my trowsers' pockets. I let them stay. He then went about his evening prayers, took out his idol, and removed the paper fireboard. By certain signs and symptoms, I thought he seemed anxious for me to join him; but well knowing what was to follow, I deliberated a moment whether, in case he invited me, I would comply or otherwise. I was a good Christian; born and bred in the bosom of the infallible Presbyterian Church. How then could I unite with ..

this wild idolator in worshipping his piece of wood? But what is worship? thought I. Do you suppose now, Ishmael, that the magnanimous God of heaven and earth --pagans and all included --can possibly be jealous of an insignificant bit of black wood? Impossible! But what is worship? --to do the will of God -- that is worship. And what is the will of God? --to do to my fellow man what I would have my fellow man to do to me -- that is the will of God. Now, Queequeg is my fellow man. And what do I wish that this Queequeg would do to me? Why, unite with me in my particular Presbyterian form of worship. consequently, i must then unite with him in his; ergo, I must turn idolator. So I kindled the shavings; helped prop up the innocent little idol; offered him burnt biscuit with Queequeg; salamed before him twice or thrice; kissed his nose; and that done, we undressed and went to bed, at peace with our own consciences and all the world. But we did not go to sleep without some little chat. How it is I know not; but there is no place like a bed for confidential disclosures between friends. Man and wife, they say, there open the very bottom of their souls to each other; and some old couples often lie and chat over old times till nearly morning. Thus, then, in our hearts' honeymoon, lay I and Queequeg --a cosy, loving pair. ..

.. < chapter xi 24 NIGHTGOWN > We had lain thus in bed, chatting and napping at short intervals, and Queequeg now and then affectionately throwing his brown tattooed legs over mine, and then drawing them back; so entirely sociable and free and easy were we; when, at last, by reason of our confabulations, what little nappishness remained in us altogether departed, and we felt like getting up again, though day-break was yet some way down the future. Yes, we became very wakeful; so much so that our recumbent ..

position began to grow wearisome, and by little and little we found ourselves sitting up; the clothes well tucked around us, leaning against the head-board with our four knees drawn up close together, and our two noses bending over them, as if our knee-pans were warming-pans. We felt very nice and snug, the more so since it was so chilly out of doors; indeed out of bed-clothes too, seeing that there was no fire in the room. The more so, I say, because truly to enjoy bodily warmth, some small part of you must be cold, for there is no quality in this world that is not what it is merely by contrast. Nothing exists in itself. If you flatter yourself that you are all over comfortable, and have been so a long time, then you cannot be said to be comfortable any more. But if, like Queequeg and me in the bed, the tip of your nose or the crown of your head be slightly chilled, why then, indeed, in the general consciousness you feel most delightfully and unmistakably warm. For this reason a sleeping apartment should never be furnished with a fire, which is one of the luxurious discomforts of the rich. For the height of this sort of deliciousness is to have nothing but the blanket between you and your snugness and the cold of the outer air. Then there you lie like the one warm spark in the heart of an arctic crystal. We had been sitting in this crouching manner for some time, when all at once I thought I would open my eyes; for when between sheets, whether by day or by night, and whether asleep or awake, I have a way of always keeping my eyes shut, in order the more to concentrate the snugness of being in bed. Because no man can ever feel his own identity aright except his eyes be closed; as if darkness were indeed the proper element of our essences, though light be more congenial to our clayey part. Upon opening my eyes then, and coming out of my own pleasant and self-created darkness into the imposed and coarse outer gloom of the unilluminated twelve-o'clock-at-night, I experienced a disagreeable revulsion. Nor did I at all object to the hint from Queequeg that perhaps it were best to strike a light, seeing that we were so wide awake; and besides he felt a strong desire to have a few quiet puffs from his Tomahawk. Be it said, that though I had felt such a strong repugnance to his smoking in ..

the bed the night before, yet see how elastic our stiff prejudices grow when love once comes to bend them. For now I liked nothing better than to have Queequeg smoking by me, even in bed, because he seemed to be full of such serene household joy then. I no more felt unduly concerned for the landlord's policy of insurance. I was only alive to the condensed confidential comfortableness of sharing a pipe and a blanket with a real friend. With our shaggy jackets drawn about our shoulders, we now passed the Tomahawk from one to the other, till slowly there grew over us a blue hanging tester of smoke, illuminated by the flame of the new-lit lamp. Whether it was that this undulating tester rolled the savage away to far distant scenes, I know not, but he now spoke of his native island; and, eager to hear his history, I begged him to go on and tell it. He gladly complied. Though at the time I but ill comprehended not a few of his words, yet subsequent disclosures, when I had become more familiar with his broken phraseology, now enable me to present the whole story such as it may prove in the mere skeleton I give. ..

.. < chapter xii 21 BIOGRAPHICAL > Queequeg was a native of Kokovoko, an island far away to the West and South. It is not down in any map; true places never are. When a new-hatched savage running wild about his native woodlands in a grass clout, followed by the nibbling goats, as if he were a green sapling; even then, in Queequeg's ambitious soul, lurked a strong desire to see something more of Christendom than a specimen whaler or two. His father was a High Chief, a King; his uncle a High Priest; and on the maternal side he boasted aunts who were the wives of unconquerable warriors. There was excellent blood in his veins --royal stuff; though ..

sadly vitiated, I fear, by the cannibal propensity he nourished in his untutored youth. A Sag Harbor ship visited his father's bay, and Queequeg sought a passage to Christian lands. But the ship, having her full complement of seamen, spurned his suit; and not all the King his father's influence could prevail. But Queequeg vowed a vow. Alone in his canoe, he paddled off to a distant strait, which he knew the ship must pass through when she quitted the island. On one side was a coral reef; on the other a low tongue of land, covered with mangrove thickets that grew out into the water. Hiding his canoe, still afloat, among these thickets, with its prow seaward, he sat down in the stern, paddle low in hand; and when the ship was gliding by, like a flash he darted out; gained her side; with one backward dash of his foot capsized and sank his canoe; climbed up the chains; and throwing himself at full length upon the deck, grappled a ringbolt there, and swore not to let it go, though hacked in pieces. In vain the captain threatened to throw him overboard; suspended a cutlass over his naked wrists; Queequeg was the son of a King, and Queequeg budged not. Struck by his desperate dauntlessness, and his wild desire to visit Christendom, the captain at last relented, and told him he might make himself at home. But this fine young savage --this sea Prince of Wales, never saw the captain's cabin. They put him down among the sailors, and made a whaleman of him. But like Czar Peter content to toil in the shipyards of foreign cities, Queequeg disdained no seeming ignominy, if thereby he might happily gain the power of enlightening his untutored countrymen. For at bottom --so he told me --he was actuated by a profound desire to learn among the Christians, the arts whereby to make his people still happier than they were; and more than that, still better than they were. But, alas! the practices of whalemen soon convinced him that even Christians could be both miserable and wicked; infinitely more so, than all his father's heathens. Arrived at last in old Sag Harbor; and seeing what the sailors did there; and then going on to Nantucket, and seeing how they spent their wages in that place also, poor Queequeg gave it up for lost. Thought he, it's a wicked world in all meridians; I'll die a pagan. ..

and thus an old idolator at heart, he yet lived among these Christians, wore their clothes, and tried to talk their gibberish. Hence the queer ways about him, though now some time from home. By hints, I asked him whether he did not propose going back, and having a coronation; since he might now consider his father dead and gone, he being very old and feeble at the last accounts. He answered no, not yet; and added that he was fearful Christianity, or rather Christians, had unfitted him for ascending the pure and undefiled throne of thirty pagan Kings before him. But by and by, he said, he would return, --as soon as he felt himself baptized again. For the nonce, however, he proposed to sail about, and sow his wild oats in all four oceans. They had made a harpooneer of him, and that barbed iron was in lieu of a sceptre now. I asked him what might be his immediate purpose, touching his future movements. He answered, to go to sea again, in his old vocation. Upon this, I told him that whaling was my own design, and informed him of my intention to sail out of Nantucket, as being the most promising port for an adventurous whaleman to embark from. He at once resolved to accompany me to that island, ship aboard the same vessel, get into the same watch, the same boat, the same mess with me, in short to share my every hap; with both my hands in his, boldly dip into the Potluck of both worlds. To all this I joyously assented; for besides the affection I now felt for Queequeg, he was an experienced harpooneer, and as such, could not fail to be of great usefulness to one, who, like me, was wholly ignorant of the mysteries of whaling, though well acquainted with the sea, as known to merchant seamen. His story being ended with his pipe's last dying puff, Queequeg embraced me, pressed his forehead against mine, and blowing out the light, we rolled over from each other, this way and that, and very soon were sleeping. ..

.. < chapter xiii 2 WHEELBARROW > wheelbarrow next morning, Monday, after disposing of the embalmed head to a barber, for a block, I settled my own and comrade's bill; using, however, my comrade's money. The grinning landlord, as well as the boarders, seemed amazingly tickled at the sudden friendship which had sprung up between me and Queequeg -- especially as Peter Coffin's cock and bull stories about him had previously so much alarmed me concerning the very person whom I now companied with. We borrowed a wheelbarrow, and embarking our things, including my own poor carpet-bag, and Queequeg's canvas sack and hammock, away we went down to the Moss, the little Nantucket packet schooner moored at the wharf. As we were going along the people stared; not at Queequeg so much --for they were used to seeing cannibals like him in their streets, -- but at seeing him and me upon such confidential terms. But we heeded them not, going along wheeling the barrow by turns, and Queequeg now and then stopping to adjust the sheath on his harpoon barbs. I asked him why he carried such a troublesome thing with him ashore, and whether all whaling ships did not find their own harpoons. To this, in substance, he replied, that though what I hinted was true enough, yet he had a particular affection for his own harpoon, because it was of assured stuff, well tried in many a mortal combat, and deeply intimate with the hearts of whales. In short, like many inland reapers and mowers, who go into the farmers' meadows armed with their own scythes --though in no wise obliged to furnished them -- even so, Queequeg, for his own private reasons, preferred his own harpoon. Shifting the barrow from my hand to his, he told me a funny story about the first wheelbarrow he had ever seen. It was in Sag Harbor. The owners of his ship, it seems, had lent him one, ..

in which to carry his heavy chest to his boarding house. Not to seem ignorant about the thing --though in truth he was entirely so, concerning the precise way in which to manage the barrow --Queequeg puts his chest upon it; lashes it fast; and then shoulders the barrow and marches up the wharf. Why, said I, Queequeg, you might have known better than that, one would think. Didn't the people laugh? Upon this, he told me another story. The people of his island of Rokovoko, it seems, at their wedding feasts express the fragrant water of young cocoanuts into a large stained calabash like a punchbowl; and this punchbowl always forms the great central ornament on the braided mat where the feast is held. Now a certain grand merchant ship once touched at Rokovoko, and its commander --from all accounts, a very stately punctilious gentleman, at least for a sea captain --this commander was invited to the wedding feast of Queequeg's sister, a pretty young princess just turned of ten. Well; when all the wedding guests were assembled at the bride's bamboo cottage, this Captain marches in, and being assigned the post of honor, placed himself over against the punchbowl, and between the High Priest and his majesty the King, Queequeg's father. Grace being said, -- for those people have their grace as well as we --though Queequeg told me that unlike us, who at such times look downwards to our platters, they, on the contrary, copying the ducks, glance upwards to the great Giver of all feasts --Grace, I say, being said, the High Priest opens the banquet by the immemorial ceremony of the island; that is, dipping his consecrated and consecrating fingers into the bowl before the blessed beverage circulates. Seeing himself placed next the Priest, and noting the ceremony, and thinking himself --being Captain of a ship --as having plain precedence over a mere island King, especially in the King's own house --the Captain coolly proceeds to wash his hands in the punch bowl; --taking it i suppose for a huge finger-glass. now, said Queequeg, what you tink now, --Didn't our people laugh? At last, passage paid, and luggage safe, we stood on board the schooner. Hoisting sail, it glided down the Acushnet river. On ..

one side, New Bedford rose in terraces of streets, their ice-covered trees all glittering in the clear, cold air. Huge hills and mountains of casks on casks were piled upon her wharves, and side by side the world-wandering whale ships lay silent and safely moored at last; while from others came a sound of carpenters and coopers, with blended noises of fires and forges to melt the pitch, all betokening that new cruises were on the start; that one most perilous and long voyage ended, only begins a second; and a second ended, only begins a third, and so on, for ever and for aye. Such is the endlessness, yea, the intolerableness of all earthly effort. Gaining the more open water, the bracing breeze waxed fresh; the little Moss tossed the quick foam from her bows, as a young colt his snortings. How I snuffed that Tartar air! --how I spurned that turnpike earth! --that common highway all over dented with the marks of slavish heels and hoofs; and turned me to admire the magnanimity of the sea which will permit no records. At the same foam-fountain, Queequeg seemed to drink and reel with me. His dusky nostrils swelled apart; he showed his filed and pointed teeth. On, on we flew, and our offing gained, the Moss did homage to the blast; ducked and dived her brows as a slave before the Sultan. Sideways leaning, we sideways darted; every ropeyarn tingling like a wire; the two tall masts buckling like Indian canes in land tornadoes. So full of this reeling scene were we, as we stood by the plunging bowsprit, that for some time we did not notice the jeering glances of the passengers, a lubber-like assembly, who marvelled that two fellow beings should be so companionable; as though a white man were anything more dignified than a whitewashed negro. But there were some boobies and bumpkins there, who, by their intense greenness, must have come from the heart and centre of all verdure. Queequeg caught one of these young saplings mimicking him behind his back. I thought the bumpkin's hour of doom was come. Dropping his harpoon, the brawny savage caught him in his arms, and by an almost miraculous dexterity and strength, sent him high up bodily into the air; then slightly ..

tapping his stern in mid-somerset, the fellow landed with bursting lungs upon his feet, while Queequeg, turning his back upon him, lighted his tomahawk pipe and passed it to me for a puff. Capting! Capting! yelled the bumpkin, running towards that officer; Capting, Capting, here's the devil. Hallo, you sir, cried the Captain, a gaunt rib of the sea, stalking up to Queequeg, what in thunder do you mean by that? Don't you know you might have killed that chap? What him say? said Queequeg, as he mildly turned to me. He say, said I, that you came near kill-e that man there, pointing to the still shivering greenhorn. Kill-e, cried Queequeg, twisting his tattooed face into an unearthly expression of disdain, ah! him bevy small-e fish-e; Queequeg no kill-e so small-e fish-e; Queequeg kill-e big whale! Look you, roared the Captain, I'll kill-e you, you cannibal, if you try any more of your tricks aboard here; so mind your eye. But it so happened just then, that it was high time for the Captain to mind his own eye. The prodigious strain upon the main-sail had parted the weather-sheet, and the tremendous boom was now flying from side to side, completely sweeping the entire after part of the deck. The poor fellow whom Queequeg had handled so roughly, was swept overboard; all hands were in a panic; and to attempt snatching at the boom to stay it, seemed madness. It flew from right to left, and back again, almost in one ticking of a watch, and every instant seemed on the point of snapping into splinters. Nothing was done, and nothing seemed capable of being done; those on deck rushed towards the bows, and stood eyeing the boom as if it were the lower jaw of an exasperated whale. In the midst of this consternation, Queequeg dropped deftly to his knees, and crawling under the path of the boom, whipped hold of a rope, secured one end to the bulwarks, and then flinging the other like a lasso, caught it round the boom as it swept over his head, and at the next jerk, the spar was that way trapped, and all was safe. The schooner was run into the wind, and while the hands were clearing away the stern boat, Queequeg, stripped to the waist, darted from the side with a long living arc of a leap. For three ..

minutes or more he was seen swimming like a dog, throwing his long arms straight out before him, and by turns revealing his brawny shoulders through the freezing foam. I looked at the grand and glorious fellow, but saw no one to be saved. The greenhorn had gone down. Shooting himself perpendicularly from the water, Queequeg now took an instant's glance around him, and seeming to see just how matters were, dived down and disappeared. A few minutes more, and he rose again, one arm still striking out, and with the other dragging a lifeless form. The boat soon picked them up. The poor bumpkin was restored. All hands voted Queequeg a noble trump; the captain begged his pardon. From that hour I clove to Queequeg like a barnacle; yea, till poor Queequeg took his last long dive. Was there ever such unconsciousness? He did not seem to think that he at all deserved a medal from the Humane and Magnanimous Societies. He only asked for water --fresh water -- something to wipe the brine off; that done, he put on dry clothes, lighted his pipe, and leaning against the bulwarks, and mildly eyeing those around him, seemed to be saying to himself -- It's a mutual, joint-stock world, in all meridians. We cannibals must help these Christians. ..

.. < chapter xiv 23 NANTUCKET > Nothing more happened on the passage worthy the mentioning; so, after a fine run, we safely arrived in Nantucket. Nantucket! Take out your map and look at it. See what a real corner of the world it occupies; how it stands there, away off shore, more lonely than the Eddystone lighthouse. Look at it --a mere hillock, and elbow of sand; all beach, without a background. There is more sand there than you would use in twenty years as a substitute for blotting paper. Some gamesome wights will tell you that they have to plant weeds there, they don't ..

grow naturally; that they import Canada thistles; that they have to send beyond seas for a spile to stop a leak in an oil cask; that pieces of wood in Nantucket are carried about like bits of the true cross in Rome; that people there plant toadstools before their houses, to get under the shade in summer time; that one blade of grass makes an oasis, three blades in a day's walk a prairie; that they wear quicksand shoes, something like Laplander snowshoes; that they are so shut up, belted about, every way inclosed, surrounded, and made an utter island of by the ocean, that to their very chairs and tables small clams will sometimes be found adhering, as to the backs of sea turtles. But these extravaganzas only show that Nantucket is no Illinois. Look now at the wondrous traditional story of how this island was settled by the red-men. Thus goes the legend. In olden times an eagle swooped down upon the New England coast, and carried off an infant Indian in his talons. With loud lament the parents saw their child borne out of sight over the wide waters. They resolved to follow in the same direction. Setting out in their canoes, after a perilous passage they discovered the island, and there they found an empty ivory casket, --the poor little Indian's skeleton. What wonder, then, that these Nantucketers, born on a beach, should take to the sea for a livelihood! They first caught crabs and quohogs in the sand; grown bolder, they waded out with nets for mackerel; more experienced, they pushed off in boats and captured cod; and at last, launching a navy of great ships on the sea, explored this watery world; put an incessant belt of circumnavigations round it; peeped in at Behring's Straits; and in all seasons and all oceans declared everlasting war with the mightiest animated mass that has survived the flood; most monstrous and most mountainous! That Himmalehan, salt-sea Mastodon, clothed with such portentousness of unconscious power, that his very panics are more to be dreaded than his most fearless and malicious assaults! And thus have these naked Nantucketers, these sea hermits, issuing from their ant-hill in the sea, overrun and conquered the watery world like so many Alexanders; parcelling out among ..

them the Atlantic, Pacific, and Indian oceans, as the three pirate powers did Poland. Let America add Mexico to Texas, and pile Cuba upon Canada; let the English overswarm all India, and hang out their blazing banner from the sun; two thirds of this terraqueous globe are the Nantucketer's. For the sea is his; he owns it, as Emperors own empires; other seamen having but a right of way through it. Merchant ships are but extension bridges; armed ones but floating forts; even pirates and privateers, though following the sea as highwaymen the road, they but plunder other ships, other fragments of the land like themselves, without seeking to draw their living from the bottomless deep itself. The Nantucketer, he alone resides and riots on the sea; he alone, in Bible language, goes down to it in ships; to and fro ploughing it as his own special plantation. There is his home; there lies his business, which a noah's flood would not interrupt, though it overwhelmed all the millions in China. He lives on the sea, as prairie cocks in the prairie; he hides among the waves, he climbs them as chamois hunters climb the Alps. For years he knows not the land; so that when he comes to it at last, it smells like another world, more strangely than the moon would to an Earthsman. With the landless gull, that at sunset folds her wings and is rocked to sleep between billows; so at nightfall, the Nantucketer, out of sight of land, furls his sails, and lays him to his rest, while under his very pillow rush herds of walruses and whales. ..

.. < chapter xv 27 CHOWDER > It was quite late in the evening when the little Moss came snugly to anchor, and Queequeg and I went ashore; so we could attend to no business that day, at least none but a supper and a bed. The landlord of the Spouter-Inn had recommended us to his cousin Hosea Hussey of the Try Pots, whom he asserted to ..

be the proprietor of one of the best kept hotels in all Nantucket, and moreover he had assured us that cousin Hosea, as he called him, was famous for his chowders. In short, he plainly hinted that we could not possibly do better than try pot-luck at the Try Pots. But the directions he had given us about keeping a yellow warehouse on our starboard hand till we opened a white church to the larboard, and then keeping that on the larboard hand till we made a corner three points to the starboard, and that done, then ask the first man we met where the place was: these crooked directions of his very much puzzled us at first, especially as, at the outset, Queequeg insisted that the yellow warehouse --our first point of departure --must be left on the larboard hand, whereas I had understood Peter Coffin to say it was on the starboard. However, by dint of beating about a little in the dark, and now and then knocking up a peaceable inhabitant to inquire the way, we at last came to something which there was no mistaking. Two enormous wooden pots painted black, and suspended by asses' ears, swung from the cross-trees of an old top-mast, planted in front of an old doorway. The horns of the cross-trees were sawed off on the other side, so that this old top-mast looked not a little like a gallows. Perhaps I was over sensitive to such impressions at the time, but I could not help staring at this gallows with a vague misgiving. A sort of crick was in my neck as I gazed up to the two remaining horns; yes, two of them, one for Queequeg, and one for me. It's ominous, thinks I. A Coffin my Innkeeper upon landing in my first whaling port; tombstones staring at me in the whalemen's chapel; and here a gallows! and a pair of prodigious black pots too! Are these last throwing out oblique hints touching tophet? I was called from these reflections by the sight of a freckled woman with yellow hair and a yellow gown, standing in the porch of the inn, under a dull red lamp swinging there, that looked much like an injured eye, and carrying on a brisk scolding with a man in a purple woollen shirt. Get along with ye, said she to the man, or I'll be combing ye! Come on, Queequeg, said I, all right. There's Mrs. Hussey. ..

And so it turned out; Mr. Hosea Hussey being from home, but leaving Mrs. Hussey entirely competent to attend to all his affairs. Upon making known our desires for a supper and a bed, Mrs. Hussey, postponing further scolding for the present, ushered us into a little room, and seating us at a table spread with the relics of a recently concluded repast, turned round to us and said-- Clam or Cod? What's that about Cods, ma'am? said I, with much politeness. Clam or Cod? she repeated. A clam for supper? a cold clam; is that what you mean, Mrs. Hussey? says I; but that's a rather cold and clammy reception in the winter time, ain't it, Mrs Hussey? But being in a great hurry to resume scolding the man in the purple shirt, who was waiting for it in the entry, and seeming to hear nothing but the word clam, Mrs. Hussey hurried towards an open door leading to the kitchen, and bawling out clam for two, disappeared. Queequeg, said I, do you think that we can make out a supper for us both on one clam? However, a warm savory steam from the kitchen served to belie the apparently cheerless prospect before us. But when that smoking chowder came in, the mystery was delightfully explained. Oh, sweet friends! hearken to me. It was made of small juicy clams, scarcely bigger than hazel nuts, mixed with pounded ship biscuit, and salted pork cut up into little flakes; the whole enriched with butter, and plentifully seasoned with pepper and salt. Our appetites being sharpened by the frosty voyage, and in particular, Queequeg seeing his favorite fishing food before him, and the chowder being surpassingly excellent, we despatched it with great expedition: when leaning back a moment and bethinking me of Mrs. Hussey's clam and cod announcement, I thought I would try a little experiment. Stepping to the kitchen door, I uttered the word cod with great emphasis, and resumed my seat. In a few moments the savory steam came forth again, but with a different flavor, and in good time a fine cod-chowder was placed before us. We resumed business; and while plying our spoons in the ..

bowl, thinks I to myself, I wonder now if this here has any effect on the head? What's that stultifying saying about chowder-headed people? But look, Queequeg, ain't that a live eel in your bowl? Where's your harpoon? Fishiest of all fishy places was the Try Pots, which well deserved its name; for the pots there were always boiling chowders. Chowder for breakfast, and chowder for dinner, and chowder for supper, till you began to look for fish-bones coming through your clothes. The area before the house was paved with clam-shells. Mrs. Hussey wore a polished necklace of codfish vertebra; and Hosea Hussey had his account books bound in superior old shark-skin. There was a fishy flavor to the milk, too, which I could not at all account for, till one morning happening to take a stroll along the beach among some fishermen's boats, I saw Hosea's brindled cow feeding on fish remnants, and marching along the sand with each foot in a cod's decapitated head, looking very slip-shod, I assure ye. Supper concluded, we received a lamp, and directions from Mrs. Hussey concerning the nearest way to bed; but, as Queequeg was about to precede me up the stairs, the lady reached forth her arm, and demanded his harpoon; she allowed no harpoon in her chambers. Why not? said I; every true whaleman sleeps with his harpoon --but why not? Because it's dangerous, says she. Ever since young Stiggs coming from that unfort'nt v'y'ge of his, when he was gone four years and a half, with only three barrels of ile, was found dead in my first floor back, with his harpoon in his side; ever since then I allow no boarders to take sich dangerous weepons in their rooms at night. So, Mr. Queequeg (for she had learned his name), I will just take this here iron, and keep it for you till morning. But the chowder; clam or cod to-morrow for breakfast, men? Both, says I; and let's have a couple of smoked herring by way of variety. ..

.. < chapter xvi 2 THE SHIP > In bed we concocted our plans for the morrow. But to my surprise and no small concern, Queequeg now gave me to understand, that he had been diligently consulting Yojo --the name of his black little god --and Yojo had told him two or three times over, and strongly insisted upon it everyway, that instead of our going together among the whaling-fleet in harbor, and in concert selecting our craft; instead of this, I say, Yojo earnestly enjoined that the selection of the ship should rest wholly with me, inasmuch as Yojo purposed befriending us; and, in order to do so, had already pitched upon a vessel, which, if left to myself, I, Ishmael, should infallibly light upon, for all the world as though it had turned out by chance; and in that vessel I must immediately ship myself, for the present irrespective of Queequeg. I have forgotten to mention that, in many things, Queequeg placed great confidence in the excellence of Yojo's judgment and surprising forecast of things; and cherished Yojo with considerable esteem, as a rather good sort of god, who perhaps meant well enough upon the whole, but in all cases did not succeed in his benevolent designs. Now, this plan of Queequeg's, or rather Yojo's, touching the selection of our craft; I did not like that plan at all. I had not a little relied on Queequeg's sagacity to point out the whaler best fitted to carry us and our fortunes securely. But as all my remonstrances produced no effect upon Queequeg, I was obliged to acquiesce; and accordingly prepared to set about this business with a determined rushing sort of energy and vigor, that should quickly settle that trifling little affair. Next morning early, leaving Queequeg shut up with Yojo in our little bedroom --for it seemed that it was some sort of Lent or Ramadan, or day of fasting, humiliation, and prayer with Queequeg and Yojo that ..

day; how it was I never could find out, for, though I applied myself to it several times, I never could master his liturgies and XXXIX Articles --leaving Queequeg, then, fasting on his tomahawk pipe, and Yojo warming himself at his sacrificial fire of shavings, I sallied out among the shipping. After much prolonged sauntering and many random inquiries, I learnt that there were three ships up for three-years' voyages --The Devil-Dam the Tit-bit, and the pequod. devil- dam, i do not know the origin of; tit-bit is obvious; Pequod, you will no doubt remember, was the name of a celebrated tribe of Massachusetts Indians, now extinct as the ancient Medes. I peered and pryed about the Devil-Dam; from her, hopped over to the Tit-bit; and, finally, going on board the Pequod, looked around her for a moment, and then decided that this was the very ship for us. You may have seen many a quaint craft in your day, for aught I know; --squared-toed luggers; mountainous Japanese junks; butter-box galliots, and what not; but take my word for it, you never saw such a rare old craft as this same rare old Pequod. She was a ship of the old school, rather small if anything; with an old fashioned claw-footed look about her. Long seasoned and weather-stained in the typhoons and calms of all four oceans, her old hull's complexion was darkened like a French grenadier's, who has alike fought in Egypt and Siberia. Her venerable bows looked bearded. Her masts--cut somewhere on the coast of Japan, where her original ones were lost overboard in a gale --her masts stood stiffly up like the spines of the three old kings of Cologne. Her ancient decks were worn and wrinkled, like the pilgrim-worshipped flag-stone in Canterbury Cathedral where Beckett bled. But to all these her old antiquities, were added new and marvellous features, pertaining to the wild business that for more than half a century she had followed. Old Captain Peleg, many years her chief-mate, before he commanded another vessel of his own, and now a retired seaman, and one of the principal owners of the Pequod, --this old Peleg, during the term of his chief-mateship, had built upon her original grotesqueness, and inlaid it, all over, with a quaintness both of material and device, unmatched by anything except it be Thorkill-Hake's carved buckler or bedstead. She was ..

apparelled like any barbaric Ethiopian emperor, his neck heavy with pendants of polished ivory. She was a thing of trophies. A cannibal of a craft, tricking herself forth in the chased bones of her enemies. All round, her unpanelled, open bulwarks were garnished like one continuous jaw, with the long sharp teeth of the sperm whale, inserted there for pins, to fasten her old hempen thews and tendons to. Those thews ran not through base blocks of land wood, but deftly travelled over sheaves of sea-ivory. Scorning a turnstile wheel at her reverend helm, she sported there a tiller; and that tiller was in one mass, curiously carved from the long narrow lower jaw of her hereditary foe. The helmsman who steered by that tiller in a tempest, felt like the Tartar, when he holds back his fiery steed by clutching its jaw. A noble craft, but somehow a most melancholy! All noble things are touched with that. Now when I looked about the quarter-deck, for some one having authority, in order to propose myself as a candidate for the voyage, at first I saw nobody; but I could not well overlook a strange sort of tent, or rather wigwam, pitched a little behind the main-mast. It seemed only a temporary erection used in port. It was of a conical shape, some ten feet high; consisting of the long, huge slabs of limber black bone taken from the middle and highest part of the jaws of the right-whale. Planted with their broad ends on the deck, a circle of these slabs laced together, mutually sloped towards each other, and at the apex united in a tufted point, where the loose hairy fibres waved to and fro like a top-knot on some old Pottowotamie Sachem's head. A triangular opening faced towards the bows of the ship, so that the insider commanded a complete view forward. And half concealed in this queer tenement, I at length found one who by his aspect seemed to have authority; and who, it being noon, and the ship's work suspended, was now enjoying respite from the burden of command. He was seated on an old-fashioned oaken chair, wriggling all over with curious carving; and the bottom of which was formed of a stout interlacing of the same elastic stuff of which the wigwam was constructed. There was nothing so very particular, perhaps, about the ..

appearance of the elderly man I saw; he was brown and brawny, like most old seamen, and heavily rolled up in blue pilot-cloth, cut in the Quaker style; only there was a fine and almost microscopic net-work of the minutest wrinkles interlacing round his eyes, which must have arisen from his continual sailings in many hard gales, and always looking to windward; --for this causes the muscles about the eyes to become pursed together. Such eye-wrinkles are very effectual in a scowl. Is this the Captain of the Pequod? said I, advancing to the door of the tent. Supposing it be the Captain of the Pequod, what dost thou want of him? he demanded. I was thinking of shipping. Thou wast, wast thou? I see thou are no Nantucketer --ever been in a stove boat? No, Sir, I never have. Dost know nothing at all about whaling, I dare say --eh? Nothing, Sir; but I have no doubt I shall soon learn. I've been several voyages in the merchant service, and I think that-- Merchant service be damned. Talk not that lingo to me. Dost see that leg? --I'll take that leg away from thy stern, if ever thou talkest of the marchant service to me again. Marchant service indeed! I suppose now ye feel considerable proud of having served in those marchant ships. But flukes! man, what makes thee want to go a whaling, eh? --it looks a little suspicious, don't it, eh? --Hast not been a pirate, hast thou? --Didst not rob thy last Captain, didst thou? --Dost not think of murdering the officers when thou gettest to sea? I protested my innocence of these things. I saw that under the mask of these half humorous inuendoes, this old seaman, as an insulated Quakerish Nantucketer, was full of his insular prejudices, and rather distrustful of all aliens, unless they hailed from Cape Cod or the Vineyard. But what takes thee a-whaling? I want to know that before I think of shipping ye. Well, sir, I want to see what whaling is. I want to see the world. Want to see what whaling is, eh? Have ye clapped eye on Captain Ahab? ..

Who is Captain Ahab, sir? Aye, aye, I thought so. Captain Ahab is the Captain of this ship. I am mistaken then. I thought I was speaking to the Captain himself. Thou art speaking to Captain Peleg --that's who ye are speaking to, young man. It belongs to me and Captain Bildad to see the Pequod fitted out for the voyage, and supplied with all her needs, including crew. We are part owners and agents. But as I was going to say, if thou wantest to know what whaling is, as thou tellest ye do, I can put ye in a way of finding it out before ye bind yourself to it, past backing out. Clap eye on Captain Ahab, young man, and thou wilt find that he has only one leg. What do you mean, sir? Was the other one lost by a whale? Lost by a whale! Young man, come nearer to me: it was devoured, chewed up, crunched by the monstrousest parmacetty that ever chipped a boat! --ah, ah! I was a little alarmed by his energy, perhaps also a little touched at the hearty grief in his concluding exclamation, but said as calmly as I could, What you say is no doubt true enough, sir; but how could I know there was any peculiar ferocity in that particular whale, though indeed I might have inferred as much from the simple fact of the accident. Look ye now, young man, thy lungs are a sort of soft, d'ye see; thou dost not talk shark a bit. Sure, ye've been to sea before now; sure of that? Sir, said I, I thought I told you that I had been four voyages in the merchant-- Hard down out of that! Mind what I said about the marchant service --don't aggravate me --I won't have it. But let us understand each other. I have given thee a hint about what whaling is; do ye yet feel inclined for it? I do, sir. Very good. Now, art thou the man to pitch a harpoon down a live whale's throat, and then jump after it? Answer, quick! I am, sir, if it should be positively indispensable to do so; not to be got rid of, that is; which I don't take to be the fact. Good again. Now then, thou not only wantest to go a-whaling, to find out by experience what whaling is, but ye also want to ..

go in order to see the world? Was not that what ye said? I thought so. Well then, just step forward there, and take a peep over the weather-bow, and then back to me and tell me what ye see there. For a moment I stood a little puzzled by this curious request, not knowing exactly how to take it, whether humorously or in earnest. But concentrating all his crow's feet into one scowl, Captain Peleg started me on the errand. Going forward and glancing over the weather bow, I perceived that the ship swinging to her anchor with the flood-tide, was now obliquely pointing towards the open ocean. The prospect was unlimited, but exceedingly monotonous and forbidding; not the slightest variety that I could see. Well, what's the report? said Peleg when I came back; what did ye see? Not much, I replied -- nothing but water; considerable horizon though, and there's a squall coming up, I think. Well, what dost thou think then of seeing the world? Do ye wish to go round Cape Horn to see any more of it, eh? Can't ye see the world where you stand? I was a little staggered, but go a-whaling I must, and I would; and the Pequod was as good a ship as any --I thought the best -- and all this I now repeated to Peleg. Seeing me so determined, he expressed his willingness to ship me. And thou mayest as well sign the papers right off, he added -- come along with ye. And so saying, he led the way below deck into the cabin. seated on the transom was what seemed to me a most uncommon and surprising figure. It turned out to be Captain Bildad, who along with Captain Peleg was one of the largest owners of the vessel; the other shares, as is sometimes the case in these ports, being held by a crowd of old annuitants; widows, fatherless children, and chancery wards; each owning about the value of a timber head, or a foot of plank, or a nail or two in the ship. People in Nantucket invest their money in whaling vessels, the same way that you do yours in approved state stocks bringing in good interest. Now, Bildad, like Peleg, and indeed many other Nantucketers, ..

was a Quaker, the island having been originally settled by that sect; and to this day its inhabitants in general retain in an uncommon measure the peculiarities of the Quaker, only variously and anomalously modified by things altogether alien and heterogeneous. For some of these same Quakers are the most sanguinary of all sailors and whale-hunters. They are fighting Quakers; they are Quakers with a vengeance. So that there are instances among them of men, who, named with Scripture names --a singularly common fashion on the island --and in childhood naturally imbibing the stately dramatic thee and thou of the Quaker idiom; still, from the audacious, daring, and boundless adventure of their subsequent lives, strangely blend with these unoutgrown peculiarities, a thousand bold dashes of character, not unworthy a Scandinavian sea-king, or a poetical Pagan Roman. And when these things unite in a man of greatly superior natural force, with a globular brain and a ponderous heart; who has also by the stillness and seclusion of many long night-watches in the remotest waters, and beneath constellations never seen here at the north, been led to think untraditionally and independently; receiving all nature's sweet or savage impressions fresh from her own virgin voluntary and confiding breast, and thereby chiefly, but with some help from accidental advantages, to learn a bold and nervous lofty language --that man makes one in a whole nation's census --a mighty pageant creature, formed for noble tragedies. Nor will it at all detract from him, dramatically regarded, if either by birth or other circumstances, he have what seems a half wilful overruling morbidness at the bottom of his nature. For all men tragically great are made so through a certain morbidness. Be sure of this, O young ambition, all mortal greatness is but disease. But, as yet we have not to do with such an one, but with quite another; and still a man, who, if indeed peculiar, it only results again from another phase of the Quaker, modified by individual circumstances. Like Captain Peleg, Captain Bildad was a well-to-do, retired whaleman. But unlike Captain Peleg --who cared not a rush for what are called serious things, and indeed deemed those selfsame serious things the veriest of all trifles --Captain Bildad ..

had not only been originally educated according to the strictest sect of Nantucket Quakerism, but all his subsequent ocean life, and the sight of many unclad, lovely island creatures, round the Horn --all that had not moved this native born Quaker one single jot, had not so much as altered one angle of his vest. Still, for all this immutableness, was there some lack of common consistency about worthy Captain Bildad. Though refusing, from conscientious scruples, to bear arms against land invaders, yet himself had illimitably invaded the Atlantic and Pacific; and though a sworn foe to human bloodshed, yet had he in his straight-bodied coat, spilled tuns upon tuns of leviathan gore. How now in the contemplative evening of his days, the pious Bildad reconciled these things in the reminiscence, I do not know; but it did not seem to concern him much, and very probably he had long since come to the sage and sensible conclusion that a man's religion is one thing, and this practical world quite another. This world pays dividends. Rising from a little cabin-boy in short clothes of the drabbest drab, to a harpooneer in a broad shad-bellied waistcoat; from that becoming boat-header, chief-mate, and captain, and finally a ship-owner; Bildad, as I hinted before, had concluded his adventurous career by wholly retiring from active life at the goodly age of sixty, and dedicating his remaining days to the quiet receiving of his well-earned income. Now Bildad, I am sorry to say, had the reputation of being an incorrigible old hunks, and in his sea-going days, a bitter, hard task-master. They told me in Nantucket, though it certainly seems a curious story, that when he sailed the old Categut whaleman, his crew, upon arriving home, were mostly all carried ashore to the hospital, sore exhausted and worn out. For a pious man, especially for a Quaker, he was certainly rather hard-hearted to say the least. He never used to swear, though, at his men, they said; but somehow he got an inordinate quantity of cruel, unmitigated hard work out of them. When Bildad was a chief-mate, to have his drab-colored eye intently looking at you, made you feel completely nervous, till you could clutch something --a hammer or a marling-spike, and go to work like mad, at something or other, never mind what. Indolence and ..

idleness perished from before him. His own person was the exact embodiment of his utilitarian character. On his long, gaunt body, he carried no spare flesh, no superfluous beard, his chin having a soft, economical nap to it, like the worn nap of his broad-brimmed hat. Such, then, was the person that I saw seated on the transom when I followed Captain Peleg down into the cabin. The space between the decks was small; and there, bolt-upright, sat old Bildad, who always sat so, and never leaned, and this to save his coat tails. His broad-brim was placed beside him; his legs were stiffly crossed; his drab vesture was buttoned up to his chin; and spectacles on nose, he seemed absorbed in reading from a ponderous volume. Bildad, cried Captain Peleg, at it again, Bildad, eh? Ye have been studying those Scriptures, now, for the last thirty years, to my certain knowledge. How far ye got, Bildad? As if long habituated to such profane talk from his old shipmate, Bildad, without noticing his present irreverence, quietly looked up, and seeing me, glanced again inquiringly towards Peleg. He says he's our man, Bildad, said Peleg, he wants to ship. Dost thee? said Bildad, in a hollow tone, and turning round to me. I dost, said I unconsciously, he was so intense a Quaker. What do ye think of him, Bildad? said Peleg. He'll do, said Bildad, eyeing me, and then went on spelling away at his book in a mumbling tone quite audible. I thought him the queerest old Quaker I ever saw, especially as Peleg, his friend and old shipmate, seemed such a blusterer. But I said nothing, only looking round me sharply. Peleg now threw open a chest, and drawing forth the ship's articles, placed pen and ink before him, and seated himself at a little table. I began to think it was high time to settle with myself at what terms I would be willing to engage for the voyage. I was already aware that in the whaling business they paid no wages; but all hands, including the captain, received certain shares of the profits called lays, and that these lays were proportioned to the degree of importance pertaining to the respective duties of the ship's company. ..

I was also aware that being a green hand at whaling, my own lay would not be very large; but considering that I was used to the sea, could steer a ship, splice a rope, and all that, I made no doubt that from all I had heard I should be offered at least the 275th lay --that is, the 275th part of the clear nett proceeds of the voyage, whatever that might eventually amount to. And though the 275th lay was what they call a rather long lay, yet it was better than nothing; and if we had a lucky voyage, might pretty nearly pay for the clothing I would wear out on it, not to speak of my three years' beef and board, for which I would not have to pay one stiver. It might be thought that this was a poor way to accumulate a princely fortune --and so it was, a very poor way indeed. But I am one of those that never take on about princely fortunes, and am quite content if the world is ready to board and lodge me, while I am putting up at this grim sign of the Thunder Cloud. Upon the whole, I thought that the 275th lay would be about the fair thing, but would not have been surprised had I been offered the 200th, considering I was of a broad-shouldered make. But one thing, nevertheless, that made me a little distrustful about receiving a generous share of the profits was this: Ashore, I had heard something of both Captain Peleg and his unaccountable old crony Bildad; how that they being the principal proprietors of the Pequod, therefore the other and more inconsiderable and scattered owners, left nearly the whole management of the ship's affairs to these two. And I did not know but what the stingy old Bildad might have a mighty deal to say about shipping hands, especially as I now found him on board the Pequod, quite at home there in the cabin, and reading his Bible as if at his own fireside. Now while Peleg was vainly trying to mend a pen with his jack-knife, old Bildad, to my no small surprise, considering that he was such an interested party in these proceedings; Bildad never heeded us, but went on mumbling to himself out of his book, Lay not up for yourselves treasures upon earth, where moth-- Well, Captain Bildad, interrupted Peleg, what d'ye say, what lay shall we give this young man? ..

Thou knowest best, was the sepulchral reply, the seven hundred and seventy-seventh wouldn't be too much, would it? -- "where moth and rust do corrupt, but lay--" Lay, indeed, thought I, and such a lay! the seven hundred and seventy-seventh! Well, old Bildad, you are determined that I, for one, shall not lay up many lays here below, where moth and rust do corrupt. It was an exceedingly long lay that, indeed; and though from the magnitude of the figure it might at first deceive a landsman, yet the slightest consideration will show that though seven hundred and seventy-seven is a pretty large number, yet, when you come to make a teenth of it, you will then see, I say, that the seven hundred and seventy-seventh part of a farthing is a good deal less than seven hundred and seventy-seven gold doubloons; and so I thought at the time. Why, blast your eyes, Bildad, cried Peleg, Thou dost not want to swindle this young man! he must have more than that. Seven hundred and seventy-seventh, again said Bildad, without lifting his eyes; and then went on mumbling -- for where your treasure is, there will your heart be also. I am going to put him down for the three hundredth, said Peleg, do ye hear that, Bildad! The three hundredth lay, I say. Bildad laid down his book, and turning solemnly towards him said, Captain Peleg, thou hast a generous heart; but thou must consider the duty thou owest to the other owners of this ship-- widows and orphans, many of them --and that if we too abundantly reward the labors of this young man, we may be taking the bread from those widows and those orphans. The seven hundred and seventy-seventh lay, Captain Peleg. Thou Bildad! roared Peleg, starting up and clattering about the cabin. Blast ye, Captain Bildad, if I had followed thy advice in these matters, I would afore now had a conscience to lug about that would be heavy enough to founder the largest ship that ever sailed round Cape Horn. Captain Peleg, said Bildad steadily, thy conscience may be drawing ten inches of water, or ten fathoms, i can't tell; but as thou art still an impenitent man, captain Peleg, I greatly fear lest thy conscience be but a leaky one; and will in the end sink thee foundering down to the fiery pit, Captain Peleg. ..

Fiery pit! fiery pit! ye insult me, man; past all natural bearing, ye insult me. It's an all-fired outrage to tell any human creature that he's bound to hell. Flukes and flames! Bildad, say that again to me, and start my soul-bolts, but I'll--I'll--yes, I'll swallow a live goat with all his hair and horns on. Out of the cabin, ye canting, drab-colored son of a wooden gun --a straight wake with ye! As he thundered out this he made a rush at Bildad, but with a marvellous oblique, sliding celerity, Bildad for that time eluded him. Alarmed at this terrible outburst between the two principal and responsible owners of the ship, and feeling half a mind to give up all idea of sailing in a vessel so questionably owned and temporarily commanded, I stepped aside from the door to give egress to Bildad, who, I made no doubt, was all eagerness to vanish from before the awakened wrath of Peleg. But to my astonishment, he sat down again on the transom very quietly, and seemed to have not the slightest intention of withdrawing. He seemed quite used to impenitent Peleg and his ways. As for Peleg, after letting off his rage as he had, there seemed no more left in him, and he, too, sat down like a lamb, though he twitched a little as if still nervously agitated. Whew! he whistled at last -- the squall's gone off to leeward, I think. Bildad, thou used to be good at sharpening a lance, mend that pen, will ye. My jack-knife here needs the grindstone. That's he; thank ye, Bildad. Now then, my young man, Ishmael's thy name, didn't ye say? Well then, down ye go here, Ishmael, for the three hundredth lay. Captain Peleg, said I, I have a friend with me who wants to ship too --shall I bring him down to-morrow? To be sure, said peleg. fetch him along, and we'll look at him. What lay does he want? groaned Bildad, glancing up from the book in which he had again been burying himself. Oh! never thee mind about that, Bildad, said Peleg. Has he ever whaled it any? turning to me. Killed more whales than I can count, Captain Peleg. Well, bring him along then. ..

And, after signing the papers, off I went; nothing doubting but that I had done a good morning's work, and that the Pequod was the identical ship that Yojo had provided to carry Queequeg and me round the Cape. But I had not proceeded far, when I began to bethink me that the captain with whom I was to sail yet remained unseen by me; though, indeed, in many cases, a whale-ship will be completely fitted out, and receive all her crew on board, ere the captain makes himself visible by arriving to take command; for sometimes these voyages are so prolonged, and the shore intervals at home so exceedingly brief, that if the captain have a family, or any absorbing concernment of that sort, he does not trouble himself much about his ship in port, but leaves her to the owners till all is ready for sea. However, it is always as well to have a look at him before irrevocably committing yourself into his hands. Turning back I accosted Captain Peleg, inquiring where Captain Ahab was to be found. And what dost thou want of Captain Ahab? It's all right enough; thou art shipped. Yes, but I should like to see him. But I don't think thou wilt be able to at present. I don't know exactly what's the matter with him; but he keeps close inside the house; a sort of sick, and yet he don't look so. In fact, he ain't sick; but no, he isn't well either. Any how, young man, he won't always see me, so I don't suppose he will thee. He's a queer man, Captain Ahab --so some think --but a good one. Oh, thou'lt like him well enough; no fear, no fear. he's a grand, ungodly, god-like man, Captain Ahab; doesn't speak much; but, when he does speak, then you may well listen. Mark ye, be forewarned; Ahab's above the common; Ahab's been in colleges, as well as 'mong the cannibals; been used to deeper wonders than the waves; fixed his fiery lance in mightier stranger foes than whales. His lance! aye, the keenest and the surest that out of all our isle! Oh! he ain't Captain Bildad; no, and he ain't Captain Peleg; he's Ahab, boy; and Ahab of old, thou knowest, was a crowned king! And a very vile one. When that wicked king was slain, the dogs, did they not lick his blood? ..

Come hither to me --hither, hither, said Peleg, with a significance in his eye that almost startled me. Look ye, lad; never say that on board the Pequod. Never say it anywhere. Captain Ahab did not name himself. 'Twas a foolish, ignorant whim of his crazy, widowed mother, who died when he was only a twelvemonth old. And yet the old squaw Tistig, at Gayhead, said that the name would somehow prove prophetic. And, perhaps, other fools like her may tell thee the same. I wish to warn thee. It's a lie. I know Captain Ahab well; I've sailed with him as mate years ago; I know what he is--a good man --not a pious, good man, like Bildad, but a swearing good man --something like me --only there's a good deal more of him. Aye, aye, I know that he was never very jolly; and I know that on the passage home, he was a little out of his mind for a spell; but it was the sharp shooting pains in his bleeding stump that brought that about, as any one might see. I know, too, that ever since he lost his leg last voyage by that accursed whale, he's been a kind of moody --desperate moody, and savage sometimes; but that will all pass off. And once for all, let me tell thee and assure thee, young man, it's better to sail with a moody good captain than a laughing bad one. So good-bye to thee --and wrong not Captain Ahab, because he happens to have a wicked name. Besides, my boy, he has a wife --not three voyages wedded --a sweet, resigned girl. Think of that; by that sweet girl that old man has a child: hold ye then there can be any utter, hopeless harm in Ahab? No, no, my lad; stricken, blasted, if he be, Ahab has his humanities! As I walked away, I was full of thoughtfulness; what had been incidentally revealed to me of Captain Ahab, filled me with a certain wild vagueness of painfulness concerning him. And somehow, at the time, I felt a sympathy and a sorrow for him, but for I don't know what, unless it was the cruel loss of his leg. And yet I also felt a strange awe of him; but that sort of awe, which I cannot at all describe, was not exactly awe; I do not know what it was. But I felt it; and it did not disincline me towards him; though I felt impatience at what seemed like mystery in him, so imperfectly as he was known to me then. However, my thoughts were at length carried in other directions, so that for the present dark Ahab slipped my mind. ..

.. < chapter xvii 2 THE RAMADAN > As Queequeg's Ramadan, or Fasting and Humiliation, was to continue all day, I did not choose to disturb him till towards night-fall; for I cherish the greatest respect towards everybody's religious obligations, never mind how comical, and could not find it in my heart to undervalue even a congregation of ants worshipping a toad-stool; or those other creatures in certain parts of our earth, who with a degree of footmanism quite unprecedented in other planets, bow down before the torso of a deceased landed proprietor merely on account of the inordinate possessions yet owned and rented in his name. I say, we good Presbyterian christians should be charitable in these things, and not fancy ourselves so vastly superior to other mortals, pagans and what not, because of their half-crazy conceits on these subjects. There was Queequeg, now, certainly entertaining the most absurd notions about Yojo and his Ramadan; --but what of that? Queequeg thought he knew what he was about, I suppose; he seemed to be content; and there let him rest. All our arguing with him would not avail; let him be, I say: and Heaven have mercy on us all --Presbyterians and Pagans alike --for we are all somehow dreadfully cracked about the head, and sadly need mending. Towards evening, when I felt assured that all his performances and rituals must be over, I went up to his room and knocked at the door; but no answer. I tried to open it, but it was fastened inside. Queequeg, said I softly through the key-hole: --all silent. I say, Queequeg! why don't you speak? It's I--Ishmael. But all remained still as before. I began to grow alarmed. I had allowed him such abundant time; I thought he might have had an apoplectic fit. I looked through the key-hole; but the door opening into an odd corner of the room, the key-hole prospect was but a crooked and sinister one. I could only see part of the foot-board of the bed and a line of ..

the wall, but nothing more. I was surprised to behold resting against the wall the wooden shaft of Queequeg's harpoon, which the landlady the evening previous had taken from him, before our mounting to the chamber. That's strange, thought I; but at any rate, since the harpoon stands yonder, and he seldom or never goes abroad without it, therefore he must be inside here, and no possible mistake. Queequeg! --Queequeg! --all still. Something must have happened. Apoplexy! I tried to burst open the door; but it stubbornly resisted. Running down stairs, I quickly stated my suspicions to the first person i met --the chambermaid. la! la! she cried, i thought something must be the matter. I went to make the bed after breakfast, and the door was locked; and not a mouse to be heard; and it's been just so silent ever since. But I thought, may be, you had both gone off and locked your baggage in for safe keeping. La! La, ma'am! --Mistress! murder! Mrs. Hussey! apoplexy! --and with these cries, she ran towards the kitchen, I following. Mrs. Hussey soon appeared, with a mustard-pot in one hand and a vinegar-cruet in the other, having just broken away from the occupation of attending to the castors, and scolding her little black boy meantime. Wood-house! cried I, which way to it? Run for God's sake, and fetch something to pry open the door --the axe! --the axe! he's had a stroke; depend upon it! --and so saying I was unmethodically rushing up stairs again empty-handed, when Mrs. Hussey interposed the mustard-pot and vinegar-cruet, and the entire castor of her countenance. What's the matter with you, young man? Get the axe! For God's sake, run for the doctor, some one, while I pry it open! Look here, said the landlady, quickly putting down the vinegar-cruet, so as to have one hand free; look here; are you talking about prying open any of my doors? --and with that she seized my arm. What's the matter with you? What's the matter with you, shipmate? In as calm, but rapid a manner as possible, I gave her to understand the whole case. Unconsciously clapping the vinegar-cruet ..

to one side of her nose, she ruminated for an instant; then exclaimed -- No! I haven't seen it since I put it there. Running to a little closet under the landing of the stairs, she glanced in, and returning, told me that Queequeg's harpoon was missing. He's killed himself, she cried. It's unfort'nate stiggs done over again --there goes another counterpane --god pity his poor mother! --it will be the ruin of my house. Has the poor lad a sister? Where's that girl? --there, Betty, go to Snarles the Painter, and tell him to paint me a sign, with --"no suicides permitted here, and no smoking in the parlor;" --might as well kill both birds at once. Kill? The Lord be merciful to his ghost! What's that noise there? You, young man, avast there! And running up after me, she caught me as I was again trying to force open the door. I won't allow it; I won't have my premises spoiled. Go for the locksmith, there's one about a mile from here. But avast! putting her hand in her side-pocket, here's a key that'll fit, I guess; let's see. And with that, she turned it in the lock; but, alas! Queequeg's supplemental bolt remained unwithdrawn within. Have to burst it open, said I, and was running down the entry a little, for a good start, when the landlady caught at me, again vowing I should not break down her premises; but I tore from her, and with a sudden bodily rush dashed myself full against the mark. With a prodigious noise the door flew open, and the knob slamming against the wall, sent the plaster to the ceiling; and there, good heavens! there sat Queequeg, altogether cool and self-collected; right in the middle of the room; squatting on his hams, and holding Yojo on top of his head. He looked neither one way nor the other way, but sat like a carved image with scarce a sign of active life. Queequeg, said I, going up to him, Queequeg, what's the matter with you? He hain't been a sittin' so all day, has he? said the landlady. But all we said, not a word could we drag out of him; I almost felt like pushing him over, so as to change his position, for it was almost intolerable, it seemed so painfully and unnaturally ..

constrained; especially, as in all probability he had been sitting so for upwards of eight or ten hours, going too without his regular meals. Mrs. Hussey, said I, he's alive at all events; so leave us, if you please, and I will see to this strange affair myself. Closing the door upon the landlady, I endeavored to prevail upon Queequeg to take a chair; but in vain. There he sat; and all he could do --for all my polite arts and blandishments --he would not move a peg, nor say a single word, nor even look at me, nor notice my presence in any the slightest way. I wonder, thought I, if this can possibly be a part of his Ramadan; do they fast on their hams that way in his native island. It must be so; yes, it's part of his creed, I suppose; well, then, let him rest; he'll get up sooner or later, no doubt. It can't last for ever, thank God, and his Ramadan only comes once a year; and I don't believe it's very punctual then. I went down to supper. After sitting a long time listening to the long stories of some sailors who had just come from a plum-pudding voyage, as they called it (that is, a short whaling-voyage in a schooner or brig, confined to the north of the line, in the Atlantic Ocean only); after listening to these plum-puddingers till nearly eleven o'clock, I went up stairs to go to bed, feeling quite sure by this time Queequeg must certainly have brought his Ramadan to a termination. But no; there he was just where I had left him; he had not stirred an inch. I began to grow vexed with him; it seemed so downright senseless and insane to be sitting there all day and half the night on his hams in a cold room, holding a piece of wood on his head. For heaven's sake, Queequeg, get up and shake yourself; get up and have some supper. You'll starve; you'll kill yourself, Queequeg. But not a word did he reply. Despairing of him, therefore, I determined to go to bed and to sleep; and no doubt, before a great while, he would follow me. But previous to turning in, I took my heavy bearskin jacket, and threw it over him, as it promised to be a very cold night; and he had nothing but his ordinary round jacket on. For some time, do all I would, I could not get into the faintest doze. I had blown out the candle; and the mere thought of Queequeg-- ..

not four feet off --sitting there in that uneasy position, stark alone in the cold and dark; this made me really wretched. Think of it; sleeping all night in the same room with a wide awake pagan on his hams in this dreary, unaccountable Ramadan! But somehow I dropped off at last, and knew nothing more till break of day; when, looking over the bedside, there squatted Queequeg, as if he had been screwed down to the floor. But as soon as the first glimpse of sun entered the window, up he got, with stiff and grating joints, but with a cheerful look; limped towards me where I lay; pressed his forehead again against mine; and said his Ramadan was over. Now, as I before hinted, I have no objection to any person's religion, be it what it may, so long as that person does not kill or insult any other person, because that other person don't believe it also. But when a man's religion becomes really frantic; when it is a positive torment to him; and, in fine, makes this earth of ours an uncomfortable inn to lodge in; then I think it high time to take that individual aside and argue the point with him. And just so I now did with Queequeg. Queequeg, said I, get into bed now, and lie and listen to me. I then went on, beginning with the rise and progress of the primitive religions, and coming down to the various religions of the present time, during which time I labored to show Queequeg that all these Lents, Ramadans, and prolonged ham-squattings in cold, cheerless rooms were stark nonsense; bad for the health; useless for the soul; opposed, in short, to the obvious laws of Hygiene and common sense. I told him, too, that he being in other things such an extremely sensible and sagacious savage, it pained me, very badly pained me, to see him now so deplorably foolish about this ridiculous Ramadan of his. Besides, argued I, fasting makes the body cave in; hence the spirit caves in; and all thoughts born of a fast must necessarily be half-starved. This is the reason why most dyspeptic religionists cherish such melancholy notions about their hereafters. In one word, Queequeg, said I, rather digressively; hell is an idea first born on an undigested apple-dumpling; and since then perpetuated through the hereditary dyspepsias nurtured by Ramadans. ..

I then asked Queequeg whether he himself was ever troubled with dyspepsia; expressing the idea very plainly, so that he could take it in. He said no; only upon one memorable occasion. It was after a great feast given by his father the king, on the gaining of a great battle wherein fifty of the enemy had been killed by about two o'clock in the afternoon, and all cooked and eaten that very evening. No more, Queequeg, said I, shuddering; that will do; for I knew the inferences without his further hinting them. I had seen a sailor who had visited that very island, and he told me that it was the custom, when a great battle had been gained there, to barbecue all the slain in the yard or garden of the victor; and then, one by one, they were placed in great wooden trenchers, and garnished round like a pilau, with breadfruit and cocoanuts; and with some parsley in their mouths, were sent round with the victor's compliments to all his friends, just as though these presents were so many Christmas turkeys. After all, I do not think that my remarks about religion made much impression upon Queequeg. Because, in the first place, he somehow seemed dull of hearing on that important subject, unless considered from his own point of view; and, in the second place, he did not more than one third understand me, couch my ideas simply as I would; and, finally, he no doubt thought he knew a good deal more about the true religion than I did. He looked at me with a sort of condescending concern and compassion, as though he thought it a great pity that such a sensible young man should be so hopelessly lost to evangelical pagan piety. At last we rose and dressed; and Queequeg, taking a prodigiously hearty breakfast of chowders of all sorts, so that the landlady should not make much profit by reason of his Ramadan, we sallied out to board the Pequod, sauntering along, and picking our teeth with halibut bones. ..

.. < chapter xviii 2 HIS MARK > As we were walking down the end of the wharf towards the ship, Queequeg carrying his harpoon, Captain Peleg in his gruff voice loudly hailed us from his wigwam, saying he had not suspected my friend was a cannibal, and furthermore announcing that he let no cannibals on board that craft, unless they previously produced their papers. What do you mean by that, Captain Peleg? said I, now jumping on the bulwarks, and leaving my comrade standing on the wharf. I mean, he replied, he must show his papers. Yea, said Captain Bildad in his hollow voice, sticking his head from behind Peleg's, out of the wigwam. He must show that he's converted. Son of darkness, he added, turning to Queequeg, art thou at present in communion with any christian church? Why, said I, he's a member of the first Congregational Church. Here be it said, that many tattooed savages sailing in Nantucket ships at last come to be converted into the churches. First Congregational Church, cried Bildad, what! that worships in Deacon Deuteronomy Coleman's meeting-house? and so saying, taking out his spectacles, he rubbed them with his great yellow bandana handkerchief, and putting them on very carefully, came out of the wigwam, and leaning stiffly over the bulwarks, took a good long look at Queequeg. How long hath he been a member? he then said, turning to me; not very long, I rather guess, young man. No, said Peleg, and he hasn't been baptized right either, or it would have washed some of that devil's blue off his face. Do tell, now, cried Bildad, is this Philistine a regular member of Deacon Deuteronomy's meeting? I never saw him going there, and I pass it every Lord's day. ..

I don't know anything about Deacon Deuteronomy or his meeeting, said I, all I know is, that Queequeg here is a born member of the First Congregational Church. He is a deacon himself, Queequeg is. Young man, said Bildad sternly, thou art skylarking with me --explain thyself, thou young Hittite. What church dost thee mean? answer me. Finding myself thus hard pushed, I replied. I mean, sir, the same ancient Catholic Church to which you and I, and Captain Peleg there, and Queequeg here, and all of us, and every mother's son and soul of us belong; the great and everlasting First Congregation of this whole worshipping world; we all belong to that; only some of us cherish some queer crotchets noways touching the grand belief; in that we all join hands. Splice, thou mean'st splice hands, cried Peleg, drawing nearer. Young man, you'd better ship for a missionary, instead of a fore-mast hand; I never heard a better sermon. Deacon Deuteronomy --why Father Mapple himself couldn't beat it, and he's reckoned something. Come aboard, come aboard; never mind about the papers. I say, tell Quohog there --what's that you call him? tell Quohog to step along. By the great anchor, what a harpoon he's got there! looks like good stuff that; and he handles it about right. I say, Quohog, or whatever your name is, did you ever stand in the head of a whale-boat? did you ever strike a fish? Without saying a word, Queequeg, in his wild sort of way, jumped upon the bulwarks, from thence into the bows of one of the whale-boats hanging to the side; and then bracing his left knee, and poising his harpoon, cried out in some such way as this: -- Cap'ain, you see him small drop tar on water dere? You see him? well, spose him one whale eye, well, den! and taking sharp aim at it, he darted the iron right over old Bildad's broad brim, clean across the ship's decks, and struck the glistening tar spot out of sight. Now, said Queequeg, quietly hauling in the line, spos-ee him whale-e eye; why, dad whale dead. Quick, Bildad, said Peleg, his partner, who, aghast at the ..

close vicinity of the flying harpoon, had retreated towards the cabin gangway. Quick, I say, you Bildad, and get the ship's papers. We must have Hedgehog there, I mean Quohog, in one of our boats. Look ye, Quohog, we'll give ye the ninetieth lay, and that's more than ever was given a harpooneer yet out of Nantucket. So down we went into the cabin, and to my great joy Queequeg was soon enrolled among the same ship's company to which I myself belonged. When all preliminaries were over and Peleg had got everything ready for signing, he turned to me and said, I guess Quohog there don't know how to write, does he? I say, Quohog, blast ye! dost thou sign thy name or make thy mark? But at this question, Queequeg, who had twice or thrice before taken part in similar ceremonies, looked no ways abashed; but taking the offered pen, copied upon the paper, in the proper place, an exact counterpart of a queer round figure which was tattooed upon his arm; so that through Captain Peleg's obstinate mistake touching his appellative, it stood something like this: -- Quohog his mark. Meanwhile Captain Bildad sat earnestly and steadfastly eyeing Queequeg, and at last rising solemnly and fumbling in the huge pockets of his broad-skirted drab coat, took out a bundle of tracts, and selecting one entitled The Latter Day Coming; or No Time to Lose, placed it in queequeg's hands, and then grasping them and the book with both his, looked earnestly into his eyes, and said, Son of darkness, I must do my duty by thee; I am part owner of this ship, and feel concerned for the souls of all its crew; if thou still clingest to thy Pagan ways, which I sadly fear, I beseech thee, remain not for aye a Belial bondsman. Spurn the idol Bell, and the hideous dragon; turn from the wrath to come; mind thine eye, I say; oh! goodness gracious! steer clear of the fiery pit! Something of the salt sea yet lingered in old Bildad's language, heterogeneously mixed with Scriptural and domestic phrases. Avast there, avast there, Bildad, avast now spoiling our harpooneer, ..

cried Peleg. Pious harpooneers never make good voyagers --it takes the shark out of 'em; no harpooneer is worth a straw who aint pretty sharkish. There was young Nat Swaine, once the bravest boat-header out of all Nantucket and the Vineyard; he joined the meeting, and never came to good. He got so frightened about his plaguy soul, that he shrinked and sheered away from whales, for fear of after-claps in case he got stove and went to Davy Jones. Peleg! Peleg! said Bildad, lifting his eyes and hands, thou thyself, as I myself, hast seen many a perilous time; thou knowest, Peleg, what it is to have the fear of death; how, then, can'st thou prate in this ungodly guise. Thou beliest thine own heart, Peleg. Tell me, when this same Pequod here had her three masts overboard in that typhoon on Japan, that same voyage when thou went mate with Captain Ahab, did'st thou not think of Death and the Judgment then? Hear him, hear him now, cried Peleg, marching across the cabin, and thrusting his hands far down into his pockets, -- hear him, all of ye. Think of that! When every moment we thought the ship would sink! Death and the judgment then? What? With all three masts making such an everlasting thundering against the side; and every sea breaking over us, fore and aft. Think of Death and the Judgment then? No! no time to think about Death then. Life was what Captain Ahab and I was thinking of; and how to save all hands --how to rig jury-masts -- how to get into the nearest port; that was what I was thinking of. Bildad said no more, but buttoning up his coat, stalked on deck, where we followed him. There he stood, very quietly overlooking some sail-makers who were mending a top-sail in the waist. Now and then he stooped to pick up a patch, or save an end of tarred twine, which otherwise might have been wasted. ..

.. < chapter xix 2 THE PROPHET > Shipmates, have ye shipped in that ship? Queequeg and I had just left the Pequod, and were sauntering away from the water, for the moment each occupied with his own thoughts, when the above words were put to us by a stranger, who, pausing before us, levelled his massive forefinger at the vessel in question. He was but shabbily apparelled in faded jacket and patched trowsers; a rag of a black handkerchief investing his neck. A confluent small-pox had in all directions flowed over his face, and left it like the complicated ribbed bed of a torrent, when the rushing waters have been dried up. Have ye shipped in her? he repeated. You mean the ship Pequod, I suppose, said I, trying to gain a little more time for an uninterrupted look at him. Aye, the Pequod --that ship there, he said, drawing back his whole arm, and then rapidly shoving it straight out from him, with the fixed bayonet of his pointed finger darted full at the object. Yes, said I, we have just signed the articles. Anything down there about your souls? About what? Oh, perhaps you hav'n't got any, he said quickly. no matter though, i know many chaps that hav'n't got any, --good luck to 'em; and they are all the better off for it. A soul's a sort of a fifth wheel to a wagon. What are you jabbering about, shipmate? said I. He's got enough, though, to make up for all deficiencies of that sort in other chaps, abruptly said the stranger, placing a nervous emphasis upon the word he. Queequeg, said I, let's go; this fellow has broken loose from somewhere; he's talking about something and somebody we don't know. ..

Stop! cried the stranger. Ye said true --ye hav'n't seen Old Thunder yet, have ye? Who's Old Thunder? said I, again riveted with the insane earnestness of his manner. Captain Ahab. What! the captain of our ship, the Pequod? Aye, among some of us old sailor chaps, he goes by that name. Ye hav'n't seen him yet, have ye? No, we hav'n't. He's sick they say, but is getting better, and will be all right again before long. All right again before long! laughed the stranger, with a solemnly derisive sort of laugh. Look ye; when captain Ahab is all right, then this left arm of mine will be all right; not before. What do you know about him? What did they tell you about him? Say that! They didn't tell much of anything about him; only I've heard that he's a good whale-hunter, and a good captain to his crew. That's true, that's true --yes, both true enough. But you must jump when he gives an order. Step and growl; growl and go --that's the word with Captain Ahab. But nothing about that thing that happened to him off Cape Horn, long ago, when he lay like dead for three days and nights; nothing about that deadly skrimmage with the Spaniard afore the altar in Santa? -- heard nothing about that, eh? Nothing about the silver calabash he spat into? And nothing about his losing his leg last voyage, according to the prophecy. Didn't ye hear a word about them matters and something more, eh? No, I don't think ye did; how could ye? Who knows it? Not all Nantucket, I guess. But hows'ever, mayhap, ye've heard tell about the leg, and how he lost it; aye, ye have heard of that, I dare say. Oh yes, that every one knows a'most --I mean they know he's only one leg; and that a parmacetti took the other off. My friend, said I, what all this gibberish of yours is about, I don't know, and I don't much care; for it seems to me that you must be a little damaged in the head. But if you are speaking of Captain Ahab, of that ship there, the Pequod, then let me tell you, that I know all about the loss of his leg. ..

All about it, eh --sure you do? --all? Pretty sure. With finger pointed and eye levelled at the Pequod, the beggar-like stranger stood a moment, as if in a troubled reverie; then starting a little, turned and said: -- Ye've shipped, have ye? Names down on the papers? Well, well, what's signed, is signed; and what's to be, will be; and then again, perhaps it wont be, after all. Any how, it's all fixed and arranged a'ready; and some sailors or other must go with him, I suppose; as well these as any other men, God pity 'em! Morning to ye, shipmates, morning; the ineffable heavens bless ye; I'm sorry I stopped ye. Look here, friend, said I, if you have anything important to tell us, out with it; but if you are only trying to bamboozle us, you are mistaken in your game; that's all I have to say. And it's said very well, and I like to hear a chap talk up that way; you are just the man for him --the likes of ye. Morning to ye, shipmates, morning! Oh, when ye get there, tell 'em I've concluded not to make one of 'em. Ah, my dear fellow, you can't fool us that way --you can't fool us. It is the easiest thing in the world for a man to look as if he had a great secret in him. Morning to ye, shipmates, morning. Morning it is, said I. Come along, Queequeg, let's leave this crazy man. But stop, tell me your name, will you? Elijah. Elijah! thought I, and we walked away, both commenting, after each other's fashion, upon this ragged old sailor; and agreed that he was nothing but a humbug, trying to be a bugbear. But we had not gone perhaps above a hundred yards, when chancing to turn a corner, and looking back as I did so, who should be seen but Elijah following us, though at a distance. Somehow, the sight of him struck me so, that I said nothing to Queequeg of his being behind, but passed on with my comrade, anxious to see whether the stranger would turn the same corner that we did. He did; and then it seemed to me that he was dogging us, but with what intent I could not for the life of me imagine. This circumstance, coupled with his ambiguous, half-hinting, half-revealing, shrouded sort of talk, now begat in me ..

all kinds of vague wonderments and half-apprehensions, and all connected with the Pequod; and Captain Ahab; and the leg he had lost; and the Cape Horn fit; and the silver calabash; and what Captain Peleg had said of him, when I left the ship the day previous; and the prediction of the squaw Tistig; and the voyage we had bound ourselves to sail; and a hundred other shadowy things. I was resolved to satisfy myself whether this ragged Elijah was really dogging us or not, and with that intent crossed the way with Queequeg, and on that side of it retraced our steps. But Elijah passed on, without seeming to notice us. This relieved me; and once more, and finally as it seemed to me, I pronounced him in my heart, a humbug. ..

.. < chapter xx 15 ALL ASTIR > A day or two passed, and there was great activity aboard the pequod. not only were the old sails being mended, but new sails were coming on board, and bolts of canvas, and coils of rigging; in short, everything betokened that the ship's preparations were hurrying to a close. Captain Peleg seldom or never went ashore, but sat in his wigwam keeping a sharp look-out upon the hands: Bildad did all the purchasing and providing at the stores; and the men employed in the hold and on the rigging were working till long after night-fall. On the day following Queequeg's signing the articles, word was given at all the inns where the ship's company were stopping, that their chests must be on board before night, for there was no telling how soon the vessel might be sailing. So Queequeg and I got down our traps, resolving, however, to sleep ashore till the last. But it seems they always give very long notice in these cases, and the ship did not sail for several days. But no wonder; there was a good deal to be done, and there ..

is no telling how many things to be thought of, before the Pequod was fully equipped. Every one knows what a multitude of things --beds, sauce-pans, knives and forks, shovels and tongs, napkins, nut-crackers, and what not, are indispensable to the business of housekeeping. Just so with whaling, which necessitates a three-years' housekeeping upon the wide ocean, far from all grocers, costermongers, doctors, bakers, and bankers. And though this also holds true of merchant vessels, yet not by any means to the same extent as with whalemen. For besides the great length of the whaling voyage, the numerous articles peculiar to the prosecution of the fishery, and the impossibility of replacing them at the remote harbors usually frequented, it must be remembered, that of all ships, whaling vessels are the most exposed to accidents of all kinds, and especially to the destruction and loss of the very things upon which the success of the voyage most depends. Hence, the spare boats, spare spars, and spare lines and harpoons, and spare everythings, almost, but a spare captain and duplicate ship. At the period of our arrival at the Island, the heaviest storage of the Pequod had been almost completed; comprising her beef, bread, water, fuel, and iron hoops and staves. But, as before hinted, for some time there was a continual fetching and carrying on board of divers odds and ends of things, both large and small. Chief among those who did this fetching and carrying was Captain Bildad's sister, a lean old lady of a most determined and indefatigable spirit, but withal very kindhearted, who seemed resolved that, if she could help it, nothing should be found wanting in the Pequod, after once fairly getting to sea. At one time she would come on board with a jar of pickles for the steward's pantry; another time with a bunch of quills for the chief mate's desk, where he kept his log; a third time with a roll of flannel for the small of some one's rheumatic back. Never did any woman better deserve her name, which was Charity --Aunt Charity, as everybody called her. And like a sister of charity did this charitable Aunt Charity bustle about hither and thither, ready to turn her hand and heart to anything that promised to yield safety, comfort, and consolation to all on board ..

a ship in which her beloved brother Bildad was concerned, and in which she herself owned a score or two of well-saved dollars. But it was startling to see this excellent hearted Quakeress coming on board, as she did the last day, with a long oil-ladle in one hand, and a still longer whaling lance in the other. Nor was Bildad himself nor Captain Peleg at all backward. As for Bildad, he carried about with him a long list of the articles needed, and at every fresh arrival, down went his mark opposite that article upon the paper. Every once and a while Peleg came hobbling out of his whalebone den, roaring at the men down the hatchways, roaring up to the riggers at the mast-head, and then concluded by roaring back into his wigwam. During these days of preparation, Queequeg and I often visited the craft, and as often I asked about Captain Ahab, and how he was, and when he was going to come on board his ship. To these questions they would answer, that he was getting better and better, and was expected aboard every day; meantime, the two Captains, Peleg and Bildad, could attend to everything necessary to fit the vessel for the voyage. If I had been downright honest with myself, I would have seen very plainly in my heart that I did but half fancy being committed this way to so long a voyage, without once laying my eyes on the man who was to be the absolute dictator of it, so soon as the ship sailed out upon the open sea. But when a man suspects any wrong, it sometimes happens that if he be already involved in the matter, he insensibly strives to cover up his suspicions even from himself. And much this way it was with me. I said nothing, and tried to think nothing. At last it was given out that some time next day the ship would certainly sail. So next morning, Queequeg and I took a very early start. ..

.. < chapter xxi 2 GOING ABOARD > It was nearly six o'clock, but only grey imperfect misty dawn, when we drew nigh the wharf. There are some sailors running ahead there, if I see right, said I to Queequeg, it can't be shadows; she's off by sunrise, I guess; come on! Avast! cried a voice, whose owner at the same time coming close behind us, laid a hand upon both our shoulders, and then insinuating himself between us, stood stooping forward a little, in the uncertain twilight, strangely peering from Queequeg to me. It was Elijah. Going aboard? Hands off, will you, said I. Lookee here, said Queequeg, shaking himself, go 'way! Aint going aboard, then? Yes, we are, said I, but what business is that of yours? Do you know, Mr. Elijah, that I consider you a little impertinent? No, no, no; I wasn't aware of that, said elijah, slowly and wonderingly looking from me to Queequeg, with the most unaccountable glances. Elijah, said I, you will oblige my friend and me by withdrawing. We are going to the Indian and Pacific Oceans, and would prefer not to be detained. Ye be, be ye? Coming back afore breakfast? He's cracked, Queequeg, said I, come on. Holloa! cried stationary Elijah, hailing us when we had removed a few paces. Never mind him, said I, Queequeg, come on. But he stole up to us again, and suddenly clapping his hand on my shoulder, said -- Did ye see anything looking like men going towards that ship a while ago? Struck by this plain matter-of-fact question, I answered, saying, ..

Yes, I thought I did see four or five men; but it was too dim to be sure. Very dim, very dim, said Elijah. Morning to ye. Once more we quitted him; but once more he came softly after us; and touching my shoulder again, said, See if you can find 'em now, will ye? Find who? Morning to ye! morning to ye! he rejoined, again moving off. Oh! I was going to warn ye against --but never mind, never mind --it's all one, all in the family too; --sharp frost this morning, ain't it? Good bye to ye. Shan't see ye again very soon, I guess; unless it's before the Grand Jury. And with these cracked words he finally departed, leaving me, for the moment, in no small wonderment at his frantic impudence. At last, stepping on board the Pequod, we found everything in profound quiet, not a soul moving. The cabin entrance was locked within; the hatches were all on, and lumbered with coils of rigging. Going forward to the forecastle, we found the slide of the scuttle open. Seeing a light, we went down, and found only an old rigger there, wrapped in a tattered pea-jacket. He was thrown at whole length upon two chests, his face downwards and inclosed in his folded arms. The profoundest slumber slept upon him. Those sailors we saw, Queequeg, where can they have gone to? said I, looking dubiously at the sleeper. But it seemed that, when on the wharf, Queequeg had not at all noticed what I now alluded to; hence I would have thought myself to have been optically deceived in that matter, were it not for Elijah's otherwise inexplicable question. But I beat the thing down; and again marking the sleeper, jocularly hinted to Queequeg that perhaps we had best sit up with the body; telling him to establish himself accordingly. He put his hand upon the sleeper's rear, as though feeling if it was soft enough; and then, without more ado, sat quietly down there. Gracious! Queequeg, don't sit there, said I. Oh! perry dood seat, said Queequeg, my country way; won't hurt him face. Face! said I, call that his face? very benevolent countenance ..

then; but how hard he breathes, he's heaving himself; get off, Queequeg, you are heavy, it's grinding the face of the poor. Get off, Queequeg! Look, he'll twitch you off soon. I wonder he don't wake. Queequeg removed himself to just beyond the head of the sleeper, and lighted his tomahawk pipe. I sat at the feet. We kept the pipe passing over the sleeper, from one to the other. Meanwhile, upon questioning him in his broken fashion, Queequeg gave me to understand that, in his land, owing to the absence of settees and sofas of all sorts, the king, chiefs, and great people generally, were in the custom of fattening some of the lower orders for ottomans; and to furnish a house comfortably in that respect, you had only to buy up eight or ten lazy fellows, and lay them round in the piers and alcoves. Besides, it was very convenient on an excursion; much better than those garden-chairs which are convertible into walking-sticks; upon occasion, a chief calling his attendant, and desiring him to make a settee of himself under a spreading tree, perhaps in some damp marshy place. While narrating these things, every time Queequeg received the tomahawk from me, he flourished the hatchet-side of it over the sleeper's head. What's that for, Queequeg? Perry easy, kill-e; oh! perry easy! He was going on with some wild reminiscences about his tomahawk-pipe, which, it seemed, had in its two uses both brained his foes and soothed his soul, when we were directly attracted to the sleeping rigger. The strong vapor now completely filling the contracted hole, it began to tell upon him. He breathed with a sort of muffledness; then seemed troubled in the nose; then revolved over once or twice; then sat up and rubbed his eyes. Holloa! he breathed at last, who be ye smokers? Shipped men, answered I, when does she sail? Aye, aye, ye are going in her, be ye? She sails to-day. The Captain came aboard last night. What Captain? --Ahab? Who but him indeed? ..

I was going to ask him some further questions concerning Ahab, when we heard a noise on deck. Halloa! Starbuck's astir, said the rigger. He's a lively chief mate, that; good man, and a pious; but all alive now, I must turn to. And so saying he went on deck, and we followed. It was now clear sunrise. Soon the crew came on board in twos and threes; the riggers bestirred themselves; the mates were actively engaged; and several of the shore people were busy in bringing various last things on board. Meanwhile Captain Ahab remained invisibly enshrined within his cabin. ..

.. < chapter xxii 12 MERRY CHRISTMAS > At length, towards noon, upon the final dismissal of the ship's riggers, and after the Pequod had been hauled out from the wharf, and after the ever-thoughtful Charity had come off in a whaleboat, with her last gift --a night-cap for Stubb, the second mate, her brother-in-law, and a spare bible for the steward -- after all this, the two captains, Peleg and Bildad, issued from the cabin, and turning to the chief mate, Peleg said: Now, Mr. Starbuck, are you sure everything is right? Captain Ahab is all ready --just spoke to him --nothing more to be got from shore, eh? Well, call all hands, then. Muster 'em aft here --blast 'em! No need of profane words, however great the hurry, Peleg, said Bildad, but away with thee, friend Starbuck, and do our bidding. How now! Here upon the very point of starting for the voyage, Captain Peleg and Captain Bildad were going it with a high hand on the quarter-deck, just as if they were to be joint-commanders at sea, as well as to all appearances in port. And, as for Captain Ahab, no sign of him was yet to be seen; Only, they said he was in the cabin. But then, the idea was, ..

that his presence was by no means necessary in getting the ship under weigh, and steering her well out to sea. Indeed, as that was not at all his proper business, but the pilot's; and as he was not yet completely recovered --so they said --therefore, Captain Ahab stayed below. And all this seemed natural enough; especially as in the merchant service many captains never show themselves on deck for a considerable time after heaving up the anchor, but remain over the cabin table, having a farewell merrymaking with their shore friends, before they quit the ship for good with the pilot. But there was not much chance to think over the matter, for Captain Peleg was now all alive. He seemed to do most of the talking and commanding, and not Bildad. Aft here, ye sons of bachelors, he cried, as the sailors lingered at the main-mast. Mr. Starbuck, drive 'em aft. Strike the tent there! --was the next order. As I hinted before, this whalebone marquee was never pitched except in port; and on board the Pequod, for thirty years, the order to strike the tent was well known to be the next thing to heaving up the anchor. Man the capstan! Blood and thunder! --jump! --was the next command, and the crew sprang for the handspikes. Now, in getting under weigh, the station generally occupied by the pilot is the forward part of the ship. And here Bildad, who, with Peleg, be it known, in addition to his other offices, was one of the licensed pilots of the port --he being suspected to have got himself made a pilot in order to save the Nantucket pilot-fee to all the ships he was concerned in, for he never piloted any other craft --Bildad, I say, might now be seen actively engaged in looking over the bows for the approaching anchor, and at intervals singing what seemed a dismal stave of psalmody, to cheer the hands at the windlass, who roared forth some sort of a chorus about the girls in Booble Alley, with hearty good will. Nevertheless, not three days previous, Bildad had told them that no profane songs would be allowed on board the Pequod, particularly in getting under weigh; and Charity, his sister, had placed a small choice copy of Watts in each seaman's berth. Meantime, overseeing the other part of the ship, Captain Peleg ..

ripped and swore astern in the most frightful manner. I almost thought he would sink the ship before the anchor could be got up; involuntarily I paused on my handspike, and told Queequeg to do the same, thinking of the perils we both ran, in starting on the voyage with such a devil for a pilot. I was comforting myself, however, with the thought that in pious Bildad might be found some salvation, spite of his seven hundred and seventy-seventh lay; when I felt a sudden sharp poke in my rear, and turning round, was horrified at the apparition of Captain Peleg in the act of withdrawing his leg from my immediate vicinity. That was my first kick. Is that the way they heave in the marchant service? he roared. Spring, thou sheep-head; spring, and break thy backbone! why don't ye spring, i say, all of ye--spring! Quohog! spring, thou chap with the red whiskers; spring there, Scotchcap; spring, thou green pants. Spring, I say, all of ye, and spring your eyes out! And so saying, he moved along the windlass, here and there using his leg very freely, while imperturbable Bildad kept leading off with his psalmody. Thinks I, Captain Peleg must have been drinking something to-day. At last the anchor was up, the sails were set, and off we glided. It was a short, cold Christmas; and as the short northern day merged into night, we found ourselves almost broad upon the wintry ocean, whose freezing spray cased us in ice, as in polished armor. The long rows of teeth on the bulwarks glistened in the moonlight; and like the white ivory tusks of some huge elephant, vast curving icicles depended from the bows. Lank Bildad, as pilot, headed the first watch, and ever and anon, as the old craft deep dived into the green seas, and sent the shivering frost all over her, and the winds howled, and the cordage rang, his steady notes were heard, -- Sweet fields beyond the swelling flood, Stand dressed in living green. So to the Jews old Canaan stood, While Jordan rolled between. Never did those sweet words sound more sweetly to me than then. They were full of hope and fruition. Spite of this frigid ..

winter night in the boisterous Atlantic, spite of my wet feet and wetter jacket, there was yet, it then seemed to me, many a pleasant haven in store; and meads and glades so eternally vernal, that the grass shot up by the spring, untrodden, unwilted, remains at midsummer. At last we gained such an offing, that the two pilots were needed no longer. The stout sail-boat that had accompanied us began ranging alongside. It was curious and not unpleasing, how Peleg and Bildad were affected at this juncture, especially Captain Bildad. For loath to depart, yet; very loath to leave, for good, a ship bound on so long and perilous a voyage --beyond both stormy Capes; a ship in which some thousands of his hard earned dollars were invested; a ship, in which an old shipmate sailed as captain; a man almost as old as he, once more starting to encounter all the terrors of the pitiless jaw; loath to say good-bye to a thing so every way brimful of every interest to him, --poor old Bildad lingered long; paced the deck with anxious strides" ran down into the cabin to speak another farewell word there; again came on deck, and looked to windward; looked towards the wide and endless waters, only bounded by the far-off unseen Eastern Continents; looked towards the land, looked aloft; looked right and left; looked everywhere and nowhere; and at last, mechanically coiling a rope upon its pin, convulsively grasped stout Peleg by the hand, and holding up a lantern, for a moment stood gazing heroically in his face, as much as to say, Nevertheless, friend Peleg, I can stand it; yes, I can. As for Peleg himself, he took it more like a philosopher; but for all his philosophy, there was a tear twinkling in his eye, when the lantern came too near. And he, too, did not a little run from cabin to deck --now a word below, and now a word with Starbuck, the chief mate. But, at last, he turned to his comrade, with a final sort of look about him, -- Captain Bildad --come, old shipmate, we must go. Back the main-yard there! Boat ahoy! Stand by to come close alongside, now! Careful, careful! --come, Bildad, boy --say your last. Luck to ye, Starbuck --luck to ye, Mr. Stubb --luck to ye, ..

Mr. Flask --good-bye, and good luck to ye all --and this day three years I'll have a hot supper smoking for ye in old Nantucket. Hurrah and away! God bless ye, and have ye in His holy keeping, men, murmured old Bildad, almost incoherently. I hope ye'll have fine weather now, so that Captain Ahab may soon be moving among ye --a pleasant sun is all he needs, and ye'll have plenty of them in the tropic voyage ye go. Be careful in the hunt, ye mates. Don't stave the boats needlessly, ye harpooneers; good white cedar plank is raised full three per cent. within the year. Don't forget your prayers, either. Mr Starbuck, mind that cooper don't waste the spare staves. Oh! the sail-needles are in the green locker! Don't whale it too much a' Lord's days, men; but don't miss a fair chance either, that's rejecting Heaven's good gifts. Have an eye to the molasses tierce, Mr. Stubb; it was a little leaky, I thought. If ye touch at the islands, Mr. Flask, beware of fornication. Good-bye, good-bye! Don't keep that cheese too long down in the hold, Mr. Starbuck; it'll spoil. Be careful with the butter --twenty cents the pound it was, and mind ye, if-- Come, come, Captain Bildad; stop palavering, --away! and with that, Peleg hurried him over the side, and both dropt into the boat. Ship and boat diverged; the cold, damp night breeze blew between; a screaming gull flew overhead; the two hulls wildly rolled; we gave three heavy-hearted cheers, and blindly plunged like fate into the lone Atlantic. ..

.. < chapter xxiii 28 THE LEE SHORE > Some chapters back, one Bulkington was spoken of, a tall, new-landed mariner, encountered in New Bedford at the inn. When on that shivering winter's night, the Pequod thrust her vindictive bows into the cold malicious waves, who should I see ..

standing at her helm but Bulkington! I looked with sympathetic awe and fearfulness upon the man, who in mid-winter just landed from a four years' dangerous voyage, could so unrestingly push off again for still another tempestuous term. The land seemed scorching to his feet. Wonderfullest things are ever the unmentionable; deep memories yield no epitaphs; this six-inch chapter is the stoneless grave of Bulkington. Let me only say that it fared with him as with the storm-tossed ship, that miserably drives along the leeward land. The port would fain give succor; the port is pitiful; in the port is safety, comfort, hearthstone, supper, warm blankets, friends, all that's kind to our mortalities. But in that gale, the port, the land, is that ship's direst jeopardy; she must fly all hospitality; one touch of land, though it but graze the keel, would make her shudder through and through. With all her might she crowds all sail off shore; in so doing, fights 'gainst the very winds that fain would blow her homeward; seeks all the lashed sea's landlessness again; for refuge's sake forlornly rushing into peril; her only friend her bitterest foe! Know ye, now, Bulkington? Glimpses do ye seem to see of that mortally intolerable truth; that all deep, earnest thinking is but the intrepid effort of the soul to keep the open independence of her sea; while the wildest winds of heaven and earth conspire to cast her on the treacherous, slavish shore? But as in landlessness alone resides the highest truth, shoreless, indefinite as God --so, better is it to perish in that howling infinite, than be ingloriously dashed upon the lee, even if that were safety! For worm-like, then, oh! who would craven crawl to land! Terrors of the terrible! is all this agony so vain? Take heart, take heart, O Bulkington! Bear thee grimly, demigod! Up from the spray of thy ocean-perishing --straight up, leaps thy apotheosis! ..

.. < chapter xxiv 2 THE ADVOCATE > As Queequeg and I are now fairly embarked in this business of whaling; and as this business of whaling has somehow come to be regarded among landsmen as a rather unpoetical and disreputable pursuit; therefore, I am all anxiety to convince ye, ye landsmen, of the injustice hereby done to us hunters of whales. In the first place, it may be deemed almost superfluous to establish the fact, that among people at large, the business of whaling is not accounted on a level with what are called the liberal professions. If a stranger were introduced into any miscellaneous metropolitan society, it would but slightly advance the general opinion of his merits, were he presented to the company as a harpooneer, say; and if in emulation of the naval officers he should append the initials S. W. F. (Sperm Whale Fishery) to his visiting card, such a procedure would be deemed pre-eminently presuming and ridiculous. Doubtless one leading reason why the world declines honoring us whalemen, is this: they think that, at best, our vocation amounts to a butchering sort of business; and that when actively engaged therein, we are surrounded by all manner of defilements. Butchers we are, that is true. But butchers, also, and butchers of the bloodiest badge have been all Martial Commanders whom the world invariably delights to honor. And as for the matter of the alleged uncleanliness of our business, ye shall soon be initiated into certain facts hitherto pretty generally unknown, and which, upon the whole, will triumphantly plant the sperm whale-ship at least among the cleanliest things of this tidy earth. But even granting the charge in question to be true; what disordered slippery decks of a whale-ship are comparable to the unspeakable carrion of those battle-fields from which so many soldiers return to drink in all ladies' plaudits? And if the ..

idea of peril so much enhances the popular conceit of the soldier's profession; let me assure ye that many a veteran who has freely marched up to a battery, would quickly recoil at the apparition of the sperm whale's vast tail, fanning into eddies the air over his head. For what are the comprehensible terrors of man compared with the interlinked terrors and wonders of God! But, though the world scouts at us whale hunters, yet does it unwittingly pay us the profoundest homage; yea, an all-abounding adoration! for almost all the tapers, lamps, and candles that burn round the globe, burn, as before so many shrines, to our glory! But look at this matter in other lights; weigh it in all sorts of scales; see what we whalemen are, and have been. Why did the Dutch in DeWitt's time have admirals of their whaling fleets? Why did Louis XVI. of France, at his own personal expense, fit out whaling ships from Dunkirk, and politely invite to that town some score or two of families from our own island of Nantucket? Why did Britain between the years and pay to her whalemen in bounties upwards of 1,000,000 pounds? And lastly, how comes it that we whalemen of America now outnumber all the rest of the banded whalemen in the world; sail a navy of upwards of seven hundred vessels; manned by eighteen thousand men; yearly consuming 00824,000,000 of dollars; the ships worth, at the time of sailing, 20,000,000 dollars; and every year importing into our harbors a well reaped harvest of 00847,000,000 dollars. How comes all this, if there be not something puissant in whaling? But this is not the half; look again. I freely assert, that the cosmopolite philosopher cannot, for his life, point out one single peaceful influence, which within the last sixty years has operated more potentially upon the whole broad world, taken in one aggregate, than the high and mighty business of whaling. One way and another, it has begotten events so remarkable in themselves, and so continuously momentous in their sequential issues, that whaling may well be regarded as that Egyptian mother, who bore offspring themselves pregnant from her womb. It would be a hopeless, endless task to catalogue all these things. Let a handful suffice. For many ..

years past the whale-ship has been the pioneer in ferreting out the remotest and least known parts of the earth. She has explored seas and archipelagoes which had no chart, where no Cook or Vancouver had ever sailed. If American and european men-of-war now peacefully ride in once savage harbors, let them fire salutes to the honor and glory of the whale-ship, which originally showed them the way, and first interpreted between them and the savages. They may celebrate as they will the heroes of Exploring Expeditions, your Cookes, Your Krusensterns; but I say that scores of anonymous Captains have sailed out of Nantucket, that were as great, and greater than your Cooke and your Krusenstern. For in their succorless emptyhandedness, they, in the heathenish sharked waters, and by the beaches of unrecorded, javelin islands, battled with virgin wonders and terrors that Cooke with all his marines and muskets would not willingly have dared. All that is made such a flourish of in the old South Sea Voyages, those things were but the lifetime commonplaces of our heroic Nantucketers. Often, adventures which Vancouver dedicates three chapters to, these men accounted unworthy of being set down in the ship's common log. Ah, the world! Oh, the world! Until the whale fishery rounded Cape Horn, no commerce but colonial, scarcely any intercourse but colonial, was carried on between Europe and the long line of the opulent Spanish provinces on the Pacific coast. It was the whaleman who first broke through the jealous policy of the Spanish crown, touching those colonies; and, if space permitted, it might be distinctly shown how from those whalemen at last eventuated the liberation of Peru, Chili, and Bolivia from the yoke of Old Spain, and the establishment of the eternal democracy in those parts. That great America on the other side of the sphere, Australia, was given to the enlightened world by the whaleman. After its first blunder-born discovery by a Dutchman, all other ships long shunned those shores as pestiferously barbarous; but the whale-ship touched there. The whale-ship is the true mother of that now mighty colony. Moreover, in the infancy of the first Australian settlement, the emigrants were several times saved ..

from starvation by the benevolent biscuit of the whale-ship luckily dropping an anchor in their waters. The uncounted isles of all Polynesia confess the same truth, and do commercial homage to the whale-ship, that cleared the way for the missionary and the merchant, and in many cases carried the primitive missionaries to their first destinations. If that double-bolted land, Japan, is ever to become hospitable, it is the whale-ship alone to whom the credit will be due; for already she is on the threshold. But if, in the face of all this, you still declare that whaling has no aesthetically noble associations connected with it, then am I ready to shiver fifty lances with you there, and unhorse you with a split helmet every time. The whale has no famous author, and whaling no famous chronicler, you will say. The whale no famous author, and whaling no famous chronicler? Who wrote the first account of our Leviathan? Who but mighty Job! And who composed the first narrative of a whaling-voyage? Who, but no less a prince than Alfred the Great, who, with his own royal pen, took down the words from Other, the Norwegian whale-hunter of those times! And who pronounced our glowing eulogy in Parliament? Who, but Edmund Burke! True enough, but then whalemen themselves are poor devils; they have no good blood in their veins. No good blood in their veins? They have something better than royal blood there. The grandmother of Benjamin Franklin was Mary Morrel" afterwards, by marriage, Mary Folger, one of the old settlers of Nantucket, and the ancestress to a long line of Folgers and harpooneers --all kith and kin to noble Benjamin --this day darting the barbed iron from one side of the world to the other. Good again; but then all confess that somehow whaling is not respectable. Whaling not respectable? Whaling is imperial! By old English statutory law, the whale is declared a royal fish. ..

Oh, that's only nominal! The whale himself has never figured in any grand imposing way. The whale never figured in any grand imposing way? In one of the mighty triumphs given to a Roman general upon his entering the world's capital, the bones of a whale, brought all the way from the Syrian coast, were the most conspicuous object in the cymballed procession. Grant it, since you cite it; but, say what you will, there is no real dignity in whaling. No dignity in whaling? The dignity of our calling the very heavens attest. Cetus is a constellation in the South! No more! Drive down your hat in presence of the Czar, and take it off to Queequeg! No more! I know a man that, in his lifetime, has taken three hundred and fifty whales. I account that man more honorable than that great captain of antiquity who boasted of taking as many walled towns. And, as for me, if, by any possibility, there be any as yet undiscovered prime thing in me; if I shall ever deserve any real repute in that small but high hushed world which I might not be unreasonably ambitious of; if hereafter I shall do anything that, upon the whole, a man might rather have done than to have left undone; if, at my death, my executors, or more properly my creditors, find any precious MSS. in my desk, then here I prospectively ascribe all the honor and the glory to whaling; for a whale-ship was my Yale College and my Harvard. ..

See subsequent chapters for something more on this head. ..

See subsequent chapters for something more on this head. ..

.. < chapter xxv 27 POSTSCRIPT > In behalf of the dignity of whaling, I would fain advance naught but substantiated facts. But after embattling his facts, an advocate who should wholly suppress a not unreasonable ..

surmise, which might tell eloquently upon his cause --such an advocate, would he not be blameworthy? It is well known that at the coronation of kings and queens, even modern ones, a certain curious process of seasoning them for their functions is gone through. There is a saltcellar of state, so called, and there may be a caster of state. How they use the salt, precisely --who knows? Certain I am, however, that a king's head is solemnly oiled at his coronation, even as a head of salad. Can it be, though, that they anoint it with a view of making its interior run well, as they anoint machinery? Much might be ruminated here, concerning the essential dignity of this regal process, because in common life we esteem but meanly and contemptibly a fellow who anoints his hair, and palpably smells of that anointing. In truth, a mature man who uses hair-oil, unless medicinally, that man has probably got a quoggy spot in him somewhere. As a general rule, he can't amount to much in his totality. But the only thing to be considered here, is this --what kind of oil is used at coronations? Certainly it cannot be olive oil, nor macassar oil, nor castor oil, nor bear's oil, nor train oil, nor cod-liver oil. What then can it possibly be, but sperm oil in its unmanufactured, unpolluted state, the sweetest of all oils? Think of that, ye loyal Britons! we whalemen supply your kings and queens with coronation stuff! ..

.. < chapter xxvi 26 KNIGHTS AND SQUIRES > The chief mate of the Pequod was Starbuck, a native of Nantucket, and a Quaker by descent. He was a long, earnest man, and though born on an icy coast, seemed well adapted to endure hot latitudes, his flesh being hard as twice-baked biscuit. Transported to the Indies, his live blood would not spoil like bottled ..

ale. He must have been born in some time of general drought and famine, or upon one of those fast days for which his state is famous. Only some thirty arid summers had he seen; those summers had dried up all his physical superfluousness. But this, his thinness, so to speak, seemed no more the token of wasting anxieties and cares, than it seemed the indication of any bodily blight. It was merely the condensation of the man. He was by no means ill-looking; quite the contrary. His pure tight skin was an excellent fit; and closely wrapped up in it, and embalmed with inner health and strength, like a revivified Egyptian, this Starbuck seemed prepared to endure for long ages to come, and to endure always, as now; for be it Polar snow or torrid sun, like a patent chronometer, his interior vitality was warranted to do well in all climates. Looking into his eyes, you seemed to see there the yet lingering images of those thousand-fold perils he had calmly confronted through life. A staid, steadfast man, whose life for the most part was a telling pantomime of action, and not a tame chapter of sounds. Yet, for all his hardy sobriety and fortitude, there were certain qualities in him which at times affected, and in some cases seemed well nigh to overbalance all the rest. Uncommonly conscientious for a seaman, and endued with a deep natural reverence, the wild watery loneliness of his life did therefore strongly incline him to superstition; but to that sort of superstition, which in some organizations seems rather to spring, somehow, from intelligence than from ignorance. Outward portents and inward presentiments were his. And if at times these things bent the welded iron of his soul, much more did his far-away domestic memories of his young Cape wife and child, tend to bend him still more from the original ruggedness of his nature, and open him still further to those latent influences which, in some honest-hearted men, restrain the gush of dare-devil daring, so often evinced by others in the more perilous vicissitudes of the fishery. I will have no man in my boat, said starbuck, who is not afraid of a whale. by this, he seemed to mean, not only that the most reliable and useful courage was that which arises from the fair estimation of the encountered peril, but that an utterly fearless man is a far more dangerous comrade than a coward. ..

Aye, aye, said Stubb, the second mate, Starbuck, there, is as careful a man as you'll find anywhere in this fishery. But we shall ere long see what that word careful precisely means when used by a man like Stubb, or almost any other whale hunter. Starbuck was no crusader after perils; in him courage was not a sentiment; but a thing simply useful to him, and always at hand upon all mortally practical occasions. Besides, he thought, perhaps, that in this business of whaling, courage was one of the great staple outfits of the ship, like her beef and her bread, and not to be foolishly wasted. Wherefore he had no fancy for lowering for whales after sun-down; nor for persisting in fighting a fish that too much persisted in fighting him. For, thought Starbuck, I am here in this critical ocean to kill whales for my living, and not to be killed by them for theirs; and that hundreds of men had been so killed Starbuck well knew. What doom was his own father's? Where, in the bottomless deeps, could he find the torn limbs of his brother? With memories like these in him, and, moreover, given to a certain superstitiousness, as has been said; the courage of this Starbuck which could, nevertheless, still flourish, must indeed have been extreme. But it was not in reasonable nature that a man so organized, and with such terrible experiences and remembrances as he had; it was not in nature that these things should fail in latently engendering an element in him, which, under suitable circumstances, would break out from its confinement, and burn all his courage up. And brave as he might be, it was that sort of bravery chiefly, visible in some intrepid men, which, while generally abiding firm in the conflict with seas, or winds, or whales, or any of the ordinary irrational horrors of the world, yet cannot withstand those more terrific, because more spiritual terrors, which sometimes menace you from the concentrating brow of an enraged and mighty man. But were the coming narrative to reveal, in any instance, the complete abasement of poor Starbuck's fortitude, scarce might I have the heart to write it; for it is a thing most sorrowful, nay shocking, to expose the fall of valor in the soul. Men may seem detestable as joint stock-companies and nations; knaves, ..

fools, and murderers there may be; men may have mean and meagre faces; but man, in the ideal, is so noble and so sparkling, such a grand and glowing creature, that over any ignominious blemish in him all his fellows should run to throw their costliest robes. That immaculate manliness we feel within ourselves, so far within us, that it remains intact though all the outer character seem gone; bleeds with keenest anguish at the undraped spectacle of a valor-ruined man. Nor can piety itself, at such a shameful sight, completely stifle her upbraidings against the permitting stars. But this august dignity I treat of, is not the dignity of kings and robes, but that abounding dignity which has no robed investiture. Thou shalt see it shining in the arm that wields a pick or drives a spike; that democratic dignity which, on all hands, radiates without end from God; Himself! The great God absolute! The centre and circumference of all democracy! His omnipresence, our divine equality! If, then, to meanest mariners, and renegades and castaways, I shall hereafter ascribe high qualities, though dark; weave round them tragic graces; if even the most mournful, perchance the most abased, among them all, shall at times lift himself to the exalted mounts; if I shall touch that workman's arm with some ethereal light; if I shall spread a rainbow over his disastrous set of sun; then against all mortal critics bear me out in it, thou just spirit of equality, which hast spread one royal mantle of humanity over all my kind! Bear me out in it, thou great democratic God! who didst not refuse to the swart convict, Bunyan, the pale, poetic pearl; Thou who didst clothe with doubly hammered leaves of finest gold, the stumped and paupered arm of old Cervantes; Thou who didst pick up Andrew Jackson from the pebbles; who didst hurl him upon a war-horse; who didst thunder him higher than a throne! Thou who, in all Thy mighty, earthly marchings, ever cullest Thy selectest champions from the kingly commons; bear me out in it, O God! ..

.. < chapter xxvii 2 KNIGHTS AND SQUIRES > Stubb was the second mate. He was a native of Cape Cod; and hence, according to local usage, was called a Cape-Cod-man. A happy-go-lucky; neither craven nor valiant; taking perils as they came with an indifferent air; and while engaged in the most imminent crisis of the chase, toiling away, calm and collected as a journeyman joiner engaged for the year. Good-humored, easy, and careless, he presided over his whale-boat as if the most deadly encounter were but a dinner, and his crew all invited guests. He was as particular about the comfortable arrangement of his part of the boat, as an old stage-driver is about the snugness of his box. When close to the whale, in the very death-lock of the fight, he handled his unpitying lance coolly and off-handedly, as a whistling tinker his hammer. He would hum over his old rigadig tunes while flank and flank with the most exasperated monster. Long usage had, for this Stubb, converted the jaws of death into an easy chair. What he thought of death itself, there is no telling. Whether he ever thought of it at all, might be a question; but, if he ever did chance to cast his mind that way after a comfortable dinner, no doubt, like a good sailor, he took it to be a sort of call of the watch to tumble aloft, and bestir themselves there, about something which he would find out when he obeyed the order, and not sooner. What, perhaps, with other things, made Stubb such an easygoing, unfearing man, so cheerily trudging off with the burden of life in a world full of grave peddlers, all bowed to the ground with their packs; what helped to bring about that almost impious good-humor of his; that thing must have been his pipe. For, like his nose, his short, black little pipe was one of the regular features of his face. You would almost as soon have expected him to turn out of his bunk without his nose as without his pipe. ..

He kept a whole row of pipes there ready loaded, stuck in a rack, within easy reach of his hand; and, whenever he turned in, he smoked them all out in succession, lighting one from the other to the end of the chapter; then loading them again to be in readiness anew. For, when Stubb dressed, instead of first putting his legs into his trowsers, he put his pipe into his mouth. I say this continual smoking must have been one cause, at least, of his peculiar disposition; for every one knows that this earthly air, whether ashore or afloat, is terribly infected with the nameless miseries of the numberless mortals who have died exhaling it; and as in time of the cholera, some people go about with a camphorated handkerchief to their mouths; so, likewise, against all mortal tribulations, Stubb's tobacco smoke might have operated as a sort of disinfecting agent. The third mate was Flask, a native of Tisbury, in Martha's Vineyard. A short, stout, ruddy young fellow, very pugnacious concerning whales, who somehow seemed to think that the great Leviathans had personally and hereditarily affronted him; and therefore it was a sort of point of honor with him, to destroy them whenever encountered. So utterly lost was he to all sense of reverence for the many marvels of their majestic bulk and mystic ways; and so dead to anything like an apprehension of any possible danger from encountering them; that in his poor opinion, the wondrous whale was but a species of magnified mouse, or at least water-rat, requiring only a little circumvention and some small application of time and trouble in order to kill and boil. This ignorant, unconscious fearlessness of his made him a little waggish in the matter of whales; he followed these fish for the fun of it; and a three years' voyage round Cape Horn was only a jolly joke that lasted that length of time. As a carpenter's nails are divided into wrought nails and cut nails; so mankind may be similarly divided. Little Flask was one of the wrought ones; made to clinch tight and last long. They called him King-Post on board of the Pequod; because, in form, he could be well likened to the short, square timber known by that name in Arctic whalers; and which by the means of many radiating side timbers inserted in it, served to brace the ship against the icy concussions of those battering seas. Now these three mates --Starbuck, Stubb, and Flask, were ..

momentous men. They it was who by universal prescription commanded three of the Pequod's boats as headsmen. In that grand order of battle in which Captain Ahab would probably marshal his forces to descend on the whales, these three headsmen were as captains of companies. Or, being armed with their long keen whaling spears, they were as a picked trio of lancers; even as the harpooneers were flingers of javelins. And since in this famous fishery, each mate or headsman, like a Gothic Knight of old, is always accompanied by his boat-steerer or harpooneer, who in certain conjunctures provides him with a fresh lance, when the former one has been badly twisted, or elbowed in the assault; and moreover, as there generally subsists between the two, a close intimacy and friendliness; it is therefore but meet, that in this place we set down who the Pequod's harpooneers were, and to what headsman each of them belonged. first of all was queequeg, whom Starbuck, the chief mate, had selected for his squire. But Queequeg is already known. Next was Tashtego, an unmixed Indian from Gay Head, the most westerly promontory of Martha's Vineyard, where there still exists the last remnant of a village of red men, which has long supplied the neighboring island of Nantucket with many of her most daring harpooneers. In the fishery, they usually go by the generic name of Gay-Headers. Tashtego's long, lean, sable hair, his high cheek bones, and black rounding eyes --for an Indian, Oriental in their largeness, but Antarctic in their glittering expression --all this sufficiently proclaimed him an inheritor of the unvitiated blood of those proud warrior hunters, who, in quest of the great New England moose, had scoured, bow in hand, the aboriginal forests of the main. But no longer snuffing in the trail of the wild beasts of the woodland, Tashtego now hunted in the wake of the great whales of the sea; the unerring harpoon of the son fitly replacing the infallible arrow of the sires. To look at the tawny brawn of his lithe snaky limbs, you would almost have credited the superstitions of some of the earlier Puritans, and half believed this wild Indian to be a son of the Prince of the Powers of the Air. Tashtego was Stubb the second mate's squire. Third among the harpooneers was Daggoo, a gigantic, coal-black ..

negro-savage, with a lion-like tread --an Ahasuerus to behold. Suspended from his ears were two golden hoops, so large that the sailors called them ring-bolts, and would talk of securing the top-sail halyards to them. In his youth Daggoo had voluntarily shipped on board of a whaler, lying in a lonely bay on his native coast. And never having been anywhere in the world but in Africa, Nantucket, and the pagan harbors most frequented by whalemen; and having now led for many years the bold life of the fishery in the ships of owners uncommonly heedful of what manner of men they shipped; daggoo retained all his barbaric virtues, and erect as a giraffe, moved about the decks in all the pomp of six feet five in his socks. There was a corporeal humility in looking up at him; and a white man standing before him seemed a white flag come to beg truce of a fortress. Curious to tell, this imperial negro, Ahasuerus Daggoo, was the Squire of little Flask, who looked like a chess-man beside him. As for the residue of the Pequod's company, be it said, that at the present day not one in two of the many thousand men before the mast employed in the American whale fishery, are Americans born, though pretty nearly all the officers are. Herein it is the same with the American whale fishery as with the American army and military and merchant navies, and the engineering forces employed in the construction of the American Canals and Railroads. The same, I say, because in all these cases the native American liberally provides the brains, the rest of the world as generously supplying the muscles. No small number of these whaling seamen belong to the Azores, where the outward bound Nantucket whalers frequently touch to augment their crews from the hardy peasants of those rocky shores. In like manner, the Greenland whalers sailing out of Hull or London, put in at the Shetland Islands, to receive the full complement of their crew. Upon the passage homewards, they drop them there again. How it is, there is no telling, but Islanders seem to make the best whalemen. They were nearly all Islanders in the Pequod, Isolatoes too, I call such, not acknowledging the common continent of men, but each Isolato living on a separate continent of his own. Yet now, federated along one keel, what a set these Isolatoes were! An Anacharsis Clootz deputation from all the ..

isles of the sea, and all the ends of the earth, accompanying Old Ahab in the pequod to lay the world's grievances before that bar from which not very many of them ever come back. Black Little Pip --he never did --oh, no! he went before. Poor Alabama boy! On the grim Pequod's forecastle, ye shall ere long see him, beating his tambourine; prelusive of the eternal time, when sent for, to the great quarter-deck on high, he was bid strike in with angels, and beat his tambourine in glory; called a coward here, hailed a hero there! ..

.. < chapter xxviii 11 AHAB > For several days after leaving Nantucket, nothing above hatches was seen of Captain Ahab. The mates regularly relieved each other at the watches, and for aught that could be seen to the contrary, they seemed to be the only commanders of the ship; only they sometimes issued from the cabin with orders so sudden and peremptory, that after all it was plain they but commanded vicariously. Yes, their supreme lord and dictator was there, though hitherto unseen by any eyes not permitted to penetrate into the now sacred retreat of the cabin. Every time I ascended to the deck from my watches below, I instantly gazed aft to mark if any strange face were visible; for my first vague disquietude touching the unknown captain, now in the seclusion of the sea, became almost a perturbation. This was strangely heightened at times by the ragged Elijah's diabolical incoherences uninvitedly recurring to me, with a subtle energy I could not have before conceived of. But poorly could I withstand them, much as in other moods I was almost ready to smile at the solemn whimsicalities of that outlandish prophet of the wharves. But whatever it was of apprehensiveness or uneasiness --to call it so --which I felt, yet whenever I came to look about me in the ship, it seemed against all warrantry to ..

cherish such emotions. For though the harpooneers, with the great body of the crew, were a far more barbaric, heathenish, and motley set than any of the tame merchant-ship companies which my previous experiences had made me acquainted with, still I ascribed this --and rightly ascribed it --to the fierce uniqueness of the very nature of that wild Scandinavian vocation in which I had so abandonedly embarked. But it was especially the aspect of the three chief officers of the ship, the mates, which was most forcibly calculated to allay these colorless misgivings, and induce confidence and cheerfulness in every presentment of the voyage. Three better, more likely sea-officers and men, each in his own different way, could not readily be found, and they were every one of them Americans; a Nantucketer, a Vineyarder, a Cape man. Now, it being Christmas when the ship shot from out her harbor, for a space we had biting Polar weather, though all the time running away from it to the southward; and by every degree and minute of latitude which we sailed, gradually leaving that merciless winter, and all its intolerable weather behind us. It was one of those less lowering, but still grey and gloomy enough mornings of the transition, when with a fair wind the ship was rushing through the water with a vindictive sort of leaping and melancholy rapidity, that as I mounted to the deck at the call of the forenoon watch, so soon as I levelled my glance towards the taffrail, foreboding shivers ran over me. Reality outran apprehension; Captain Ahab stood upon his quarter-deck. There seemed no sign of common bodily illness about him, nor of the recovery from any. He looked like a man cut away from the stake, when the fire has overrunningly wasted all the limbs without consuming them, or taking away one particle from their compacted aged robustness. His whole high, broad form, seemed made of solid bronze, and shaped in an unalterable mould, like Cellini's cast Perseus. Threading its way out from among his grey hairs, and continuing right down one side of his tawny scorched face and neck, till it disappeared in his clothing, you saw a slender rod-like mark, lividly whitish. It resembled that perpendicular seam sometimes made in the straight, lofty trunk of a great tree, when the upper lightning ..

tearingly darts down it, and without wrenching a single twig, peels and grooves out the bark from top to bottom, ere running off into the soil, leaving the tree still greenly alive, but branded. Whether that mark was born with him, or whether it was the scar left by some desperate wound, no one could certainly say. By some tacit consent, throughout the voyage little or no allusion was made to it, especially by the mates. But once Tashtego's senior, an old Gay-Head Indian among the crew, superstitiously asserted that not till he was full forty years old did Ahab become that way branded, and then it came upon him, not in the fury of any mortal fray, but in an elemental strife at sea. Yet, this wild hint seemed inferentially negatived, by what a grey Manxman insinuated, an old sepulchral man, who, having never before sailed out of Nantucket, had never ere this laid eye upon wild Ahab. Nevertheless, the old sea-traditions, the immemorial credulities, popularly invested this old Manxman with preternatural powers of discernment. So that no white sailor seriously contradicted him when he said that if ever Captain Ahab should be tranquilly laid out --which might hardly come to pass, so he muttered --then, whoever should do that last office for the dead, would find a birth-mark on him from crown to sole. So powerfully did the whole grim aspect of Ahab affect me, and the livid brand which streaked it, that for the first few moments I hardly noted that not a little of this overbearing grimness was owing to the barbaric white leg upon which he partly stood. It had previously come to me that this ivory leg had at sea been fashioned from the polished bone of the sperm whale's jaw. Aye, he was dismasted off Japan, said the old Gay-Head Indian once; but like his dismasted craft, he shipped another mast without coming home for it. he has a quiver of 'em. I was struck with the singular posture he maintained. Upon each side of the Pequod's quarter deck, and pretty close to the mizen shrouds, there was an auger hole, bored about half an inch or so, into the plank. His bone leg steadied in that hole; one arm elevated, and holding by a shroud; Captain Ahab stood erect, looking straight out beyond the ship's ever-pitching prow. There was an infinity of firmest fortitude, a determinate unsurrenderable ..

wilfulness, in the fixed and fearless, forward dedication of that glance. Not a word he spoke; nor did his officers say aught to him; though by all their minutest gestures and expressions, they plainly showed the uneasy, if not painful, consciousness of being under a troubled master-eye. And not only that, but moody stricken Ahab stood before them with a crucifixion in his face; in all the nameless regal overbearing dignity of some mighty woe. Ere long, from his first visit in the air, he withdrew into his cabin. But after that morning, he was every day visible to the crew; either standing in his pivot-hole, or seated upon an ivory stool he had; or heavily walking the deck. As the sky grew less gloomy; indeed, began to grow a little genial, he became still less and less a recluse; as if, when the ship had sailed from home, nothing but the dead wintry bleakness of the sea had then kept him so secluded. And, by and by, it came to pass, that he was almost continually in the air; but, as yet, for all that he said, or perceptibly did, on the at last sunny deck, he seemed as unnecessary there as another mast. But the Pequod was only making a passage now; not regularly cruising; nearly all whaling preparatives needing supervision the mates were fully competent to, so that there was little or nothing, out of himself, to employ or excite Ahab, now; and thus chase away, for that one interval, the clouds that layer upon layer were piled upon his brow, as ever all clouds choose the loftiest peaks to pile themselves upon. Nevertheless, ere long, the warm, warbling persuasiveness of the pleasant, holiday weather we came to, seemed gradually to charm him from his mood. For, as when the red-cheeked, dancing girls, April and May, trip home to the wintry, misanthropic woods; even the barest, ruggedest, most thunder-cloven old oak will at least send forth some few green sprouts, to welcome such glad-hearted visitants; so Ahab did, in the end, a little respond to the playful allurings of that girlish air. More than once did he put forth the faint blossom of a look, which, in any other man, would have soon flowered out in a smile. ..

.. < chapter xxix 2 ENTER AHAB; TO HIM, STUBB > Some days elapsed, and ice and icebergs all astern, the Pequod now went rolling through the bright Quito spring, which, at sea, almost perpetually reigns on the threshold of the eternal August of the Tropic. The warmly cool, clear, ringing, perfumed, overflowing, redundant days, were as crystal goblets of Persian sherbet, heaped up --flaked up, with rose-water snow. The starred and stately nights seemed haughty dames in jewelled velvets, nursing at home in lonely pride, the memory of their absent conquering Earls, the golden helmeted suns! For sleeping man, 'twas hard to choose between such winsome days and such seducing nights. But all the witcheries of that unwaning weather did not merely lend new spells and potencies to the outward world. Inward they turned upon the soul, especially when the still mild hours of eve came on; then, memory shot her crystals as the clear ice most forms of noiseless twilights. And all these subtle agencies, more and more they wrought on Ahab's texture. Old age is always wakeful; as if, the longer linked with life, the less man has to do with aught that looks like death. among sea-commanders, the old greybeards will oftenest leave their berths to visit the night-cloaked deck. It was so with Ahab; only that now, of late, he seemed so much to live in the open air, that truly speaking, his visits were more to the cabin, than from, the cabin to the planks. It feels like going down into one's tomb, --he would mutter to himself, -- for an old captain like me to be descending this narrow scuttle, to go to my grave-dug berth. So, almost every twenty-four hours, when the watches of the night were set, and the band on deck sentinelled the slumbers of the band below; and when if a rope was to be hauled upon the forecastle, the sailors flung it not rudely down, as by day, ..

but with some cautiousness dropt it to its place, for fear of disturbing their slumbering shipmates; when this sort of steady quietude would begin to prevail, habitually, the silent steersman would watch the cabin-scuttle; and ere long the old man would emerge, griping at the iron banister, to help his crippled way. Some considerating touch of humanity was in him; for at times like these, he usually abstained from patrolling the quarter-deck; because to his wearied mates, seeking repose within six inches of his ivory heel, such would have been the reverberating crack and din of that bony step, that their dreams would have been of the crunching teeth of sharks. But once, the mood was on him too deep for common regardings; and as with heavy, lumber-like pace he was measuring the ship from taffrail to mainmast, Stubb, the odd second mate, came up from below, and with a certain unassured, deprecating humorousness, hinted that if Captain Ahab was pleased to walk the planks, then, no one could say nay; but there might be some way of muffling the noise; hinting something indistinctly and hesitatingly about a globe of tow, and the insertion into it, of the ivory heel. Ah! Stubb, thou did'st not know Ahab then. Am I a cannon-ball, Stubb, said Ahab, that thou wouldst wad me that fashion? But go thy ways; I had forgot. Below to thy nightly grave; where such as ye sleep between shrouds, to use ye to the filling one at last. --Down, dog, and kennel! Starting at the unforeseen concluding exclamation of the so suddenly scornful old man, Stubb was speechless a moment; then said excitedly, I am not used to be spoken to that way, sir; I do but less than half like it, sir. Avast! gritted Ahab between his set teeth, and violently moving away, as if to avoid some passionate temptation. No, sir; not yet, said Stubb, emboldened, I will not tamely be called a dog, sir. Then be called ten times a donkey, and a mule, and an ass, and begone, or I'll clear the world of thee! As he said this, Ahab advanced upon him with such overbearing terrors in his aspect, that Stubb involuntarily retreated. I was never served so before without giving a hard blow for it, muttered Stubb, as he found himself descending the cabin-scuttle. ..

It's very queer. Stop, Stubb; somehow, now, I don't well know whether to go back and strike him, or --what's that? -- down here on my knees and pray for him? Yes, that was the thought coming up in me; but it would be the first time I ever did pray. It's queer; very queer; and he's queer too; aye, take him fore and aft, he's about the queerest old man Stubb ever sailed with. How he flashed at me! --his eyes like powder-pans! is he mad? Anyway there's something on his mind, as sure as there must be something on a deck when it cracks. He aint in his bed now, either, more than three hours out of the twenty-four; and he don't sleep then. Didn't that Dough-Boy, the steward, tell me that of a morning he always finds the old man's hammock clothes all rumpled and tumbled, and the sheets down at the foot, and the coverlid almost tied into knots, and the pillow a sort of frightful hot, as though a baked brick had been on it? A hot old man! I guess he's got what some folks ashore call a conscience; it's a kind of Tic-Dolly-row they say --worse nor a toothache. Well, well; I don't know what it is, but the Lord keep me from catching it. He's full of riddles; I wonder what he goes into the after hold for, every night, as Dough-Boy tells me he suspects; what's that for, I should like to know? Who's made appointments with him in the hold? Ain't that queer, now? But there's no telling, it's the old game --Here goes for a snooze. Damn me, it's worth a fellow's while to be born into the world, if only to fall right asleep. And now that I think of it, that's about the first thing babies do, and that's a sort of queer, too. Damn me, but all things are queer, come to think of 'em. But that's against my principles. Think not, is my eleventh commandment; and sleep when you can, is my twelfth -- So here goes again. But how's that? didn't he call me a dog? blazes! he called me ten times a donkey, and piled a lot of jackasses on top of that! He might as well have kicked me, and done with it. Maybe he did kick me, and I didn't observe it, I was so taken all aback with his brow, somehow. It flashed like a bleached bone. What the devil's the matter with me? I don't stand right on my legs. Coming afoul of that old man has a sort of turned me wrong side out. By the Lord, I must have been dreaming, though --How? how? how? --but the only way's ..

to stash it; so here goes to hammock again; and in the morning, I'll see how this plaguey juggling thinks over by day-light. ..

.. < chapter xxx 4 THE PIPE > When Stubb had departed, Ahab stood for a while leaning over the bulwarks; and then, as had been usual with him of late, calling a sailor of the watch, he sent him below for his ivory stool, and also his pipe. lighting the pipe at the binnacle lamp and planting the stool on the weather side of the deck, he sat and smoked. In old Norse times, the thrones of the sea-loving Danish kings were fabricated, saith tradition, of the tusks of the narwhale. How could one look at Ahab then, seated on that tripod of bones, without bethinking him of the royalty it symbolized? For a Khan of the plank, and a king of the sea, and a great lord of Leviathans was Ahab. Some moments passed, during which the thick vapor came from his mouth in quick and constant puffs, which blew back again into his face. How now, he soliloquized at last, withdrawing the tube, this smoking no longer soothes. Oh, my pipe! hard must it go with me if thy charm be gone! Here have I been unconsciously toiling, not pleasuring, --aye, and ignorantly smoking to windward all the while; to windward, and with such nervous whiffs, as if, like the dying whale, my final jets were the strongest and fullest of trouble. What business have I with this pipe? This thing that is meant for sereneness, to send up mild white vapors among mild white hairs, not among torn iron-grey locks like mine. I'll smoke no more-- He tossed the still lighted pipe into the sea. The fire hissed in the waves; the same instant the ship shot by the bubble the sinking pipe made. With slouched hat, Ahab lurchingly paced the planks. ..

.. < chapter xxxi 2 QUEEN MAB > Next morning Stubb accosted Flask. Such a queer dream, King-Post, I never had. You know the old man's ivory leg, well I dreamed he kicked me with it; and when I tried to kick back, upon my soul, my little man, I kicked my leg right off! And then, presto! Ahab seemed a pyramid, and I, like a blazing fool, kept kicking at it. But what was still more curious, Flask--you know how curious all dreams are-- through all this rage that I was in, I somehow seemed to be thinking to myself, that after all, it was not much of an insult, that kick from ahab. "Why," thinks I,"what's the row? It's not a real leg, only a false leg." And there's a mighty difference between a living thump and a dead thump. That's what makes a blow from the hand, Flask, fifty times more savage to bear than a blow from a cane. The living member --that makes the living insult, my little man. And thinks I to myself all the while, mind, while I was stubbing my silly toes against that cursed pyramid -- so confoundedly contradictory was it all, all the while, I say, I was thinking to myself, "what's his leg now, but a cane --a whalebone cane. Yes," thinks I,"it was only a playful cudgelling --in fact, only a whaleboning that he gave me --not a base kick. Besides," thinks I,"look at it once; why, the end of it --the foot part --what a small sort of end it is; whereas, if a broad footed farmer kicked me, there's a devilish broad insult. But this insult is whittled down to a point only." But now comes the greatest joke of the dream, Flask. While I was battering away at the pyramid, a sort of badger-haired old merman, with a hump on his back, takes me by the shoulders, and slews me round. "What are you 'bout?" says he. Slid! man, but I was frightened. Such a phiz! But, somehow, next moment I was over the fright. "What am I about?" says I at last. "And what business is that of yours, I should like to know, Mr. Humpback? Do you want a ..

kick?" By the lord, Flask, I had no sooner said that, than he turned round his stern to me, bent over, and dragging up a lot of seaweed he had for a clout --what do you think, I saw? --why thunder alive, man, his stern was stuck full of marlinspikes, with the points out. Says I, on second thoughts,"I guess I won't kick you, old fellow." "Wise Stubb," said he,"wise Stubb;" and kept muttering it all the time, a sort of eating of his own gums like a chimney hag. seeing he wasn't going to stop saying over his "wise Stubb, wise Stubb," I thought I might as well fall to kicking the pyramid again. But I had only just lifted my foot for it, when he roared out, "Stop that kicking!" "Halloa," says I,"what's the matter now, old fellow?" "Look ye here," says he;"let's argue the insult. Captain Ahab kicked ye, didn't he?" "Yes, he did," says I --"right here it was." "Very good," says he --"he used his ivory leg, didn't he?" "Yes, he did," says I. "Well then," says he, "wise Stubb, what have you to complain of? Didn't he kick with right good will? it wasn't a common pitch pine leg he kicked with, was it? No, you were kicked by a great man, and with a beautiful ivory leg, Stubb. It's an honor; I consider it an honor. Listen, wise Stubb. In old England the greatest lords think it great glory to be slapped by a queen, and made garter-knights of; but, be your boast, Stubb, that ye were kicked by old Ahab, and made a wise man of. Remember what I say; be kicked by him; account his kicks honors; and on no account kick back; for you can't help yourself, wise Stubb. Don't you see that pyramid?" With that, he all of a sudden seemed somehow, in some queer fashion, to swim off into the air. I snored; rolled over; and there I was in my hammock! Now, what do you think of that dream, Flask? I don't know; it seems a sort of foolish to me, tho'. May be, may be. But it's made a wise man of me, Flask. D'ye see Ahab standing there, sideways looking over the stern? Well, the best thing you can do, Flask, is to let that old man alone; never speak to him, whatever he says. Halloa! what's that he shouts? Hark! Mast-head, there! Look sharp, all of ye! There are whales hereabouts! If ye see a white one, split your lungs for him! What d'ye think of that now, Flask? ain't there a small drop ..

of something queer about that, eh? a white whale--did ye mark that, man? Look ye--there's something special in the wind. Stand by for it, Flask. Ahab has that that's bloody on his mind. But, mum; he comes this way. ..

.. < chapter xxxii 6 CETOLOGY > Already we are boldly launched upon the deep; but soon we shall be lost in its unshored, harborless immensities. Ere that come to pass; ere the Pequod's weedy hull rolls side by side with the barnacled hulls of the leviathan; at the outset it is but well to attend to a matter almost indispensable to a thorough appreciative understanding of the more special leviathanic revelations and allusions of all sorts which are to follow. It is some systematized exhibition of the whale in his broad genera, that I would now fain put before you. Yet is it no easy task. The classification of the constituents of a chaos, nothing less is here essayed. Listen to what the best and latest authorities have laid down. No branch of Zoology is so much involved as that which is entitled Cetology, says Captain Scoresby, A. D. . It is not my intention, were it in my power, to enter into the inquiry as to the true method of dividing the cetacea into groups and families.... Utter confusion exists among the historians of this animal (sperm whale), says Surgeon Beale, A. D. . Unfitness to pursue our research in the unfathomable waters. Impenetrable veil covering our knowledge of the cetacea. A field strewn with thorns. All these incomplete indications but serve to torture us naturalists. Thus speak of the whale, the great Cuvier, and John Hunter, and Lesson, those lights of zoology and anatomy. Nevertheless, though of real knowledge there be little, yet of books there are ..

a plenty; and so in some small degree, with cetology, or the science of whales. many are the men, small and great, old and new, landsmen and seamen, who have at large or in little, written of the whale. Run over a few: --The Authors of the Bible; Aristotle; Pliny; Aldrovandi; Sir Thomas Browne; Gesner; Ray; Linnaeus; Rondeletius; Willoughby; Green; Artedi; Sibbald; Brisson; Marten; Lacepede; Bonneterre; Desmarest; Baron Cuvier; Frederick Cuvier; John Hunter; Owen; Scoresby; Beale; Bennett; J. Ross Browne; the Author of Miriam Coffin; Olmstead; and the Rev. T. Cheever. But to what ultimate generalizing purpose all these have written, the above cited extracts will show. Of the names in this list of whale authors, only those following Owen ever saw living whales; and but one of them was a real professional harpooneer and whaleman. I mean Captain Scoresby. On the separate subject of the Greenland or right-whale, he is the best existing authority. But Scoresby knew nothing and says nothing of the great sperm whale, compared with which the Greenland whale is almost unworthy mentioning. And here be it said, that the Greenland whale is an usurper upon the throne of the seas. He is not even by any means the largest of the whales. Yet, owing to the long priority of his claims, and the profound ignorance which, till some seventy years back, invested the then fabulous and utterly unknown sperm-whale, and which ignorance to this present day still reigns in all but some few scientific retreats and whale-ports; this usurpation has been every way complete. Reference to nearly all the leviathanic allusions in the great poets of past days, will satisfy you that the Greenland whale, without one rival, was to them the monarch of the seas. But the time has at last come for a new proclamation. This is Charing Cross; hear ye! good people all, --the Greenland whale is deposed, --the great sperm whale now reigneth! There are only two books in being which at all pretend to put the living sperm whale before you, and at the same time, in the remotest degree succeed in the attempt. Those books are Beale's and Bennett's; both in their time surgeons to English South-Sea whale-ships, and both exact and reliable men. The ..

original matter touching the sperm whale to be found in their volumes is necessarily small; but so far as it goes, it is of excellent quality, though mostly confined to scientific description. As yet, however, the sperm whale, scientific or poetic, lives not complete in any literature. Far above all other hunted whales, his is an unwritten life. Now the various species of whales need some sort of popular comprehensive classification, if only an easy outline one for the present, hereafter to be filled in all its departments by subsequent laborers. As no better man advances to take this matter in hand, I hereupon offer my own poor endeavors. I promise nothing complete; because any human thing supposed to be complete, must for that very reason infallibly be faulty. I shall not pretend to a minute anatomical description of the various species, or-- in this place at least --to much of any description. My object here is simply to project the draught of a systematization of cetology. I am the architect, not the builder. But it is a ponderous task; no ordinary letter-sorter in the Post-office is equal to it. To grope down into the bottom of the sea after them; to have one's hands among the unspeakable foundations, ribs, and very pelvis of the world; this is a fearful thing. What am I that I should essay to hook the nose of this leviathan! The awful tauntings in Job might well appal me. Will he (the leviathan) make a covenant with thee? Behold the hope of him is vain! But I have swam through libraries and sailed through oceans; I have had to do with whales with these visible hands; I am in earnest; and I will try. There are some preliminaries to settle. first: the uncertain, unsettled condition of this science of Cetology is in the very vestibule attested by the fact, that in some quarters it still remains a moot point whether a whale be a fish. In his System of Nature, A. D. , Linnaeus declares, I hereby separate the whales from the fish. But of my own knowledge, I know that down to the year , sharks and shad, alewives and herring, against Linnaeus's express edict, were still found dividing the possession of the same seas with the Leviathan. The grounds upon which Linnaeus would fain have banished ..

the whales from the waters, he states as follows: On account of their warm bilocular heart, their lungs, their movable eyelids, their hollow ears, penem intrantem feminam mammis lactantem, and finally, ex lege naturae jure meritoque. I submitted all this to my friends Simeon Macey and Charley Coffin, of Nantucket, both messmates of mine in a certain voyage, and they united in the opinion that the reasons set forth were altogether insufficient. Charley profanely hinted they were humbug. Be it known that, waiving all argument, I take the good old fashioned ground that the whale is a fish, and call upon holy Jonah to back me. This fundamental thing settled, the next point is, in what internal respect does the whale differ from other fish. Above, Linnaeus has given you those items. But in brief, they are these: lungs and warm blood; whereas, all other fish are lungless and cold blooded. Next: how shall we define the whale, by his obvious externals, so as conspicuously to label him for all time to come? To be short, then, a whale is a spouting fish with a horizontal tail. There you have him. However contracted, that definition is the result of expanded meditation. A walrus spouts much like a whale, but the walrus is not a fish, because he is amphibious. but the last term of the definition is still more cogent, as coupled with the first. Almost any one must have noticed that all the fish familiar to landsmen have not a flat, but a vertical, or up-and-down tail. Whereas, among spouting fish the tail, though it may be similarly shaped, invariably assumes a horizontal position. By the above definition of what a whale is, I do by no means exclude from the leviathanic brotherhood any sea creature hitherto identified with the whale by the best informed Nantucketers; nor, on the other hand, link with it any fish hitherto authoritatively regarded as alien. Hence, all the smaller, spouting, ..

and horizontal tailed fish must be included in this ground-plan of Cetology. Now, then, come the grand divisions of the entire whale host. First: According to magnitude I divide the whales into three primary BOOKS (subdivisible into Chapters), and these shall comprehend them all, both small and large. I. The FOLIO WHALE; II. the OCTAVO WHALE; III. the DUODECIMO WHALE. As the type of the FOLIO I present the Sperm Whale; of the OCTAVO, the Grampus; of the DUODECIMO, the Porpoise. FOLIOS. Among these I here include the following chapters: -- I. The Sperm Whale; II. the Right Whale; III. the Fin Back Whale; IV. the Hump-backed Whale; V. the Razor Back Whale; VI. the Sulphur Bottom Whale. BOOK I. ( Folio), CHAPTER I. ( Sperm Whale). --This whale, among the English of old vaguely known as the Trumpa whale, and the Physeter whale, and the Anvil Headed whale, is the present Cachalot of the French, and the Pottsfich of the Germans, and the Macrocephalus of the Long Words. He is, without doubt, the largest inhabitant of the globe; the most formidable of all whales to encounter; the most majestic in aspect; and lastly, by far the most valuable in commerce; he being the only creature from which that valuable substance, spermaceti, is obtained. All his peculiarities will, in many other places, be enlarged upon. It is chiefly with his name that I now have to do. Philologically considered, it is absurd. Some centuries ago, when the Sperm whale was almost wholly unknown in his own proper individuality, and when his oil was only accidentally obtained from the stranded fish; in those days spermaceti, it would seem, was popularly supposed to be derived from a creature identical with the one then known in England as the Greenland or Right Whale. It was the idea also, that this same spermaceti was that quickening humor of the Greenland Whale which the first syllable of the word literally expresses. In those times, also, spermaceti was exceedingly scarce, not being used for light, but only as an ointment and medicament. It was only to be had from the druggists as you nowadays buy an ounce of rhubarb. When, as I opine, in the course of time, the true nature of spermaceti became ..

known, its original name was still retained by the dealers; no doubt to enhance its value by a notion so strangely significant of its scarcity. And so the appellation must at last have come to be bestowed upon the whale from which this spermaceti was really derived. BOOK I. ( Folio), CHAPTER II. ( Right Whale).--In one respect this is the most venerable of the leviathans, being the one first regularly hunted by man. It yields the article commonly known as whalebone or baleen; and the oil specially known as whale oil, an inferior article in commerce. Among the fishermen, he is indiscriminately designated by all the following titles: The Whale; the Greenland Whale; the Black Whale; the Great Whale; the True Whale; the Right whale. there is a deal of obscurity concerning the identity of the species thus multitudinously baptized. What then is the whale, which I include in the second species of my Folios? It is the Great Mysticetus of the English naturalists; the Greenland Whale of the English Whalemen; the Baliene Ordinaire of the French whalemen; the Growlands Walfish of the Swedes. It is the whale which for more than two centuries past has been hunted by the Dutch and English in the Arctic seas; it is the whale which the American fishermen have long pursued in the Indian ocean, on the Brazil Banks, on the Nor' West Coast, and various other parts of the world, designated by them Right Whale Cruising Grounds. Some pretend to see a difference between the Greenland whale of the English and the right whale of the Americans. But they precisely agree in all their grand features; nor has there yet been presented a single determinate fact upon which to ground a radical distinction. It is by endless subdivisions based upon the most inconclusive differences, that some departments of natural history become so repellingly intricate. The right whale will be elsewhere treated of at some length, with reference to elucidating the sperm whale. BOOK I. ( Folio), CHAPTER III. ( Fin-Back). --Under this head I reckon a monster which, by the various names of Fin-Back, Tall-Spout, and Long-John, has been seen almost in every sea and is commonly the whale whose distant jet is so often descried by passengers crossing the Atlantic, in the New York ..

packet-tracks. In the length he attains, and in his baleen, the Fin-back resembles the right whale, but is of a less portly girth, and a lighter color, approaching to olive. His great lips present a cable-like aspect, formed by the intertwisting, slanting folds of large wrinkles. His grand distinguishing feature, the fin, from which he derives his name, is often a conspicuous object. this fin is some three or four feet long, growing vertically from the hinder part of the back, of an angular shape, and with a very sharp pointed end. Even if not the slightest other part of the creature be visible, this isolated fin will, at times, be seen plainly projecting from the surface. When the sea is moderately calm, and slightly marked with spherical ripples, and this gnomon-like fin stands up and casts shadows upon the wrinkled surface, it may well be supposed that the watery circle surrounding it somewhat resembles a dial, with its style and wavy hour-lines graved on it. On that Ahaz-dial the shadow often goes back. The Fin-Back is not gregarious. He seems a whale-hater, as some men are man-haters. Very shy; always going solitary; unexpectedly rising to the surface in the remotest and most sullen waters; his straight and single lofty jet rising like a tall misanthropic spear upon a barren plain; gifted with such wondrous power and velocity in swimming, as to defy all present pursuit from man; this leviathan seems the banished and unconquerable Cain of his race, bearing for his mark that style upon his back. From having the baleen in his mouth, the Fin-Back is sometimes included with the right whale, among a theoretic species denominated Whalebone whales, that is, whales with baleen. Of these so called Whalebone whales, there would seem to be several varieties, most of which, however, are little known. Broad-nosed whales and beaked whales; pike-headed whales; bunched whales; under-jawed whales and rostrated whales, are the fishermen's names for a few sorts. In connexion with this appellative of Whalebone whales , it is of great importance to mention, that however such a nomenclature may be convenient in facilitating allusions to some kind of whales, yet it is in vain to attempt a clear classification of the Leviathan, founded upon either his baleen, or hump, or fin, or teeth; notwithstanding that those marked parts or features very ..

obviously seem better adapted to afford the basis for a regular system of Cetology than any other detached bodily distinctions, which the whale, in his kinds, presents. How then? The baleen, hump, back-fin, and teeth; these are things whose peculiarities are indiscriminately dispersed among all sorts of whales, without any regard to what may be the nature of their structure in other and more essential particulars. Thus, the sperm whale and the humpbacked whale, each has a hump; but there the similitude ceases. Then, this same humpbacked whale and the Greenland whale, each of these has baleen; but there again the similitude ceases. And it is just the same with the other parts above mentioned. In various sorts of whales, they form such irregular combinations; or, in the case of any one of them detached, such an irregular isolation; as utterly to defy all general methodization formed upon such a basis. On this rock every one of the whale-naturalists has split. But it may possibly be conceived that, in the internal parts of the whale, in his anatomy --there, at least, we shall be able to hit the right classification. Nay; what thing, for example, is there in the Greenland whale's anatomy more striking than his baleen? Yet we have seen that by his baleen it is impossible correctly to classify the Greenland whale. And if you descend into the bowels of the various leviathans, why there you will not find distinctions a fiftieth part as available to the systematizer as those external ones already enumerated. What then remains? nothing but to take hold of the whales bodily, in their entire liberal volume, and boldly sort them that way. And this is the Bibliographical system here adopted; and it is the only one that can possibly succeed, for it alone is practicable. To proceed. book i. ( folio), chapter iv. ( hump back). --this whale is often seen on the northern American coast. He has been frequently captured there, and towed into harbor. He has a great pack on him like a peddler; or you might call him the Elephant and Castle whale. At any rate, the popular name for him does not sufficiently distinguish him, since the sperm whale also has a hump, though a smaller one. His oil is not very valuable. He has baleen. He is the most gamesome and light-hearted of all ..

the whales, making more gay foam and white water generally than any other of them. BOOK I. ( Folio), CHAPTER V. ( Razor Back). --Of this whale little is known but his name. I have seen him at a distance off Cape Horn. Of a retiring nature, he eludes both hunters and philosophers. Though no coward, he has never yet shown any part of him but his back, which rises in a long sharp ridge. Let him go. I know little more of him, nor does anybody else. BOOK I. ( Folio), CHAPTER VI. ( Sulphur Bottom). -- Another retiring gentleman, with a brimstone belly, doubtless got by scraping along the Tartarian tiles in some of his profounder divings. He is seldom seen; at least I have never seen him except in the remoter southern seas, and then always at too great a distance to study his countenance. He is never chased; he would run away with rope-walks of line. Prodigies are told of him. Adieu, Sulphur Bottom! I can say nothing more that is true of ye, nor can the oldest Nantucketer. Thus ends BOOK I. ( Folio), and now begins BOOK II. ( octavo). OCTAVOES. These embrace the whales of middling magnitude, among which at present may be numbered: --I., the Grampus; II., the Black Fish; III., the Narwhale; IV., the Thrasher; V., the Killer. BOOK II. ( Octavo), CHAPTER I. ( Grampus). --Though this fish, whose loud sonorous breathing, or rather blowing, has furnished a proverb to landsmen, is so well known a denizen of the deep, yet is he not popularly classed among whales. But possessing all the grand distinctive features of the leviathan, most naturalists have recognised him for one. He is of moderate octavo size, varying from fifteen to twenty-five feet in length, and of corresponding dimensions round the waist. He swims in herds; he is never regularly hunted, though his oil is considerable ..

in quantity, and pretty good for light. By some fishermen his approach is regarded as premonitory of the advance of the great sperm whale. BOOK II. ( Octavo), CHAPTER II. ( Black Fish). --I give the popular fishermen's names for all these fish, for generally they are the best. Where any name happens to be vague or inexpressive, I shall say so, and suggest another. I do so now, touching the Black Fish, so called, because blackness is the rule among almost all whales. So, call him the Hyena Whale, if you please. His voracity is well known, and from the circumstance that the inner angles of his lips are curved upwards, he carries an everlasting Mephistophelean grin on his face. This whale averages some sixteen or eighteen feet in length. He is found in almost all latitudes. He has a peculiar way of showing his dorsal hooked fin in swimming, which looks something like a Roman nose. When not more profitably employed, the sperm whale hunters sometimes capture the Hyena whale, to keep up the supply of cheap oil for domestic employment --as some frugal housekeepers, in the absence of company, and quite alone by themselves, burn unsavory tallow instead of odorous wax. Though their blubber is very thin, some of these whales will yield you upwards of thirty gallons of oil. BOOK II. ( Octavo), CHAPTER III. ( Narwhale), that is, Nostril whale. --Another instance of a curiously named whale, so named I suppose from his peculiar horn being originally mistaken for a peaked nose. The creature is some sixteen feet in length, while its horn averages five feet, though some exceed ten, and even attain to fifteen feet. Strictly speaking, this horn is but a lengthened tusk, growing out from the jaw in a line a little depressed from the horizontal. But it is only found on the sinister side, which has an ill effect, giving its owner something analogous to the aspect of a clumsy left-handed man. What precise purpose this ivory horn or lance answers, it would be hard to say. It does not seemed to be used like the blade of the sword-fish and bill-fish; though some sailors tell me that the Narwhale employs it for a rake in turning over the bottom of the sea for food. Charley Coffin said it was used for an ice-piercer; for the Narwhale, rising to the surface of the Polar Sea, ..

and finding it sheeted with ice, thrusts his horn up, and so breaks through. But you cannot prove either of these surmises to be correct. My own opinion is, that however this one-sided horn may really be used by the Narwhale --however that may be --it would certainly be very convenient to him for a folder in reading pamphlets. The Narwhale I have heard called the Tusked whale, the Horned whale, and the Unicorn whale. He is certainly a curious example of the Unicornism to be found in almost every kingdom of animated nature. From certain cloistered old authors I have gathered that this same sea-unicorn's horn was in ancient days regarded as the great antidote against poison, and as such, preparations of it brought immense prices. It was also distilled to a volatile salts for fainting ladies, the same way that the horns of the male deer are manufactured into hartshorn. Originally it was in itself accounted an object of great curiosity. Black Letter tells me that Sir Martin Frobisher on his return from that voyage, when Queen Bess did gallantly wave her jewelled hand to him from a window of Greenwich Palace, as his bold ship sailed down the Thames; when Sir Martin returned from that voyage, saith Black Letter, on bended knees he presented to her highness a prodigious long horn of the Narwhale, which for a long period after hung in the castle at Windsor. An Irish author avers that the Earl of Leicester, on bended knees, did likewise present to her highness another horn, pertaining to a land beast of the unicorn nature. The Narwhale has a very picturesque, leopard-like look, being of a milk-white ground color, dotted with round and oblong spots of black. His oil is very superior, clear and fine; but there is little of it, and he is seldom hunted. He is mostly found in the circumpolar seas. BOOK II. ( Octavo), CHAPTER IV. ( Killer). --Of this whale little is precisely known to the Nantucketer, and nothing at all to the professed naturalist. From what I have seen of him at a distance, I should say that he was about the bigness of a grampus. He is very savage --a sort of Feegee fish. He sometimes takes the great Folio whales by the lip, and hangs there like a leech, till the mighty brute is worried to death. The Killer is never hunted. I never heard what sort of oil he has. Exception ..

might be taken to the name bestowed upon this whale, on the ground of its indistinctness. For we are all killers, on land and on sea; Bonapartes and Sharks included. BOOK II. ( Octavo), CHAPTER V. ( Thrasher). --This gentleman is famous for his tail, which he uses for a ferule in thrashing his foes. He mounts the Folio whale's back, and as he swims, he works his passage by flogging him; as some schoolmasters get along in the world by a similar process. Still less is known of the Thrasher than of the Killer. Both are outlaws, even in the lawless seas. thus ends book II. ( Octavo), and begins BOOK III. ( Duodecimo). DUODECIMOES. --These include the smaller whales. I. The Huzza Porpoise. II. The Algerine Porpoise. III. The Mealy-mouthed Porpoise. To those who have not chanced specially to study the subject, it may possibly seem strange, that fishes not commonly exceeding four or five feet should be marshalled among WHALES --a word, which, in the popular sense, always conveys an idea of hugeness. But the creatures set down above as Duodecimoes are infallibly whales, by the terms of my definition of what a whale is --i. e. a spouting fish, with a horizontal tail. BOOK III. ( Duodecimo), CHAPTER I ( Huzza Porpoise). -- This is the common porpoise found almost all over the globe. The name is of my own bestowal; for there are more than one sort of porpoises, and something must be done to distinguish them. I call them thus, because he always swims in hilarious shoals, which upon the broad sea keep tossing themselves to heaven like caps in a Fourth-of-July crowd. Their appearance is generally hailed with delight by the mariner. Full of fine spirits, they invariably come from the breezy billows to windward. They are the lads that always live before the wind. They are accounted a lucky omen. If you yourself can withstand three cheers at beholding these vivacious fish, then heaven help ye; the spirit of godly gamesomeness is not in ye. A well-fed, plump Huzza Porpoise will yield you one good gallon of good oil. But the fine and delicate fluid extracted from his jaws is exceedingly valuable. It is in request among jewellers and watchmakers. ..

Sailors put it on their hones. Porpoise meat is good eating, you know. It may never have occurred to you that a porpoise spouts. Indeed, his spout is so small that it is not very readily discernible. But the next time you have a chance, watch him; and you will then see the great Sperm whale himself in miniature. BOOK III. ( Duodecimo), CHAPTER II. ( Algerine Porpoise). -- A pirate. Very savage. He is only found, I think, in the Pacific. He is somewhat larger than the Huzza Porpoise, but much of the same general make. Provoke him, and he will buckle to a shark. I have lowered for him many times, but never yet saw him captured. BOOK III. ( Duodecimo), CHAPTER III. ( Mealy-mouthed Porpoise). The largest kind of Porpoise; and only found in the Pacific, so far as it is known. The only English name, by which he has hitherto been designated, is that of the fishers -- Right-Whale Porpoise, from the circumstance that he is chiefly found in the vicinity of that Folio. In shape, he differs in some degree from the Huzza Porpoise, being of a less rotund and jolly girth; indeed, he is of quite a neat and gentleman-like figure. He has no fins on his back (most other porpoises have), he has a lovely tail, and sentimental Indian eyes of a hazel hue. But his mealy-mouth spoils all. Though his entire back down to his side fins is of a deep sable, yet a boundary line, distinct as the mark in a ship's hull, called the bright waist, that line streaks him from stem to stern, with two separate colors, black above and white below. The white comprises part of his head, and the whole of his mouth, which makes him look as if he had just escaped from a felonious visit to a meal-bag. A most mean and mealy aspect! His oil is much like that of the common porpoise. Beyond the DUODECIMO, this system does not proceed, inasmuch as the Porpoise is the smallest of the whales. Above, you have all the Leviathans of note. But there are a rabble of uncertain, fugitive, half-fabulous whales, which, as an American whaleman, I know by reputation, but not personally. I shall enumerate them by their forecastle appellations; for possibly such a list may be valuable to future investigators, who may complete what I have here but begun. If any of the following ..

whales, shall hereafter be caught and marked, then he can readily be incorporated into this System, according to his Folio, Octavo, or Duodecimo magnitude: --The Bottle-Nose Whale; the Junk Whale; the Pudding-Headed Whale; the Cape Whale; the Leading Whale; the Cannon Whale; the Scragg Whale; the Coppered Whale; the Elephant Whale; the Iceberg Whale; the Quog Whale; the Blue Whale; etc. From Icelandic, Dutch, and old English authorities, there might be quoted other lists of uncertain whales, blessed with all manner of uncouth names. But I omit them as altogether obsolete; and can hardly help suspecting them for mere sounds, full of Leviathanism, but signifying nothing. Finally: It was stated at the outset, that this system would not be here, and at once, perfected. You cannot but plainly see that I have kept my word. But I now leave my cetological System standing thus unfinished, even as the great Cathedral of Cologne was left, with the crane still standing upon the top of the uncompleted tower. For small erections may be finished by their first architects; grand ones, true ones, ever leave the copestone to posterity. God keep me from ever completing anything. This whole book is but a draught --nay, but the draught of a draught. Oh Time, Strength, Cash, and Patience! ..

I am aware that down to the present time, the fish styled Lamatins and Dugongs (Pig-fish and Sow-fish of the Coffins of Nantucket) are included by many naturalists among the whales. But as these pig-fish are a nosy, contemptible set, mostly lurking in the mouths of rivers, and feeding on wet hay, and especially as they do not spout, I deny their credentials as whales; and have presented them with their passports to quit the kingdom of Cetology. ..

Why this book of whales is not denominated the Quarto is very plain. Because, while the whales of this order, though smaller than those of the former order, nevertheless retain a proportionate likeness to them in figure, yet the bookbinder's Quarto volume in its diminished form does not preserve the shape of the Folio volume, but the Octavo volume does. ..

.. < chapter xxxiii 24 THE SPECKSYNDER > Concerning the officers of the whale-craft, this seems as good a place as any to set down a little domestic peculiarity on ship-board, arising from the existence of the harpooneer class of officers, a class unknown of course in any other marine than the whale-fleet. The large importance attached to the harpooneer's vocation is evinced by the fact, that originally in the old Dutch Fishery, two centuries and more ago, the command of a whale ship was ..

not wholly lodged in the person now called the captain, but was divided between him and an officer called the Specksynder. Literally this word means Fat-Cutter; usage, however, in time made it equivalent to Chief Harpooneer. In those days, the captain's authority was restricted to the navigation and general management of the vessel: while over the whale-hunting department and all its concerns, the Specksynder or Chief Harpooneer reigned supreme. In the British Greenland Fishery, under the corrupted title of Specksioneer, this old Dutch official is still retained, but his former dignity is sadly abridged. At present he ranks simply as senior Harpooneer; and as such, is but one of the captain's more inferior subalterns. Nevertheless, as upon the good conduct of the harpooneers the success of a whaling voyage largely depends, and since in the American Fishery he is not only an important officer in the boat, but under certain circumstances (night watches on a whaling ground) the command of the ship's deck is also his; therefore the grand political maxim of the sea demands, that he should nominally live apart from the men before the mast, and be in some way distinguished as their professional superior; though always, by them, familiarly regarded as their social equal. Now, the grand distinction drawn between officer and man at sea, is this--the first lives aft, the last forward. Hence, in whale-ships and merchantmen alike, the mates have their quarters with the captain; and so, too, in most of the American whalers the harpooneers are lodged in the after part of the ship. That is to say, they take their meals in the captain's cabin, and sleep in a place indirectly communicating with it. Though the long period of a Southern whaling voyage (by far the longest of all voyages now or ever made by man), the peculiar perils of it, and the community of interest prevailing among a company, all of whom, high or low, depend for their profits, not upon fixed wages, but upon their common luck, together with their common vigilance, intrepidity, and hard work; though all these things do in some cases tend to beget a less rigorous discipline than in merchantmen generally; yet, never mind how much like an old Mesopotamian family these whalemen may, in some primitive instances, live together; for all that, ..

the punctilious externals, at least, of the quarter-deck are seldom materially relaxed, and in no instance done away. Indeed, many are the Nantucket ships in which you will see the skipper parading his quarter-deck with an elated grandeur not surpassed in any military navy; nay, extorting almost as much outward homage as if he wore the imperial purple, and not the shabbiest of pilot-cloth. And though of all men the moody captain of the Pequod was the least given to that sort of shallowest assumption; and though the only homage he ever exacted, was implicit, instantaneous obedience; though he required no man to remove the shoes from his feet ere stepping upon the quarter-deck; and though there were times when, owing to peculiar circumstances connected with events hereafter to be detailed, he addressed them in unusual terms, whether of condescension or in terrorem, or otherwise; yet even Captain Ahab was by no means unobservant of the paramount forms and usages of the sea. Nor, perhaps, will it fail to be eventually perceived, that behind those forms and usages, as it were, he sometimes masked himself; incidentally making use of them for other and more private ends than they were legitimately intended to subserve. That certain sultanism of his brain, which had otherwise in a good degree remained unmanifested; through those forms that same sultanism became incarnate in an irresistible dictatorship. For be a man's intellectual superiority what it will, it can never assume the practical, available supremacy over other men, without the aid of some sort of external arts and entrenchments, always, in themselves, more or less paltry and base. This it is, that for ever keeps God's true princes of the Empire from the world's hustings; and leaves the highest honors that this air can give, to those men who become famous more through their infinite inferiority to the choice hidden handful of the Divine Inert, than through their undoubted superiority over the dead level of the mass. Such large virtue lurks in these small things when extreme political superstitions invest them, that in some royal instances even to idiot imbecility they have imparted potency. But when, as in the case of Nicholas the Czar, the ringed crown of geographical empire encircles an imperial brain; ..

then, the plebeian herds crouch abased before the tremendous centralization. Nor, will the tragic dramatist who would depict mortal indomitableness in its fullest sweep and direct swing, ever forget a hint, incidentally so important in his art, as the one now alluded to. But Ahab, my Captain, still moves before me in all his Nantucket grimness and shagginess; and in this episode touching Emperors and Kings, I must not conceal that I have only to do with a poor old whale-hunter like him; and, therefore, all outward majestical trappings and housings are denied me. Oh, Ahab! what shall be grand in thee, it must needs be plucked at from the skies, and dived for in the deep, and featured in the unbodied air! ..

.. < chapter xxxiv 15 THE CABIN-TABLE > It is noon; and Dough-Boy, the steward, thrusting his pale loaf-of-bread face from the cabin-scuttle, announces dinner to his lord and master; who, sitting in the lee quarter-boat, has just been taking an observation of the sun; and is now mutely reckoning the latitude on the smooth, medallion-shaped tablet, reserved for that daily purpose on the upper part of his ivory leg. From his complete inattention to the tidings, you would think that moody Ahab had not heard his menial. But presently, catching hold of the mizen shrouds, he swings himself to the deck, and in an even, unexhilarated voice, saying, Dinner, Mr. Starbuck, disappears into the cabin. When the last echo of his sultan's step has died away, and Starbuck, the first Emir, has every reason to suppose that he is seated, then Starbuck rouses from his quietude, takes a few turns along the planks, and, after a grave peep into the binnacle, says, with some touch of pleasantness, Dinner, Mr. Stubb, and descends the scuttle. The second Emir lounges about the rigging ..

awhile, and then slightly shaking the main brace, to see whether it be all right with that important rope, he likewise takes up the old burden, and with a rapid Dinner, Mr. Flask, follows after his predecessors. But the third emir, now seeing himself all alone on the quarter-deck, seems to feel relieved from some curious restraint; for, tipping all sorts of knowing winks in all sorts of directions, and kicking off his shoes, he strikes into a sharp but noiseless squall of a hornpipe right over the Grand Turk's head; and then, by a dexterous sleight, pitching his cap up into the mizentop for a shelf, he goes down rollicking, so far at least as he remains visible from the deck, reversing all other processions, by bringing up the rear with music. But ere stepping into the cabin doorway below, he pauses, ships a new face altogether, and, then, independent, hilarious little Flask enters King Ahab's presence, in the character of Abjectus, or the Slave. It is not the least among the strange things bred by the intense artificialness of sea-usages, that while in the open air of the deck some officers will, upon provocation, bear themselves boldly and defyingly enough towards their commander; yet, ten to one, let those very officers the next moment go down to their customary dinner in that same commander's cabin, and straightway their inoffensive, not to say deprecatory and humble air towards him, as he sits at the head of the table; this is marvellous, sometimes most comical. Wherefore this difference? A problem? Perhaps not. To have been Belshazzar, King of Babylon; and to have been Belshazzar, not haughtily but courteously, therein certainly must have been some touch of mundane grandeur. But he who in the rightly regal and intelligent spirit presides over his own private dinner-table of invited guests, that man's unchallenged power and dominion of individual influence for the time; that man's royalty of state transcends Belshazzar's, for Belshazzar was not the greatest. Who has but once dined his friends, has tasted what it is to be Caesar. It is a witchery of social czarship which there is no withstanding. Now, if to this consideration you superadd the official supremacy of a ship-master, then, by inference, you will derive the cause of that peculiarity of sea-life just mentioned. ..

Over his ivory-inlaid table, Ahab presided like a mute, maned sea-lion on the white coral beach, surrounded by his warlike but still deferential cubs. In his own proper turn, each officer waited to be served. They were as little children before Ahab; and yet, in Ahab, there seemed not to lurk the smallest social arrogance. With one mind, their intent eyes all fastened upon the old man's knife, as he carved the chief dish before him. I do not suppose that for the world they would have profaned that moment with the slightest observation, even upon so neutral a topic as the weather. No! And when reaching out his knife and fork, between which the slice of beef was locked, Ahab thereby motioned Starbuck's plate towards him, the mate received his meat as though receiving alms; and cut it tenderly; and a little started if, perchance, the knife grazed against the plate; and chewed it noiselessly; and swallowed it, not without circumspection. For, like the Coronation banquet at Frankfort, where the German Emperor profoundly dines with the seven Imperial Electors, so these cabin meals were somehow solemn meals, eaten in awful silence; and yet at table old Ahab forbade not conversation; only he himself was dumb. What a relief it was to choking Stubb, when a rat made a sudden racket in the hold below. And poor little Flask, he was the youngest son, and little boy of this weary family party. His were the shinbones of the saline beef; his would have been the drumsticks. For Flask to have presumed to help himself, this must have seemed to him tantamount to larceny in the first degree. Had he helped himself at that table, doubtless, never more would he have been able to hold his head up in this honest world; nevertheless, strange to say, Ahab never forbade him. And had Flask helped himself, the chances were Ahab had never so much as noticed it. Least of all, did flask presume to help himself to butter. Whether he thought the owners of the ship denied it to him, on account of its clotting his clear, sunny complexion; or whether he deemed that, on so long a voyage in such marketless waters, butter was at a premium, and therefore was not for him, a subaltern; however it was, Flask, alas! was a butterless man! Another thing. Flask was the last person down at the dinner, ..

and Flask is the first man up. Consider! For hereby Flask's dinner was badly jammed in point of time. Starbuck and Stubb both had the start of him; and yet they also have the privilege of lounging in the rear. If Stubb even, who is but a peg higher than Flask, happens to have but a small appetite, and soon shows symptoms of concluding his repast, then Flask must bestir himself, he will not get more than three mouthfuls that day; for it is against holy usage for Stubb to precede Flask to the deck. Therefore it was that Flask once admitted in private, that ever since he had arisen to the dignity of an officer, from that moment he had never known what it was to be otherwise than hungry, more or less. For what he ate did not so much relieve his hunger, as keep it immortal in him. Peace and satisfaction, thought Flask, have for ever departed from my stomach. I am an officer; but, how I wish I could fist a bit of old-fashioned beef in the forecastle, as I used to when I was before the mast. There's the fruits of promotion now; there's the vanity of glory: there's the insanity of life! Besides, if it were so that any mere sailor of the Pequod had a grudge against Flask in Flask's official capacity, all that sailor had to do, in order to obtain ample vengeance, was to go aft at dinner-time, and get a peep at Flask through the cabin sky-light, sitting silly and dumfoundered before awful Ahab. Now, Ahab and his three mates formed what may be called the first table in the Pequod's cabin. After their departure, taking place in inverted order to their arrival, the canvas cloth was cleared, or rather was restored to some hurried order by the pallid steward. And then the three harpooneers were bidden to the feast, they being its residuary legatees. They made a sort of temporary servants' hall of the high and mighty cabin. In strange contrast to the hardly tolerable constraint and nameless invisible domineerings of the captain's table, was the entire care-free license and ease, the almost frantic democracy of those inferior fellows the harpooneers. While their masters, the mates, seemed afraid of the sound of the hinges of their own jaws, the harpooneers chewed their food with such a relish that there was a report to it. They dined like lords; they filled their bellies like Indian ships all day loading with spices. Such portentous ..

appetites had Queequeg and Tashtego, that to fill out the vacancies made by the previous repast, often the pale Dough-Boy was fain to bring on a great baron of salt-junk, seemingly quarried out of the solid ox. And if he were not lively about it, if he did not go with a nimble hop-skip-and-jump, then Tashtego had an ungentlemanly way of accelerating him by darting a fork at his back, harpoonwise. And once Daggoo, seized with a sudden humor, assisted Dough-Boy's memory by snatching him up bodily, and thrusting his head into a great empty wooden trencher, while Tashtego, knife in hand, began laying out the circle preliminary to scalping him. He was naturally a very nervous, shuddering sort of little fellow, this bread-faced steward; the progeny of a bankrupt baker and a hospital nurse. And what with the standing spectacle of the black terrific Ahab, and the periodical tumultuous visitations of these three savages, Dough-Boy's whole life was one continual lip-quiver. Commonly, after seeing the harpooneers furnished with all things they demanded, he would escape from their clutches into his little pantry adjoining, and fearfully peep out at them through the blinds of its door, till all was over. It was a sight to see Queequeg seated over against Tashtego, opposing his filed teeth to the Indian's: crosswise to them, Daggoo seated on the floor, for a bench would have brought his hearse-plumed head to the low carlines; at every motion of his colossal limbs, making the low cabin framework to shake, as when an African elephant goes passenger in a ship. But for all this, the great negro was wonderfully abstemious, not to say dainty. It seemed hardly possible that by such comparatively small mouthfuls he could keep up the vitality diffused through so broad, baronial, and superb a person. But, doubtless, this noble savage fed strong and drank deep of the abounding element of air; and through his dilated nostrils snuffed in the sublime life of the worlds. Not by beef or by bread, are giants made or nourished. But Queequeg, he had a mortal, barbaric smack of the lip in eating --an ugly sound enough --so much so, that the trembling Dough-Boy almost looked to see whether any marks of teeth lurked in his own lean arms. And when he would hear Tashtego singing out for him to produce himself, ..

that his bones might be picked, the simple-witted Steward all but shattered the crockery hanging round him in the pantry, by his sudden fits of the palsy. Nor did the whetstone which the harpooneers carried in their pockets, for their lances and other weapons; and with which whetstones, at dinner, they would ostentatiously sharpen their knives; that grating sound did not at all tend to tranquillize poor Dough-Boy. How could he forget that in his Island days, Queequeg, for one, must certainly have been guilty of some murderous, convivial indiscretions. Alas! Dough-Boy! hard fares the white waiter who waits upon cannibals. Not a napkin should he carry on his arm, but a buckler. in good time, though, to his great delight, the three salt-sea warriors would rise and depart; to his credulous, fable-mongering ears, all their martial bones jingling in them at every step, like Moorish scimetars in scabbards. But, though these barbarians dined in the cabin, and nominally lived there; still, being anything but sedentary in their habits, they were scarcely ever in it except at meal-times, and just before sleeping-time, when they passed through it to their own peculiar quarters. In this one matter, Ahab seemed no exception to most American whale captains, who, as a set, rather incline to the opinion that by rights the ship's cabin belongs to them; and that it is by courtesy alone that anybody else is, at any time, permitted there. So that, in real truth, the mates and harpooneers of the Pequod might more properly be said to have lived out of the cabin than in it. For when they did enter it, it was something as a street-door enters a house; turning inwards for a moment, only to be turned out the next; and, as a permanent thing, residing in the open air. Nor did they lose much hereby; in the cabin was no companionship; socially, Ahab was inaccessible. Though nominally included in the census of Christendom, he was still an alien to it. He lived in the world, as the last of the Grisly Bears lived in settled Missouri. And as when Spring and Summer had departed, that wild Logan of the woods, burying himself in the hollow of a tree, lived out the winter there, sucking his own paws; so, in his inclement, howling old age, Ahab's soul, shut up in the caved trunk of his body, there fed upon the sullen paws of its gloom! ..

.. < chapter xxxv 2 THE MAST-HEAD > It was during the more pleasant weather, that in due rotation with the other seamen my first mast-head came round. In most American whalemen the mast-heads are manned almost simultaneously with the vessel's leaving her port; even though she may have fifteen thousand miles, and more, to sail ere reaching her proper cruising ground. and if, after a three, four, or five years' voyage she is drawing nigh home with anything empty in her --say, an empty vial even --then, her mast-heads are kept manned to the last; and not till her skysail-poles sail in among the spires of the port, does she altogether relinquish the hope of capturing one whale more. Now, as the business of standing mast-heads, ashore or afloat, is a very ancient and interesting one, let us in some measure expatiate here. I take it, that the earliest standers of mast-heads were the old Egyptians; because, in all my researches, I find none prior to them. For though their progenitors, the builders of Babel, must doubtless, by their tower, have intended to rear the loftiest mast-head in all Asia, or Africa either; yet (ere the final truck was put to it) as that great stone mast of theirs may be said to have gone by the board, in the dread gale of God's wrath; therefore, we cannot give these Babel builders priority over the Egyptians. And that the Egyptians were a nation of mast-head standers, is an assertion based upon the general belief among archaeologists, that the first pyramids were founded for astronomical purposes: a theory singularly supported by the peculiar stair-like formation of all four sides of those edifices; whereby, with prodigious long upliftings of their legs, those old astronomers were wont to mount to the apex, and sing out for new stars; even as the look-outs of a modern ship sing out for a sail, or a whale just bearing in sight. In Saint Stylites, the famous Christian hermit of old times, who built him a lofty stone pillar in the desert and spent the whole latter portion of ..

his life on its summit, hoisting his food from the ground with a tackle; in him we have a remarkable instance of a dauntless stander-of-mast-heads; who was not to be driven from his place by fogs or frosts, rain, hail, or sleet; but valiantly facing everything out to the last, literally died at his post. Of modern standers-of-mast-heads we have but a lifeless set; mere stone, iron, and bronze men; who, though well capable of facing out a stiff gale, are still entirely incompetent to the business of singing out upon discovering any strange sight. There is Napoleon; who, upon the top of the column of Vendome, stands with arms folded, some one hundred and fifty feet in the air; careless, now, who rules the decks below; whether Louis Philippe, Louis Blanc, or Louis the Devil. Great Washington, too, stands high aloft on his towering main-mast in Baltimore, and like one of Hercules' pillars, his column marks that point of human grandeur beyond which few mortals will go. Admiral Nelson, also, on a capstan of gun-metal, stands his mast-head in Trafalgar Square; and ever when most obscured by that London smoke, token is yet given that a hidden hero is there; for where there is smoke, must be fire. But neither great Washington, nor Napoleon, nor Nelson, will answer a single hail from below, however madly invoked to befriend by their counsels the distracted decks upon which they gaze; however it may be surmised, that their spirits penetrate through the thick haze of the future, and descry what shoals and what rocks must be shunned. It may seem unwarrantable to couple in any respect the mast-head standers of the land with those of the sea; but that in truth it is not so, is plainly evinced by an item for which Obed Macy, the sole historian of Nantucket, stands accountable. The worthy Obed tells us, that in the early times of the whale fishery, ere ships were regularly launched in pursuit of the game, the people of that island erected lofty spars along the sea-coast, to which the look-outs ascended by means of nailed cleats, something as fowls go upstairs in a hen-house. A few years ago this same plan was adopted by the Bay whalemen of New Zealand, who, upon descrying the game, gave notice to the ready-manned boats nigh the beach. But this custom has now become obsolete; turn we then to the one proper mast-head, that of a whale-ship ..

at sea. The three mast-heads are kept manned from sun-rise to sun-set; the seamen taking their regular turns (as at the helm), and relieving each other every two hours. In the serene weather of the tropics it is exceedingly pleasant the mast-head; nay, to a dreamy meditative man it is delightful. There you stand, a hundred feet above the silent decks, striding along the deep, as if the masts were gigantic stilts, while beneath you and between your legs, as it were, swim the hugest monsters of the sea, even as ships once sailed between the boots of the famous Colossus at old Rhodes. There you stand, lost in the infinite series of the sea, with nothing ruffled but the waves. The tranced ship indolently rolls; the drowsy trade winds blow; everything resolves you into languor. For the most part, in this tropic whaling life, a sublime uneventfulness invests you; you hear no news; read no gazettes; extras with startling accounts of commonplaces never delude you into unnecessary excitements; you hear of no domestic afflictions; bankrupt securities; fall of stocks; are never troubled with the thought of what you shall have for dinner --for all your meals for three years and more are snugly stowed in casks, and your bill of fare is immutable. In one of those southern whalemen, on a long three or four years' voyage, as often happens, the sum of the various hours you spend at the mast-head would amount to several entire months. And it is much to be deplored that the place to which you devote so considerable a portion of the whole term of your natural life, should be so sadly destitute of anything approaching to a cosy inhabitiveness, or adapted to breed a comfortable localness of feeling, such as pertains to a bed, a hammock, a hearse, a sentry box, a pulpit, a coach, or any other of those small and snug contrivances in which men temporarily isolate themselves. Your most usual point of perch is the head of the t' gallant-mast, where you stand upon two thin parallel sticks (almost peculiar to whalemen) called the t' gallant cross-trees. Here, tossed about by the sea, the beginner feels about as cosy as he would standing on a bull's horns. To be sure, in cold weather you may carry your house aloft with you, in the shape of a watch-coat; but properly speaking the thickest watch-coat is no more of a house than the unclad body; for as the soul is glued inside ..

of its fleshly tabernacle, and cannot freely move about in it, nor even move out of it, without running great risk of perishing (like an ignorant pilgrim crossing the snowy Alps in winter); so a watch-coat is not so much of a house as it is a mere envelope, or additional skin encasing you. You cannot put a shelf or chest of drawers in your body, and no more can you make a convenient closet of your watch-coat. Concerning all this, it is much to be deplored that the mast-heads of a southern whale ship are unprovided with those enviable little tents or pulpits, called crow's-nests, in which the lookouts of a Greenland whaler are protected from the inclement weather of the frozen seas. In the fire-side narrative of Captain Sleet, entitled A Voyage among the Icebergs, in quest of the Greenland Whale, and incidentally for the re-discovery of the Lost Icelandic Colonies of Old Greenland; in this admirable volume, all standers of mast-heads are furnished with a charmingly circumstantial account of the then recently invented crow's-nest of the Glacier, which was the name of Captain Sleet's good craft. He called it the Sleet's crow's-nest, in honor of himself; he being the original inventor and patentee, and free from all ridiculous false delicacy, and holding that if we call our own children after our own names (we fathers being the original inventors and patentees), so likewise should we denominate after ourselves any other apparatus we may beget. In shape, the Sleet's crow's-nest is something like a large tierce or pipe; it is open above, however, where it is furnished with a movable side-screen to keep to windward of your head in a hard gale. Being fixed on the summit of the mast, you ascend into it through a little trap-hatch in the bottom. On the after side, or side next the stern of the ship, is a comfortable seat, with a locker underneath for umbrellas, comforters, and coats. In front is a leather rack, in which to keep your speaking trumpet, pipe, telescope, and other nautical conveniences. When Captain Sleet in person stood his mast-head in this crow's nest of his, he tells us that he always had a rifle with him (also fixed in the rack), together with a powder flask and shot, for the purpose of popping off the stray narwhales, or vagrant sea unicorns infesting those waters; for you cannot successfully shoot at them from ..

the deck owing to the resistance of the water, but to shoot down upon them is a very different thing. Now, it was plainly a labor of love for Captain Sleet to describe, as he does, all the little detailed conveniences of his crow's-nest; but though he so enlarges upon many of these, and though he treats us to a very scientific account of his experiments in this crow's-nest, with a small compass he kept there for the purpose of counteracting the errors resulting from what is called the local attraction of all binnacle magnets; an error ascribable to the horizontal vicinity of the iron in the ship's planks, and in the Glacier's case, perhaps, to there having been so many broken-down blacksmiths among her crew; I say, that though the Captain is very discreet and scientific here, yet, for all his learned binnacle deviations, azimuth compass observations, and approximate errors, he knows very well, Captain Sleet, that he was not so much immersed in those profound magnetic meditations, as to fail being attracted occasionally towards that well replenished little case-bottle, so nicely tucked in on one side of his crow's nest, within easy reach of his hand. Though, upon the whole, I greatly admire and even love the brave, the honest, and learned Captain; yet I take it very ill of him that he should so utterly ignore that case-bottle, seeing what a faithful friend and comforter it must have been, while with mittened fingers and hooded head he was studying the mathematics aloft there in that bird's nest within three or four perches of the pole. But if we Southern whale-fishers are not so snugly housed aloft as Captain Sleet and his Greenland-men were; yet that disadvantage is greatly counterbalanced by the widely contrasting serenity of those seductive seas in which we South fishers mostly float. For one, I used to lounge up the rigging very leisurely, resting in the top to have a chat with Queequeg, or any one else off duty whom I might find there; then ascending a little way further, and throwing a lazy leg over the top-sail yard, take a preliminary view of the watery pastures, and so at last mount to my ultimate destination. Let me make a clean breast of it here, and frankly admit that I kept but sorry guard. With the problem of the universe revolving in me, how could I--being left completely to myself ..

at such a thought-engendering altitude, --how could I but lightly hold my obligations to observe all whale-ships' standing orders, Keep your weather eye open, and sing out every time. And let me in this place movingly admonish you, ye ship-owners of Nantucket! Beware of enlisting in your vigilant fisheries any lad with lean brow and hollow eye; given to unseasonable meditativeness; and who offers to ship with the phaedon instead of Bowditch in his head. Beware of such an one, I say; your whales must be seen before they can be killed; and this sunken-eyed young Platonist will tow you ten wakes round the world, and never make you one pint of sperm the richer. Nor are these monitions at all unneeded. For nowadays, the whale-fishery furnishes an asylum for many romantic, melancholy, and absent-minded young men, disgusted with the carking cares of earth, and seeking sentiment in tar and blubber. Childe Harold not unfrequently perches himself upon the mast-head of some luckless disappointed whale-ship, and in moody phrase ejaculates: -- Roll on, thou deep and dark blue ocean, roll! Ten thousand blubber-hunters sweep over thee in vain. Very often do the captains of such ships take those absent-minded young philosophers to task, upbraiding them with not feeling sufficient interest in the voyage; half-hinting that they are so hopelessly lost to all honorable ambition, as that in their secret souls they would rather not see whales than otherwise. But all in vain; those young Platonists have a notion that their vision is imperfect; they are short-sighted; what use, then, to strain the visual nerve? They have left their opera-glasses at home. Why, thou monkey, said a harpooneer to one of these lads, we've been cruising now hard upon three years, and thou hast not raised a whale yet. Whales are scarce as hen's teeth whenever thou art up here. Perhaps they were; or perhaps there might have been shoals of them in the far horizon; but lulled into such an opium-like listlessness of vacant, unconscious reverie is this absent-minded youth by the blending cadence of waves with thoughts, that at last he loses his identity; takes the mystic ..

ocean at his feet for the visible image of that deep, blue, bottomless soul, pervading mankind and nature; and every strange, half-seen, gliding, beautiful thing that eludes him; every dimly-discovered, uprising fin of some undiscernible form, seems to him the embodiment of those elusive thoughts that only people the soul by continually flitting through it. In this enchanted mood, thy spirit ebbs away to whence it came; becomes diffused through time and space; like Cranmer's sprinkled Pantheistic ashes, forming at last a part of every shore the round globe over. There is no life in thee, now, except that rocking life imparted by a gently rolling ship; by her, borrowed from the sea; by the sea, from the inscrutable tides of God. But while this sleep, this dream is on ye, move your foot or hand an inch; slip your hold at all; and your identity comes back in horror. Over Descartian vortices you hover. And perhaps, at mid-day, in the fairest weather, with one half-throttled shriek you drop through that transparent air into the summer sea, no more to rise for ever. Heed it well, ye Pantheists! ..

.. < chapter xxxvi 21 THE QUARTER-DECK > ( enter Ahab: Then, all.) It was not a great while after the affair of the pipe, that one morning shortly after breakfast, Ahab, as was his wont, ascended the cabin-gangway to the deck. There most sea-captains usually walk at that hour, as country gentlemen, after the same meal, take a few turns in the garden. Soon his steady, ivory stride was heard, as to and fro he paced his old rounds, upon planks so familiar to his tread, that they were all over dented, like geological stones, with the peculiar mark of his walk. Did you fixedly gaze, too, upon that ribbed ..

and dented brow; there also, you would see still stranger foot-prints --the foot-prints of his one unsleeping, ever-pacing thought. But on the occasion in question, those dents looked deeper, even as his nervous step that morning left a deeper mark. And, so full of his thought was Ahab, that at every uniform turn that he made, now at the main-mast and now at the binnacle, you could almost see that thought turn in him as he turned, and pace in him as he paced; so completely possessing him, indeed, that it all but seemed the inward mould of every outer movement. D'ye mark him, Flask? whispered Stubb; the chick that's in him pecks the shell. T'will soon be out. The hours wore on; --Ahab now shut up within his cabin; anon, pacing the deck, with the same intense bigotry of purpose in his aspect. It drew near the close of day. Suddenly he came to a halt by the bulwarks, and inserting his bone leg into the auger-hole there, and with one hand grasping a shroud, he ordered Starbuck to send everybody aft. Sir! said the mate, astonished at an order seldom or never given on ship-board except in some extraordinary case. Send everybody aft, repeated Ahab. Mast-heads, there! come down! When the entire ship's company were assembled, and with curious and not wholly unapprehensive faces, were eyeing him, for he looked not unlike the weather horizon when a storm is coming up, Ahab, after rapidly glancing over the bulwarks, and then darting his eyes among the crew, started from his standpoint; and as though not a soul were nigh him resumed his heavy turns upon the deck. With bent head and half-slouched hat he continued to pace, unmindful of the wondering whispering among the men; till Stubb cautiously whispered to Flask, that Ahab must have summoned them there for the purpose of witnessing a pedestrian feat. But this did not last long. Vehemently pausing, he cried: -- What do ye do when ye see a whale, men? Sing out for him! was the impulsive rejoinder from a score of clubbed voices. ..

Good! cried Ahab, with a wild approval in his tones; observing the hearty animation into which his unexpected question had so magnetically thrown them. And what do ye next, men? Lower away, and after him! And what tune is it ye pull to, men? A dead whale or a stove boat! More and more strangely and fiercely glad and approving, grew the countenance of the old man at every shout; while the mariners began to gaze curiously at each other, as if marvelling how it was that they themselves became so excited at such seemingly purposeless questions. But, they were all eagerness again, as Ahab, now half-revolving in his pivot-hole, with one hand reaching high up a shroud, and tightly, almost convulsively grasping it, addressed them thus: -- All ye mast-headers have before now heard me give orders about a white whale. Look ye! d'ye see this Spanish ounce of gold? --holding up a broad bright coin to the sun -- it is a sixteen dollar piece, men. D'ye see it? Mr. Starbuck, hand me yon top-maul. While the mate was getting the hammer, Ahab, without speaking, was slowly rubbing the gold piece against the skirts of his jacket, as if to heighten its lustre, and without using any words was meanwhile lowly humming to himself, producing a sound so strangely muffled and inarticulate that it seemed the mechanical humming of the wheels of his vitality in him. Receiving the top-maul from Starbuck, he advanced towards the main-mast with the hammer uplifted in one hand, exhibiting the gold with the other, and with a high raised voice exclaiming: Whosoever of ye raises me a white-headed whale with a wrinkled brow and a crooked jaw; whosoever of ye raises me that white-headed whale, with three holes punctured in his starboard fluke --look ye, whosoever of ye raises me that same white whale, he shall have this gold ounce, my boys! Huzza! huzza! cried the seamen, as with swinging tarpaulins they hailed the act of nailing the gold to the mast. It's a white whale, I say, resumed Ahab, as he threw down ..

the top-maul; a white whale. Skin your eyes for him, men; look sharp for white water; if ye see but a bubble, sing out. All this while Tashtego, Daggoo, and Queequeg had looked on with even more intense interest and surprise than the rest, and at the mention of the wrinkled brow and crooked jaw they had started as if each was separately touched by some specific recollection. Captain Ahab, said Tashtego, that white whale must be the same that some call Moby Dick. Moby Dick? shouted Ahab. Do ye know the white whale then, Tash? Does he fan-tail a little curious, sir, before he goes down? said the Gay-Header deliberately. And has he a curious spout, too, said Daggoo, very bushy, even for a parmacetty, and mighty quick, Captain Ahab? And he have one, two, tree --oh! good many iron in him hide, too, Captain, cried Queequeg disjointedly, all twiske-tee betwisk, like him--him-- faltering hard for a word, and screwing his hand round and round as though uncorking a bottle -- like him--him-- Corkscrew! cried Ahab, aye, Queequeg, the harpoons lie all twisted and wrenched in him; aye, Daggoo, his spout is a big one, like a whole shock of wheat, and white as a pile of our Nantucket wool after the great annual sheep-shearing; aye, Tashtego, and he fan-tails like a split jib in a squall. Death and devils! men, it is Moby Dick ye have seen --Moby Dick-- Moby Dick! Captain Ahab, said Starbuck, who, with Stubb and Flask, had thus far been eyeing his superior with increasing surprise, but at last seemed struck with a thought which somewhat explained all the wonder. Captain Ahab, I have heard of Moby Dick--but it was not Moby Dick that took off thy leg? Who told thee that? cried Ahab; then pausing, Aye, Starbuck; aye, my hearties all round; it was Moby Dick that dismasted me; Moby Dick that brought me to this dead stump I stand on now. Aye, aye, he shouted with a terrific, loud, animal sob, like that of a heart-stricken moose; Aye, aye! it was that accursed white whale that razeed me; made a poor pegging ..

lubber of me for ever and a day! Then tossing both arms, with measureless imprecations he shouted out: Aye, aye! and I'll chase him round Good Hope, and round the horn, and round the norway maelstrom, and round perdition's flames before I give him up. And this is what ye have shipped for, men! to chase that white whale on both sides of land, and over all sides of earth, till he spouts black blood and rolls fin out. What say ye, men, will ye splice hands on it, now? I think ye do look brave. Aye, aye! shouted the harpooneers and seamen, running closer to the excited old man: A sharp eye for the White Whale; a sharp lance for Moby Dick! God bless ye, he seemed to half sob and half shout. God bless ye, men. Steward! go draw the great measure of grog. But what's this long face about, Mr. Starbuck; wilt thou not chase the white whale? art not game for Moby Dick? I am game for his crooked jaw, and for the jaws of Death too, Captain Ahab, if it fairly comes in the way of the business we follow; but I came here to hunt whales, not my commander's vengeance. How many barrels will thy vengeance yield thee even if thou gettest it, Captain Ahab? it will not fetch thee much in our Nantucket market. Nantucket market! Hoot! But come closer, Starbuck; thou requirest a little lower layer. If money's to be the measurer, man, and the accountants have computed their great counting-house the globe, by girdling it with guineas, one to every three parts of an inch; then, let me tell thee, that my vengeance will fetch a great premium here! He smites his chest, whispered Stubb, what's that for? methinks it rings most vast, but hollow. Vengeance on a dumb brute! cried Starbuck, that simply smote thee from blindest instinct! Madness! To be enraged with a dumb thing, Captain Ahab, seems blasphemous. Hark ye yet again, --the little lower layer. All visible objects, man, are but as pasteboard masks. But in each event --in the living act, the undoubted deed --there, some unknown but still reasoning thing puts forth the mouldings of its features from behind the unreasoning mask. If man will strike, strike through ..

the mask! How can the prisoner reach outside except by thrusting through the wall? To me, the white whale is that wall, shoved near to me. Sometimes I think there's naught beyond. But 'tis enough. He tasks me; he heaps me; I see in him outrageous strength, with an inscrutable malice sinewing it. That inscrutable thing is chiefly what I hate; and be the white whale agent, or be the white whale principal, I will wreak that hate upon him. Talk not to me of blasphemy, man; I'd strike the sun if it insulted me. For could the sun do that, then could I do the other; since there is ever a sort of fair play herein, jealousy presiding over all creations. But not my master, man, is even that fair play. Who's over me? Truth hath no confines. Take off thine eye! more intolerable than fiends' glarings is a doltish stare! So, so; thou reddenest and palest; my heat has melted thee to anger-glow. But look ye, Starbuck, what is said in heat, that thing unsays itself. There are men from whom warm words are small indignity. I meant not to incense thee. Let it go. Look! see yonder Turkish cheeks of spotted tawn -- living, breathing pictures painted by the sun. The Pagan leopards --the unrecking and unworshipping things, that live; and seek, and give no reasons for the torrid life they feel! The crew, man, the crew! Are they not one and all with Ahab, in this matter of the whale? See Stubb! he laughs! See yonder Chilian! he snorts to think of it. Stand up amid the general hurricane, thy one tost sapling cannot, Starbuck! And what is it? Reckon it. 'Tis but to help strike a fin; no wondrous feat for Starbuck. What is it more? From this one poor hunt, then, the best lance out of all Nantucket, surely he will not hang back, when every foremast-hand has clutched a whetstone? Ah! constrainings seize thee; I see! the billow lifts thee! Speak, but speak! --Aye, aye! thy silence, then, that voices thee. ( aside) something shot from my dilated nostrils, he has inhaled it in his lungs. Starbuck now is mine; cannot oppose me now, without rebellion. God keep me! --keep us all! murmured Starbuck, lowly. But in his joy at the enchanted, tacit acquiescence of the mate, Ahab did not hear his foreboding invocation; nor yet the low laugh from the hold; nor yet the presaging vibrations of ..

the winds in the cordage; nor yet the hollow flap of the sails against the masts, as for a moment their hearts sank in. For again Starbuck's downcast eyes lighted up with the stubbornness of life; the subterranean laugh died away; the winds blew on; the sails filled out; the ship heaved and rolled as before. Ah, ye admonitions and warnings! why stay ye not when ye come? But rather are ye predictions than warnings, ye shadows! Yet not so much predictions from without, as verifications of the foregoing things within. For with little external to constrain us, the innermost necessities in our being, these still drive us on. The measure! the measure! cried Ahab. Receiving the brimming pewter, and turning to the harpooneers, he ordered them to produce their weapons. Then ranging them before him near the capstan, with their harpoons in their hands, while his three mates stood at his side with their lances, and the rest of the ship's company formed a circle round the group; he stood for an instant searchingly eyeing every man of his crew. But those wild eyes met his, as the bloodshot eyes of the prairie wolves meet the eye of their leader, ere he rushes on at their head in the trail of the bison; but, alas! only to fall into the hidden snare of the Indian. Drink and pass! he cried, handing the heavy charged flagon to the nearest seaman. The crew alone now drink. Round with it, round! Short draughts --long swallows, men; 'tis hot as Satan's hoof. So, so; it goes round excellently. It spiralizes in ye; forks out at the serpent-snapping eye. well done; almost drained. That way it went, this way it comes. Hand it me -- here's a hollow! Men, ye seem the years; so brimming life is gulped and gone. Steward, refill! Attend now, my braves. I have mustered ye all round this capstan; and ye mates, flank me with your lances; and ye harpooneers, stand there with your irons; and ye, stout mariners, ring me in, that I may in some sort revive a noble custom of my fisherman fathers before me. O men, you will yet see that-- Ha! boy, come back? bad pennies come not sooner. Hand it me. Why, now, this pewter had run brimming again, wer't not thou St. Vitus' imp --away, thou ague! Advance, ye mates! Cross your lances full before me. Well ..

done! Let me touch the axis. So saying, with extended arm, he grasped the three level, radiating lances at their crossed centre; while so doing, suddenly and nervously twitched them; meanwhile, glancing intently from Starbuck to Stubb; from Stubb to Flask. It seemed as though, by some nameless, interior volition, he would fain have shocked into them the same fiery emotion accumulated within the Leyden jar of his own magnetic life. The three mates quailed before his strong, sustained, and mystic aspect. Stubb and Flask looked sideways from him; the honest eye of Starbuck fell downright. In vain! cried Ahab; but, maybe, 'tis well. For did ye three but once take the full-forced shock, then mine own electric thing, that had perhaps expired from out me. Perchance, too, it would have dropped ye dead. Perchance ye need it not. Down lances! And now, ye mates, I do appoint ye three cup-bearers to my three pagan kinsmen there --yon three most honorable gentlemen and noblemen, my valiant harpooneers. Disdain the task? What, when the great Pope washes the feet of beggars, using his tiara for ewer? Oh, my sweet cardinals! your own condescension, that shall bend ye to it. I do not order ye; ye will it. Cut your seizings and draw the poles, ye harpooneers! Silently obeying the order, the three harpooneers now stood with the detached iron part of their harpoons, some three feet long, held, barbs up, before him. Stab me not with that keen steel! Cant them; cant them over! know ye not the goblet end? Turn up the socket! So, so; now, ye cup-bearers, advance. The irons! take them; hold them while I fill! Forthwith, slowly going from one officer to the other, he brimmed the harpoon sockets with the fiery waters from the pewter. Now, three to three, ye stand. Commend the murderous chalices! Bestow them, ye who are now made parties to this indissoluble league. Ha! Starbuck! but the deed is done! Yon ratifying sun now waits to sit upon it. Drink, ye harpooneers! drink and swear, ye men that man the deathful whaleboat's bow -- Death to Moby Dick! God hunt us all, if we do not hunt Moby Dick to his death! The long, barbed steel goblets were lifted; and to cries and maledictions against the white whale, the spirits ..

were simultaneously quaffed down with a hiss. Starbuck paled, and turned, and shivered. Once more, and finally, the replenished pewter went the rounds among the frantic crew; when, waving his free hand to them, they all dispersed; and Ahab retired within his cabin. ..

.. < chapter xxxvii 7 SUNSET > The cabin; by the stern windows; Ahab sitting alone, and gazing out. I leave a white and turbid wake; pale waters, paler cheeks, where'er I sail. The envious billows sidelong swell to whelm my track; let them; but first I pass. Yonder, by the ever-brimming goblet's rim, the warm waves blush like wine. The gold brow plumbs the blue. The diver sun --slow dived from noon, --goes down; my soul mounts up! she wearies with her endless hill. Is, then, the crown too heavy that I wear? this Iron Crown of Lombardy. Yet is it bright with many a gem; i, the wearer, see not its far flashings; but darkly feel that i wear that, that dazzlingly confounds. 'Tis iron --that I know--not gold. 'Tis split, too --that I feel; the jagged edge galls me so, my brain seems to beat against the solid metal; aye, steel skull, mine; the sort that needs no helmet in the most brain-battering fight! Dry heat upon my brow? Oh! time was, when as the sunrise nobly spurred me, so the sunset soothed. No more. This lovely light, it lights not me; all loveliness is anguish to me, since I can ne'er enjoy. Gifted with the high perception, I lack the low, enjoying power; damned, most subtly and most malignantly! damned in the midst of Paradise! Good night --good night! ( waving his hand, he moves from the window.) 'Twas not so hard a task. I thought to find one stubborn, at ..

the least; but my one cogged circle fits into all their various wheels, and they revolve. Or, if you will, like so many ant-hills of powder, they all stand before me; and I their match. Oh, hard! that to fire others, the match itself must needs be wasting! What I've dared, I've willed; and what I've willed, I'll do! They think me mad --Starbuck does; but I'm demoniac, I am madness maddened! That wild madness that's only calm to comprehend itself! The prophecy was that I should be dismembered; and--Aye! I lost this leg. I now prophesy that I will dismember my dismemberer. Now, then, be the prophet and the fulfiller one. That's more than ye, ye great gods, ever were. I laugh and hoot at ye, ye cricket-players, ye pugilists, ye deaf Burkes and blinded Bendigoes! I will not say as school-boys do to bullies, --Take some one of your own size; don't pommel me! No, ye've knocked me down, and I am up again; but ye have run and hidden. Come forth from behind your cotton bags! I have no long gun to reach ye. Come, Ahab's compliments to ye; come and see if ye can swerve me. Swerve me? ye cannot swerve me, else ye swerve yourselves! man has ye there. Swerve me? The path to my fixed purpose is laid with iron rails, whereon my soul is grooved to run. Over unsounded gorges, through the rifled hearts of mountains, under torrents' beds, unerringly I rush! Naught's an obstacle, naught's an angle to the iron way! ..

.. < chapter xxxviii 26 DUSK > By the Mainmast; Starbuck leaning against it. My soul is more than matched; she's overmanned; and by a madman! Insufferable sting, that sanity should ground arms on such a field! But he drilled deep down, and blasted all my reason out of me! I think I see his impious end; but feel that ..

I must help him to it. Will I, nill I, the ineffable thing has tied me to him; tows me with a cable I have no knife to cut. Horrible old man! Who's over him, he cries; --aye, he would be a democrat to all above; look, how he lords it over all below! Oh! I plainly see my miserable office, --to obey, rebelling; and worse yet, to hate with touch of pity! For in his eyes I read some lurid woe would shrivel me up, had I it. Yet is there hope. Time and tide flow wide. The hated whale has the round watery world to swim in, as the small gold-fish has its glassy globe. His heaven-insulting purpose, God may wedge aside. I would up heart, were it not like lead. But my whole clock's run down; my heart the all-controlling weight, I have no key to lift again. [ A burst of revelry from the forecastle.] Oh, God! to sail with such a heathen crew that have small touch of human mothers in them! Whelped somewhere by the sharkish sea. The white whale is their demigorgon. Hark! the infernal orgies! that revelry is forward! mark the unfaltering silence aft! Methinks it pictures life. Foremost through the sparkling sea shoots on the gay, embattled, bantering bow, but only to drag dark Ahab after it, where he broods within his sternward cabin, builded over the dead water of the wake, and further on, hunted by its wolfish gurglings. The long howl thrills me through! Peace! ye revellers, and set the watch! Oh, life! 'tis in an hour like this, with soul beat down and held to knowledge, --as wild, untutored things are forced to feed --Oh, life! 'tis now that I do feel the latent horror in thee! but 'tis not me! that horror's out of me! and with the soft feeling of the human in me, yet will I try to fight ye, ye grim, phantom futures! Stand by me, hold me, bind me, O ye blessed influences! ..

.. < chapter xxxix 2 FIRST NIGHT-WATCH FORE-TOP > ( Stubb solus, and mending a brace.) Ha! ha! ha! ha! hem! clear my throat! --I've been thinking over it ever since, and that ha, ha's the final consequence. Why so? Because a laugh's the wisest, easiest answer to all that's queer; and come what will, one comfort's always left -- that unfailing comfort is, it's all predestinated. I heard not all his talk with Starbuck; but to my poor eye Starbuck then looked something as I the other evening felt. Be sure the old Mogul has fixed him, too. I twigged it, knew it; had had the gift, might readily have prophesied it --for when I clapped my eye upon his skull I saw it. Well, Stubb, wise Stubb --that's my title --well, Stubb, what of it, Stubb? Here's a carcase. I know not all that may be coming, but be it what it will, I'll go to it laughing. Such a waggish leering as lurks in all your horribles! I feel funny. Fa, la! lirra, skirra! What's my juicy little pear at home doing now? Crying its eyes out? --Giving a party to the last arrived harpooneers, I dare say, gay as a frigate's pennant, and so am I--fa, la! lirra, skirra! Oh-- We'll drink to-night with hearts as light, To love, as gay and fleeting As bubbles that swim, on the beaker's brim, And break on the lips while meeting. a brave stave that --who calls? mr. starbuck? Aye, aye, sir -- ( Aside) he's my superior, he has his too, if I'm not mistaken. -- Aye, aye, sir, just through with this job --coming. ..

.. < chapter xl 2 MIDNIGHT, FORECASTLE HARPOONERS AND SAILORS > ( Foresail rises and discovers the watch standing, lounging, leaning, and lying in various attitudes, all singing in chorus.) Farewell and adieu to you, Spanish ladies! Farewell and adieu to you, ladies of Spain! Our captain's commanded. -- 1st Nantucket Sailor Oh, boys, don't be sentimental; it's bad for the digestion! Take a tonic, follow me! ( Sings, and all follow.) Our captain stood upon the deck, A spy-glass in his hand, A viewing of those gallant whales That blew at every strand. Oh, your tubs in your boats, my boys, And by your braces stand, And we'll have one of those fine whales, Hand, boys, over hand! So, be cheery, my lads! may your hearts never fail! While the bold harpooneer is striking the whale! Mate's Voice from the Quarter-Deck Eight bells there, forward! 2nd Nantucket Sailor Avast the chorus! Eight bells there! d'ye hear, bell-boy? Strike the bell eight, thou Pip! thou blackling! and let me call the watch. I've the sort of mouth for that --the hogshead mouth. So, so, ( thrusts his head down the scuttle,) Star--bo--l-e-e-n-s, a-h-o-y! Eight bells there below! Tumble up! Dutch Sailor Grand snoozing to-night, maty; fat night for that. I mark this in our old Mogul's wine; it's quite as deadening to some as ..

filliping to others. We sing; they sleep --aye, lie down there, like ground-tier butts. At 'em again! There, take this copper-pump, and hail 'em through it. Tell 'em to avast dreaming of their lasses. Tell 'em it's the resurrection; they must kiss their last, and come to judgment. That's the way -- that's it; thy throat ain't spoiled with eating Amsterdam butter. French Sailor Hist, boys! let's have a jig or two before we ride to anchor in Blanket Bay. What say ye? There comes the other watch. Stand by all legs! Pip! little Pip! hurrah with your tambourine! Pip ( Sulky and sleepy.) Don't know where it is. French Sailor Beat thy belly, then, and wag thy ears. Jig it, men, I say; merry's the word; hurrah! Damn me, won't you dance? Form, now, Indian-file, and gallop into the double-shuffle? Throw yourselves! Legs! Legs! Iceland Sailor I don't like your floor, maty; it's too springy to my taste. I'm used to ice-floors. I'm sorry to throw cold water on the subject; but excuse me. Maltese Sailor Me too; where's your girls? Who but a fool would take his left hand by his right, and say to himself, how d'ye do? Partners! I must have partners! Sicilian Sailor Aye; girls and a green! --then I'll hop with ye; yea, turn grasshopper! Long-Island Sailor Well, well, ye sulkies, there's plenty more of us. Hoe corn when you may, I say. All legs go to harvest soon. Ah! here comes the music; now for it! Azore Sailor ( Ascending, and pitching the tambourine up the scuttle.) ..

Here you are, Pip; and there's the windlass-bitts; up you mount! Now, boys! ( The half of them dance to the tambourine; some go below; some sleep or lie among the coils of rigging. Oaths a-plenty.) Azore Sailor ( Dancing.) Go it, Pip! Bang it, bell-boy! Rig it, dig it, stig it, quig it, bell-boy; Make fire-flies; break the jinglers! Pip Jinglers, you say? --there goes another, dropped off; I pound it so. China Sailor Rattle thy teeth, then, and pound away; make a pagoda of thyself. French Sailor Merry-mad! Hold up thy hoop, Pip, till I jump through it! split jibs! tear yourselves! Tashtego ( Quietly smoking.) That's a white man; he calls that fun: humph! I save my sweat. Old Manx Sailor I wonder whether those jolly lads bethink them of what they are dancing over. I'll dance over your grave, I will --that's the bitterest threat of your night-women, that beat head-winds round corners. O Christ! to think of the green navies and the green-skulled crews! Well, well; belike the whole world's a ball, as you scholars have it; and so 'tis right to make one ballroom of it. Dance on, lads, you're young; I was once. 3d Nantucket Sailor Spell oh! --whew! this is worse than pulling after whales in a calm --give us a whiff, Tash. ( They cease dancing, and gather in clusters. Meantime the sky darkens -- the wind rises.) ..

Lascar Sailor By Brahma! boys, it'll be douse sail soon. The sky-born, high-tide Ganges turned to wind! Thou showest thy black brow, Seeva! Maltese Sailor ( Reclining and shaking his cap.) It's the waves --the snow's caps turn to jig it now. They'll shake their tassels soon. Now would all the waves were women, then I'd go drown, and chassee with them evermore! There's naught so sweet on earth --heaven may not match it! --as those swift glances of warm, wild bosoms in the dance, when the over-arboring arms hide such ripe, bursting grapes. Sicilian Sailor ( Reclining.) Tell me not of it! Hark ye, lad --fleet interlacings of the limbs --lithe swayings --coyings --flutterings! lip! heart! hip! all graze: unceasing touch and go! not taste, observe ye, else come satiety. Eh, Pagan? ( Nudging.) Tahitan Sailor ( Reclining on a mat.) Hail, holy nakedness of our dancing girls! --the Heeva-Heeva! Ah! low veiled, high palmed Tahiti! I still rest me on thy mat, but the soft soil has slid! I saw thee woven in the wood, my mat! green the first day i brought ye thence; now worn and wilted quite. Ah me! --not thou nor I can bear the change! How then, if so be transplanted to yon sky? Hear I the roaring streams from Pirohitee's peak of spears, when they leap down the crags and drown the villages? --The blast! the blast! Up, spine, and meet it! ( Leaps to his feet.) Portuguese Sailor How the sea rolls swashing 'gainst the side! Stand by for reefing, hearties! the winds are just crossing swords, pell-mell they'll go lunging presently. Danish Sailor Crack, crack, old ship! so long as thou crackest, thou holdest! Well done! The mate there holds ye to it stiffly. He's no more ..

afraid than the isle fort at Cattegat, put there to fight the Baltic with storm-lashed guns, on which the sea-salt cakes! 4th Nantucket Sailor He has his orders, mind ye that. I heard old Ahab tell him he must always kill a squall, something as they burst a waterspout with a pistol --fire your ship right into it! English Sailor Blood! but that old man's a grand old cove! We are the lads to hunt him up his whale! All Aye! aye! Old Manx Sailor How the three pines shake! Pines are the hardest sort of tree to live when shifted to any other soil, and here there's none but the crew's cursed clay. Steady, helmsman! steady. This is the sort of weather when brave hearts snap ashore, and keeled hulls split at sea. Our captain has his birth-mark; look yonder, boys, there's another in the sky --lurid-like, ye see, all else pitch black. Daggoo What of that? Who's afraid of black's afraid of me! I'm quarried out of it! Spanish Sailor ( Aside.) He wants to bully, ah! --the old grudge makes me touchy. ( Advancing.) Aye, harpooneer, thy race is the undeniable dark side of mankind --devilish dark at that. No offence. Daggoo ( grimly) None. St. Jago's Sailor That Spaniard's mad or drunk. But that can't be, or else in his one case our old Mogul's fire-waters are somewhat long in working. 5th Nantucket Sailor What's that I saw--lightning? Yes. ..

Spanish Sailor No; Daggoo showing his teeth. Daggoo ( springing) Swallow thine, mannikin! White skin, white liver! Spanish Sailor ( meeting him) Knife thee heartily! big frame, small spirit! All A row! a row! a row! Tashtego ( with a whiff) A row a'low, and a row aloft --Gods and men --both brawlers! Humph! Belfast Sailor A row! arrah a row! The Virgin be blessed, a row! Plunge in with ye! English Sailor Fair play! Snatch the Spaniard's knife! A ring, a ring! Old Manx Sailor Ready formed. There! the ringed horizon. In that ring Cain struck Abel. Sweet work, right work! No? Why then, God, mad'st thou the ring? Mate's Voice from the Quarter Deck Hands by the halyards! in top-gallant sails! Stand by to reef topsails! All The squall! the squall! jump, my jollies! ( They scatter.) Pip ( shrinking under the windlass) Jollies? Lord help such jollies! Crish, crash! there goes the jib-stay! Blang-whang! God! Duck lower, Pip, here comes the royal yard! It's worse than being in the whirled woods, the last day of the year; Who'd go climbing after chestnuts now? But there they go, all cursing, and here I don't. Fine prospects to 'em; they're on the road to heaven. Hold on hard! Jimmini, what a squall! But those chaps there are worse yet --they are your white squalls, they. White squalls? white whale, shirr! ..

shirr! Here have I heard all their chat just now, and the white whale --shirr! shirr! --but spoken of once! and only this evening -- it makes me jingle all over like my tambourine --that anaconda of an old man swore 'em in to hunt him! Oh, thou big white God aloft there somewhere in yon darkness, have mercy on this small black boy down here; preserve him from all men that have no bowels to feel fear! ..

.. < chapter xli 9 MOBY DICK > I, Ishmael, was one of that crew; my shouts had gone up with the rest; my oath had been welded with theirs; and stronger I shouted, and more did I hammer and clinch my oath, because of the dread in my soul. A wild, mystical, sympathetical feeling was in me; Ahab's quenchless feud seemed mine. With greedy ears I learned the history of that murderous monster against whom I and all the others had taken our oaths of violence and revenge. For some time past, though at intervals only, the unaccompanied, secluded White Whale had haunted those uncivilized seas mostly frequented by the Sperm Whale fishermen. But not all of them knew of his existence; only a few of them, comparatively, had knowingly seen him; while the number who as yet had actually and knowingly given battle to him, was small indeed. For, owing to the large number of whale-cruisers; the disorderly way they were sprinkled over the entire watery circumference, many of them adventurously pushing their quest along solitary latitudes, so as seldom or never for a whole twelvemonth or more on a stretch, to encounter a single news-telling sail of any sort; the inordinate length of each separate voyage; the irregularity of the times of sailing from home; all these, with other circumstances, direct and indirect, long obstructed ..

the spread through the whole world-wide whaling-fleet of the special individualizing tidings concerning Moby Dick. It was hardly to be doubted, that several vessels reported to have encountered, at such or such a time, or on such or such a meridian, a Sperm Whale of uncommon magnitude and malignity, which whale, after doing great mischief to his assailants, had completely escaped them; to some minds it was not an unfair presumption, I say, that the whale in question must have been no other than moby Dick. Yet as of late the Sperm Whale fishery had been marked by various and not unfrequent instances of great ferocity, cunning, and malice in the monster attacked; therefore it was, that those who by accident ignorantly gave battle to Moby Dick; such hunters, perhaps, for the most part, were content to ascribe the peculiar terror he bred, more, as it were, to the perils of the Sperm Whale fishery at large, than to the individual cause. In that way, mostly, the disastrous encounter between Ahab and the whale had hitherto been popularly regarded. And as for those who, previously hearing of the White Whale, by chance caught sight of him; in the beginning of the thing they had every one of them, almost, as boldly and fearlessly lowered for him, as for any other whale of that species. But at length, such calamities did ensue in these assaults --not restricted to sprained wrists and ancles, broken limbs, or devouring amputations --but fatal to the last degree of fatality; those repeated disastrous repulses, all accumulating and piling their terrors upon Moby Dick; those things had gone far to shake the fortitude of many brave hunters, to whom the story of the White Whale had eventually come. Nor did wild rumors of all sorts fail to exaggerate, and still the more horrify the true histories of these deadly encounters. For not only do fabulous rumors naturally grow out of the very body of all surprising terrible events, --as the smitten tree gives birth to its fungi; but, in maritime life, far more than in that of terra firma, wild rumors abound, wherever there is any adequate reality for them to cling to. And as the sea surpasses the land in this matter, so the whale fishery surpasses every other sort of maritime life, in the wonderfulness and fearfulness of the ..

rumors which sometimes circulate there. For not only are whalemen as a body unexempt from that ignorance and superstitiousness hereditary to all sailors; but of all sailors, they are by all odds the most directly brought into contact with whatever is appallingly astonishing in the sea; face to face they not only eye its greatest marvels, but, hand to jaw, give battle to them. Alone, in such remotest waters, that though you sailed a thousand miles, and passed a thousand shores, you would not come to any chiselled hearthstone, or aught hospitable beneath that part of the sun; in such latitudes and longitudes, pursuing too such a calling as he does, the whaleman is wrapped by influences all tending to make his fancy pregnant with many a mighty birth. No wonder, then, that ever gathering volume from the mere transit over the widest watery spaces, the outblown rumors of the White Whale did in the end incorporate with themselves all manner of morbid hints, and half-formed foetal suggestions of supernatural agencies, which eventually invested Moby Dick with new terrors unborrowed from anything that visibly appears. So that in many cases such a panic did he finally strike, that few who by those rumors, at least, had heard of the White Whale, few of those hunters were willing to encounter the perils of his jaw. But there were still other and more vital practical influences at work. Not even at the present day has the original prestige of the Sperm Whale, as fearfully distinguished from all other species of the leviathan, died out of the minds of the whalemen as a body. There are those this day among them, who, though intelligent and courageous enough in offering battle to the Greenland or Right whale, would perhaps --either from professional inexperience, or incompetency, or timidity, decline a contest with the Sperm Whale; at any rate, there are plenty of whalemen, especially among those whaling nations not sailing under the American flag, who have never hostilely encountered the Sperm Whale, but whose sole knowledge of the leviathan is restricted to the ignoble monster primitively pursued in the North; seated on their hatches, these men will hearken with a childish fire-side interest and awe, to the wild, strange tales of ..

Southern whaling. Nor is the pre-eminent tremendousness of the great Sperm Whale anywhere more feelingly comprehended, than on board of those prows which stem him. And as if the now tested reality of his might had in former legendary times thrown its shadow before it; we find some book naturalists --Olassen and Povelson --declaring the Sperm Whale not only to be a consternation to every other creature in the sea, but also to be so incredibly ferocious as continually to be athirst for human blood. Nor even down to so late a time as Cuvier's, were these or almost similar impressions effaced. For in his Natural History, the Baron himself affirms that at sight of the Sperm Whale, all fish (sharks included) are struck with the most lively terrors, and often in the precipitancy of their flight dash themselves against the rocks with such violence as to cause instantaneous death. And however the general experiences in the fishery may amend such reports as these; yet in their full terribleness, even to the bloodthirsty item of Povelson, the superstitious belief in them is, in some vicissitudes of their vocation, revived in the minds of the hunters. So that overawed by the rumors and portents concerning him, not a few of the fishermen recalled, in reference to Moby Dick, the earlier days of the Sperm Whale fishery, when it was oftentimes hard to induce long practised Right whalemen to embark in the perils of this new and daring warfare; such men protesting that although other leviathans might be hopefully pursued, yet to chase and point lance at such an apparition as the Sperm Whale was not for mortal man. That to attempt it, would be inevitably to be torn into a quick eternity. on this head, there are some remarkable documents that may be consulted. Nevertheless, some there were, who even in the face of these things were ready to give chase to Moby Dick; and a still greater number who, chancing only to hear of him distantly and vaguely, without the specific details of any certain calamity, and without superstitious accompaniments, were sufficiently hardy not to flee from the battle if offered. One of the wild suggestings referred to, as at last coming to be linked with the White Whale in the minds of the superstitiously inclined, was the unearthly conceit that Moby Dick was ..

ubiquitous; that he had actually been encountered in opposite latitudes at one and the same instant of time. Nor, credulous as such minds must have been, was this conceit altogether without some faint show of superstitious probability. For as the secrets of the currents in the seas have never yet been divulged, even to the most erudite research; so the hidden ways of the Sperm Whale when beneath the surface remain, in great part, unaccountable to his pursuers; and from time to time have originated the most curious and contradictory speculations regarding them, especially concerning the mystic modes whereby, after sounding to a great depth, he transports himself with such vast swiftness to the most widely distant points. It is a thing well known to both American and English whale-ships, and as well a thing placed upon authoritative record years ago by Scoresby, that some whales have been captured far north in the Pacific, in whose bodies have been found the barbs of harpoons darted in the Greenland seas. Nor is it to be gainsaid, that in some of these instances it has been declared that the interval of time between the two assaults could not have exceeded very many days. Hence, by inference, it has been believed by some whalemen, that the nor' west passage, so long a problem to man, was never a problem to the whale. So that here, in the real living experience of living men, the prodigies related in old times of the inland Strello mountain in Portugal (near whose top there was said to be a lake in which the wrecks of ships floated up to the surface); and that still more wonderful story of the Arethusa fountain near Syracuse (whose waters were believed to have come from the Holy Land by an underground passage); these fabulous narrations are almost fully equalled by the realities of the whaleman. Forced into familiarity, then, with such prodigies as these; and knowing that after repeated, intrepid assaults, the White Whale had escaped alive; it cannot be much matter of surprise that some whalemen should go still further in their superstitions; declaring Moby Dick not only ubiquitous, but immortal (for immortality is but ubiquity in time); that though groves of spears should be planted in his flanks, he would still swim away unharmed; or if indeed he should ever be made to spout thick ..

blood, such a sight would be but a ghastly deception; for again in unensanguined billows hundreds of leagues away, his unsullied jet would once more be seen. But even stripped of these supernatural surmisings, there was enough in the earthly make and incontestable character of the monster to strike the imagination with unwonted power. For, it was not so much his uncommon bulk that so much distinguished him from other sperm whales, but, as was elsewhere thrown out --a peculiar snow-white wrinkled forehead, and a high, pyramidical white hump. These were his prominent features; the tokens whereby, even in the limitless, uncharted seas, he revealed his identity, at a long distance, to those who knew him. The rest of his body was so streaked, and spotted, and marbled with the same shrouded hue, that, in the end, he had gained his distinctive appellation of the white Whale; a name, indeed, literally justified by his vivid aspect, when seen gliding at high noon through a dark blue sea, leaving a milky-way wake of creamy foam, all spangled with golden gleamings. Nor was it his unwonted magnitude, nor his remarkable hue, nor yet his deformed lower jaw, that so much invested the whale with natural terror, as that unexampled, intelligent malignity which, according to specific accounts, he had over and over again evinced in his assaults. More than all, his treacherous retreats struck more of dismay than perhaps aught else. For, when swimming before his exulting pursuers, with every apparent symptom of alarm, he had several times been known to turn around suddenly, and, bearing down upon them, either stave their boats to splinters, or drive them back in consternation to their ship. Already several fatalities had attended his chase. But though similar disasters, however little bruited ashore, were by no means unusual in the fishery; yet, in most instances, such seemed the White Whale's infernal aforethought of ferocity, that every dismembering or death that he caused, was not wholly regarded as having been inflicted by an unintelligent agent. Judge, then, to what pitches of inflamed, distracted fury the ..

minds of his more desperate hunters were impelled, when amid the chips of chewed boats, and the sinking limbs of torn comrades, they swam out of the white curds of the whale's direful wrath into the serene, exasperating sunlight, that smiled on, as if at a birth or a bridal. His three boats stove around him, and oars and men both whirling in the eddies; one captain, seizing the line-knife from his broken prow, had dashed at the whale, as an Arkansas duellist at his foe, blindly seeking with a six inch blade to reach the fathom-deep life of the whale. That captain was Ahab. And then it was, that suddenly sweeping his sickle-shaped lower jaw beneath him, Moby Dick had reaped away ahab's leg, as a mower a blade of grass in the field. No turbaned Turk, no hired Venetian or Malay, could have smote him with more seeming malice. Small reason was there to doubt, then, that ever since that almost fatal encounter, Ahab had cherished a wild vindictiveness against the whale, all the more fell for that in his frantic morbidness he at last came to identify with him, not only all his bodily woes, but all his intellectual and spiritual exasperations. The White Whale swam before him as the monomaniac incarnation of all those malicious agencies which some deep men feel eating in them, till they are left living on with half a heart and half a lung. That intangible malignity which has been from the beginning; to whose dominion even the modern Christians ascribe one-half of the worlds; which the ancient Ophites of the east reverenced in their statue devil; -- Ahab did not fall down and worship it like them; but deliriously transferring its idea to the abhorred white whale, he pitted himself, all mutilated, against it. All that most maddens and torments; all that stirs up the lees of things; all truth with malice in it; all that cracks the sinews and cakes the brain; all the subtle demonisms of life and thought; all evil, to crazy Ahab, were visibly personified, and made practically assailable in Moby Dick. He piled upon the whale's white hump the sum of all the general rage and hate felt by his whole race from Adam down; and then, as if his chest had been a mortar, he burst his hot heart's shell upon it. ..

It is not probable that this monomania in him took its instant rise at the precise time of his bodily dismemberment. Then, in darting at the monster, knife in hand, he had but given loose to a sudden, passionate, corporal animosity; and when he received the stroke that tore him, he probably but felt the agonizing bodily laceration, but nothing more. Yet, when by this collision forced to turn towards home, and for long months of days and weeks, ahab and anguish lay stretched together in one hammock, rounding in mid winter that dreary, howling Patagonian Cape; then it was, that his torn body and gashed soul bled into one another; and so interfusing, made him mad. That it was only then, on the homeward voyage, after the encounter, that the final monomania seized him, seems all but certain from the fact that, at intervals during the passage, he was a raving lunatic; and, though unlimbed of a leg, yet such vital strength yet lurked in his Egyptian chest, and was moreover intensified by his delirium, that his mates were forced to lace him fast, even there, as he sailed, raving in his hammock. In a strait-jacket, he swung to the mad rockings of the gales. And, when running into more sufferable latitudes, the ship, with mild stun'sails spread, floated across the tranquil tropics, and, to all appearances, the old man's delirium seemed left behind him with the Cape Horn swells, and he came forth from his dark den into the blessed light and air; even then, when he bore that firm, collected front, however pale, and issued his calm orders once again; and his mates thanked God the direful madness was now gone; even then, Ahab, in his hidden self, raved on. Human madness is oftentimes a cunning and most feline thing. When you think it fled, it may have but become transfigured into some still subtler form. Ahab's full lunacy subsided not, but deepeningly contracted; like the unabated Hudson, when that noble Northman flows narrowly, but unfathomably through the Highland gorge. But, as in his narrow-flowing monomania, not one jot of Ahab's broad madness had been left behind; so in that broad madness, not one jot of his great natural intellect had perished. That before living agent, now became the living instrument. If such a furious trope may stand, his special lunacy ..

stormed his general sanity, and carried it, and turned all its concentred cannon upon its own mad mark; so that far from having lost his strength, Ahab, to that one end, did now possess a thousand fold more potency than ever he had sanely brought to bear upon any one reasonable object. This is much; yet Ahab's larger, darker, deeper part remains unhinted. But vain to popularize profundities, and all truth is profound. Winding far down from within the very heart of this spiked Hotel de Cluny where we here stand --however grand and wonderful, now quit it; --and take your way, ye nobler, sadder souls, to those vast Roman halls of Thermes; where far beneath the fantastic towers of man's upper earth, his root of grandeur, his whole awful essence sits in bearded state; an antique buried beneath antiquities, and throned on torsoes! So with a broken throne, the great gods mock that captive king; so like a Caryatid, he patient sits, upholding on his frozen brow the piled entablatures of ages. Wind ye down there, ye prouder, sadder souls! question that proud, sad king! A family likeness! aye, he did beget ye, ye young exiled royalties; and from your grim sire only will the old State-secret come. Now, in his heart, Ahab had some glimpse of this, namely: all my means are sane, my motive and my object mad. Yet without power to kill, or change, or shun the fact; he likewise knew that to mankind he did now long dissemble; in some sort, did still. But that thing of his dissembling was only subject to his perceptibility, not to his will determinate. Nevertheless, so well did he succeed in that dissembling, that when with ivory leg he stepped ashore at last, no Nantucketer thought him otherwise than but naturally grieved, and that to the quick, with the terrible casualty which had overtaken him. The report of his undeniable delirium at sea was likewise popularly ascribed to a kindred cause. And so too, all the added moodiness which always afterwards, to the very day of sailing in the pequod on the present voyage, sat brooding on his brow. Nor is it so very unlikely, that far from distrusting his fitness for another whaling voyage, on account of such dark symptoms, the calculating people of that prudent isle were inclined to ..

harbor the conceit, that for those very reasons he was all the better qualified and set on edge, for a pursuit so full of rage and wildness as the bloody hunt of whales. Gnawed within and scorched without, with the infixed, unrelenting fangs of some incurable idea; such an one, could he be found, would seem the very man to dart his iron and lift his lance against the most appalling of all brutes. Or, if for any reason thought to be corporeally incapacitated for that, yet such an one would seem superlatively competent to cheer and howl on his underlings to the attack. But be all this as it may, certain it is, that with the mad secret of his unabated rage bolted up and keyed in him, Ahab had purposely sailed upon the present voyage with the one only and all-engrossing object of hunting the White Whale. Had any one of his old acquaintances on shore but half dreamed of what was lurking in him then, how soon would their aghast and righteous souls have wrenched the ship from such a fiendish man! They were bent on profitable cruises, the profit to be counted down in dollars from the mint. He was intent on an audacious, immitigable, and supernatural revenge. Here, then, was this grey-headed, ungodly old man, chasing with curses a Job's whale round the world, at the head of a crew, too, chiefly made up of mongrel renegades, and castaways, and cannibals --morally enfeebled also, by the incompetence of mere unaided virtue or right-mindedness in Starbuck, the invulnerable jollity of indifference and recklessness in Stubb, and the pervading mediocrity in Flask. Such a crew, so officered, seemed specially picked and packed by some infernal fatality to help him to his monomaniac revenge. How it was that they so aboundingly responded to the old man's ire --by what evil magic their souls were possessed, that at times his hate seemed almost theirs; the White Whale as much their insufferable foe as his; how all this came to be --what the White Whale was to them, or how to their unconscious understandings, also, in some dim, unsuspected way, he might have seemed the gliding great demon of the seas of life, --all this to explain, would be to dive deeper than Ishmael can go. The subterranean miner that works in us all, how can one tell whither leads his shaft by the ever shifting, muffled sound of his pick? Who does not feel the ..

irresistible arm drag? What skiff in tow of a seventy-four can stand still? For one, I gave myself up to the abandonment of the time and the place; but while yet all a-rush to encounter the whale, could see naught in that brute but the deadliest ill. ..

.. < chapter xlii 6 THE WHITENESS OF THE WHALE > What the white whale was to Ahab, has been hinted; what, at times, he was to me, as yet remains unsaid. Aside from those more obvious considerations touching Moby Dick, which could not but occasionally awaken in any man's soul some alarm, there was another thought, or rather vague, nameless horror concerning him, which at times by its intensity completely overpowered all the rest; and yet so mystical and well nigh ineffable was it, that I almost despair of putting it in a comprehensible form. It was the whiteness of the whale that above all things appalled me. But how can I hope to explain myself here; and yet, in some dim, random way, explain myself I must, else all these chapters might be naught. Though in many natural objects, whiteness refiningly enhances beauty, as if imparting some special virtue of its own, as in marbles, japonicas, and pearls; and though various nations have in some way recognised a certain royal pre-eminence in this hue; even the barbaric, grand old kings of Pegu placing the title Lord of the White Elephants above all their other magniloquent ascriptions of dominion; and the modern kings of Siam unfurling the same snow-white quadruped in the royal standard; and the Hanoverian flag bearing the one figure of a snow-white charger; and the great Austrian Empire, Caesarian, heir to overlording Rome, having for the imperial color the same imperial hue; and though this pre-eminence in it applies to the human race itself, giving the white man ideal mastership over every dusky tribe; and though, besides all this, whiteness has been ..

even made significant of gladness, for among the Romans a white stone marked a joyful day; and though in other mortal sympathies and symbolizings, this same hue is made the emblem of many touching, noble things --the innocence of brides, the benignity of age; though among the Red Men of America the giving of the white belt of wampum was the deepest pledge of honor; though in many climes, whiteness typifies the majesty of Justice in the ermine of the Judge, and contributes to the daily state of kings and queens drawn by milk-white steeds; though even in the higher mysteries of the most august religions it has been made the symbol of the divine spotlessness and power; by the Persian fire worshippers, the white forked flame being held the holiest on the altar; and in the Greek mythologies, Great Jove himself made incarnate in a snow-white bull; and though to the noble Iroquois, the midwinter sacrifice of the sacred White Dog was by far the holiest festival of their theology, that spotless, faithful creature being held the purest envoy they could send to the Great Spirit with the annual tidings of their own fidelity; and though directly from the Latin word for white, all Christian priests derive the name of one part of their sacred vesture, the alb or tunic, worn beneath the cassock; and though among the holy pomps of the Romish faith, white is specially employed in the celebration of the Passion of our Lord; though in the Vision of St. John, white robes are given to the redeemed, and the four-and-twenty elders stand clothed in white before the great white throne, and the Holy One that sitteth there white like wool; yet for all these accumulated associations, with whatever is sweet, and honorable, and sublime, there yet lurks an elusive something in the innermost idea of this hue, which strikes more of panic to the soul than that redness which affrights in blood. This elusive quality it is, which causes the thought of whiteness, when divorced from more kindly associations, and coupled with any object terrible in itself, to heighten that terror to the furthest bounds. Witness the white bear of the poles, and the white shark of the tropics; what but their smooth, flaky whiteness makes them the transcendent horrors they are? That ghastly whiteness it is which imparts such an abhorrent mildness, even ..

more loathsome than terrific, to the dumb gloating of their aspect. So that not the fierce-fanged tiger in his heraldic coat can so stagger courage as the white-shrouded bear or shark. Bethink thee of the albatross, whence come those clouds of spiritual wonderment and pale dread, in which that white phantom sails in all imaginations? Not Coleridge first threw that spell; but God's great, unflattering laureate, Nature. ..

Most famous in our Western annals and Indian traditions is that of the White Steed of the Prairies; a magnificent milk-white charger, large-eyed, small-headed, bluff-chested, and with the dignity of a thousand monarchs in his lofty, overscorning carriage. He was the elected Xerxes of vast herds of wild horses, whose pastures in those days were only fenced by the Rocky Mountains and the Alleghanies. At their flaming head he westward trooped it like that chosen star which every evening leads on the hosts of light. The flashing cascade of his mane, the curving comet of his tail, invested him with housings more resplendent than gold and silver-beaters could have furnished him. A most imperial and archangelical apparition of that unfallen, western world, which to the eyes of the old trappers and hunters revived the glories of those primeval times when Adam walked majestic as a god, bluff-bowed and fearless as this mighty steed. Whether marching amid his aides and marshals in the van of countless cohorts that endlessly streamed it over the plains, like an Ohio; or whether with his circumambient subjects browsing all around at the horizon, the White Steed gallopingly reviewed them with warm nostrils reddening through his cool milkiness; in whatever aspect he presented himself, always to the bravest Indians he was the object of trembling reverence and awe. Nor can it be questioned from what stands on legendary record of ..

this noble horse, that it was his spiritual whiteness chiefly, which so clothed him with divineness; and that this divineness had that in it which, though commanding worship, at the same time enforced a certain nameless terror. But there are other instances where this whiteness loses all that accessory and strange glory which invests it in the White Steed and Albatross. What is it that in the Albino man so peculiarly repels and often shocks the eye, as that sometimes he is loathed by his own kith and kin! It is that whiteness which invests him, a thing expressed by the name he bears. The Albino is as well made as other men --has no substantive deformity --and yet this mere aspect of all-pervading whiteness makes him more strangely hideous than the ugliest abortion. Why should this be so? Nor, in quite other aspects, does Nature in her least palpable but not the less malicious agencies, fail to enlist among her forces this crowning attribute of the terrible. From its snowy aspect, the gauntleted ghost of the Southern Seas has been denominated the White Squall. Nor, in some historic instances, has the art of human malice omitted so potent an auxiliary. How wildly it heightens the effect of that passage in Froissart, when, masked in the snowy symbol of their faction, the desperate White Hoods of Ghent murder their bailiff in the market-place! Nor, in some things, does the common, hereditary experience of all mankind fail to bear witness to the supernaturalism of this hue. It cannot well be doubted, that the one visible quality in the aspect of the dead which most appals the gazer, is the marble pallor lingering there; as if indeed that pallor were as much like the badge of consternation in the other world, as of mortal trepidation here. And from that pallor of the dead, we borrow the expressive hue of the shroud in which we wrap them. Nor even in our superstitions do we fail to throw the same snowy mantle round our phantoms; all ghosts rising in a milk-white fog --Yea, while these terrors seize us, let us add, that even the king of terrors, when personified by the evangelist, rides on his pallid horse. Therefore, in his other moods, symbolize whatever grand or ..

gracious thing he will by whiteness, no man can deny that in its profoundest idealized significance it calls up a peculiar apparition to the soul. But though without dissent this point be fixed, how is mortal man to account for it? To analyse it, would seem impossible. Can we, then, by the citation of some of those instances wherein this thing of whiteness --though for the time either wholly or in great part stripped of all direct associations calculated to impart to it aught fearful, but, nevertheless, is found to exert over us the same sorcery, however modified; --can we thus hope to light upon some chance clue to conduct us to the hidden cause we seek? Let us try. But in a matter like this, subtlety appeals to subtlety, and without imagination no man can follow another into these halls. And though, doubtless, some at least of the imaginative impressions about to be presented may have been shared by most men, yet few perhaps were entirely conscious of them at the time, and therefore may not be able to recall them now. Why to the man of untutored ideality, who happens to be but loosely acquainted with the peculiar character of the day, does the bare mention of Whitsuntide marshal in the fancy such long, dreary, speechless processions of slow-pacing pilgrims, downcast and hooded with new-fallen snow? Or, to the unread, unsophisticated Protestant of the Middle American States, why does the passing mention of a White Friar or a White Nun, evoke such an eyeless statue in the soul? Or what is there apart from the traditions of dungeoned warriors and kings (which will not wholly account for it) that makes the White Tower of London tell so much more strongly on the imagination of an untravelled American, than those other storied structures, its neighbors --the Byward Tower, or even the Bloody? And those sublimer towers, the White Mountains of New Hampshire, whence, in peculiar moods, comes that gigantic ghostliness over the soul at the bare mention of that name, while the thought of Virginia's Blue Ridge is full of a soft, dewy, distant dreaminess? Or why, irrespective of all latitudes and longitudes, does the name of the White Sea exert such a spectralness ..

over the fancy, while that of the Yellow Sea lulls us with mortal thoughts of long lacquered mild afternoons on the waves, followed by the gaudiest and yet sleepiest of sunsets? Or, to choose a wholly unsubstantial instance, purely addressed to the fancy, why, in reading the old fairy tales of Central Europe, does the tall pale man of the Hartz forests, whose changeless pallor unrestingly glides through the green of the groves --why is this phantom more terrible than all the whooping imps of the Blocksburg? Nor is it, altogether, the remembrance of her cathedral-toppling earthquakes; nor the stampedoes of her frantic seas: nor the tearlessness of arid skies that never rain; nor the sight of her wide field of leaning spires, wrenched cope-stones, and crosses all adroop (like canted yards of anchored fleets); and her suburban avenues of house-walls lying over upon each other, as a tossed pack of cards; --it is not these things alone which make tearless Lima, the strangest, saddest city thou can'st see. For Lima has taken the white veil; and there is a higher horror in this whiteness of her woe. Old as Pizarro, this whiteness keeps her ruins for ever new; admits not the cheerful greenness of complete decay; spreads over her broken ramparts the rigid pallor of an apoplexy that fixes its own distortions. I know that, to the common apprehension, this phenomenon of whiteness is not confessed to be the prime agent in exaggerating the terror of objects otherwise terrible; nor to the unimaginative mind is there aught of terror in those appearances whose awfulness to another mind almost solely consists in this one phenomenon, especially when exhibited under any form at all approaching to muteness or universality. What I mean by these two statements may perhaps be respectively elucidated by the following examples. First: The mariner, when drawing nigh the coasts of foreign lands, if by night he hear the roar of breakers, starts to vigilance, and feels just enough of trepidation to sharpen all his faculties; but under precisely similar circumstances, let him be called from his hammock to view his ship sailing through a midnight sea of milky whiteness --as if from encircling headlands shoals of combed white bears were swimming round him, then he feels ..

a silent, superstitious dread; the shrouded phantom of the whitened waters is horrible to him as a real ghost; in vain the lead assures him he is still off soundings; heart and helm they both go down; he never rests till blue water is under him again. Yet where is the mariner who will tell thee, Sir, it was not so much the fear of striking hidden rocks, as the fear of that hideous whiteness that so stirred me? Second: To the native Indian of Peru, the continual sight of the snow-howdahed Andes conveys naught of dread, except, perhaps, in the mere fancying of the eternal frosted desolateness reigning at such vast altitudes, and the natural conceit of what a fearfulness it would be to lose oneself in such inhuman solitudes. Much the same is it with the backwoodsman of the West, who with comparative indifference views an unbounded prairie sheeted with driven snow, no shadow of tree or twig to break the fixed trance of whiteness. Not so the sailor, beholding the scenery of the Antarctic seas; where at times, by some infernal trick of legerdemain in the powers of frost and air, he, shivering and half shipwrecked, instead of rainbows speaking hope and solace to his misery, views what seems a boundless church-yard grinning upon him with its lean ice monuments and splintered crosses. But thou sayest, methinks this white-lead chapter about whiteness is but a white flag hung out from a craven soul; thou surrenderest to a hypo, Ishmael. Tell me, why this strong young colt, foaled in some peaceful valley of Vermont, far removed from all beasts of prey --why is it that upon the sunniest day, if you but shake a fresh buffalo robe behind him, so that he cannot even see it, but only smells its wild animal muskiness --why will he start, snort, and with bursting eyes paw the ground in phrensies of affright? There is no remembrance in him of any gorings of wild creatures in his green northern home, so that the strange muskiness he smells cannot recall to him anything associated with the experience of former perils; for what knows he, this New England colt, of the black bisons of distant oregon? no: but here thou beholdest even in a dumb brute, the instinct of the knowledge of the demonism in the world. Though ..

thousands of miles from Oregon, still when he smells that savage musk, the rending, goring bison herds are as present as to the deserted wild foal of the prairies, which this instant they may be trampling into dust. Thus, then, the muffled rollings of a milky sea; the bleak rustlings of the festooned frosts of mountains; the desolate shiftings of the windrowed snows of prairies; all these, to Ishmael, are as the shaking of that buffalo robe to the frightened colt! Though neither knows where lie the nameless things of which the mystic sign gives forth such hints; yet with me, as with the colt, somewhere those things must exist. Though in many of its aspects this visible world seems formed in love, the invisible spheres were formed in fright. But not yet have we solved the incantation of this whiteness, and learned why it appeals with such power to the soul; and more strange and far more portentous --why, as we have seen, it is at once the most meaning symbol of spiritual things, nay, the very veil of the Christian's Deity; and yet should be as it is, the intensifying agent in things the most appalling to mankind. Is it that by its indefiniteness it shadows forth the heartless voids and immensities of the universe, and thus stabs us from behind with the thought of annihilation, when beholding the white depths of the milky way? Or is it, that as in essence whiteness is not so much a color as the visible absence of color, and at the same time the concrete of all colors; is it for these reasons that there is such a dumb blankness, full of meaning, in a wide landscape of snows --a colorless, all-color of atheism from which we shrink? And when we consider that other theory of the natural philosophers, that all other earthly hues --every stately or lovely emblazoning --the sweet tinges of sunset skies and woods; yea, and the gilded velvets of butterflies, and the butterfly cheeks of young girls; all these are but subtile deceits, not actually inherent in substances, but only laid on from without; so that all deified Nature absolutely paints like the harlot, whose allurements cover nothing but the charnel-house within; and when we proceed further, and consider that the mystical cosmetic which produces every one of her hues, the great principle of light, for ever remains white or colorless in itself, and if ..

operating without medium upon matter, would touch all objects, even tulips and roses, with its own blank tinge --pondering all this, the palsied universe lies before us a leper; and like wilful travellers in Lapland, who refuse to wear colored and coloring glasses upon their eyes, so the wretched infidel gazes himself blind at the monumental white shroud that wraps all the prospect around him. And of all these things the Albino whale was the symbol. Wonder ye then at the fiery hunt? ..

With reference to the Polar bear, it may possibly be urged by him who would fain go still deeper into this matter, that it is not the whiteness, separately regarded, which heightens the intolerable hideousness of that brute; for, analysed, that heightened hideousness, it might be said, only arises from the circumstance, that the irresponsible ferociousness of the creature stands invested in the fleece of celestial innocence and love; and hence, by bringing together two such opposite emotions in our minds, the Polar bear frightens us with so unnatural a contrast. But even assuming all this to be true; yet, were it not for the whiteness, you would not have that intensified terror. As for the white shark, the white gliding ghostliness of repose in that creature, when beheld in his ordinary moods, strangely tallies with the same quality in the Polar quadruped. This peculiarity is most vividly hit by the French in the name they bestow upon that fish. The Romish mass for the dead begins with Requiem eternam (eternal rest), whence Requiem denominating the mass itself, and any other funereal music. Now, in allusion to the white, silent stillness of death in this shark, and the mild deadliness of his habits, the French call him Requin. I remember the first albatross I ever saw. It was during a prolonged gale, in waters hard upon the Antarctic seas. From my forenoon watch below, I ascended to the overclouded deck; and there, dashed upon the main hatches, I saw a regal, feathery thing of unspotted whiteness, and with a hooked, Roman bill sublime. At intervals, it arched forth its vast archangel wings, as if to embrace some holy ark. Wondrous flutterings and throbbings shook it. Though bodily unharmed, it uttered cries, as some king's ghost in supernatural distress. Through its inexpressible, strange eyes, methought I peeped to secrets which took hold of God. As Abraham before the angels, I bowed myself; the white thing was so white, its wings so wide, and in those for ever exiled waters, I had lost the miserable warping memories of traditions and of towns. Long I gazed at that prodigy of plumage. I cannot tell, can only hint, the things that darted through me then. But at last I awoke; and turning, asked a sailor what bird was this. A goney, he replied. Goney! I never had heard that name before; is it conceivable that this glorious thing is utterly unknown to men ashore! never! But some time after, I learned that goney was some seaman's name for albatross. So that by no possibility could Coleridge's wild Rhyme have had ..

aught to do with those mystical impressions which were mine, when I saw that bird upon our deck. For neither had I then read the Rhyme, nor knew the bird to be an albatross. Yet, in saying this, I do but indirectly burnish a little brighter the noble merit of the poem and the poet. I assert, then, that in the wondrous bodily whiteness of the bird chiefly lurks the secret of the spell; a truth the more evinced in this, that by a solecism of terms there are birds called grey albatrosses; and these I have frequently seen, but never with such emotions as when I beheld the Antarctic fowl. But how had the mystic thing been caught? Whisper it not, and I will tell; with a treacherous hook and line, as the fowl floated on the sea. At last the Captain made a postman of it; tying a lettered, leathern tally round its neck, with the ship's time and place; and then letting it escape. But I doubt not, that leathern tally, meant for man, was taken off in Heaven, when the white fowl flew to join the wing-folding, the invoking, and adoring cherubim! ..

.. < chapter xliii 10 HARK > ! Hist! Did you hear that noise, Cabaco? It was the middle-watch; a fair moonlight; the seamen were standing in a cordon, extending from one of the fresh-water butts in the waist, to the scuttle-butt near the taffrail. In this manner, they passed the buckets to fill the scuttle-butt. Standing, for the most part, on the hallowed precincts of the quarter-deck, they were careful not to speak or rustle their feet. From hand to hand, the buckets went in the deepest silence, only broken by the occasional flap of a sail, and the steady hum of the unceasingly advancing keel. It was in the midst of this repose, that Archy, one of the cordon, whose post was near the after-hatches, whispered to his neighbor, a Cholo, the words above. Hist! did you hear that noise, Cabaco? Take the bucket, will ye, Archy? what noise d'ye mean? There it is again --under the hatches --don't you hear it --a cough--it sounded like a cough. Cough be damned! Pass along that return bucket. There again --there it is! --it sounds like two or three sleepers turning over, now! Caramba! have done, shipmate, will ye? It's the three soaked biscuits ye eat for supper turning over inside of ye --nothing else. Look to the bucket! ..

Say what ye will, shipmate; I've sharp ears. Aye, you are the chap, ain't ye, that heard the hum of the old Quakeress's knitting-needles fifty miles at sea from Nantucket; you're the chap. Grin away; we'll see what turns up. Hark ye, Cabaco, there is somebody down in the after-hold that has not yet been seen on deck; and I suspect our old Mogul knows something of it too. I heard Stubb tell Flask, one morning watch, that there was something of that sort in the wind. Tish! the bucket! ..

.. < chapter xliv 12 THE CHART > Had you followed Captain Ahab down into his cabin after the squall that took place on the night succeeding that wild ratification of his purpose with his crew, you would have seen him go to a locker in the transom, and bringing out a large wrinkled roll of yellowish sea charts, spread them before him on his screwed-down table. Then seating himself before it, you would have seen him intently study the various lines and shadings which there met his eye; and with slow but steady pencil trace additional courses over spaces that before were blank. At intervals, he would refer to piles of old log-books beside him, wherein were set down the seasons and places in which, on various former voyages of various ships, sperm whales had been captured or seen. While thus employed, the heavy pewter lamp suspended in chains over his head, continually rocked with the motion of the ship, and for ever threw shifting gleams and shadows of lines upon his wrinkled brow, till it almost seemed that while he himself was marking out lines and courses on the wrinkled charts, some invisible pencil was also tracing lines and courses upon the deeply marked chart of his forehead. But it was not this night in particular that, in the solitude of ..

his cabin, Ahab thus pondered over his charts. Almost every night they were brought out; almost every night some pencil marks were effaced, and others were substituted. For with the charts of all four oceans before him, Ahab was threading a maze of currents and eddies, with a view to the more certain accomplishment of that monomaniac thought of his soul. Now, to any one not fully acquainted with the ways of the leviathans, it might seem an absurdly hopeless task thus to seek out one solitary creature in the unhooped oceans of this planet. But not so did it seem to Ahab, who knew the sets of all tides and currents; and thereby calculating the driftings of the sperm whale's food; and, also, calling to mind the regular, ascertained seasons for hunting him in particular latitudes; could arrive at reasonable surmises, almost approaching to certainties, concerning the timeliest day to be upon this or that ground in search of his prey. So assured, indeed, is the fact concerning the periodicalness of the sperm whale's resorting to given waters, that many hunters believe that, could he be closely observed and studied throughout the world; were the logs for one voyage of the entire whale fleet carefully collated, then the migrations of the sperm whale would be found to correspond in invariability to those of the herring-shoals or the flights of swallows. On this hint, attempts have been made to construct elaborate migratory charts of the sperm whale. Besides, when making a passage from one feeding-ground to another, the sperm whales, guided by some infallible instinct -- say, rather, secret intelligence from the Deity --mostly swim in ..

veins, as they are called; continuing their way along a given ocean-line with such undeviating exactitude, that no ship ever sailed her course, by any chart, with one tithe of such marvellous precision. Though, in these cases, the direction taken by any one whale be straight as a surveyor's parallel, and though the line of advance be strictly confined to its own unavoidable, straight wake, yet the arbitrary vein in which at these times he is said to swim, generally embraces some few miles in width (more or less, as the vein is presumed to expand or contract); but never exceeds the visual sweep from the whale-ship's mast-heads, when circumspectly gliding along this magic zone. The sum is, that at particular seasons within that breadth and along that path, migrating whales may with great confidence be looked for. And hence not only at substantiated times, upon well known separate feeding-grounds, could Ahab hope to encounter his prey; but in crossing the widest expanses of water between those grounds he could, by his art, so place and time himself on his way, as even then not to be wholly without prospect of a meeting. There was a circumstance which at first sight seemed to entangle his delirious but still methodical scheme. But not so in the reality, perhaps. Though the gregarious sperm whales have their regular seasons for particular grounds, yet in general you cannot conclude that the herds which hunted such and such a latitude or longitude this year, say, will turn out to be identically the same with those that were found there the preceding season; though there are peculiar and unquestionable instances where the contrary of this has proved true. In general, the same remark, only within a less wide limit, applies to the solitaries and hermits among the matured, aged sperm whales. So that though Moby Dick had in a former year been seen, for example, on what is called the Seychelle ground in the Indian ocean, or Volcano Bay on the Japanese Coast; yet it did not follow, that were the pequod to visit either of those spots at any subsequent corresponding season, she would infallibly encounter him there. So, too, with some other feeding grounds, where he had at times revealed himself. But all these seemed only his casual stopping-places and ocean-inns, so to speak, not his places of prolonged abode. And where Ahab's chances of accomplishing ..

his object have hitherto been spoken of, allusion has only been made to whatever way-side, antecedent, extra prospects were his, ere a particular set time or place were attained, when all possibilities would become probabilities, and, as Ahab fondly thought, every possibility the next thing to a certainty. That particular set time and place were conjoined in the one technical phrase --the Season-on-the-Line. For there and then, for several consecutive years, Moby Dick had been periodically descried, lingering in those waters for awhile, as the sun, in its annual round, loiters for a predicted interval in any one sign of the Zodiac. There it was, too, that most of the deadly encounters with the white whale had taken place; there the waves were storied with his deeds; there also was that tragic spot where the monomaniac old man had found the awful motive to his vengeance. But in the cautious comprehensiveness and unloitering vigilance with which Ahab threw his brooding soul into this unfaltering hunt, he would not permit himself to rest all his hopes upon the one crowning fact above mentioned, however flattering it might be to those hopes; nor in the sleeplessness of his vow could he so tranquillize his unquiet heart as to postpone all intervening quest. Now, the Pequod had sailed from Nantucket at the very beginning of the Season-on-the-Line. No possible endeavor then could enable her commander to make the great passage southwards, double Cape Horn, and then running down sixty degrees of latitude arrive in the equatorial Pacific in time to cruise there. Therefore, he must wait for the next ensuing season. Yet the premature hour of the Pequod's sailing had, perhaps, been correctly selected by Ahab, with a view to this very complexion of things. Because, an interval of three hundred and sixty-five days and nights was before him; an interval which, instead of impatiently enduring ashore, he would spend in a miscellaneous hunt; if by chance the White Whale, spending his vacation in seas far remote from his periodical feeding-grounds, should turn up his wrinkled brow off the Persian Gulf, or in the Bengal Bay, or China Seas, or in any other waters haunted by his race. So that Monsoons, Pampas, Nor-Westers, Harmattans, Trades; any wind but the Levanter and Simoom, might blow Moby Dick into ..

the devious zig-zag world-circle of the Pequod's circumnavigating wake. But granting all this; yet, regarded discreetly and coolly, seems it not but a mad idea, this; that in the broad boundless ocean, one solitary whale, even if encountered, should be thought capable of individual recognition from his hunter, even as a white-bearded Mufti in the thronged thoroughfares of Constantinople? Yes. For the peculiar snow-white brow of Moby Dick, and his snow-white hump, could not but be unmistakable. And have I not tallied the whale, Ahab would mutter to himself, as after poring over his charts till long after midnight he would throw himself back in reveries --tallied him, and shall he escape? His broad fins are bored, and scalloped out like a lost sheep's ear! And here, his mad mind would run on in a breathless race; till a weariness and faintness of pondering came over him; and in the open air of the deck he would seek to recover his strength. Ah, God! what trances of torments does that man endure who is consumed with one unachieved revengeful desire. He sleeps with clenched hands; and wakes with his own bloody nails in his palms. often, when forced from his hammock by exhausting and intolerably vivid dreams of the night, which, resuming his own intense thoughts through the day, carried them on amid a clashing of phrensies, and whirled them round and round in his blazing brain, till the very throbbing of his life-spot became insufferable anguish; and when, as was sometimes the case, these spiritual throes in him heaved his being up from its base, and a chasm seemed opening in him, from which forked flames and lightnings shot up, and accursed fiends beckoned him to leap down among them; when this hell in himself yawned beneath him, a wild cry would be heard through the ship; and with glaring eyes Ahab would burst from his state room, as though escaping from a bed that was on fire. Yet these, perhaps, instead of being the unsuppressable symptoms of some latent weakness, or fright at his own resolve, were but the plainest tokens of its intensity. For, at such times, crazy Ahab, the scheming, unappeasedly steadfast hunter of the white whale; this Ahab that had gone to his hammock, was not the agent that so caused ..

him to burst from it in horror again. The latter was the eternal, living principle or soul in him; and in sleep, being for the time dissociated from the characterizing mind, which at other times employed it for its outer vehicle or agent, it spontaneously sought escape from the scorching contiguity of the frantic thing, of which, for the time, it was no longer an integral. But as the mind does not exist unless leagued with the soul, therefore it must have been that, in Ahab's case, yielding up all his thoughts and fancies to his one supreme purpose; that purpose, by its own sheer inveteracy of will, forced itself against gods and devils into a kind of self-assumed, independent being of its own. Nay, could grimly live and burn, while the common vitality to which it was conjoined, fled horror-stricken from the unbidden and unfathered birth. Therefore, the tormented spirit that glared out of bodily eyes, when what seemed Ahab rushed from his room, was for the time but a vacated thing, a formless somnambulistic being, a ray of living light, to be sure, but without an object to color, and therefore a blankness in itself. God help thee, old man, thy thoughts have created a creature in thee; and he whose intense thinking thus makes him a Prometheus; a vulture feeds upon that heart for ever; that vulture the very creature he creates. ..

Since the above was written, the statement is happily borne out by an official circular, issued by Lieutenant Maury, of the National Observatory, Washington, April 16th, . By that circular, it appears that precisely such a chart is in course of completion; and portions of it are presented in the circular. This chart divides the ocean into districts of five degrees of latitude by five degrees of longitude; perpendicularly through each of which districts are twelve columns for the twelve months; and horizontally through each of which districts are three lines; one to show the number of days that have been spent in each month in every district, and the two others to show the number of days in which whales, sperm or right, have been seen. ..

.. < chapter xlv 24 THE AFFIDAVIT > So far as what there may be of a narrative in this book; and, indeed, as indirectly touching one or two very interesting and curious particulars in the habits of sperm whales, the foregoing chapter, in its earliest part, is as important a one as will be found in this volume; but the leading matter of it requires to be still further and more familiarly enlarged upon, in order to be adequately understood, and moreover to take away any incredulity which a profound ignorance of the entire subject may ..

induce in some minds, as to the natural verity of the main points of this affair. I care not to perform this part of my task methodically; but shall be content to produce the desired impression by separate citations of items, practically or reliably known to me as a whaleman; and from these citations, I take it --the conclusion aimed at will naturally follow of itself. First: I have personally known three instances where a whale, after receiving a harpoon, has effected a complete escape; and, after an interval (in one instance of three years), has been again struck by the same hand, and slain; when the two irons, both marked by the same private cypher, have been taken from the body. In the instance where three years intervened between the flinging of the two harpoons; and I think it may have been something more than that; the man who darted them happening, in the interval, to go in a trading ship on a voyage to Africa, went ashore there, joined a discovery party, and penetrated far into the interior, where he travelled for a period of nearly two years, often endangered by serpents, savages, tigers, poisonous miasmas, with all the other common perils incident to wandering in the heart of unknown regions. Meanwhile, the whale he had struck must also have been on its travels; no doubt it had thrice circumnavigated the globe, brushing with its flanks all the coasts of Africa; but to no purpose. This man and this whale again came together, and the one vanquished the other. I say I, myself, have known three instances similar to this; that is in two of them I saw the whales struck; and, upon the second attack, saw the two irons with the respective marks cut in them, afterwards taken from the dead fish. In the three-year instance, it so fell out that I was in the boat both times, first and last, and the last time distinctly recognized a peculiar sort of huge mole under the whale's eye, which I had observed there three years previous. I say three years, but I am pretty sure it was more than that. Here are three instances, then, which I personally know the truth of; but I have heard of many other instances from persons whose veracity in the matter there is no good ground to impeach. secondly: It is well known in the Sperm Whale Fishery, ..

however ignorant the world ashore may be of it, that there have been several memorable historical instances where a particular whale in the ocean has been at distant times and places popularly cognisable. Why such a whale became thus marked was not altogether and originally owing to his bodily peculiarities as distinguished from other whales; for however peculiar in that respect any chance whale may be, they soon put an end to his peculiarities by killing him, and boiling him down into a peculiarly valuable oil. No: the reason was this: that from the fatal experiences of the fishery there hung a terrible prestige of perilousness about such a whale as there did about Rinaldo Rinaldini, insomuch that most fishermen were content to recognise him by merely touching their tarpaulins when he would be discovered lounging by them on the sea, without seeking to cultivate a more intimate acquaintance. Like some poor devils ashore that happen to know an irascible great man, they make distant unobtrusive salutations to him in the street, lest if they pursued the acquaintance further, they might receive a summary thump for their presumption. But not only did each of these famous whales enjoy great individual celebrity --nay, you may call it an ocean-wide renown; not only was he famous in life and now is immortal in forecastle stories after death, but he was admitted into all the rights, privileges, and distinctions of a name; had as much a name indeed as Cambyses or Caesar. Was it not so, O Timor Tom! thou famed leviathan, scarred like an iceberg, who so long did'st lurk in the Oriental straits of that name, whose spout was oft seen from the palmy beach of Ombay? Was it not so, O New Zealand Jack! thou terror of all cruisers that crossed their wakes in the vicinity of the Tattoo Land? Was it not so, O Morquan! King of Japan, whose lofty jet they say at times assumed the semblance of a snow-white cross against the sky? Was it not so, O Don Miguel! thou Chilian whale, marked like an old tortoise with mystic hieroglyphics upon the back! In plain prose, here are four whales as well known to the students of Cetacean History as Marius or Sylla to the classic scholar. But this is not all. New Zealand Tom and Don Miguel, after at various times creating great havoc among the boats of different ..

vessels, were finally gone in quest of, systematically hunted out, chased and killed by valiant whaling captains, who heaved up their anchors with that express object as much in view, as in setting out through the Narragansett Woods, Captain Butler of old had it in his mind to capture that notorious murderous savage Annawon, the headmost warrior of the Indian King Philip. I do not know where I can find a better place than just here, to make mention of one or two other things, which to me seem important, as in printed form establishing in all respects the reasonableness of the whole story of the White Whale, more especially the catastrophe. For this is one of those disheartening instances where truth requires full as much bolstering as error. So ignorant are most landsmen of some of the plainest and most palpable wonders of the world, that without some hints touching the plain facts, historical and otherwise, of the fishery, they might scout at Moby Dick as a monstrous fable, or still worse and more detestable, a hideous and intolerable allegory. First: Though most men have some vague flitting ideas of the general perils of the grand fishery, yet they have nothing like a fixed, vivid conception of those perils, and the frequency with which they recur. One reason perhaps is, that not one in fifty of the actual disasters and deaths by casualties in the fishery, ever finds a public record at home, however transient and immediately forgotten that record. Do you suppose that that poor fellow there, who this moment perhaps caught by the whale-line off the coast of New Guinea, is being carried down to the bottom of the sea by the sounding leviathan --do you suppose that that poor fellow's name will appear in the newspaper obituary you will read to-morrow at your breakfast? No: because the mails are very irregular between here and New Guinea. In fact, did you ever hear what might be called regular news direct or indirect from New Guinea? Yet I tell you that upon one particular voyage which I made to the Pacific, among many others we spoke thirty different ships, every one of which had had a death by a whale, some of them more than one, and three that had each lost a boat's crew. For God's sake, be economical with your lamps and candles! not a gallon you burn, but at least one drop of man's blood was spilled for it. ..

Secondly: People ashore have indeed some indefinite idea that a whale is an enormous creature of enormous power; but I have ever found that when narrating to them some specific example of this two-fold enormousness, they have significantly complimented me upon my facetiousness; when, I declare upon my soul, I had no more idea of being facetious than Moses, when he wrote the history of the plagues of Egypt. But fortunately the special point I here seek can be established upon testimony entirely independent of my own. That point is this: The Sperm Whale is in some cases sufficiently powerful, knowing, and judiciously malicious, as with direct aforethought to stave in, utterly destroy, and sink a large ship; and what is more, the Sperm Whale has done it. First: In the year the ship Essex, Captain Pollard, of Nantucket, was cruising in the Pacific Ocean. One day she saw spouts, lowered her boats, and gave chase to a shoal of sperm whales. Ere long, several of the whales were wounded; when, suddenly, a very large whale escaping from the boats, issued from the shoal, and bore directly down upon the ship. dashing his forehead against her hull, he so stove her in, that in less than ten minutes she settled down and fell over. Not a surviving plank of her has been seen since. After the severest exposure, part of the crew reached the land in their boats. Being returned home at last, Captain Pollard once more sailed for the Pacific in command of another ship, but the gods shipwrecked him again upon unknown rocks and breakers; for the second time his ship was utterly lost, and forthwith forswearing the sea, he has never tempted it since. At this day Captain Pollard is a resident of Nantucket. I have seen Owen Chace, who was chief mate of the Essex at the time of the tragedy; I have read his plain and faithful narrative; I have conversed with his son; and all this within a few miles of the scene of the catastrophe. ..

Secondly: The ship Union, also of Nantucket, was in the year totally lost off the Azores by a similar onset, but the authentic particulars of this catastrophe I have never chanced to encounter, though from the whale hunters I have now and then heard casual allusions to it. Thirdly: Some eighteen or twenty years ago Commodore J--- then commanding an American sloop-of-war of the first class, happened to be dining with a party of whaling captains, on board a Nantucket ship in the harbor of Oahu, Sandwich Islands. Conversation turning upon whales, the Commodore was pleased to be sceptical touching the amazing strength ascribed to them by the professional gentlemen present. He peremptorily denied for example, that any whale could so smite his stout sloop-of-war as to cause her to leak so much as a thimbleful. Very good; but there is more coming. Some weeks after, the commodore set sail in this impregnable craft for Valparaiso. But he was stopped on the way by a portly sperm whale, that begged a few moments' confidential business with him. that business consisted in fetching the Commodore's craft ..

such a thwack, that with all his pumps going he made straight for the nearest port to heave down and repair. I am not superstitious, but I consider the Commodore's interview with that whale as providential. Was not Saul of Tarsus converted from unbelief by a similar fright? I tell you, the sperm whale will stand no nonsense. I will now refer you to Langsdorff's Voyages for a little circumstance in point, peculiarly interesting to the writer hereof. Langsdorff, you must know by the way, was attached to the Russian Admiral Krusenstern's famous Discovery Expedition in the beginning of the present century. Captain Langsdorff thus begins his seventeenth chapter. By the thirteenth of May our ship was ready to sail, and the next day we were out in the open sea, on our way to Ochotsh. The weather was very clear and fine, but so intolerably cold that we were obliged to keep on our fur clothing. For some days we had very little wind; it was not till the nineteenth that a brisk gale from the northwest sprang up. An uncommon large whale, the body of which was larger than the ship itself, lay almost at the surface of the water, but was not perceived by any one on board till the moment when the ship, which was in full sail, was almost upon him, so that it was impossible to prevent its striking against him. We were thus placed in the most imminent danger, as this gigantic creature, setting up its back, raised the ship three feet at least out of the water. The masts reeled, and the sails fell altogether, while we who were below all sprang instantly upon the deck, concluding that we had struck upon some rock; instead of this we saw the monster sailing off with the utmost gravity and solemnity. Captain D'Wolf applied immediately to the pumps to examine whether or not the vessel had received any damage from the shock, but we found that very happily it had escaped entirely uninjured. now, the captain d'wolf here alluded to as commanding the ship in question, is a New Englander, who, after a long life of unusual adventures as a sea-captain, this day resides in the village of Dorchester near Boston. I have the honor of being a nephew of his. I have particularly questioned him concerning this passage in Langsdorff. He substantiates every word. ..

The ship, however, was by no means a large one: a Russian craft built on the Siberian coast, and purchased by my uncle after bartering away the vessel in which he sailed from home. In that up and down manly book of old-fashioned adventure, so full, too, of honest wonders --the voyage of Lionel Wafer, one of ancient Dampier's old chums --I found a little matter set down so like that just quoted from Langsdorff, that I cannot forbear inserting it here for a corroborative example, if such be needed. Lionel, it seems, was on his way to John Ferdinando, as he calls the modern Juan Fernandes. In our way thither, he says, about four o'clock in the morning, when we were about one hundred and fifty leagues from the Main of America, our ship felt a terrible shock, which put our men in such consternation that they could hardly tell where they were or what to think; but every one began to prepare for death. And, indeed, the shock was so sudden and violent, that we took it for granted the ship had struck against a rock; but when the amazement was a little over, we cast the lead, and sounded, but found no ground. The suddenness of the shock made the guns leap in their carriages, and several of the men were shaken out of their hammocks. Captain Davis, who lay with his head on a gun, was thrown out of his cabin! Lionel then goes on to impute the shock to an earthquake, and seems to substantiate the imputation by stating that a great earthquake, somewhere about that time, did actually do great mischief along the spanish land. but i should not much wonder if, in the darkness of that early hour of the morning, the shock was after all caused by an unseen whale vertically bumping the hull from beneath. I might proceed with several more examples, one way or another known to me, of the great power and malice at times of the sperm whale. In more than one instance, he has been known, not only to chase the assailing boats back to their ships, but to pursue the ship itself, and long withstand all the lances hurled at him from its decks. The English ship Pusie Hall can tell a story on that head; and, as for his strength, let me say, that there have been examples where the lines attached to ..

a running sperm whale have, in a calm, been transferred to the ship, and secured there; the whale towing her great hull through the water, as a horse walks off with a cart. Again, it is very often observed that, if the sperm whale, once struck, is allowed time to rally, he then acts, not so often with blind rage, as with wilful, deliberate designs of destruction to his pursuers; nor is it without conveying some eloquent indication of his character, that upon being attacked he will frequently open his mouth, and retain it in that dread expansion for several consecutive minutes. But I must be content with only one more and a concluding illustration; a remarkable and most significant one, by which you will not fail to see, that not only is the most marvellous event in this book corroborated by plain facts of the present day, but that these marvels (like all marvels) are mere repetitions of the ages; so that for the millionth time we say amen with Solomon --Verily there is nothing new under the sun. In the sixth Christian century lived Procopius, a Christian magistrate of Constantinople, in the days when Justinian was Emperor and Belisarius general. As many know, he wrote the history of his own times, a work every way of uncommon value. By the best authorities, he has always been considered a most trustworthy and unexaggerating historian, except in some one or two particulars, not at all affecting the matter presently to be mentioned. Now, in this history of his, Procopius mentions that, during the term of his prefecture at Constantinople, a great sea-monster was captured in the neighboring Propontis, or Sea of Marmora, after having destroyed vessels at intervals in those waters for a period of more than fifty years. A fact thus set down in substantial history cannot easily be gainsaid. Nor is there any reason it should be. Of what precise species this sea-monster was, is not mentioned. But as he destroyed ships, as well as for other reasons, he must have been a whale; and I am strongly inclined to think a sperm whale. And I will tell you why. For a long time I fancied that the sperm whale had been always unknown in the Mediterranean and the deep waters connecting with it. Even now I am certain that those seas are not, and perhaps never can be, in the present constitution of ..

things, a place for his habitual gregarious resort. But further investigations have recently proved to me, that in modern times there have been isolated instances of the presence of the sperm whale in the Mediterranean. I am told, on good authority, that on the Barbary coast, a Commodore Davis of the British navy found the skeleton of a sperm whale. Now, as a vessel of war readily passes through the Dardanelles, hence a sperm whale could, by the same route, pass out of the Mediterranean into the Propontis. In the Propontis, as far as I can learn, none of that peculiar substance called brit is to be found, the aliment of the right whale. But I have every reason to believe that the food of the sperm whale --squid or cuttle-fish --lurks at the bottom of that sea, because large creatures, but by no means the largest of that sort, have been found at its surface. If, then, you properly put these statements together, and reason upon them a bit, you will clearly perceive that, according to all human reasoning, Procopius's sea-monster, that for half a century stove the ships of a Roman Emperor, must in all probability have been a sperm whale. ..

The following are extracts from Chace's narrative: Every fact seemed to warrant me in concluding that it was anything but chance which directed his operations; he made two several attacks upon the ship, at a short interval between them, both of which, according to their direction, were calculated to do us the most injury, by being made ahead, and thereby ..

combining the speed of the two objects for the shock; to effect which, the exact manoeuvres which he made were necessary. His aspect was most horrible, and such as indicated resentment and fury. He came directly from the shoal which we had just before entered, and in which we had struck three of his companions, as if fired with revenge for their sufferings. Again: At all events, the whole circumstances taken together, all happening before my own eyes, and producing, at the time, impressions in my mind of decided, calculating mischief, on the part of the whale (many of which impressions I cannot now recall), induce me to be satisfied that I am correct in my opinion. Here are his reflections some time after quitting the ship, during a black night in an open boat, when almost despairing of reaching any hospitable shore. The dark ocean and swelling waters were nothing; the fears of being swallowed up by some dreadful tempest, or dashed upon hidden rocks, with all the other ordinary subjects of fearful contemplation, seemed scarcely entitled to a moment's thought; the dismal looking wreck, and the horrid aspect and revenge of the whale, wholly engrossed my reflections, until day again made its appearance. In another place --p. 45, --he speaks of the mysterious and mortal attack of the animal. ..

.. < chapter xlvi 22 SURMISES > Though, consumed with the hot fire of his purpose, Ahab in all his thoughts and actions ever had in view the ultimate capture of Moby Dick; though he seemed ready to sacrifice all mortal interests to that one passion; nevertheless it may have been that he was by nature and long habituation far too wedded to a fiery whaleman's ways, altogether to abandon the collateral prosecution of the voyage. Or at least if this were otherwise, there were not wanting other motives much more influential with him. It would be refining too much, perhaps, even considering his monomania, to hint that his vindictiveness towards ..

the White Whale might have possibly extended itself in some degree to all sperm whales, and that the more monsters he slew by so much the more he multiplied the chances that each subsequently encountered whale would prove to be the hated one he hunted. But if such an hypothesis be indeed exceptionable, there were still additional considerations which, though not so strictly according with the wildness of his ruling passion, yet were by no means incapable of swaying him. To accomplish his object Ahab must use tools; and of all tools used in the shadow of the moon, men are most apt to get out of order. He knew, for example, that however magnetic his ascendency in some respects was over Starbuck, yet that ascendency did not cover the complete spiritual man any more than mere corporeal superiority involves intellectual mastership; for to the purely spiritual, the intellectual but stand in a sort of corporeal relation. Starbuck's body and Starbuck's coerced will were Ahab's, so long as Ahab kept his magnet at Starbuck's brain; still he knew that for all this the chief mate, in his soul, abhorred his captain's quest, and could he, would joyfully disintegrate himself from it, or even frustrate it. it might be that a long interval would elapse ere the White Whale was seen. During that long interval Starbuck would ever be apt to fall into open relapses of rebellion against his captain's leadership, unless some ordinary, prudential, circumstantial influences were brought to bear upon him. Not only that, but the subtle insanity of Ahab respecting Moby Dick was noways more significantly manifested than in his superlative sense and shrewdness in foreseeing that, for the present, the hunt should in some way be stripped of that strange imaginative impiousness which naturally invested it; that the full terror of the voyage must be kept withdrawn into the obscure background (for few men's courage is proof against protracted meditation unrelieved by action); that when they stood their long night watches, his officers and men must have some nearer things to think of than Moby Dick. For however eagerly and impetuously the savage crew had hailed the announcement of his quest; yet all sailors of all sorts are more or less capricious and unreliable --they live in the varying outer weather, and they inhale its fickleness --and when retained ..

for any object remote and blank in the pursuit, however promissory of life and passion in the end, it is above all things requisite that temporary interests and employment should intervene and hold them healthily suspended for the final dash. Nor was Ahab unmindful of another thing. In times of strong emotion mankind disdain all base considerations; but such times are evanescent. The permanent constitutional condition of the manufactured man, thought Ahab, is sordidness. Granting that the White Whale fully incites the hearts of this my savage crew, and playing round their savageness even breeds a certain generous knight-errantism in them, still, while for the love of it they give chase to Moby Dick, they must also have food for their more common, daily appetites. For even the high lifted and chivalric Crusaders of old times were not content to traverse two thousand miles of land to fight for their holy sepulchre, without committing burglaries, picking pockets, and gaining other pious perquisites by the way. Had they been strictly held to their one final and romantic object --that final and romantic object, too many would have turned from in disgust. I will not strip these men, thought Ahab, of all hopes of cash --aye, cash. They may scorn cash now; but let some months go by, and no perspective promise of it to them, and then this same quiescent cash all at once mutinying in them, this same cash would soon cashier Ahab. Nor was there wanting still another precautionary motive more related to Ahab personally. Having impulsively, it is probable, and perhaps somewhat prematurely revealed the prime but private purpose of the Pequod's voyage, Ahab was now entirely conscious that, in so doing, he had indirectly laid himself open to the unanswerable charge of usurpation; and with perfect impunity, both moral and legal, his crew if so disposed, and to that end competent, could refuse all further obedience to him, and even violently wrest from him the command. From even the barely hinted imputation of usurpation, and the possible consequences of such a suppressed impression gaining ground, Ahab must of course have been most anxious to protect himself. That protection could only consist in his own predominating brain and heart and hand, backed by a heedful, closely calculating ..

attention to every minute atmospheric influence which it was possible for his crew to be subjected to. For all these reasons then, and others perhaps too analytic to be verbally developed here, Ahab plainly saw that he must still in a good degree continue true to the natural, nominal purpose of the Pequod's voyage; observe all customary usages; and not only that, but force himself to evince all his well known passionate interest in the general pursuit of his profession. be all this as it may, his voice was now often heard hailing the three mast-heads and admonishing them to keep a bright look-out, and not omit reporting even a porpoise. This vigilance was not long without reward. ..

.. < chapter xlvii 14 THE MAT-MAKER > It was a cloudy, sultry afternoon; the seamen were lazily lounging about the decks, or vacantly gazing over into the lead-colored waters. Queequeg and I were mildly employed weaving what is called a sword-mat, for an additional lashing to our boat. So still and subdued and yet somehow preluding was all the scene, and such an incantation of revery lurked in the air, that each silent sailor seemed resolved into his own invisible self. I was the attendant or page of Queequeg, while busy at the mat. As I kept passing and repassing the filling or woof of marline between the long yarns of the warp, using my own hand for the shuttle, and as Queequeg, standing sideways, ever and anon slid his heavy oaken sword between the threads, and idly looking off upon the water, carelessly and unthinkingly drove home every yarn: I say so strange a dreaminess did there then reign all over the ship and all over the sea, only broken by the intermitting dull sound of the sword, that it seemed as if this were the Loom of Time, and I myself were a shuttle mechanically weaving and weaving away at the Fates. There lay the fixed ..

threads of the warp subject to but one single, ever returning, unchanging vibration, and that vibration merely enough to admit of the crosswise interblending of other threads with its own. This warp seemed necessity; and here, thought I, with my own hand I ply my own shuttle and weave my own destiny into these unalterable threads. Meantime, Queequeg's impulsive, indifferent sword, sometimes hitting the woof slantingly, or crookedly, or strongly, or weakly, as the case might be; and by this difference in the concluding blow producing a corresponding contrast in the final aspect of the completed fabric; this savage's sword, thought I, which thus finally shapes and fashions both warp and woof; this easy, indifferent sword must be chance --aye, chance, free will, and necessity --no wise incompatible --all interweavingly working together. The straight warp of necessity, not to be swerved from its ultimate course --its every alternating vibration, indeed, only tending to that; free will still free to ply her shuttle between given threads; and chance, though restrained in its play within the right lines of necessity, and sideways in its motions directed by free will, though thus prescribed to by both, chance by turns rules either, and has the last featuring blow at events. Thus we were weaving and weaving away when I started at a sound so strange, long drawn, and musically wild and unearthly, that the ball of free will dropped from my hand, and I stood gazing up at the clouds whence that voice dropped like a wing. High aloft in the cross-trees was that mad Gay-Header, Tashtego. His body was reaching eagerly forward, his hand stretched out like a wand, and at brief sudden intervals he continued his cries. To be sure the same sound was that very moment perhaps being heard all over the seas, from hundreds of whalemen's look-outs perched as high in the air; but from few of those lungs could that accustomed old cry have derived such a marvellous cadence as from Tashtego the Indian's. As he stood hovering over you half suspended in air, so wildly and eagerly peering towards the horizon, you would have thought him some prophet or seer beholding the shadows of Fate, and by those wild cries announcing their coming. There she blows! there! there! there! she blows! she blows! ..

Where-away? On the lee-beam, about two miles off! a school of them! Instantly all was commotion. The Sperm Whale blows as a clock ticks, with the same undeviating and reliable uniformity. And thereby whalemen distinguish this fish from other tribes of his genus. There go flukes! was now the cry from Tashtego; and the whales disappeared. Quick, steward! cried Ahab. Time! time! Dough-Boy hurried below, glanced at the watch, and reported the exact minute to Ahab. The ship was now kept away from the wind, and she went gently rolling before it. Tashtego reporting that the whales had gone down heading to leeward, we confidently looked to see them again directly in advance of our bows. For that singular craft at times evinced by the Sperm Whale when, sounding with his head in one direction, he nevertheless, while concealed beneath the surface, mills round, and swiftly swims off in the opposite quarter --this deceitfulness of his could not now be in action; for there was no reason to suppose that the fish seen by Tashtego had been in any way alarmed, or indeed knew at all of our vicinity. One of the men selected for shipkeepers -- that is, those not appointed to the boats, by this time relieved the Indian at the main-mast head. The sailors at the fore and mizzen had come down; the line tubs were fixed in their places; the cranes were thrust out; the mainyard was backed, and the three boats swung over the sea like three samphire baskets over high cliffs. Outside of the bulwarks their eager crews with one hand clung to the rail, while one foot was expectantly poised on the gunwale. So look the long line of man-of-war's men about to throw themselves on board an enemy's ship. But at this critical instant a sudden exclamation was heard that took every eye from the whale. With a start all glared at dark Ahab, who was surrounded by five dusky phantoms that seemed fresh formed out of air. ..

.. < chapter xlviii 2 THE FIRST LOWERING > The phantoms, for so they then seemed, were flitting on the other side of the deck, and, with a noiseless celerity, were casting loose the tackles and bands of the boat which swung there. This boat had always been deemed one of the spare boats, though technically called the captain's, on account of its hanging from the starboard quarter. The figure that now stood by its bows was tall and swart, with one white tooth evilly protruding from its steel-like lips. A rumpled Chinese jacket of black cotton funereally invested him, with wide black trowsers of the same dark stuff. But strangely crowning his ebonness was a glistening white plaited turban, the living hair braided and coiled round and round upon his head. Less swart in aspect, the companions of this figure were of that vivid, tiger-yellow complexion peculiar to some of the aboriginal natives of the Manillas; --a race notorious for a certain diabolism of subtilty, and by some honest white mariners supposed to be the paid spies and secret confidential agents on the water of the devil, their lord, whose counting-room they suppose to be elsewhere. While yet the wondering ship's company were gazing upon these strangers, Ahab cried out to the white-turbaned old man at their head, All ready there, Fedallah? Ready, was the half-hissed reply. Lower away then; d'ye hear? shouting across the deck. Lower away there, I say. Such was the thunder of his voice, that spite of their amazement the men sprang over the rail; the sheaves whirled round in the blocks; with a wallow, the three boats dropped into the sea; while, with a dexterous, off-handed daring, unknown in any other vocation, the sailors, goat-like, leaped down the rolling ship's side into the tossed boats below. Hardly had they pulled out from under the ship's lee, when ..

a fourth keel, coming from the windward side, pulled round under the stern, and showed the five strangers rowing Ahab, who, standing erect in the stern, loudly hailed Starbuck, Stubb, and Flask, to spread themselves widely, so as to cover a large expanse of water. but with all their eyes again riveted upon the swart Fedallah and his crew, the inmates of the other boats obeyed not the command. Captain Ahab?-- said Starbuck. Spread yourselves, cried Ahab; give way, all four boats. Thou, Flask, pull out more to leeward! Aye, aye, sir, cheerily cried little King-Post, sweeping round his great steering oar. Lay back! addressing his crew. There! --there! --there again! There she blows right ahead, boys! -- lay back! Never heed yonder yellow boys, Archy. Oh, I don't mind 'em, sir, said Archy; I knew it all before now. Didn't I hear 'em in the hold? And didn't I tell Cabaco here of it? What say ye, Cabaco? They are stowaways, Mr. Flask. Pull, pull, my fine hearts-alive; pull, my children; pull, my little ones, drawingly and soothingly sighed Stubb to his crew, some of whom still showed signs of uneasiness. Why don't you break your backbones, my boys? What is it you stare at? Those chaps in yonder boat? Tut! They are only five more hands come to help us --never mind from where --the more the merrier. Pull, then, do pull; never mind the brimstone --devils are good fellows enough. So, so; there you are now; that's the stroke for a thousand pounds; that's the stroke to sweep the stakes! Hurrah for the gold cup of sperm oil, my heroes! Three cheers, men --all hearts alive! Easy, easy; don't be in a hurry --don't be in a hurry. Why don't you snap your oars, you rascals? Bite something, you dogs! So, so, so, then; --softly, softly! That's it -- that's it! long and strong. Give way there, give way! The devil fetch ye, ye ragamuffin rapscallions; ye are all asleep. Stop snoring, ye sleepers, and pull. Pull, will ye? pull, can't ye? pull, won't ye? Why in the name of gudgeons and ginger-cakes don't ye pull? --pull and break something! pull, and start your ..

eyes out! Here! whipping out the sharp knife from his girdle; every mother's son of ye draw his knife, and pull with the blade between his teeth. That's it --that's it. Now ye do something; that looks like it, my steel-bits. Start her --start her, my silver-spoons! Start her, marling-spikes! Stubb's exordium to his crew is given here at large, because he had rather a peculiar way of talking to them in general, and especially in inculcating the religion of rowing. But you must not suppose from this specimen of his sermonizings that he ever flew into downright passions with his congregation. Not at all; and therein consisted his chief peculiarity. He would say the most terrific things to his crew, in a tone so strangely compounded of fun and fury, and the fury seemed so calculated merely as a spice to the fun, that no oarsman could hear such queer invocations without pulling for dear life, and yet pulling for the mere joke of the thing. Besides he all the time looked so easy and indolent himself, so loungingly managed his steering-oar, and so broadly gaped --open-mouthed at times --that the mere sight of such a yawning commander, by sheer force of contrast, acted like a charm upon the crew. Then again, Stubb was one of those odd sort of humorists, whose jollity is sometimes so curiously ambiguous, as to put all inferiors on their guard in the matter of obeying them. In obedience to a sign from Ahab, Starbuck was now pulling obliquely across Stubb's bow; and when for a minute or so the two boats were pretty near to each other, Stubb hailed the mate. Mr. Starbuck! larboard boat there, ahoy! a word with ye, sir, if ye please! Halloa! returned Starbuck, turning round not a single inch as he spoke; still earnestly but whisperingly urging his crew; his face set like a flint from Stubb's. What think ye of those yellow boys, sir! Smuggled on board, somehow, before the ship sailed. (Strong, strong, boys! ) in a whisper to his crew, then speaking out loud again: A sad business, Mr. Stubb! (seethe her, seethe her, my lads!) but never mind, Mr. Stubb, all for the best. Let all your crew pull strong, come what will. (Spring, my men, spring!) ..

There's hogsheads of sperm ahead, Mr. Stubb, and that's what ye came for. (Pull, my boys!) Sperm, sperm's the play! This at least is duty; duty and profit hand in hand! Aye, aye, I thought as much, soliloquized Stubb, when the boats diverged, as soon as I clapt eye on 'em, I thought so. Aye, and that's what he went into the after hold for, so often, as Dough-Boy long suspected. They were hidden down there. The White Whale's at the bottom of it. Well, well, so be it! Can't be helped! All right! Give way, men! It ain't the White Whale to-day! Give way! Now the advent of these outlandish strangers at such a critical instant as the lowering of the boats from the deck, this had not unreasonably awakened a sort of superstitious amazement in some of the ship's company; but Archy's fancied discovery having some time previous got abroad among them, though indeed not credited then, this had in some small measure prepared them for the event. It took off the extreme edge of their wonder; and so what with all this and Stubb's confident way of accounting for their appearance, they were for the time freed from superstitious surmisings; though the affair still left abundant room for all manner of wild conjectures as to dark Ahab's precise agency in the matter from the beginning. For me, I silently recalled the mysterious shadows I had seen creeping on board the Pequod during the dim Nantucket dawn, as well as the enigmatical hintings of the unaccountable Elijah. Meantime, Ahab, out of hearing of his officers, having sided the furthest to windward, was still ranging ahead of the other boats; a circumstance bespeaking how potent a crew was pulling him. those tiger yellow creatures of his seemed all steel and whale-bone; like five trip-hammers they rose and fell with regular strokes of strength, which periodically started the boat along the water like a horizontal burst boiler out of a Mississippi steamer. As for Fedallah, who was seen pulling the harpooneer oar, he had thrown aside his black jacket, and displayed his naked chest with the whole part of his body above the gunwale, clearly cut against the alternating depressions of the watery horizon; while at the other end of the boat Ahab, with one ..

arm, like a fencer's, thrown half backward into the air, as if to counterbalance any tendency to trip: Ahab was seen steadily managing his steering oar as in a thousand boat lowerings ere the White Whale had torn him. All at once the out-stretched arm gave a peculiar motion and then remained fixed, while the boat's five oars were seen simultaneously peaked. Boat and crew sat motionless on the sea. Instantly the three spread boats in the rear paused on their way. The whales had irregularly settled bodily down into the blue, thus giving no distantly discernible token of the movement, though from his closer vicinity Ahab had observed it. Every man look out along his oars! cried Starbuck. Thou, Queequeg, stand up! Nimbly springing up on the triangular raised box in the bow, the savage stood erect there, and with intensely eager eyes gazed off towards the spot where the chase had last been descried. Likewise upon the extreme stern of the boat where it was also triangularly platformed level with the gunwale, Starbuck himself was seen coolly and adroitly balancing himself to the jerking tossings of his chip of a craft, and silently eyeing the vast blue eye of the sea. Not very far distant Flask's boat was also lying breathlessly still; its commander recklessly standing upon the top of the loggerhead, a stout sort of post rooted in the keel, and rising some two feet above the level of the stern platform. it is used for catching turns with the whale line. Its top is not more spacious than the palm of a man's hand, and standing upon such a base as that, Flask seemed perched at the mast-head of some ship which had sunk to all but her trucks. But little King-Post was small and short, and at the same time little King-Post was full of a large and tall ambition, so that this loggerhead stand-point of his did by no means satisfy King-Post. I can't see three seas off; tip us up an oar there, and let me on to that. Upon this, Daggoo, with either hand upon the gunwale to steady his way, swiftly slid aft, and then erecting himself volunteered his lofty shoulders for a pedestal. ..

Good a mast-head as any, sir. Will you mount? That I will, and thank ye very much, my fine fellow; only I wish you fifty feet taller. Whereupon planting his feet firmly against two opposite planks of the boat, the gigantic negro, stooping a little, presented his flat palm to Flask's foot, and then putting Flask's hand on his hearse-plumed head and bidding him spring as he himself should toss, with one dexterous fling landed the little man high and dry on his shoulders. And here was Flask now standing, Daggoo with one lifted arm furnishing him with a breast-band to lean against and steady himself by. At any time it is a strange sight to the tyro to see with what wondrous habitude of unconscious skill the whaleman will maintain an erect posture in his boat, even when pitched about by the most riotously perverse and cross-running seas. Still more strange to see him giddily perched upon the loggerhead itself, under such circumstances. But the sight of little Flask mounted upon gigantic Daggoo was yet more curious; for sustaining himself with a cool, indifferent, easy, unthought of, barbaric majesty, the noble negro to every roll of the sea harmoniously rolled his fine form. On his broad back, flaxen-haired flask seemed a snow-flake. The bearer looked nobler than the rider. Though truly vivacious, tumultuous, ostentatious little Flask would now and then stamp with impatience; but not one added heave did he thereby give to the negro's lordly chest. So have I seen Passion and Vanity stamping the living magnanimous earth, but the earth did not alter her tides and her seasons for that. Meanwhile Stubb, the third mate, betrayed no such far-gazing solicitudes. The whales might have made one of their regular soundings, not a temporary dive from mere fright; and if that were the case, Stubb, as his wont in such cases, it seems, was resolved to solace the languishing interval with his pipe. He withdrew it from his hatband, where he always wore it aslant like a feather. He loaded it, and rammed home the loading with his thumb-end; but hardly had he ignited his match across the rough sand-paper of his hand, when Tashtego, his harpooneer, whose eyes had been setting to windward like two fixed stars, suddenly dropped like light from his erect attitude to his seat, ..

crying out in a quick phrensy of hurry, Down, down all, and give way! --there they are! To a landsman, no whale, nor any sign of a herring, would have been visible at that moment; nothing but a troubled bit of greenish white water, and thin scattered puffs of vapor hovering over it, and suffusingly blowing off to leeward, like the confused scud from white rolling billows. The air around suddenly vibrated and tingled, as it were, like the air over intensely heated plates of iron. Beneath this atmospheric waving and curling, and partially beneath a thin layer of water, also, the whales were swimming. Seen in advance of all the other indications, the puffs of vapor they spouted, seemed their forerunning couriers and detached flying outriders. All four boats were now in keen pursuit of that one spot of troubled water and air. But it bade far to outstrip them; it flew on and on, as a mass of interblending bubbles borne down a rapid stream from the hills. Pull, pull, my good boys, said Starbuck, in the lowest possible but intensest concentrated whisper to his men; while the sharp fixed glance from his eyes darted straight ahead of the bow, almost seemed as two visible needles in two unerring binnacle compasses. He did not say much to his crew, though, nor did his crew say anything to him. Only the silence of the boat was at intervals startlingly pierced by one of his peculiar whispers, now harsh with command, now soft with entreaty. How different the loud little King-Post. Sing out and say something, my hearties. Roar and pull, my thunderbolts! Beach me, beach me on their black backs, boys; only do that for me, and I'll sign over to you my Martha's Vineyard plantation, boys; including wife and children, boys. Lay me on --lay me on! O Lord, Lord! but I shall go stark, staring mad: See! see that white water! And so shouting, he pulled his hat from his head, and stamped up and down on it; then picking it up, flirted it far off upon the sea; and finally fell to rearing and plunging in the boat's stern like a crazed colt from the prairie. Look at that chap now, philosophically drawled Stubb, who, with his unlighted short pipe, mechanically retained between his teeth, at a short distance, followed after -- He's got fits, that ..

Flask has. Fits? yes, give him fits --that's the very word -- pitch fits into 'em. Merrily, merrily, hearts-alive. Pudding for supper, you know; --merry's the word. Pull, babes --pull, sucklings -- pull, all. But what the devil are you hurrying about? Softly, softly, and steadily, my men. Only pull, and keep pulling; nothing more. Crack all your backbones, and bite your knives in two -- that's all. Take it easy --why don't ye take it easy, I say, and burst all your livers and lungs! But what it was that inscrutable Ahab said to that tiger-yellow crew of his --these were words best omitted here; for you live under the blessed light of the evangelical land. Only the infidel sharks in the audacious seas may give ear to such words, when, with tornado brow, and eyes of red murder, and foam-glued lips, Ahab leaped after his prey. Meanwhile, all the boats tore on. The repeated specific allusions of Flask to that whale, as he called the fictitious monster which he declared to be incessantly tantalizing his boat's bow with its tail --these allusions of his were at times so vivid and life-like, that they would cause some one or two of his men to snatch a fearful look over the shoulder. But this was against all rule; for the oarsmen must put out their eyes, and ram a skewer through their necks; usage pronouncing that they must have no organs but ears, and no limbs but arms, in these critical moments. It was a sight full of quick wonder and awe! The vast swells of the omnipotent sea; the surging, hollow roar they made, as they rolled along the eight gunwales, like gigantic bowls in a boundless bowling-green; the brief suspended agony of the boat, as it would tip for an instant on the knife-like edge of the sharper waves, that almost seemed threatening to cut it in two; the sudden profound dip into the watery glens and hollows; the keen spurrings and goadings to gain the top of the opposite hill; the headlong, sled-like slide down its other side; --all these, with the cries of the headsmen and harpooneers, and the shuddering gasps of the oarsmen, with the wondrous sight of the ivory Pequod bearing down upon her boats with outstretched sails, like a wild hen after her screaming brood; --all this was thrilling. Not the raw recruit, marching from the bosom of his wife into the fever heat of his first battle; not the dead man's ghost encountering ..

the first unknown phantom in the other world; --neither of these can feel stranger and stronger emotions than that man does, who for the first time finds himself pulling into the charmed, churned circle of the hunted sperm whale. The dancing white water made by the chase was now becoming more and more visible, owing to the increasing darkness of the dun cloud-shadows flung upon the sea. The jets of vapor no longer blended, but tilted everywhere to right and left; the whales seemed separating their wakes. The boats were pulled more apart; Starbuck giving chase to three whales running dead to leeward. Our sail was now set, and, with the still rising wind, we rushed along; the boat going with such madness through the water, that the lee oars could scarcely be worked rapidly enough to escape being torn from the row-locks. Soon we were running through a suffusing wide veil of mist; neither ship nor boat to be seen. Give way, men, whispered Starbuck, drawing still further aft the sheet of his sail; there is time to kill a fish yet before the squall comes. There's white water again! --close to! Spring! Soon after, two cries in quick succession on each side of us denoted that the other boats had got fast; but hardly were they overheard, when with a lightning-like hurtling whisper Starbuck said: Stand up! and Queequeg, harpoon in hand, sprang to his feet. Though not one of the oarsmen was then facing the life and death peril so close to them ahead, yet with their eyes on the intense countenance of the mate in the stern of the boat, they knew that the imminent instant had come; they heard, too, an enormous wallowing sound as of fifty elephants stirring in their litter. Meanwhile the boat was still booming through the mist, the waves curling and hissing around us like the erected crests of enraged serpents. That's his hump. There, there, give it to him! whispered Starbuck. A short rushing sound leaped out of the boat; it was the darted iron of Queequeg. Then all in one welded commotion came an invisible push from astern, while forward the boat seemed striking on a ledge; the sail collapsed and exploded; a ..

gush of scalding vapor shot up near by; something rolled and tumbled like an earthquake beneath us. The whole crew were half suffocated as they were tossed helter-skelter into the white curdling cream of the squall. Squall, whale, and harpoon had all blended together; and the whale, merely grazed by the iron, escaped. Though completely swamped, the boat was nearly unharmed. Swimming round it we picked up the floating oars, and lashing them across the gunwale, tumbled back to our places. There we sat up to our knees in the sea, the water covering every rib and plank, so that to our downward gazing eyes the suspended craft seemed a coral boat grown up to us from the bottom of the ocean. The wind increased to a howl; the waves dashed their bucklers together; the whole squall roared, forked, and crackled around us like a white fire upon the prairie, in which, unconsumed, we were burning; immortal in these jaws of death! In vain we hailed the other boats; as well roar to the live coals down the chimney of a flaming furnace as hail those boats in that storm. Meanwhile the driving scud, rack, and mist, grew darker with the shadows of night; no sign of the ship could be seen. The rising sea forbade all attempts to bale out the boat. The oars were useless as propellers, performing now the office of life-preservers. So, cutting the lashing of the water-proof match keg, after many failures Starbuck contrived to ignite the lamp in the lantern; then stretching it on a waif pole, handed it to Queequeg as the standard-bearer of this forlorn hope. There, then, he sat, holding up that imbecile candle in the heart of that almighty forlornness. There, then, he sat, the sign and symbol of a man without faith, hopelessly holding up hope in the midst of despair. Wet, drenched through, and shivering cold, despairing of ship or boat, we lifted up our eyes as the dawn came on. The mist still spread over the sea, the empty lantern lay crushed in the bottom of the boat. Suddenly Queequeg started to his feet, hollowing his hand to his ear. We all heard a faint creaking, as of ropes and yards hitherto muffled by the storm. The sound came nearer and nearer; the thick mists were dimly parted by ..

a huge, vague form. Affrighted, we all sprang into the sea as the ship at last loomed into view, bearing right down upon us within a distance of not much more than its length. Floating on the waves we saw the abandoned boat, as for one instant it tossed and gaped beneath the ship's bows like a chip at the base of a cataract; and then the vast hull rolled over it, and it was seen no more till it came up weltering astern. Again we swam for it, were dashed against it by the seas, and were at last taken up and safely landed on board. Ere the squall came close to, the other boats had cut loose from their fish and returned to the ship in good time. The ship had given us up, but was still cruising, if haply it might light upon some token of our perishing, --an oar or a lance pole. ..

.. < chapter xlix 15 THE HYENA > There are certain queer times and occasions in this strange mixed affair we call life when a man takes this whole universe for a vast practical joke, though the wit thereof he but dimly discerns, and more than suspects that the joke is at nobody's expense but his own. However, nothing dispirits, and nothing seems worth while disputing. He bolts down all events, all creeds, and beliefs, and persuasions, all hard things visible and invisible, never mind how knobby; as an ostrich of potent digestion gobbles down bullets and gun flints. And as for small difficulties and worryings, prospects of sudden disaster, peril of life and limb; all these, and death itself, seem to him only sly, good-natured hits, and jolly punches in the side bestowed by the unseen and unaccountable old joker. That odd sort of wayward mood I am speaking of, comes over a man only in some time of extreme tribulation; it comes in the very midst of his earnestness, so that what just before might have seemed to him a thing most momentous, now seems but a part of the general ..

joke. There is nothing like the perils of whaling to breed this free and easy sort of genial, desperado philosophy; and with it I now regarded this whole voyage of the Pequod, and the great White Whale its object. Queequeg, said I, when they had dragged me, the last man, to the deck, and I was still shaking myself in my jacket to fling off the water; Queequeg, my fine friend, does this sort of thing often happen? Without much emotion, though soaked through just like me, he gave me to understand that such things did often happen. Mr. Stubb, said I, turning to that worthy, who, buttoned up in his oil-jacket, was now calmly smoking his pipe in the rain; Mr. Stubb, I think I have heard you say that of all whalemen you ever met, our chief mate, Mr. Starbuck, is by far the most careful and prudent. I suppose then, that going plump on a flying whale with your sail set in a foggy squall is the height of a whaleman's discretion? Certain. I've lowered for whales from a leaking ship in a gale off Cape Horn. Mr. Flask, said I, turning to little King-Post, who was standing close by; you are experienced in these things, and I am not. Will you tell me whether it is an unalterable law in this fishery, Mr. Flask, for an oarsman to break his own back pulling himself back-foremost into death's jaws? Can't you twist that smaller? said Flask. Yes, that's the law. I should like to see a boat's crew backing water up to a whale face foremost. Ha, ha! the whale would give them squint for squint, mind that! here then, from three impartial witnesses, i had a deliberate statement of the entire case. Considering, therefore, that squalls and capsizings in the water and consequent bivouacks on the deep, were matters of common occurrence in this kind of life; considering that at the superlatively critical instant of going on to the whale I must resign my life into the hands of him who steered the boat --oftentimes a fellow who at that very moment is in his impetuousness upon the point of scuttling the craft with his own frantic stampings; considering that the particular disaster to our own particular boat was chiefly to be ..

imputed to Starbuck's driving on to his whale almost in the teeth of a squall, and considering that Starbuck, notwithstanding, was famous for his great heedfulness in the fishery; considering that I belonged to this uncommonly prudent Starbuck's boat; and finally considering in what a devil's chase I was implicated, touching the White Whale: taking all things together, I say, I thought I might as well go below and make a rough draft of my will. Queequeg, said I, come along, you shall be my lawyer, executor, and legatee. It may seem strange that of all men sailors should be tinkering at their last wills and testaments, but there are no people in the world more fond of that diversion. This was the fourth time in my nautical life that I had done the same thing. After the ceremony was concluded upon the present occasion, I felt all the easier; a stone was rolled away from my heart. Besides, all the days I should now live would be as good as the days that Lazarus lived after his resurrection; a supplementary clean gain of so many months or weeks as the case might be. I survived myself; my death and burial were locked up in my chest. I looked round me tranquilly and contentedly, like a quiet ghost with a clean conscience sitting inside the bars of a snug family vault. now then, thought i, unconsciously rolling up the sleeves of my frock, here goes a cool, collected dive at death and destruction, and the devil fetch the hindmost. ..

.. < chapter L 27 AHAB'S BOAT AND CREW. FEDALLAH > Who would have thought it, Flask! cried Stubb; if I had but one leg you would not catch me in a boat, unless maybe to stop the plug-hole with my timber toe. Oh! he's a wonderful old man! I don't think it so strange, after all, on that account, said ..

Flask. If his leg were off at the hip, now, it would be a different thing. That would disable him; but he has one knee, and good part of the other left, you know. I don't know that, my little man; I never yet saw him kneel. Among whale-wise people it has often been argued whether, considering the paramount importance of his life to the success of the voyage, it is right for a whaling captain to jeopardize that life in the active perils of the chase. So Tamerlane's soldiers often argued with tears in their eyes, whether that invaluable life of his ought to be carried into the thickest of the fight. But with Ahab the question assumed a modified aspect. Considering that with two legs man is but a hobbling wight in all times of danger; considering that the pursuit of whales is always under great and extraordinary difficulties; that every individual moment, indeed, then comprises a peril; under these circumstances is it wise for any maimed man to enter a whale-boat in the hunt? As a general thing, the joint-owners of the Pequod must have plainly thought not. Ahab well knew that although his friends at home would think little of his entering a boat in certain comparatively harmless vicissitudes of the chase, for the sake of being near the scene of action and giving his orders in person, yet for Captain Ahab to have a boat actually apportioned to him as a regular headsman in the hunt --above all for Captain Ahab to be supplied with five extra men, as that same boat's crew, he well knew that such generous conceits never entered the heads of the owners of the Pequod. Therefore he had not solicited a boat's crew from them, nor had he in any way hinted his desires on that head. Nevertheless he had taken private measures of his own touching all that matter. Until Cabaco's published discovery, the sailors had little foreseen it, though to be sure when, after being a little while out of port, all hands had concluded the customary business of fitting the whaleboats for service; when some time after this Ahab was now and then found bestirring himself in the matter of making thole-pins with his own hands for what was thought to be one of the spare boats, and even solicitously cutting the small wooden skewers, which when the ..

line is running out are pinned over the groove in the bow: when all this was observed in him, and particularly his solicitude in having an extra coat of sheathing in the bottom of the boat, as if to make it better withstand the pointed pressure of his ivory limb; and also the anxiety he evinced in exactly shaping the thigh board, or clumsy cleat, as it is sometimes called, the horizontal piece in the boat's bow for bracing the knee against in darting or stabbing at the whale; when it was observed how often he stood up in that boat with his solitary knee fixed in the semi-circular depression in the cleat, and with the carpenter's chisel gouged out a little here and straightened it a little there; all these things, I say, had awakened much interest and curiosity at the time. But almost everybody supposed that this particular preparative heedfulness in Ahab must only be with a view to the ultimate chase of Moby Dick; for he had already revealed his intention to hunt that mortal monster in person. But such a supposition did by no means involve the remotest suspicion as to any boat's crew being assigned to that boat. now, with the subordinate phantoms, what wonder remained soon waned away; for in a whaler wonders soon wane. Besides, now and then such unaccountable odds and ends of strange nations come up from the unknown nooks and ash-holes of the earth to man these floating outlaws of whalers; and the ships themselves often pick up such queer castaway creatures found tossing about the open sea on planks, bits of wreck, oars, whale-boats, canoes, blown-off Japanese junks, and what not; that Beelzebub himself might climb up the side and step down into the cabin to chat with the captain, and it would not create any unsubduable excitement in the forecastle. But be all this as it may, certain it is that while the subordinate phantoms soon found their place among the crew, though still as it were somehow distinct from them, yet that hair-turbaned Fedallah remained a muffled mystery to the last. Whence he came in a mannerly world like this, by what sort of unaccountable tie he soon evinced himself to be linked with Ahab's peculiar fortunes; nay, so far as to have some sort of a half-hinted influence; Heaven knows, but it might have been even authority over him; all this none knew. But one cannot sustain ..

an indifferent air concerning Fedallah. He was such a creature as civilized, domestic people in the temperate zone only see in their dreams, and that but dimly; but the like of whom now and then glide among the unchanging Asiatic communities, especially the Oriental isles to the east of the continent --those insulated, immemorial, unalterable countries, which even in these modern days still preserve much of the ghostly aboriginalness of earth's primal generations, when the memory of the first man was a distinct recollection, and all men his descendants, unknowing whence he came, eyed each other as real phantoms, and asked of the sun and the moon why they were created and to what end; when though, according to genesis, the angels indeed consorted with the daughters of men, the devils also, add the uncanonical Rabbins, indulged in mundane amours. ..

.. < chapter li 16 THE SPIRIT-SPOUT > Days, weeks passed, and under easy sail, the ivory Pequod had slowly swept across four several cruising-grounds; that off the Azores; off the Cape de Verdes; on the Plate (so called), being off the mouth of the Rio de la Plata; and the Carrol Ground, an unstaked, watery locality, southerly from St. Helena. It was while gliding through these latter waters that one serene and moonlight night, when all the waves rolled by like scrolls of silver; and, by their soft, suffusing seethings, made what seemed a silvery silence, not a solitude: on such a silent night a silvery jet was seen far in advance of the white bubbles at the bow. Lit up by the moon, it looked celestial; seemed some plumed and glittering god uprising from the sea. Fedallah first descried this jet. For of these moonlight nights, it was his wont to mount to the main-mast head, and stand a look-out there, with the same precision as if it had been day. And yet, though herds of whales were seen by night, not one whaleman ..

in a hundred would venture a lowering for them. You may think with what emotions, then, the seamen beheld this old Oriental perched aloft at such unusual hours; his turban and the moon, companions in one sky. But when, after spending his uniform interval there for several successive nights without uttering a single sound; when, after all this silence, his unearthly voice was heard announcing that silvery, moon-lit jet, every reclining mariner started to his feet as if some winged spirit had lighted in the rigging, and hailed the mortal crew. There she blows! Had the trump of judgment blown, they could not have quivered more; yet still they felt no terror; rather pleasure. for though it was a most unwonted hour, yet so impressive was the cry, and so deliriously exciting, that almost every soul on board instinctively desired a lowering. Walking the deck with quick, side-lunging strides, Ahab commanded the t'gallant sails and royals to be set, and every stunsail spread. The best man in the ship must take the helm. Then, with every mast-head manned, the piled-up craft rolled down before the wind. The strange, upheaving, lifting tendency of the taffrail breeze filling the hollows of so many sails, made the buoyant, hovering deck to feel like air beneath the feet; while still she rushed along, as if two antagonistic influences were struggling in her --one to mount direct to heaven, the other to drive yawingly to some horizontal goal. And had you watched Ahab's face that night, you would have thought that in him also two different things were warring. While his one live leg made lively echoes along the deck, every stroke of his dead limb sounded like a coffin-tap. On life and death this old man walked. But though the ship so swiftly sped, and though from every eye, like arrows, the eager glances shot, yet the silvery jet was no more seen that night. Every sailor swore he saw it once, but not a second time. This midnight-spout had almost grown a forgotten thing, when, some days after, lo! at the same silent hour, it was again announced: again it was descried by all; but upon making sail to overtake it, once more it disappeared as if it had never been. And so it served us night after night, till no one heeded it but to wonder at it. Mysteriously jetted into the clear moonlight, ..

or starlight, as the case might be; disappearing again for one whole day, or two days, or three; and somehow seeming at every distinct repetition to be advancing still further and further in our van, this solitary jet seemed for ever alluring us on. Nor with the immemorial superstition of their race, and in accordance with the preternaturalness, as it seemed, which in many things invested the Pequod, were there wanting some of the seamen who swore that whenever and wherever descried; at however remote times, or in however far apart latitudes and longitudes, that unnearable spout was cast by one self-same whale; and that whale, Moby Dick. For a time, there reigned, too, a sense of peculiar dread at this flitting apparition, as if it were treacherously beckoning us on and on, in order that the monster might turn round upon us, and rend us at last in the remotest and most savage seas. These temporary apprehensions, so vague but so awful, derived a wondrous potency from the contrasting serenity of the weather, in which, beneath all its blue blandness, some thought there lurked a devilish charm, as for days and days we voyaged along, through seas so wearily, lonesomely mild, that all space, in repugnance to our vengeful errand, seemed vacating itself of life before our urn-like prow. But, at last, when turning to the eastward, the Cape winds began howling around us, and we rose and fell upon the long, troubled seas that are there; when the ivory-tusked Pequod sharply bowed to the blast, and gored the dark waves in her madness, till, like showers of silver chips, the foam-flakes flew over her bulwarks; then all this desolate vacuity of life went away, but gave place to sights more dismal than before. Close to our bows, strange forms in the water darted hither and thither before us; while thick in our rear flew the inscrutable sea-ravens. And every morning, perched on our stays, rows of these birds were seen; and spite of our hootings, for a long time obstinately clung to the hemp, as though they deemed our ship some drifting, uninhabited craft; a thing appointed to desolation, and therefore fit roosting-place for their homeless selves. And heaved and heaved, still unrestingly heaved the black sea, as if its vast tides were a conscience; and the great ..

mundane soul were in anguish and remorse for the long sin and suffering it had bred. Cape of Good Hope, do they call ye? Rather Cape Tormentoto, as called of yore; for long allured by the perfidious silences that before had attended us, we found ourselves launched into this tormented sea, where guilty beings transformed into those fowls and these fish, seemed condemned to swim on everlastingly without any haven in store, or beat that black air without any horizon. But calm, snow-white, and unvarying; still directing its fountain of feathers to the sky; still beckoning us on from before, the solitary jet would at times be descried. During all this blackness of the elements, Ahab, though assuming for the time the almost continual command of the drenched and dangerous deck, manifested the gloomiest reserve; and more seldom than ever addressed his mates. In tempestuous times like these, after everything above and aloft has been secured, nothing more can be done but passively to await the issue of the gale. Then Captain and crew become practical fatalists. So, with his ivory leg inserted into its accustomed hole, and with one hand firmly grasping a shroud, Ahab for hours and hours would stand gazing dead to windward, while an occasional squall of sleet or snow would all but congeal his very eyelashes together. Meantime, the crew driven from the forward part of the ship by the perilous seas that burstingly broke over its bows, stood in a line along the bulwarks in the waist; and the better to guard against the leaping waves, each man had slipped himself into a sort of bowline secured to the rail, in which he swung as in a loosened belt. Few or no words were spoken; and the silent ship, as if manned by painted sailors in wax, day after day tore on through all the swift madness and gladness of the demoniac waves. By night the same muteness of humanity before the shrieks of the ocean prevailed; still in silence the men swung in the bowlines; still wordless ahab stood up to the blast. Even when wearied nature seemed demanding repose he would not seek that repose in his hammock. Never could Starbuck forget the old man's aspect, when one night going down into the cabin to mark how the ..

barometer stood, he saw him with closed eyes sitting straight in his floor-screwed chair; the rain and half-melted sleet of the storm from which he had some time before emerged, still slowly dripping from the unremoved hat and coat. On the table beside him lay unrolled one of those charts of tides and currents which have previously been spoken of. His lantern swung from his tightly clenched hand. Though the body was erect, the head was thrown back so that the closed eyes were pointed towards the needle of the tell-tale that swung from a beam in the ceiling. Terrible old man! thought Starbuck with a shudder, sleeping in this gale, still thou steadfastly eyest thy purpose. ..

.. < chapter lii 13 THE ALBATROSS > South-eastward from the Cape, off the distant Crozetts, a good cruising ground for Right Whalemen, a sail loomed ahead, the Goney (Albatross) by name. As she slowly drew nigh, from my lofty perch at the fore-mast-head, I had a good view of that sight so remarkable to a tyro in the far ocean fisheries --a whaler at sea, and long absent from home. As if the waves had been fullers, this craft was bleached like the skeleton of a stranded walrus. All down her sides, this spectral appearance was traced with long channels of reddened rust, while all her spars and her rigging were like the thick branches of trees furred over with hoar-frost. Only her lower sails were set. A wild sight it was to see her long-bearded look-outs at those three mast-heads. They seemed clad in the skins of beasts, so torn and bepatched the raiment that had survived nearly four years of cruising. Standing in iron hoops nailed to the mast, they swayed and swung over a fathomless sea; ..

and though, when the ship slowly glided close under our stern, we six men in the air came so nigh to each other that we might almost have leaped from the mast-heads of one ship to those of the other; yet, those forlorn-looking fishermen, mildly eyeing us as they passed, said not one word to our own look-outs, while the quarter-deck hail was being heard from below. Ship ahoy! Have ye seen the White Whale? But as the strange captain, leaning over the pallid bulwarks, was in the act of putting his trumpet to his mouth, it somehow fell from his hand into the sea; and the wind now rising amain, he in vain strove to make himself heard without it. Meantime his ship was still increasing the distance between. While in various silent ways the seamen of the Pequod were evincing their observance of this ominous incident at the first mere mention of the White Whale's name to another ship, Ahab for a moment paused; it almost seemed as though he would have lowered a boat to board the stranger, had not the threatening wind forbade. But taking advantage of his windward position, he again seized his trumpet, and knowing by her aspect that the stranger vessel was a Nantucketer and shortly bound home, he loudly hailed -- Ahoy there! This is the Pequod, bound round the world! Tell them to address all future letters to the Pacific ocean! and this time three years, if I am not at home, tell them to address them to----- At that moment the two wakes were fairly crossed, and instantly, then, in accordance with their singular ways, shoals of small harmless fish, that for some days before had been placidly swimming by our side, darted away with what seemed shuddering fins, and ranged themselves fore and aft with the stranger's flanks. Though in the course of his continual voyagings Ahab must often before have noticed a similar sight, yet, to any monomaniac man, the veriest trifles capriciously carry meanings. Swim away from me, do ye? murmured Ahab, gazing over into the water. There seemed but little in the words, but the tone conveyed more of deep helpless sadness than the insane old man had ever before evinced. But turning to the steersman, who thus far had been holding the ship in the wind to diminish ..

her headway, he cried out in his old lion voice, -- Up helm! Keep her off round the world! Round the world! There is much in that sound to inspire proud feelings; but whereto does all that circumnavigation conduct? Only through numberless perils to the very point whence we started, where those that we left behind secure, were all the time before us. Were this world an endless plain, and by sailing eastward we could for ever reach new distances, and discover sights more sweet and strange than any Cyclades or Islands of King Solomon, then there were promise in the voyage. But in pursuit of those far mysteries we dream of, or in tormented chase of that demon phantom that, some time or other, swims before all human hearts; while chasing such over this round globe, they either lead us on in barren mazes or midway leave us whelmed. ..

The cabin-compass is called the tell-tale, because without going to the compass at the helm, the Captain, while below, can inform himself of the course of the ship. ..

.. < chapter liii 17 THE GAM > The ostensible reason why Ahab did not go on board of the whaler we had spoken was this: the wind and sea betokened storms. But even had this not been the case, he would not after all, perhaps, have boarded her --judging by his subsequent conduct on similar occasions --if so it had been that, by the process of hailing, he had obtained a negative answer to the question he put. For, as it eventually turned out, he cared not to consort, even for five minutes, with any stranger captain, except he could contribute some of that information he so absorbingly sought. But all this might remain inadequately estimated, were not something said here of the peculiar usages of whaling-vessels when meeting each other in foreign seas, and especially on a common cruising-ground. If two strangers crossing the Pine Barrens in New York State, or the equally desolate Salisbury Plain in England; if ..

casually encountering each other in such inhospitable wilds, these twain, for the life of them, cannot well avoid a mutual salutation; and stopping for a moment to interchange the news; and, perhaps, sitting down for a while and resting in concert: then, how much more natural that upon the illimitable Pine Barrens and Salisbury Plains of the sea, two whaling vessels descrying each other at the ends of the earth --off lone Fanning's Island, or the far away King's Mills; how much more natural, I say, that under such circumstances these ships should not only interchange hails, but come into still closer, more friendly and sociable contact. And especially would this seem to be a matter of course, in the case of vessels owned in one seaport, and whose captains, officers, and not a few of the men are personally known to each other; and consequently, have all sorts of dear domestic things to talk about. For the long absent ship, the outward-bounder, perhaps, has letters on board; at any rate, she will be sure to let her have some papers of a date a year or two later than the last one on her blurred and thumb-worn files. And in return for that courtesy, the outward-bound ship would receive the latest whaling intelligence from the cruising-ground to which she may be destined, a thing of the utmost importance to her. And in degree, all this will hold true concerning whaling vessels crossing each other's track on the cruising-ground itself, even though they are equally long absent from home. for one of them may have received a transfer of letters from some third, and now far remote vessel; and some of those letters may be for the people of the ship she now meets. Besides, they would exchange the whaling news, and have an agreeable chat. For not only would they meet with all the sympathies of sailors, but likewise with all the peculiar congenialities arising from a common pursuit and mutually shared privations and perils. Nor would difference of country make any very essential difference; that is, so long as both parties speak one language, as is the case with Americans and English. Though, to be sure, from the small number of English whalers, such meetings do not very often occur, and when they do occur there is too apt to be a sort of shyness between them; for your Englishman is rather ..

reserved, and your Yankee, he does not fancy that sort of thing in anybody but himself. Besides, the English whalers sometimes affect a kind of metropolitan superiority over the American whalers; regarding the long, lean Nantucketer, with his nondescript provincialisms, as a sort of sea-peasant. But where this superiority in the English whalemen does really consist, it would be hard to say, seeing that the Yankees in one day, collectively, kill more whales than all the English, collectively, in ten years. But this is a harmless little foible in the English whale-hunters, which the Nantucketer does not take much to heart; probably, because he knows that he has a few foibles himself. So, then, we see that of all ships separately sailing the sea, the whalers have most reason to be sociable --and they are so. Whereas, some merchant ships crossing each other's wake in the mid-Atlantic, will oftentimes pass on without so much as a single word of recognition, mutually cutting each other on the high seas, like a brace of dandies in Broadway; and all the time indulging, perhaps, in finical criticism upon each other's rig. As for Men-of-War, when they chance to meet at sea, they first go through such a string of silly bowings and scrapings, such a ducking of ensigns, that there does not seem to be much right-down hearty good-will and brotherly love about it at all. As touching Slave-ships meeting, why, they are in such a prodigious hurry, they run away from each other as soon as possible. And as for Pirates, when they chance to cross each other's cross-bones, the first hail is -- How many skulls? --the same way that whalers hail-- How many barrels? And that question once answered, pirates straightway steer apart, for they are infernal villains on both sides, and don't like to see overmuch of each other's villanous likenesses. But look at the godly, honest, unostentatious, hospitable, sociable, free-and-easy whaler! What does the whaler do when she meets another whaler in any sort of decent weather? She has a Gam, a thing so utterly unknown to all other ships that they never heard of the name even; and if by chance they should hear of it, they only grin at it, and repeat gamesome stuff about spouters and blubber-boilers, and such like pretty exclamations. Why it is that all Merchant-seamen, and also all ..

Pirates and Man-of-War's men, and Slave-ship sailors, cherish such a scornful feeling towards Whale-ships; this is a question it would be hard to answer. Because, in the case of pirates, say, I should like to know whether that profession of theirs has any peculiar glory about it. It sometimes ends in uncommon elevation, indeed; but only at the gallows. And besides, when a man is elevated in that odd fashion, he has no proper foundation for his superior altitude. Hence, I conclude, that in boasting himself to be high lifted above a whaleman, in that assertion the pirate has no solid basis to stand on. but what is a gam? you might wear out your index-finger running up and down the columns of dictionaries, and never find the word. Dr. Johnson never attained to that erudition; Noah Webster's ark does not hold it. Nevertheless, this same expressive word has now for many years been in constant use among some fifteen thousand true born Yankees. Certainly it needs a definition, and should be incorporated into the Lexicon. With that view, let me learnedly define it. Gam. Noun --A social meeting of two (or more) Whale-ships, generally on a cruising-ground; when, after exchanging hails, they exchange visits by boats' crews: the two captains remaining, for the time, on board of one ship, and the two chief mates on the other. There is another little item about Gamming which must not be forgotten here. All professions have their own little peculiarities of detail; so has the whale fishery. In a pirate, man-of-war, or slave ship, when the captain is rowed anywhere in his boat, he always sits in the stern sheets on a comfortable, sometimes cushioned seat there, and often steers himself with a pretty little milliner's tiller decorated with gay cords and ribbons. But the whale-boat has no seat astern, no sofa of that sort whatever, and no tiller at all. High times indeed, if whaling captains were wheeled about the water on castors like gouty old aldermen in patent chairs. And as for a tiller, the whale-boat never admits of any such effeminacy; and therefore as in gamming a complete boat's crew must leave the ship, and hence as the boat steerer or harpooneer is of the number, that subordinate is the steersman upon the occasion, and the captain, having no ..

place to sit in, is pulled off to his visit all standing like a pine tree. And often you will notice that being conscious of the eyes of the whole visible world resting on him from the sides of the two ships, this standing captain is all alive to the importance of sustaining his dignity by maintaining his legs. nor is this any very easy matter; for in his rear is the immense projecting steering oar hitting him now and then in the small of his back, the after-oar reciprocating by rapping his knees in front. He is thus completely wedged before and behind, and can only expand himself sideways by settling down on his stretched legs; but a sudden, violent pitch of the boat will often go far to topple him, because length of foundation is nothing without corresponding breadth. Merely make a spread angle of two poles, and you cannot stand them up. Then, again, it would never do in plain sight of the world's riveted eyes, it would never do, I say, for this straddling captain to be seen steadying himself the slightest particle by catching hold of anything with his hands; indeed, as token of his entire, buoyant self-command, he generally carries his hands in his trowsers' pockets; but perhaps being generally very large, heavy hands, he carries them there for ballast. Nevertheless there have occurred instances, well authenticated ones too, where the captain has been known for an uncommonly critical moment or two, in a sudden squall say --to seize hold of the nearest oarsman's hair, and hold on there like grim death. ..

.. < chapter liv 26 THE TOWN-HO'S STORY > ( As told at the Golden Inn.) The Cape of Good Hope, and all the watery region round about there, is much like some noted four corners of a great highway, where you meet more travellers than in any other part. It was not very long after speaking the Goney that another ..

homeward-bound whaleman, the Town-Ho, was encountered. She was manned almost wholly by Polynesians. In the short gam that ensued she gave us strong news of Moby Dick. To some the general interest in the White Whale was now wildly heightened by a circumstance of the Town-Ho's story, which seemed obscurely to involve with the whale a certain wondrous, inverted visitation of one of those so called judgments of God which at times are said to overtake some men. This latter circumstance, with its own particular accompaniments, forming what may be called the secret part of the tragedy about to be narrated, never reached the ears of Captain Ahab or his mates. For that secret part of the story was unknown to the captain of the Town-Ho himself. It was the private property of three confederate white seamen of that ship, one of whom, it seems, communicated it to Tashtego with Romish injunctions of secresy, but the following night Tashtego rambled in his sleep, and revealed so much of it in that way, that when he was wakened he could not well withhold the rest. Nevertheless, so potent an influence did this thing have on those seamen in the Pequod who came to the full knowledge of it, and by such a strange delicacy, to call it so, were they governed in this matter, that they kept the secret among themselves so that it never transpired abaft the Pequod's main-mast. Interweaving in its proper place this darker thread with the story as publicly narrated on the ship, the whole of this strange affair I now proceed to put on lasting record. For my humor's sake, I shall preserve the style in which I once narrated it at Lima, to a lounging circle of my Spanish friends, one saint's eve, smoking upon the thick-gilt tiled piazza of the Golden Inn. Of those fine cavaliers, the young Dons, Pedro and Sebastian, were on the closer terms with me; and hence the interluding questions they occasionally put, and which are duly answered at the time. Some two years prior to my first learning the events which I am about rehearsing to you, gentlemen, the Town-Ho, Sperm ..

Whaler of Nantucket, was cruising in your Pacific here, not very many days' sail westward from the eaves of this good Golden Inn. She was somewhere to the northward of the Line. One morning upon handling the pumps, according to daily usage, it was observed that she made more water in her hold than common. They supposed a sword-fish had stabbed her, gentlemen. But the captain, having some unusual reason for believing that rare good luck awaited him in those latitudes; and therefore being very averse to quit them, and the leak not being then considered at all dangerous, though, indeed, they could not find it after searching the hold as low down as was possible in rather heavy weather, the ship still continued her cruisings, the mariners working at the pumps at wide and easy intervals; but no good luck came; more days went by, and not only was the leak yet undiscovered, but it sensibly increased. So much so, that now taking some alarm, the captain, making all sail, stood away for the nearest harbor among the islands, there to have his hull hove out and repaired. Though no small passage was before her, yet, if the commonest chance favored, he did not at all fear that his ship would founder by the way, because his pumps were of the best, and being periodically relieved at them, those six-and-thirty men of his could easily keep the ship free; never mind if the leak should double on her. In truth, well nigh the whole of this passage being attended by very prosperous breezes, the Town-Ho had all but certainly arrived in perfect safety at her port without the occurrence of the least fatality, had it not been for the brutal overbearing of Radney, the mate, a Vineyarder, and the bitterly provoked vengeance of Steelkilt, a Lakeman and desperado from Buffalo. "Lakeman! --Buffalo! Pray, what is a Lakeman, and where is Buffalo?" said Don Sebastian, rising in his swinging mat of grass. On the eastern shore of our Lake Erie, Don; but--I crave your courtesy--may be, you shall soon hear further of all that. Now, gentlemen, in square-sail brigs and three-masted ships, well-nigh as large and stout as any that ever sailed out of your old Callao to far manilla; this lakeman, in the land-locked heart of our America, had yet been nurtured by all those agrarian ..

freebooting impressions popularly connected with the open ocean. For in their interflowing aggregate, those grand fresh-water seas of ours --Erie, and Ontario, and Huron, and Superior, and Michigan, --possess an ocean-like expansiveness, with many of the ocean's noblest traits; with many of its rimmed varieties of races and of climes. They contain round archipelagoes of romantic isles, even as the Polynesian waters do; in large part, are shored by two great contrasting nations, as the Atlantic is; they furnish long maritime approaches to our numerous territorial colonies from the East, dotted all round their banks; here and there are frowned upon by batteries, and by the goat-like craggy guns of lofty Mackinaw; they have heard the fleet thunderings of naval victories; at intervals, they yield their beaches to wild barbarians, whose red painted faces flash from out their peltry wigwams; for leagues and leagues are flanked by ancient and unentered forests, where the gaunt pines stand like serried lines of kings in Gothic genealogies; those same woods harboring wild Afric beasts of prey, and silken creatures whose exported furs give robes to Tartar Emperors; they mirror the paved capitals of Buffalo and Cleveland, as well as Winnebago villages; they float alike the full-rigged merchant ship, the armed cruiser of the State, the steamer, and the beech canoe; they are swept by Borean and dismasting blasts as direful as any that lash the salted wave; they know what shipwrecks are, for out of sight of land, however inland, they have drowned full many a midnight ship with all its shrieking crew. Thus, gentlemen, though an inlander, Steelkilt was wild-ocean born, and wild-ocean nurtured; as much of an audacious mariner as any. And for Radney, though in his infancy he may have laid him down on the lone Nantucket beach, to nurse at his maternal sea; though in after life he had long followed our austere Atlantic and your contemplative Pacific; yet was he quite as vengeful and full of social quarrel as the backwoods seaman, fresh from the latitudes of buck-horn handled Bowie-knives. Yet was this Nantucketer a man with some good-hearted traits; and this Lakeman, a mariner, who though a sort of devil indeed, might yet by inflexible firmness, only tempered by that common decency of human recognition which is the meanest slave's right; thus ..

treated, this Steelkilt had long been retained harmless and docile. At all events, he had proved so thus far; but Radney was doomed and made mad, and Steelkilt --but, gentlemen, you shall hear. It was not more than a day or two at the furthest after pointing her prow for her island haven, that the Town-Ho's leak seemed again increasing, but only so as to require an hour or more at the pumps every day. You must know that in a settled and civilized ocean like our Atlantic, for example, some skippers think little of pumping their whole way across it; though of a still, sleepy night, should the officer of the deck happen to forget his duty in that respect, the probability would be that he and his shipmates would never again remember it, on account of all hands gently subsiding to the bottom. Nor in the solitary and savage seas far from you to the westward, gentlemen, is it altogether unusual for ships to keep clanging at their pump-handles in full chorus even for a voyage of considerable length; that is, if it lie along a tolerably accessible coast, or if any other reasonable retreat is afforded them. It is only when a leaky vessel is in some very out of the way part of those waters, some really landless latitude, that her captain begins to feel a little anxious. Much this way had it been with the Town-Ho; so when her leak was found gaining once more, there was in truth some small concern manifested by several of her company; especially by radney the mate. He commanded the upper sails to be well hoisted, sheeted home anew, and every way expanded to the breeze. Now this Radney, I suppose, was as little of a coward, and as little inclined to any sort of nervous apprehensiveness touching his own person as any fearless, unthinking creature on land or on sea that you can conveniently imagine, gentlemen. Therefore when he betrayed this solicitude about the safety of the ship, some of the seamen declared that it was only on account of his being a part owner in her. So when they were working that evening at the pumps, there was on this head no small gamesomeness slily going on among them, as they stood with their feet continually overflowed by the rippling clear water; clear as any mountain spring, gentlemen --that bubbling from ..

the pumps ran across the deck, and poured itself out in steady spouts at the lee scupper-holes. Now, as you well know, it is not seldom the case in this conventional world of ours --watery or otherwise; that when a person placed in command over his fellow-men finds one of them to be very significantly his superior in general pride of manhood, straightway against that man he conceives an unconquerable dislike and bitterness; and if he have a chance he will pull down and pulverize that subaltern's tower, and make a little heap of dust of it. Be this conceit of mine as it may, gentlemen, at all events Steelkilt was a tall and noble animal with a head like a Roman, and a flowing golden beard like the tasseled housings of your last viceroy's snorting charger; and a brain, and a heart, and a soul in him, gentlemen, which had made Steelkilt Charlemagne, had he been born son to Charlemagne's father. But Radney, the mate, was ugly as a mule; yet as hardy, as stubborn, as malicious. He did not love Steelkilt, and Steelkilt knew it. Espying the mate drawing near as he was toiling at the pump with the rest, the Lakeman affected not to notice him, but unawed, went on with his gay banterings. "Aye, aye, my merry lads, it's a lively leak this; hold a cannikin, one of ye, and let's have a taste. By the Lord, it's worth bottling! I tell ye what, men, old Rad's investment must go for it! he had best cut away his part of the hull and tow it home. The fact is, boys, that sword-fish only began the job; he's come back again with a gang of ship-carpenters, saw-fish, and file-fish, and what not; and the whole posse of 'em are now hard at work cutting and slashing at the bottom; making improvements, I suppose. If old Rad were here now, I'd tell him to jump overboard and scatter 'em. They're playing the devil with his estate, I can tell him. But he's a simple old soul, -- Rad, and a beauty too. Boys, they say the rest of his property is invested in looking-glasses. I wonder if he'd give a poor devil like me the model of his nose." "Damn your eyes! what's that pump stopping for?" roared Radney, pretending not to have heard the sailors' talk. "Thunder away at it!" ..

"Aye, aye, sir," said Steelkilt, merry as a cricket. "Lively, boys, lively, now!" And with that the pump clanged like fifty fire-engines; the men tossed their hats off to it, and ere long that peculiar gasping of the lungs was heard which denotes the fullest tension of life's utmost energies. Quitting the pump at last, with the rest of his band, the Lakeman went forward all panting, and sat himself down on the windlass; his face fiery red, his eyes bloodshot, and wiping the profuse sweat from his brow. Now what cozening fiend it was, gentlemen, that possessed Radney to meddle with such a man in that corporeally exasperated state, I know not; but so it happened. Intolerably striding along the deck, the mate commanded him to get a broom and sweep down the planks, and also a shovel, and remove some offensive matters consequent upon allowing a pig to run at large. Now, gentlemen, sweeping a ship's deck at sea is a piece of household work which in all times but raging gales is regularly attended to every evening; it has been known to be done in the case of ships actually foundering at the time. Such, gentlemen, is the inflexibility of sea-usages and the instinctive love of neatness in seamen; some of whom would not willingly drown without first washing their faces. But in all vessels this broom business is the prescriptive province of the boys, if boys there be aboard. Besides, it was the stronger men in the Town-Ho that had been divided into gangs, taking turns at the pumps; and being the most athletic seaman of them all, Steelkilt had been regularly assigned captain of one of the gangs; consequently he should have been freed from any trivial business not connected with truly nautical duties, such being the case with his comrades. I mention all these particulars so that you may understand exactly how this affair stood between the two men. But there was more than this: the order about the shovel was almost as plainly meant to sting and insult Steelkilt, as though Radney had spat in his face. Any man who has gone sailor in a whale-ship will understand this; and all this and doubtless much more, the Lakeman fully comprehended when the mate uttered his command. But as he sat still for a moment, and as he steadfastly looked into the mate's malignant eye and ..

perceived the stacks of powder-casks heaped up in him and the slow-match silently burning along towards them; as he instinctively saw all this, that strange forbearance and unwillingness to stir up the deeper passionateness in any already ireful being --a repugnance most felt, when felt at all, by really valiant men even when aggrieved --this nameless phantom feeling, gentlemen, stole over Steelkilt. Therefore, in his ordinary tone, only a little broken by the bodily exhaustion he was temporarily in, he answered him saying that sweeping the deck was not his business, and he would not do it. and then, without at all alluding to the shovel, he pointed to three lads as the customary sweepers; who, not being billeted at the pumps, had done little or nothing all day. To this, Radney replied with an oath, in a most domineering and outrageous manner unconditionally reiterating his command; meanwhile advancing upon the still seated Lakeman, with an uplifted cooper's club hammer which he had snatched from a cask near by. Heated and irritated as he was by his spasmodic toil at the pumps, for all his first nameless feeling of forbearance the sweating Steelkilt could but ill brook this bearing in the mate; but somehow still smothering the conflagration within him, without speaking he remained doggedly rooted to his seat, till at last the incensed Radney shook the hammer within a few inches of his face, furiously commanding him to do his bidding. Steelkilt rose, and slowly retreating round the windlass, steadily followed by the mate with his menacing hammer, deliberately repeated his intention not to obey. Seeing, however, that his forbearance had not the slightest effect, by an awful and unspeakable intimation with his twisted hand he warned off the foolish and infatuated man; but it was to no purpose. And in this way the two went once slowly round the windlass; when, resolved at last no longer to retreat, bethinking him that he had now forborne as much as comported with his humor, the Lakeman paused on the hatches and thus spoke to the officer: "Mr. Radney, I will not obey you. Take that hammer away, or look to yourself." But the predestinated mate coming still closer to him, where the Lakeman stood fixed, now shook the ..

heavy hammer within an inch of his teeth; meanwhile repeating a string of insufferable maledictions. Retreating not the thousandth part of an inch; stabbing him in the eye with the unflinching poniard of his glance, steelkilt, clenching his right hand behind him and creepingly drawing it back, told his persecutor that if the hammer but grazed his cheek he (Steelkilt) would murder him. But, gentlemen, the fool had been branded for the slaughter by the gods. Immediately the hammer touched the cheek; the next instant the lower jaw of the mate was stove in his head; he fell on the hatch spouting blood like a whale. Ere the cry could go aft Steelkilt was shaking one of the backstays leading far aloft to where two of his comrades were standing their mast-heads. They were both Canallers. "Canallers!" cried Don Pedro, "We have seen many whale-ships in our harbors, but never heard of your Canallers. Pardon: who and what are they?" "Canallers, Don, are the boatmen belonging to our grand Erie Canal. You must have heard of it." "Nay, Senor; hereabouts in this dull, warm, most lazy, and hereditary land, we know but little of your vigorous North." "Aye? Well then, Don, refill my cup. Your chicha's very fine; and ere proceeding further I will tell ye what our Canallers are; for such information may throw side-light upon my story." For three hundred and sixty miles, gentlemen, through the entire breadth of the state of New York; through numerous populous cities and most thriving villages; through long, dismal, uninhabited swamps, and affluent, cultivated fields, unrivalled for fertility; by billiard-room and bar-room; through the holy-of-holies of great forests; on Roman arches over Indian rivers; through sun and shade; by happy hearts or broken; through all the wide contrasting scenery of those noble Mohawk counties; and especially, by rows of snow-white chapels, whose spires stand almost like milestones, flows one continual stream of Venetianly corrupt and often lawless life. There's your true Ashantee, gentlemen; there howl your pagans; where you ever find them, next door to you; under the long-flung shadow, and the snug patronizing lee of churches. For by some curious fatality, as it is often noted of your metropolitan freebooters ..

that they ever encamp around the halls of justice, so sinners, gentlemen, most abound in holiest vicinities. "Is that a friar passing?" said Don Pedro, looking downwards into the crowded plazza, with humorous concern. "Well for our northern friend, Dame Isabella's Inquisition wanes in Lima," laughed Don Sebastian. "Proceed, Senor." "A moment! Pardon!" cried another of the company. "In the name of all us Limeese, I but desire to express to you, sir sailor, that we have by no means overlooked your delicacy in not substituting present Lima for distant Venice in your corrupt comparison. Oh! do not bow and look surprised; you know the proverb all along this coast -- Corrupt as Lima. It but bears out your saying, too; churches more plentiful than billiard-tables, and for ever open--and Corrupt as Lima. So, too, Venice; I have been there; the holy city of the blessed evangelist, St. Mark! --St. Dominic, purge it! Your cup! Thanks: here I refill; now, you pour out again." Freely depicted in his own vocation, gentlemen, the Canaller would make a fine dramatic hero, so abundantly and picturesquely wicked is he. Like Mark Antony, for days and days along his green-turfed, flowery Nile, he indolently floats, openly toying with his red-cheeked Cleopatra, ripening his apricot thigh upon the sunny deck. But ashore, all this effeminacy is dashed. The brigandish guise which the Canaller so proudly sports; his slouched and gaily-ribboned hat betoken his grand features. A terror to the smiling innocence of the villages through which he floats; his swart visage and bold swagger are not unshunned in cities. Once a vagabond on his own canal, I have received good turns from one of these Canallers; I thank him heartily; would fain be not ungrateful; but it is often one of the prime redeeming qualities of your man of violence, that at times he has as stiff an arm to back a poor stranger in a strait, as to plunder a wealthy one. In sum, gentlemen, what the wildness of this canal life is, is emphatically evinced by this; that our wild whale-fishery contains so many of its most finished graduates, and that scarce any race of mankind, except Sydney men, are so much distrusted by our whaling captains. Nor does it at all diminish the curiousness of this matter, that to many thousands of our ..

rural boys and young men born along its line, the probationary life of the Grand Canal furnishes the sole transition between quietly reaping in a Christian corn-field, and recklessly ploughing the waters of the most barbaric seas. "I see! I see! " impetuously exclaimed Don Pedro, spilling his chicha upon his silvery ruffles. "No need to travel! The world's one Lima. I had thought, now, that at your temperate North the generations were cold and holy as the hills. --But the story." I left off, gentlemen, where the Lakeman shook the back-stay. Hardly had he done so, when he was surrounded by the three junior mates and the four harpooneers, who all crowded him to the deck. But sliding down the ropes like baleful comets, the two Canallers rushed into the uproar, and sought to drag their man out of it towards the forecastle. Others of the sailors joined with them in this attempt, and a twisted turmoil ensued; while standing out of harm's way, the valiant captain danced up and down with a whale-pike, calling upon his officers to manhandle that atrocious scoundrel, and smoke him along to the quarter-deck. At intervals, he ran close up to the revolving border of the confusion, and prying into the heart of it with his pike, sought to prick out the object of his resentment. But Steelkilt and his desperadoes were too much for them all; they succeeded in gaining the forecastle deck, where, hastily slewing about three or four large casks in a line with the windlass, these sea-Parisians entrenched themselves behind the barricade. "come out of that, ye pirates!" roared the captain, now menacing them with a pistol in each hand, just brought to him by the steward. "Come out of that, ye cut-throats!" Steelkilt leaped on the barricade, and striding up and down there, defied the worst the pistols could do; but gave the captain to understand distinctly, that his (Steelkilt's) death would be the signal for a murderous mutiny on the part of all hands. Fearing in his heart lest this might prove but too true, the captain a little desisted, but still commanded the insurgents instantly to return to their duty. "Will you promise not to touch us, if we do?" demanded their ringleader. ..

"Turn to! turn to! --I make no promise; --to your duty! Do you want to sink the ship, by knocking off at a time like this? Turn to!" and he once more raised a pistol. "Sink the ship?" cried Steelkilt. "Aye, let her sink. Not a man of us turns to, unless you swear not to raise a rope-yarn against us. What say ye, men?" turning to his comrades. A fierce cheer was their response. The Lakeman now patrolled the barricade, all the while keeping his eye on the Captain, and jerking out such sentences as these: --"It's not our fault; we didn't want it; I told him to take his hammer away; it was boy's business; he might have known me before this; I told him not to prick the buffalo; I believe I have broken a finger here against his cursed jaw; ain't those mincing knives down in the forecastle there, men? look to those handspikes, my hearties. Captain, by God, look to yourself; say the word; don't be a fool; forget it all; we are ready to turn to; treat us decently, and we're your men; but we won't be flogged." "Turn to! I make no promises, turn to, I say!" "Look ye, now," cried the Lakeman, flinging out his arm towards him. "there are a few of us here (and I am one of them) who have shipped for the cruise, d'ye see; now as you well know, sir, we can claim our discharge as soon as the anchor is down; so we don't want a row; it's not our interest; we want to be peaceable; we are ready to work, but we won't be flogged." "Turn to!" roared the Captain. Steelkilt glanced round him a moment, and then said: --"I tell you what it is now, Captain, rather than kill ye, and be hung for such a shabby rascal, we won't lift a hand against ye unless ye attack us; but till you say the word about not flogging us, we won't do a hand's turn." "Down into the forecastle then, down with ye, I'll keep ye there till ye're sick of it. Down ye go." "Shall we?" cried the ringleader to his men. Most of them were against it; but at length, in obedience to Steelkilt, they preceded him down into their dark den, growlingly disappearing, like bears into a cave. As the Lakeman's bare head was just level with the planks, ..

the Captain and his posse leaped the barricade, and rapidly drawing over the slide of the scuttle, planted their group of hands upon it, and loudly called for the steward to bring the heavy brass padlock, belonging to the companion-way. Then opening the slide a little, the Captain whispered something down the crack, closed it, and turned the key upon them --ten in number --leaving on deck some twenty or more, who thus far had remained neutral. All night a wide-awake watch was kept by all the officers, forward and aft, especially about the forecastle scuttle and fore hatchway; at which last place it was feared the insurgents might emerge, after breaking through the bulkhead below. But the hours of darkness passed in peace; the men who still remained at their duty toiling hard at the pumps, whose clinking and clanking at intervals through the dreary night dismally resounded through the ship. at sunrise the captain went forward, and knocking on the deck, summoned the prisoners to work; but with a yell they refused. Water was then lowered down to them, and a couple of handfuls of biscuit were tossed after it; when again turning the key upon them and pocketing it, the Captain returned to the quarter-deck. Twice every day for three days this was repeated; but on the fourth morning a confused wrangling, and then a scuffling was heard, as the customary summons was delivered; and suddenly four men burst up from the forecastle, saying they were ready to turn to. The fetid closeness of the air, and a famishing diet, united perhaps to some fears of ultimate retribution, had constrained them to surrender at discretion. Emboldened by this, the Captain reiterated his demand to the rest, but Steelkilt shouted up to him a terrific hint to stop his babbling and betake himself where he belonged. On the fifth morning three others of the mutineers bolted up into the air from the desperate arms below that sought to restrain them. Only three were left. "Better turn to, now?" said the Captain with a heartless jeer. "Shut us up again, will ye!" cried Steelkilt. "Oh! certainly," said the Captain and the key clicked. It was at this point, gentlemen, that enraged by the defection ..

of seven of his former associates, and stung by the mocking voice that had last hailed him, and maddened by his long entombment in a place as black as the bowels of despair; it was then that Steelkilt proposed to the two Canallers, thus far apparently of one mind with him, to burst out of their hole at the next summoning of the garrison; and armed with their keen mincing knives (long, crescentic, heavy implements with a handle at each end) run a muck from the bowsprit to the taffrail; and if by any devilishness of desperation possible, seize the ship. For himself, he would do this, he said, whether they joined him or not. That was the last night he should spend in that den. but the scheme met with no opposition on the part of the other two; they swore they were ready for that, or for any other mad thing, for anything in short but a surrender. And what was more, they each insisted upon being the first man on deck, when the time to make the rush should come. But to this their leader as fiercely objected, reserving that priority for himself; particularly as his two comrades would not yield, the one to the other, in the matter; and both of them could not be first, for the ladder would but admit one man at a time. And here, gentlemen, the foul play of these miscreants must come out. Upon hearing the frantic project of their leader, each in his own separate soul had suddenly lighted, it would seem, upon the same piece of treachery, namely: to be foremost in breaking out, in order to be the first of the three, though the last of the ten, to surrender; and thereby secure whatever small chance of pardon such conduct might merit. But when Steelkilt made known his determination still to lead them to the last, they in some way, by some subtle chemistry of villany, mixed their before secret treacheries together; and when their leader fell into a doze, verbally opened their souls to each other in three sentences; and bound the sleeper with cords, and gagged him with cords; and shrieked out for the Captain at midnight. Thinking murder at hand, and smelling in the dark for the blood, he and all his armed mates and harpooneers rushed for the forecastle. In a few minutes the scuttle was opened, and, bound hand and foot, the still struggling ringleader was shoved up into the air by his perfidious allies, who at once claimed the ..

honor of securing a man who had been fully ripe for murder. But all these were collared, and dragged along the deck like dead cattle; and, side by side, were seized up into the mizen rigging, like three quarters of meat, and there they hung till morning. "Damn ye," cried the Captain, pacing to and fro before them, "the vultures would not touch ye, ye villains!" At sunrise he summoned all hands; and separating those who had rebelled from those who had taken no part in the mutiny, he told the former that he had a good mind to flog them all round --thought, upon the whole, he would do so --he ought to --justice demanded it; but for the present, considering their timely surrender, he would let them go with a reprimand, which he accordingly administered in the vernacular. "But as for you, ye carrion rogues," turning to the three men in the rigging --"for you, I mean to mince ye up for the try-pots;" and, seizing a rope, he applied it with all his might to the backs of the two traitors, till they yelled no more, but lifelessly hung their heads sideways, as the two crucified thieves are drawn. "My wrist is sprained with ye!" he cried, at last; "but there is still rope enough left for you, my fine bantam, that wouldn't give up. Take that gag from his mouth, and let us hear what he can say for himself." For a moment the exhausted mutineer made a tremulous motion of his cramped jaws, and then painfully twisting round his head, said in a sort of hiss, "What I say is this --and mind it well--- if you flog me, I murder you!" "Say ye so? then see how ye frighten me" --and the Captain drew off with the rope to strike. "Best not," hissed the Lakeman. "But I must," --and the rope was once more drawn back for the stroke. Steelkilt here hissed out something, inaudible to all but the Captain; who, to the amazement of all hands, started back, paced the deck rapidly two or three times, and then suddenly throwing down his rope, said,"I won't do it --let him go--cut him down: d'ye hear?" But as the junior mates were hurrying to execute the order, ..

a pale man, with a bandaged head, arrested them --Radney the chief mate. Ever since the blow, he had lain in his berth; but that morning, hearing the tumult on the deck, he had crept out, and thus far had watched the whole scene. Such was the state of his mouth, that he could hardly speak; but mumbling something about his being willing and able to do what the captain dared not attempt, he snatched the rope and advanced to his pinioned foe. "You are a coward!" hissed the Lakeman. "So I am, but take that." The mate was in the very act of striking, when another hiss stayed his uplifted arm. He paused: and then pausing no more, made good his word, spite of Steelkilt's threat, whatever that might have been. The three men were then cut down, all hands were turned to, and, sullenly worked by the moody seamen, the iron pumps clanged as before. Just after dark that day, when one watch had retired below, a clamor was heard in the forecastle; and the two trembling traitors running up, besieged the cabin door, saying they durst not consort with the crew. Entreaties, cuffs, and kicks could not drive them back, so at their own instance they were put down in the ship's run for salvation. Still, no sign of mutiny reappeared among the rest. On the contrary, it seemed, that mainly at Steelkilt's instigation, they had resolved to maintain the strictest peacefulness, obey all orders to the last, and, when the ship reached port, desert her in a body. But in order to insure the speediest end to the voyage, they all agreed to another thing --namely, not to sing out for whales, in case any should be discovered. For, spite of her leak, and spite of all her other perils, the Town-Ho still maintained her mast-heads, and her captain was just as willing to lower for a fish that moment, as on the day his craft first struck the cruising ground; and Radney the mate was quite as ready to change his berth for a boat, and with his bandaged mouth seek to gag in death the vital jaw of the whale. But though the Lakeman had induced the seamen to adopt this sort of passiveness in their conduct, he kept his own counsel (at least till all was over) concerning his own proper and private revenge upon the man who had stung him in the ventricles ..

of his heart. He was in Radney the chief mate's watch; and as if the infatuated man sought to run more than half way to meet his doom, after the scene at the rigging, he insisted, against the express counsel of the captain, upon resuming the head of his watch at night. Upon this, and one or two other circumstances, Steelkilt systematically built the plan of his revenge. During the night, Radney had an unseamanlike way of sitting on the bulwarks of the quarter-deck, and leaning his arm upon the gunwale of the boat which was hoisted up there, a little above the ship's side. In this attitude, it was well known, he sometimes dozed. There was a considerable vacancy between the boat and the ship, and down between this was the sea. Steelkilt calculated his time, and found that his next trick at the helm would come round at two o'clock, in the morning of the third day from that in which he had been betrayed. At his leisure, he employed the interval in braiding something very carefully in his watches below. "What are you making there?" said a shipmate. "What do you think? what does it look like?" "Like a lanyard for your bag; but it's an odd one, seems to me." "Yes, rather oddish," said the Lakeman, holding it at arm's length before him; "but I think it will answer. Shipmate, I haven't enough twine, --have you any?" But there was none in the forecastle. "Then I must get some from old Rad;" and he rose to go aft. "You don't mean to go a begging to him!" said a sailor. "Why not? Do you think he won't do me a turn, when it's to help himself in the end, shipmate?" and going to the mate, he looked at him quietly, and asked him for some twine to mend his hammock. It was given him --neither twine nor lanyard were seen again; but the next night an iron ball, closely netted, partly rolled from the pocket of the Lakeman's monkey jacket, as he was tucking the coat into his hammock for a pillow. Twenty-four hours after, his trick at the silent helm --nigh to the man who was apt to doze over the grave always ready dug to the seaman's hand --that fatal hour was then to come; and in ..

the fore-ordaining soul of Steelkilt, the mate was already stark and stretched as a corpse, with his forehead crushed in. But, gentlemen, a fool saved the would-be murderer from the bloody deed he had planned. Yet complete revenge he had, and without being the avenger. For by a mysterious fatality, Heaven itself seemed to step in to take out of his hands into its own the damning thing he would have done. It was just between daybreak and sunrise of the morning of the second day, when they were washing down the decks, that a stupid Teneriffe man, drawing water in the main-chains, all at once shouted out, "There she rolls! there she rolls!" Jesu, what a whale! It was Moby Dick. "Moby Dick!" cried Don Sebastian; "St. Dominic! Sir sailor, but do whales have christenings? Whom call you Moby Dick?" "A very white, and famous, and most deadly immortal monster, Don; --but that would be too long a story." "How? how!" cried all the young Spaniards, crowding. "Nay, Dons, Dons --nay, nay! I cannot rehearse that now. Let me get more into the air, Sirs." "The chicha! the chicha!" cried Don Pedro; "our vigorous friend looks faint; --fill up his empty glass!" No need, gentlemen; one moment, and I proceed. --Now, gentlemen, so suddenly perceiving the snowy whale within fifty yards of the ship --forgetful of the compact among the crew --in the excitement of the moment, the Teneriffe man had instinctively and involuntarily lifted his voice for the monster, though for some little time past it had been plainly beheld from the three sullen mast-heads. All was now a phrensy. "The White Whale --the White Whale!" was the cry from captain, mates, and harpooneers, who, undeterred by fearful rumors, were all anxious to capture so famous and precious a fish; while the dogged crew eyed askance, and with curses, the appalling beauty of the vast milky mass, that lit up by a horizontal spangling sun, shifted and glistened like a living opal in the blue morning sea. Gentlemen, a strange fatality pervades the whole career of these events, as if verily mapped out before the world itself was charted. The mutineer was the bowsman of the mate, and when fast to a fish, it was his duty to sit next him, while Radney stood ..

up with his lance in the prow, and haul in or slacken the line, at the word of command. Moreover, when the four boats were lowered, the mate's got the start; and none howled more fiercely with delight than did Steelkilt, as he strained at his oar. After a stiff pull, their harpooneer got fast, and, spear in hand, Radney sprang to the bow. He was always a furious man, it seems, in a boat. And now his bandaged cry was, to beach him on the whale's topmost back. Nothing loath, his bowsman hauled him up and up, through a blinding foam that blent two whitenesses together; till of a sudden the boat struck as against a sunken ledge, and keeling over, spilled out the standing mate. That instant, as he fell on the whale's slippery back, the boat righted, and was dashed aside by the swell, while Radney was tossed over into the sea, on the other flank of the whale. He struck out through the spray, and, for an instant, was dimly seen through that veil, wildly seeking to remove himself from the eye of Moby Dick. But the whale rushed round in a sudden maelstrom; seized the swimmer between his jaws; and rearing high up with him, plunged headlong again, and went down. Meantime, at the first tap of the boat's bottom, the Lakeman had slackened the line, so as to drop astern from the whirlpool; calmly looking on, he thought his own thoughts. But a sudden, terrific, downward jerking of the boat, quickly brought his knife to the line. He cut it; and the whale was free. But, at some distance, Moby Dick rose again, with some tatters of Radney's red woollen shirt, caught in the teeth that had destroyed him. All four boats gave chase again; but the whale eluded them, and finally wholly disappeared. In good time, the Town-Ho reached her port --a savage, solitary place --where no civilized creature resided. There, headed by the Lakeman, all but five or six of the foremast-men deliberately deserted among the palms; eventually, as it turned out, seizing a large double war-canoe of the savages, and setting sail for some other harbor. The ship's company being reduced to but a handful, the captain called upon the Islanders to assist him in the laborious business of heaving down the ship to stop the leak. But to such unresting vigilance over their dangerous allies was this small ..

band of whites necessitated, both by night and by day, and so extreme was the hard work they underwent, that upon the vessel being ready again for sea, they were in such a weakened condition that the captain durst not put off with them in so heavy a vessel. After taking counsel with his officers, he anchored the ship as far off shore as possible; loaded and ran out his two cannon from the bows; stacked his muskets on the poop; and warning the Islanders not to approach the ship at their peril, took one man with him, and setting the sail of his best whale-boat, steered straight before the wind for Tahiti, five hundred miles distant, to procure a reinforcement to his crew. On the fourth day of the sail, a large canoe was descried, which seemed to have touched at a low isle of corals. He steered away from it; but the savage craft bore down on him; and soon the voice of Steelkilt hailed him to heave to, or he would run him under water. the captain presented a pistol. With one foot on each prow of the yoked war-canoes, the Lakeman laughed him to scorn; assuring him that if the pistol so much as clicked in the lock, he would bury him in bubbles and foam. "What do you want of me? cried the captain. "Where are you bound? and for what are you bound?" demanded Steelkilt; "no lies." "I am bound to Tahiti for more men." "Very good. Let me board you a moment --I come in peace." With that he leaped from the canoe, swam to the boat; and climbing the gunwale, stood face to face with the captain. "Cross your arms, sir; throw back your head. Now, repeat after me. As soon as Steelkilt leaves me, I swear to beach this boat on yonder island, and remain there six days. If I do not, may lightnings strike me!" "A pretty scholar," laughed the Lakeman."Adios, Senor!" and leaping into the sea, he swam back to his comrades. Watching the boat till it was fairly beached, and drawn up to the roots of the cocoa-nut trees, Steelkilt made sail again, and in due time arrived at Tahiti, his own place of destination. There, luck befriended him; two ships were about to sail for France, and were providentially in want of precisely that number ..

of men which the sailor headed. They embarked; and so for ever got the start of their former captain, had he been at all minded to work them legal retribution. Some ten days after the French ships sailed, the whale-boat arrived, and the captain was forced to enlist some of the more civilized Tahitians, who had been somewhat used to the sea. Chartering a small native schooner, he returned with them to his vessel; and finding all right there, again resumed his cruisings. Where Steelkilt now is, gentlemen, none know; but upon the island of Nantucket, the widow of Radney still turns to the sea which refuses to give up its dead; still in dreams sees the awful white whale that destroyed him. "Are you through?" said Don Sebastian, quietly. "I am, Don." "Then I entreat you, tell me if to the best of your own convictions, this story is in substance really true? It is so passing wonderful! Did you get it from an unquestionable source? Bear with me if I seem to press." "Also bear with all of us, sir sailor; for we all join in Don Sebastian's suit," cried the company, with exceeding interest. "Is there a copy of the Holy Evangelists in the Golden Inn, gentlemen?" "Nay," said Don Sebastian; "but I know a worthy priest near by, who will quickly procure one for me. I go for it; but are you well advised? this may grow too serious." "Will you be so good as to bring the priest also, Don?" "Though there are no Auto-da-Fes in Lima now," said one of the company to another: "I fear our sailor friend runs risk of the archiepiscopacy. Let us withdraw more out of the moonlight. I see no need for this." "Excuse me for running after you, Don Sebastian; but may I also beg that you will be particular in procuring the largest sized Evangelists you can." "This is the priest, he brings you the Evangelists," said Don Sebastian, gravely, returning with a tall and solemn figure. "Let me remove my hat. Now, venerable priest, further into the light, and hold the Holy Book before me that I may touch it." ..

"So help me Heaven, and on my honor the story I have told ye, gentlemen, is in substance and its great items, true. I know it to be true; it happened on this ball; I trod the ship; I knew the crew; I have seen and talked with Steelkilt since the death of Radney." ..

The ancient whale-cry upon first sighting a whale from the mast-head, still used by whalemen in hunting the famous Gallipagos terrapin. ..

.. < chapter lv 7 OF THE MONSTROUS PICTURES OF WHALES > I shall ere long paint to you as well as one can without canvas, something like the true form of the whale as he actually appears to the eye of the whaleman when in his own absolute body the whale is moored alongside the whale-ship so that he can be fairly stepped upon there. It may be worth while, therefore, previously to advert to those curious imaginary portraits of him which even down to the present day confidently challenge the faith of the landsman. It is time to set the world right in this matter, by proving such pictures of the whale all wrong. It may be that the primal source of all those pictorial delusions will be found among the oldest Hindoo, Egyptian, and Grecian sculptures. For ever since those inventive but unscrupulous times when on the marble panellings of temples, the pedestals of statues, and on shields, medallions, cups, and coins, the dolphin was drawn in scales of chain-armor like Saladin's, and a helmeted head like St. George's; ever since then has something of the same sort of license prevailed, not only in most popular pictures of the whale, but in many scientific presentations of him. Now, by all odds, the most ancient extant portrait anyways purporting to be the whale's, is to be found in the famous cavern-pagoda of Elephanta, in India. The Brahmins maintain that in the almost endless sculptures of that immemorial pagoda, all the trades and pursuits, every conceivable avocation of man, were prefigured ages before any of them actually came into being. No wonder then, that in some sort our noble profession ..

of whaling should have been there shadowed forth. The Hindoo whale referred to, occurs in a separate department of the wall, depicting the incarnation of Vishnu in the form of leviathan, learnedly known as the Matse Avatar. But though this sculpture is half man and half whale, so as only to give the tail of the latter, yet that small section of him is all wrong. It looks more like the tapering tail of an anaconda, than the broad palms of the true whale's majestic flukes. But go to the old Galleries, and look now at a great Christian painter's portrait of this fish; for he succeeds no better than the antediluvian Hindoo. It is Guido's picture of Perseus rescuing Andromeda from the sea-monster or whale. Where did Guido get the model of such a strange creature as that? Nor does Hogarth, in painting the same scene in his own Perseus Descending, make out one whit better. The huge corpulence of that Hogarthian monster undulates on the surface, scarcely drawing one inch of water. It has a sort of howdah on its back, and its distended tusked mouth into which the billows are rolling, might be taken for the Traitors' Gate leading from the Thames by water into the Tower. Then, there are the Prodromus whales of the old Scotch Sibbald, and Jonah's whale, as depicted in the prints of old Bibles and the cuts of old primers. What shall be said of these? As for the book-binder's whale winding like a vine-stalk round the stock of a descending anchor --as stamped and gilded on the backs and title-pages of many books both old and new --that is a very picturesque but purely fabulous creature, imitated, I take it, from the like figures on antique vases. Though universally denominated a dolphin, I nevertheless call this book-binder's fish an attempt at a whale; because it was so intended when the device was first introduced. It was introduced by an old Italian publisher somewhere about the 15th century, during the Revival of Learning; and in those days, and even down to a comparatively late period, dolphins were popularly supposed to be a species of the Leviathan. In the vignettes and other embellishments of some ancient books you will at times meet with very curious touches at the whale, where all manner of spouts, jets d'eau, hot springs and cold, Saratoga and Baden-Baden, come bubbling up from his ..

unexhausted brain. In the title-page of the original edition of the Advancement of Learning you will find some curious whales. But quitting all these unprofessional attempts, let us glance at those pictures of leviathan purporting to be sober, scientific delineations, by those who know. In old Harris's collection of voyages there are some plates of whales extracted from a Dutch book of voyages, A. D. , entitled A Whaling Voyage to Spitzbergen in the ship Jonas in the Whale, Peter Peterson of Friesland, master. In one of those plates the whales, like great rafts of logs, are represented lying among ice-isles, with white bears running over their living backs. In another plate, the prodigious blunder is made of representing the whale with perpendicular flukes. Then again, there is an imposing quarto, written by one Captain Colnett, a Post Captain in the English navy, entitled A Voyage round Cape Horn into the South Seas, for the purpose of extending the Spermaceti Whale Fisheries. In this book is an outline purporting to be a Picture of a Physeter or Spermaceti whale, drawn by scale from one killed on the coast of Mexico, August, , and hoisted on deck. I doubt not the captain had this veracious picture taken for the benefit of his marines. To mention but one thing about it, let me say that it has an eye which applied, according to the accompanying scale, to a full grown sperm whale, would make the eye of that whale a bow-window some five feet long. Ah, my gallant captain, why did ye not give us Jonah looking out of that eye! Nor are the most conscientious compilations of Natural History for the benefit of the young and tender, free from the same heinousness of mistake. Look at that popular work Goldsmith's Animated Nature. In the abridged London edition of , there are plates of an alleged whale and a narwhale. I do not wish to seem inelegant, but this unsightly whale looks much like an amputated sow; and, as for the narwhale, one glimpse at it is enough to amaze one, that in this nineteenth century such a hippogriff could be palmed for genuine upon any intelligent public of schoolboys. Then, again, in , Bernard Germain, Count de Lacepede, ..

a great naturalist, published a scientific systemized whale book, wherein are several pictures of the different species of the Leviathan. All these are not only incorrect, but the picture of the Mysticetus or Greenland whale (that is to say, the Right whale), even Scoresby, a long experienced man as touching that species, declares not to have its counterpart in nature. But the placing of the cap-sheaf to all this blundering business was reserved for the scientific Frederick Cuvier, brother to the famous Baron. In , he published a Natural History of Whales, in which he gives what he calls a picture of the Sperm Whale. Before showing that picture to any Nantucketer, you had best provide for your summary retreat from Nantucket. In a word, Frederick Cuvier's Sperm Whale is not a Sperm Whale, but a squash. Of course, he never had the benefit of a whaling voyage (such men seldom have), but whence he derived that picture, who can tell? Perhaps he got it as his scientific predecessor in the same field, Desmarest, got one of his authentic abortions; that is, from a Chinese drawing. And what sort of lively lads with the pencil those Chinese are, many queer cups and saucers inform us. As for the sign-painters' whales seen in the streets hanging over the shops of oil-dealers, what shall be said of them? They are generally Richard III. whales, with dromedary humps, and very savage; breakfasting on three or four sailor tarts, that is whaleboats full of mariners: their deformities floundering in seas of blood and blue paint. but these manifold mistakes in depicting the whale are not so very surprising after all. Consider! Most of the scientific drawings have been taken from the stranded fish; and these are about as correct as a drawing of a wrecked ship, with broken back, would correctly represent the noble animal itself in all its undashed pride of hull and spars. Though elephants have stood for their full-lengths, the living Leviathan has never yet fairly floated himself for his portrait. The living whale, in his full majesty and significance, is only to be seen at sea in unfathomable waters; and afloat the vast bulk of him is out of sight, like a launched line-of-battle ship; and out of that element it is a thing eternally impossible for mortal man to hoist ..

him bodily into the air, so as to preserve all his mighty swells and undulations. And, not to speak of the highly presumable difference of contour between a young sucking whale and a full-grown Platonian Leviathan; yet, even in the case of one of those young sucking whales hoisted to a ship's deck, such is then the outlandish, eel-like, limbered, varying shape of him, that his precise expression the devil himself could not catch. But it may be fancied, that from the naked skeleton of the stranded whale, accurate hints may be derived touching his true form. Not at all. For it is one of the more curious things about this Leviathan, that his skeleton gives very little idea of his general shape. Though Jeremy Bentham's skeleton, which hangs for candelabra in the library of one of his executors, correctly conveys the idea of a burly-browed utilitarian old gentleman, with all Jeremy's other leading personal characteristics; yet nothing of this kind could be inferred from any leviathan's articulated bones. In fact, as the great Hunter says, the mere skeleton of the whale bears the same relation to the fully invested and padded animal as the insect does to the chrysalis that so roundingly envelopes it. This peculiarity is strikingly evinced in the head, as in some part of this book will be incidentally shown. It is also very curiously displayed in the side fin, the bones of which almost exactly answer to the bones of the human hand, minus only the thumb. This fin has four regular bone-fingers, the index, middle, ring, and little finger. But all these are permanently lodged in their fleshy covering, as the human fingers in an artificial covering. However recklessly the whale may sometimes serve us, said humorous Stubb one day, he can never be truly said to handle us without mittens. For all these reasons, then, any way you may look at it, you must needs conclude that the great Leviathan is that one creature in the world which must remain unpainted to the last. True, one portrait may hit the mark much nearer than another, but none can hit it with any very considerable degree of exactness. So there is no earthly way of finding out precisely what the whale really looks like. And the only mode in which you can derive even a tolerable idea of his living contour, is by ..

going a whaling yourself; but by so doing, you run no small risk of being eternally stove and sunk by him. Wherefore, it seems to me you had best not be too fastidious in your curiosity touching this Leviathan. ..

.. < chapter lvi 6 OF THE LESS ERRONEOUS PICTURES OF WHALES, AND THE TRUE > PICTURES OF WHALING SCENES In connexion with the monstrous pictures of whales, I am strongly tempted here to enter upon those still more monstrous stories of them which are to be found in certain books, both ancient and modern, especially in Pliny, Purchas, Hackluyt, Harris, Cuvier, etc. But I pass that matter by. i know of only four published outlines of the great Sperm Whale; Colnett's, Huggins's, Frederick Cuvier's, and Beale's. In the previous chapter Colnett and Cuvier have been referred to. Huggins's is far better than theirs; but, by great odds, Beale's is the best. All Beale's drawings of this whale are good, excepting the middle figure in the picture of three whales in various attitudes, capping his second chapter. His frontispiece, boats attacking Sperm Whales, though no doubt calculated to excite the civil scepticism of some parlor men, is admirably correct and life-like in its general effect. Some of the Sperm Whale drawings in J. Ross Browne are pretty correct in contour; but they are wretchedly engraved. That is not his fault though. Of the Right Whale, the best outline pictures are in Scoresby; but they are drawn on too small a scale to convey a desirable impression. He has but one picture of whaling scenes, and this is a sad deficiency, because it is by such pictures only, when at all well done, that you can derive anything like a truthful idea of the living whale as seen by his living hunters. But, taken for all in all, by far the finest, though in some details not the most correct, presentations of whales and whaling ..

scenes to be anywhere found, are two large French engravings, well executed, and taken from paintings by one Garnery. Respectively, they represent attacks on the Sperm and Right Whale. In the first engraving a noble Sperm Whale is depicted in full majesty of might, just risen beneath the boat from the profundities of the ocean, and bearing high in the air upon his back the terrific wreck of the stoven planks. The prow of the boat is partially unbroken, and is drawn just balancing upon the monster's spine; and standing in that prow, for that one single incomputable flash of time, you behold an oarsman, half shrouded by the incensed boiling spout of the whale, and in the act of leaping, as if from a precipice. The action of the whole thing is wonderfully good and true. The half-emptied line-tub floats on the whitened sea; the wooden poles of the spilled harpoons obliquely bob in it; the heads of the swimming crew are scattered about the whale in contrasting expressions of affright; while in the black stormy distance the ship is bearing down upon the scene. Serious fault might be found with the anatomical details of this whale, but let that pass; since, for the life of me, I could not draw so good a one. In the second engraving, the boat is in the act of drawing alongside the barnacled flank of a large running Right Whale, that rolls his black weedy bulk in the sea like some mossy rock-slide from the Patagonian cliffs. His jets are erect, full, and black like soot; so that from so abounding a smoke in the chimney, you would think there must be a brave supper cooking in the great bowels below. Sea fowls are pecking at the small crabs, shell-fish, and other sea candies and maccaroni, which the Right Whale sometimes carries on his pestilent back. And all the while the thick-lipped leviathan is rushing through the deep, leaving tons of tumultuous white curds in his wake, and causing the slight boat to rock in the swells like a skiff caught nigh the paddle-wheels of an ocean steamer. Thus, the foreground is all raging commotion; but behind, in admirable artistic contrast, is the glassy level of a sea becalmed, the drooping unstarched sails of the powerless ship, and the inert mass of a dead whale, a conquered fortress, with the flag of capture lazily hanging from the whale-pole inserted into his spout-hole. ..

Who Garnery the painter is, or was, I know not. But my life for it he was either practically conversant with his subject, or else marvellously tutored by some experienced whaleman. The French are the lads for painting action. Go and gaze upon all the paintings in Europe, and where will you find such a gallery of living and breathing commotion on canvas, as in that triumphal hall at Versailles; where the beholder fights his way, pell-mell, through the consecutive great battles of France; where every sword seems a flash of the Northern Lights, and the successive armed kings and Emperors dash by, like a charge of crowned centaurs? Not wholly unworthy of a place in that gallery, are these sea battle-pieces of Garnery. The natural aptitude of the French for seizing the picturesqueness of things seems to be peculiarly evinced in what paintings and engravings they have of their whaling scenes. With not one tenth of England's experience in the fishery, and not the thousandth part of that of the Americans, they have nevertheless furnished both nations with the only finished sketches at all capable of conveying the real spirit of the whale hunt. For the most part, the English and American whale draughtsmen seem entirely content with presenting the mechanical outline of things, such as the vacant profile of the whale; which, so far as picturesqueness of effect is concerned, is about tantamount to sketching the profile of a pyramid. Even Scoresby, the justly renowned Right whaleman, after giving us a stiff full length of the Greenland whale, and three or four delicate miniatures of narwhales and porpoises, treats us to a series of classical engravings of boat hooks, chopping knives, and grapnels; and with the microscopic diligence of a Leuwenhoeck submits to the inspection of a shivering world ninety-six fac-similes of magnified Arctic snow crystals. I mean no disparagement to the excellent voyager (I honor him for a veteran), but in so important a matter it was certainly an oversight not to have procured for every crystal a sworn affidavit taken before a Greenland Justice of the Peace. In addition to those fine engravings from Garnery, there are two other French engravings worthy of note, by some one who subscribes himself h. durand. one of them, though not precisely ..

adapted to our present purpose, nevertheless deserves mention on other accounts. It is a quiet noon-scene among the isles of the Pacific; a French whaler anchored, inshore, in a calm, and lazily taking water on board; the loosened sails of the ship, and the long leaves of the palms in the background, both drooping together in the breezeless air. The effect is very fine, when considered with reference to its presenting the hardy fishermen under one of their few aspects of oriental repose. The other engraving is quite a different affair: the ship hove-to upon the open sea, and in the very heart of the Leviathanic life, with a Right Whale alongside; the vessel (in the act of cutting-in) hove over to the monster as if to a quay; and a boat, hurriedly pushing off from this scene of activity, is about giving chase to whales in the distance. The harpoons and lances lie levelled for use; three oarsmen are just setting the mast in its hole; while from a sudden roll of the sea, the little craft stands half-erect out of the water, like a rearing horse. From the ship, the smoke of the torments of the boiling whale is going up like the smoke over a village of smithies; and to windward, a black cloud, rising up with earnest of squalls and rains, seems to quicken the activity of the excited seamen. ..

.. < chapter lvii 23 OF WHALES IN PAINT; IN TEETH; IN WOOD; IN > SHEET-IRON; IN STONE; IN MOUNTAINS; IN STARS On Tower-hill, as you go down to the London docks, you may have seen a crippled beggar (or kedger, as the sailors say) holding a painted board before him, representing the tragic scene in which he lost his leg. There are three whales and three boats; and one of the boats (presumed to contain the missing leg in all its original integrity) is being crunched by the jaws of the foremost whale. Any time these ten years, they tell me, has that man held up that picture, and exhibited ..

that stump to an incredulous world. But the time of his justification has now come. His three whales are as good whales as were ever published in Wapping, at any rate; and his stump as unquestionable a stump as any you will find in the western clearings. But, though for ever mounted on that stump, never a stump-speech does the poor whaleman make; but, with downcast eyes, stands ruefully contemplating his own amputation. Throughout the Pacific, and also in Nantucket, and New Bedford, and Sag Harbor, you will come across lively sketches of whales and whaling-scenes, graven by the fishermen themselves on Sperm Whale-teeth, or ladies' busks wrought out of the Right Whale-bone, and other like skrimshander articles, as the whalemen call the numerous little ingenious contrivances they elaborately carve out of the rough material, in their hours of ocean leisure. Some of them have little boxes of dentistical-looking implements, specially intended for the skrimshandering business. But, in general, they toil with their jack-knives alone; and, with that almost omnipotent tool of the sailor, they will turn you out anything you please, in the way of a mariner's fancy. Long exile from Christendom and civilization inevitably restores a man to that condition in which God placed him, i. e. what is called savagery. Your true whale-hunter is as much a savage as an Iroquois. I myself am a savage; owning no allegiance but to the King of the Cannibals; and ready at any moment to rebel against him. Now, one of the peculiar characteristics of the savage in his domestic hours, is his wonderful patience of industry. An ancient Hawaiian war-club or spear-paddle, in its full multiplicity and elaboration of carving, is as great a trophy of human perseverance as a Latin lexicon. For, with but a bit of broken sea-shell or a shark's tooth, that miraculous intricacy of wooden net-work has been achieved; and it has cost steady years of steady application. As with the Hawaiian savage, so with the white sailor-savage. With the same marvellous patience, and with the same single shark's tooth, of his one poor jack-knife, he will carve you a bit of bone sculpture, not quite as workmanlike, but as close ..

packed in its maziness of design, as the Greek savage, Achilles's shield; and full of barbaric spirit and suggestiveness, as the prints of that fine old Dutch savage, Albert Durer. Wooden whales, or whales cut in profile out of the small dark slabs of the noble South Sea war-wood, are frequently met with in the forecastles of American whalers. Some of them are done with much accuracy. At some old gable-roofed country houses you will see brass whales hung by the tail for knockers to the road-side door. When the porter is sleepy, the anvil-headed whale would be best. But these knocking whales are seldom remarkable as faithful essays. On the spires of some old-fashioned churches you will see sheet-iron whales placed there for weather-cocks; but they are so elevated, and besides that are to all intents and purposes so labelled with Hands off! you cannot examine them closely enough to decide upon their merit. In bony, ribby regions of the earth, where at the base of high broken cliffs masses of rock lie strewn in fantastic groupings upon the plain, you will often discover images as of the petrified forms of the Leviathan partly merged in grass, which of a windy day breaks against them in a surf of green surges. Then, again, in mountainous countries where the traveller is continually girdled by amphitheatrical heights; here and there from some lucky point of view you will catch passing glimpses of the profiles of whales defined along the undulating ridges. But you must be a thorough whaleman, to see these sights; and not only that, but if you wish to return to such a sight again, you must be sure and take the exact intersecting latitude and longitude of your first stand-point, else so chance-like are such observations of the hills, that your precise, previous stand-point would require a laborious re-discovery; like the Solomon islands, which still remain incognita, though once high-ruffed Mendanna trod them and old Figuera chronicled them. Nor when expandingly lifted by your subject, can you fail to trace out great whales in the starry heavens, and boats in pursuit of them; as when long filled with thoughts of war the Eastern nations saw armies locked in battle among the clouds. Thus at the North have I chased Leviathan round and round ..

the Pole with the revolutions of the bright points that first defined him to me. And beneath the effulgent Antarctic skies I have boarded the Argo-Navis, and joined the chase against the starry Cetus far beyond the utmost stretch of Hydrus and the Flying Fish. With a frigate's anchors for my bridle-bitts and fasces of harpoons for spurs, would I could mount that whale and leap the topmost skies, to see whether the fabled heavens with all their countless tents really lie encamped beyond my mortal sight! ..

.. < chapter lviii 11 BRIT > Steering north-eastward from the Crozetts, we fell in with vast meadows of brit, the minute, yellow substance, upon which the Right Whale largely feeds. For leagues and leagues it undulated round us, so that we seemed to be sailing through boundless fields of ripe and golden wheat. On the second day, numbers of Right Whales were seen, who, secure from the attack of a Sperm Whaler like the Pequod, with open jaws sluggishly swam through the brit, which, adhering to the fringing fibres of that wondrous Venetian blind in their mouths, was in that manner separated from the water that escaped at the lip. As morning mowers, who side by side slowly and seethingly advance their scythes through the long wet grass of marshy meads; even so these monsters swam, making a strange, grassy, cutting sound; and leaving behind them endless swaths of blue upon the yellow sea. ..

But it was only the sound they made as they parted the brit which at all reminded one of mowers. Seen from the mast-heads, especially when they paused and were stationary for a while, their vast black forms looked more like lifeless masses of rock than anything else. And as in the great hunting countries of India, the stranger at a distance will sometimes pass on the plains recumbent elephants without knowing them to be such, taking them for bare, blackened elevations of the soil; even so, often, with him, who for the first time beholds this species of the leviathans of the sea. And even when recognised at last, their immense magnitude renders it very hard really to believe that such bulky masses of overgrowth can possibly be instinct, in all parts, with the same sort of life that lives in a dog or a horse. Indeed, in other respects, you can hardly regard any creatures of the deep with the same feelings that you do those of the shore. For though some old naturalists have maintained that all creatures of the land are of their kind in the sea; and though taking a broad general view of the thing, this may very well be; yet coming to specialties, where, for example, does the ocean furnish any fish that in disposition answers to the sagacious kindness of the dog? The accursed shark alone can in any generic respect be said to bear comparative analogy to him. But though, to landsmen in general, the native inhabitants of the seas have ever been regarded with emotions unspeakably unsocial and repelling; though we know the sea to be an everlasting terra incognita, so that Columbus sailed over numberless unknown worlds to discover his one superficial western one; though, by vast odds, the most terrific of all mortal disasters have immemorially and indiscriminately befallen tens and hundreds of thousands of those who have gone upon the waters; though but a moment's consideration will teach, that however baby man may brag of his science and skill, and however much, in a flattering future, that science and skill may augment; yet for ever and for ever, to the crack of doom, the sea will insult and murder him, and pulverize the stateliest, stiffest frigate he can make; nevertheless, by the continual repetition of these ..

very impressions, man has lost that sense of the full awfulness of the sea which aboriginally belongs to it. The first boat we read of, floated on an ocean, that with Portuguese vengeance had whelmed a whole world without leaving so much as a widow. That same ocean rolls now; that same ocean destroyed the wrecked ships of last year. Yea, foolish mortals, Noah's flood is not yet subsided; two thirds of the fair world it yet covers. Wherein differ the sea and the land, that a miracle upon one is not a miracle upon the other? Preternatural terrors rested upon the Hebrews, when under the feet of Korah and his company the live ground opened and swallowed them up for ever; yet not a modern sun ever sets, but in precisely the same manner the live sea swallows up ships and crews. But not only is the sea such a foe to man who is an alien to it, but it is also a fiend to its own offspring; worse than the Persian host who murdered his own guests; sparing not the creatures which itself hath spawned. Like a savage tigress that tossing in the jungle overlays her own cubs, so the sea dashes even the mightiest whales against the rocks, and leaves them there side by side with the split wrecks of ships. No mercy, no power but its own controls it. Panting and snorting like a mad battle steed that has lost its rider, the masterless ocean overruns the globe. Consider the subtleness of the sea; how its most dreaded creatures glide under water, unapparent for the most part, and treacherously hidden beneath the loveliest tints of azure. Consider also the devilish brilliance and beauty of many of its most remorseless tribes, as the dainty embellished shape of many species of sharks. Consider, once more, the universal cannibalism of the sea; all whose creatures prey upon each other, carrying on eternal war since the world began. Consider all this; and then turn to this green, gentle, and most docile earth; consider them both, the sea and the land; and do you not find a strange analogy to something in yourself? For as this appalling ocean surrounds the verdant land, so in the soul of man there lies one insular Tahiti, full of peace and joy, but encompassed by all the horrors of the half known life. ..

God keep thee! Push not off from that isle, thou canst never return! ..

That part of the sea known among whalemen as the Brazil Banks does not bear that name as the Banks of Newfoundland do, because of there being shallows and soundings there, but because of this remarkable meadow-like appearance, caused by the vast drifts of brit continually floating in those latitudes, where the Right Whale is often chased. ..

.. < chapter lix 4 SQUID > Slowly wading through the meadows of brit, the Pequod still held on her way north-eastward towards the island of Java; a gentle air impelling her keel, so that in the surrounding serenity her three tall tapering masts mildly waved to that languid breeze, as three mild palms on a plain. And still, at wide intervals in the silvery night, the lonely, alluring jet would be seen. But one transparent blue morning, when a stillness almost preternatural spread over the sea, however unattended with any stagnant calm; when the long burnished sun-glade on the waters seemed a golden finger laid across them, enjoining some secresy; when the slippered waves whispered together as they softly ran on; in this profound hush of the visible sphere a strange spectre was seen by Daggoo from the main-mast-head. In the distance, a great white mass lazily rose, and rising higher and higher, and disentangling itself from the azure, at last gleamed before our prow like a snow-slide, new slid from the hills. Thus glistening for a moment, as slowly it subsided, and sank. Then once more arose, and silently gleamed. It seemed not a whale; and yet is this Moby Dick? thought Daggoo. Again the phantom went down, but on re-appearing once more, with a stiletto-like cry that startled every man from his nod, the negro yelled out -- There! there again! there she breaches! right ahead! The White Whale, the White Whale! Upon this, the seamen rushed to the yard-arms, as in swarming-time the bees rush to the boughs. Bare-headed in the sultry sun, Ahab stood on the bowsprit, and with one hand pushed far behind in readiness to wave his orders to the helmsman, cast ..

his eager glance in the direction indicated aloft by the outstretched motionless arm of Daggoo. Whether the flitting attendance of the one still and solitary jet had gradually worked upon Ahab, so that he was now prepared to connect the ideas of mildness and repose with the first sight of the particular whale he pursued; however this was, or whether his eagerness betrayed him; whichever way it might have been, no sooner did he distinctly perceive the white mass, than with a quick intensity he instantly gave orders for lowering. The four boats were soon on the water; Ahab's in advance, and all swiftly pulling towards their prey. Soon it went down, and while, with oars suspended, we were awaiting its reappearance, lo! in the same spot where it sank, once more it slowly rose. Almost forgetting for the moment all thoughts of Moby Dick, we now gazed at the most wondrous phenomenon which the secret seas have hitherto revealed to mankind. A vast pulpy mass, furlongs in length and breadth, of a glancing cream-color, lay floating on the water, innumerable long arms radiating from its centre, and curling and twisting like a nest of anacondas, as if blindly to clutch at any hapless object within reach. No perceptible face or front did it have; no conceivable token of either sensation or instinct; but undulated there on the billows, an unearthly, formless, chance-like apparition of life. As with a low sucking sound it slowly disappeared again, Starbuck still gazing at the agitated waters where it had sunk, with a wild voice exclaimed -- Almost rather had I seen Moby Dick and fought him, than to have seen thee, thou white ghost! What was it, Sir? said Flask. The great live squid, which they say, few whale-ships ever beheld, and returned to their ports to tell of it. But Ahab said nothing; turning his boat, he sailed back to the vessel; the rest as silently following. Whatever superstitions the sperm whalemen in general have connected with the sight of this object, certain it is, that a glimpse of it being so very unusual, that circumstance has gone far to invest it with portentousness. So rarely is it beheld, that though one and all of them declare it to be the largest animated thing in the ocean, yet very few of them have any but ..

the most vague ideas concerning its true nature and form; notwithstanding, they believe it to furnish to the sperm whale his only food. For though other species of whales find their food above water, and may be seen by man in the act of feeding, the spermaceti whale obtains his whole food in unknown zones below the surface; and only by inference is it that any one can tell of what, precisely, that food consists. At times, when closely pursued, he will disgorge what are supposed to be the detached arms of the squid; some of them thus exhibited exceeding twenty and thirty feet in length. They fancy that the monster to which these arms belonged ordinarily clings by them to the bed of the ocean; and that the sperm whale, unlike other species, is supplied with teeth in order to attack and tear it. There seems some ground to imagine that the great Kraken of Bishop Pontoppodan may ultimately resolve itself into Squid. The manner in which the Bishop describes it, as alternately rising and sinking, with some other particulars he narrates, in all this the two correspond. But much abatement is necessary with respect to the incredible bulk he assigns it. By some naturalists who have vaguely heard rumors of the mysterious creature, here spoken of, it is included among the class of cuttle-fish, to which, indeed, in certain external respects it would seem to belong, but only as the Anak of the tribe. ..

.. < chapter lx 26 THE LINE > With reference to the whaling scene shortly to be described, as well as for the better understanding of all similar scenes elsewhere presented, I have here to speak of the magical, sometimes horrible whale-line. The line originally used in the fishery was of the best hemp, slightly vapored with tar, not impregnated with it, as in the ..

case of ordinary ropes; for while tar, as ordinarily used, makes the hemp more pliable to the rope-maker, and also renders the rope itself more convenient to the sailor for common ship use; yet, not only would the ordinary quantity too much stiffen the whale-line for the close coiling to which it must be subjected; but as most seamen are beginning to learn, tar in general by no means adds to the rope's durability or strength, however much it may give it compactness and gloss. Of late years the Manilla rope has in the American fishery almost entirely superseded hemp as a material for whale-lines; for, though not so durable as hemp, it is stronger, and far more soft and elastic; and I will add (since there is an aesthetics in all things), is much more handsome and becoming to the boat, than hemp. Hemp is a dusky, dark fellow, a sort of Indian; but Manilla is as a golden-haired Circassian to behold. The whale line is only two thirds of an inch in thickness. At first sight, you would not think it so strong as it really is. By experiment its one and fifty yarns will each suspend a weight of one hundred and twenty pounds; so that the whole rope will bear a strain nearly equal to three tons. In length, the common sperm whale-line measures something over two hundred fathoms. Towards the stern of the boat it is spirally coiled away in the tub, not like the worm-pipe of a still though, but so as to form one round, cheese-shaped mass of densely bedded sheaves, or layers of concentric spiralizations, without any hollow but the heart, or minute vertical tube formed at the axis of the cheese. As the least tangle or kink in the coiling would, in running out, infallibly take somebody's arm, leg, or entire body off, the utmost precaution is used in stowing the line in its tub. Some harpooneers will consume almost an entire morning in this business, carrying the line high aloft and then reeving it downwards through a block towards the tub, so as in the act of coiling to free it from all possible wrinkles and twists. In the English boats two tubs are used instead of one; the same line being continuously coiled in both tubs. There is some advantage in this; because these twin-tubs being so small they fit more readily into the boat, and do not strain it so much; whereas, the American tub, nearly three feet in diameter and ..

of proportionate depth, makes a rather bulky freight for a craft whose planks are but one half-inch in thickness; for the bottom of the whale-boat is like critical ice, which will bear up a considerable distributed weight, but not very much of a concentrated one. When the painted canvas cover is clapped on the american line-tub, the boat looks as if it were pulling off with a prodigious great wedding-cake to present to the whales. Both ends of the line are exposed; the lower end terminating in an eye-splice or loop coming up from the bottom against the side of the tub, and hanging over its edge completely disengaged from everything. This arrangement of the lower end is necessary on two accounts. First: In order to facilitate the fastening to it of an additional line from a neighboring boat, in case the stricken whale should sound so deep as to threaten to carry off the entire line originally attached to the harpoon. In these instances, the whale of course is shifted like a mug of ale, as it were, from the one boat to the other; though the first boat always hovers at hand to assist its consort. Second: This arrangement is indispensable for common safety's sake; for were the lower end of the line in any way attached to the boat, and were the whale then to run the line out to the end almost in a single, smoking minute as he sometimes does, he would not stop there, for the doomed boat would infallibly be dragged down after him into the profundity of the sea; and in that case no town-crier would ever find her again. Before lowering the boat for the chase, the upper end of the line is taken aft from the tub, and passing round the logger-head there, is again carried forward the entire length of the boat, resting crosswise upon the loom or handle of every man's oar, so that it jogs against his wrist in rowing; and also passing between the men, as they alternately sit at the opposite gunwales, to the leaded chocks or grooves in the extreme pointed prow of the boat, where a wooden pin or skewer the size of a common quill, prevents it from slipping out. From the chocks it hangs in a slight festoon over the bows, and is then passed inside the boat again; and some ten or twenty fathoms (called box-line) being coiled upon the box in the bows, it continues its way to the gunwale still a little further aft, and is then ..

attached to the short-warp --the rope which is immediately connected with the harpoon; but previous to that connexion, the short-warp goes through sundry mystifications too tedious to detail. Thus the whale-line folds the whole boat in its complicated coils, twisting and writhing around it in almost every direction. All the oarsmen are involved in its perilous contortions; so that to the timid eye of the landsman, they seem as Indian jugglers, with the deadliest snakes sportively festooning their limbs. Nor can any son of mortal woman, for the first time, seat himself amid those hempen intricacies, and while straining his utmost at the oar, bethink him that at any unknown instant the harpoon may be darted, and all these horrible contortions be put in play like ringed lightnings; he cannot be thus circumstanced without a shudder that makes the very marrow in his bones to quiver in him like a shaken jelly. Yet habit --strange thing! what cannot habit accomplish? --Gayer sallies, more merry mirth, better jokes, and brighter repartees, you never heard over your mahogany, than you will hear over the half-inch white cedar of the whale-boat, when thus hung in hangman's nooses; and, like the six burghers of Calais before King Edward, the six men composing the crew pull into the jaws of death, with a halter around every neck, as you may say. Perhaps a very little thought will now enable you to account for those repeated whaling disasters --some few of which are casually chronicled --of this man or that man being taken out of the boat by the line, and lost. For, when the line is darting out, to be seated then in the boat, is like being seated in the midst of the manifold whizzings of a steam-engine in full play, when every flying beam, and shaft, and wheel, is grazing you. It is worse; for you cannot sit motionless in the heart of these perils, because the boat is rocking like a cradle, and you are pitched one way and the other, without the slightest warning; and only by a certain self-adjusting buoyancy and simultaneousness of volition and action, can you escape being made a Mazeppa of, and run away with where the all-seeing sun himself could never pierce you out. Again: as the profound calm which only apparently precedes ..

and prophesies of the storm, is perhaps more awful than the storm itself; for, indeed, the calm is but the wrapper and envelope of the storm; and contains it in itself, as the seemingly harmless rifle holds the fatal powder, and the ball, and the explosion; so the graceful repose of the line, as it silently serpentines about the oarsmen before being brought into actual play -- this is a thing which carries more of true terror than any other aspect of this dangerous affair. But why say more? All men live enveloped in whale-lines. All are born with halters round their necks; but it is only when caught in the swift, sudden turn of death, that mortals realize the silent, subtle, ever-present perils of life. And if you be a philosopher, though seated in the whale-boat, you would not at heart feel one whit more of terror, than though seated before your evening fire with a poker, and not a harpoon, by your side. ..

.. < chapter lxi 17 STUBB KILLS A WHALE > If to Starbuck the apparition of the Squid was a thing of portents, to Queequeg it was quite a different object. When you see him 'quid, said the savage, honing his harpoon in the bow of his hoisted boat, then you quick see him 'parm whale. The next day was exceedingly still and sultry, and with nothing special to engage them, the Pequod's crew could hardly resist the spell of sleep induced by such a vacant sea. For this part of the Indian Ocean through which we then were voyaging is not what whalemen call a lively ground; that is, it affords fewer glimpses of porpoises, dolphins, flying-fish, and other vivacious denizens of more stirring waters, than those off the Rio de la Plata, or the in-shore ground off Peru. It was my turn to stand at the foremast-head; and with my shoulders leaning against the slackened royal shrouds, to and ..

fro I idly swayed in what seemed an enchanted air. No resolution could withstand it; in that dreamy mood losing all consciousness, at last my soul went out of my body; though my body still continued to sway as a pendulum will, long after the power which first moved it is withdrawn. Ere forgetfulness altogether came over me, I had noticed that the seamen at the main and mizen mast-heads were already drowsy. So that at last all three of us lifelessly swung from the spars, and for every swing that we made there was a nod from below from the slumbering helmsman. The waves, too, nodded their indolent crests; and across the wide trance of the sea, east nodded to west, and the sun over all. Suddenly bubbles seemed bursting beneath my closed eyes; like vices my hands grasped the shrouds; some invisible, gracious agency preserved me; with a shock I came back to life. And lo! close under our lee, not forty fathoms off, a gigantic Sperm Whale lay rolling in the water like the capsized hull of a frigate, his broad, glossy back, of an Ethiopian hue, glistening in the sun's rays like a mirror. But lazily undulating in the trough of the sea, and ever and anon tranquilly spouting his vapory jet, the whale looked like a portly burgher smoking his pipe of a warm afternoon. But that pipe, poor whale, was thy last. As if struck by some enchanter's wand, the sleepy ship and every sleeper in it all at once started into wakefulness; and more than a score of voices from all parts of the vessel, simultaneously with the three notes from aloft, shouted forth the accustomed cry, as the great fish slowly and regularly spouted the sparkling brine into the air. clear away the boats! luff! cried Ahab. And obeying his own order, he dashed the helm down before the helmsman could handle the spokes. The sudden exclamations of the crew must have alarmed the whale; and ere the boats were down, majestically turning, he swam away to the leeward, but with such a steady tranquillity, and making so few ripples as he swam, that thinking after all he might not as yet be alarmed, Ahab gave orders that not an oar should be used, and no man must speak but in whispers. So seated like Ontario Indians on the gunwales of the boats, ..

we swiftly but silently paddled along; the calm not admitting of the noiseless sails being set. Presently, as we thus glided in chase, the monster perpendicularly flitted his tail forty feet into the air, and then sank out of sight like a tower swallowed up. There go flukes! was the cry, an announcement immediately followed by Stubb's producing his match and igniting his pipe, for now a respite was granted. After the full interval of his sounding had elapsed, the whale rose again, and being now in advance of the smoker's boat, and much nearer to it than to any of the others, Stubb counted upon the honor of the capture. It was obvious, now, that the whale had at length become aware of his pursuers. All silence of cautiousness was therefore no longer of use. Paddles were dropped, and oars came loudly into play. And still puffing at his pipe, Stubb cheered on his crew to the assault. Yes, a mighty change had come over the fish. All alive to his jeopardy, he was going head out; that part obliquely projecting from the mad yeast which he brewed. Start her, start her, my men! Don't hurry yourselves; take plenty of time --but start her; start her like thunder-claps, that's all, cried Stubb, spluttering out the smoke as he spoke. start her, now; give 'em the long and strong stroke, tashtego. Start her, Tash, my boy --start her, all; but keep cool, keep cool-- cucumbers is the word --easy, easy --only start her like grim death and grinning devils, and raise the buried dead perpendicular out of their graves, boys --that's all. Start her! Woo-hoo! Wa-hee! screamed the Gay-Header in reply, raising some old war-whoop to the skies; as every oarsman in the strained boat involuntarily bounced forward with the one tremendous leading stroke which the eager Indian gave. ..

But his wild screams were answered by others quite as wild. Kee-hee! Kee-hee! yelled Daggoo, straining forwards and backwards on his seat, like a pacing tiger in his cage. Ka-la! Koo-loo! howled Queequeg, as if smacking his lips over a mouthful of Grenadier's steak. And thus with oars and yells the keels cut the sea. Meanwhile, Stubb retaining his place in the van, still encouraged his men to the onset, all the while puffing the smoke from his mouth. Like desperadoes they tugged and they strained, till the welcome cry was heard -- Stand up, Tashtego! --give it to him! The harpoon was hurled. Stern all! The oarsmen backed water; the same moment something went hot and hissing along every one of their wrists. It was the magical line. An instant before, Stubb had swiftly caught two additional turns with it round the loggerhead, whence, by reason of its increased rapid circlings, a hempen blue smoke now jetted up and mingled with the steady fumes from his pipe. As the line passed round and round the loggerhead; so also, just before reaching that point, it blisteringly passed through and through both of Stubb's hands, from which the hand-cloths, or squares of quilted canvas sometimes worn at these times, had accidentally dropped. It was like holding an enemy's sharp two-edged sword by the blade, and that enemy all the time striving to wrest it out of your clutch. Wet the line! wet the line! cried stubb to the tub oarsman (him seated by the tub) who, snatching off his hat, dashed the sea-water into it. More turns were taken, so that the line began holding its place. The boat now flew through the boiling water like a shark all fins. Stubb and Tashtego here changed places -- stem for stern --a staggering business truly in that rocking commotion. From the vibrating line extending the entire length of the upper part of the boat, and from its now being more tight than a harpstring, you would have thought the craft had two keels -- one cleaving the water, the other the air --as the boat churned ..

on through both opposing elements at once. A continual cascade played at the bows; a ceaseless whirling eddy in her wake; and, at the slightest motion from within, even but of a little finger, the vibrating, cracking craft canted over her spasmodic gunwale into the sea. Thus they rushed; each man with might and main clinging to his seat, to prevent being tossed to the foam; and the tall form of Tashtego at the steering oar crouching almost double, in order to bring down his centre of gravity. Whole Atlantics and Pacifics seemed passed as they shot on their way, till at length the whale somewhat slackened his flight. Haul in --haul in! cried Stubb to the bowsman! and, facing round towards the whale, all hands began pulling the boat up to him, while yet the boat was being towed on. Soon ranging up by his flank, Stubb, firmly planting his knee in the clumsy cleat, darted dart after dart into the flying fish; at the word of command, the boat alternately sterning out of the way of the whale's horrible wallow, and then ranging up for another fling. The red tide now poured from all sides of the monster like brooks down a hill. His tormented body rolled not in brine but in blood, which bubbled and seethed for furlongs behind in their wake. The slanting sun playing upon this crimson pond in the sea, sent back its reflection into every face, so that they all glowed to each other like red men. And all the while, jet after jet of white smoke was agonizingly shot from the spiracle of the whale, and vehement puff after puff from the mouth of the excited headsman; as at every dart, hauling in upon his crooked lance (by the line attached to it), Stubb straightened it again and again, by a few rapid blows against the gunwale, then again and again sent it into the whale. Pull up --pull up! he now cried to the bowsman, as the waning whale relaxed in his wrath. Pull up! --close to! and the boat ranged along the fish's flank. When reaching far over the bow, Stubb slowly churned his long sharp lance into the fish, and kept it there, carefully churning and churning, as if cautiously seeking to feel after some gold watch that the whale might have swallowed, and which he was fearful of breaking ere he could hook it out. But that gold watch he sought was the innermost life of the fish. And now it is struck; for, starting ..

from his trance into that unspeakable thing called his flurry, the monster horribly wallowed in his blood, over-wrapped himself in impenetrable, mad, boiling spray, so that the imperilled craft, instantly dropping astern, had much ado blindly to struggle out from that phrensied twilight into the clear air of the day. And now abating in his flurry, the whale once more rolled out into view; surging from side to side; spasmodically dilating and contracting his spout-hole, with sharp, cracking, agonized respirations. At last, gush after gush of clotted red gore, as if it had been the purple lees of red wine, shot into the frighted air; and falling back again, ran dripping down his motionless flanks into the sea. His heart had burst! He's dead, Mr. Stubb, said Daggoo. Yes; both pipes smoked out! and withdrawing his own from his mouth, Stubb scattered the dead ashes over the water; and, for a moment, stood thoughtfully eyeing the vast corpse he had made. ..

It will be seen in some other place of what a very light substance the entire interior of the sperm whale's enormous head consists. Though apparently the most massive, it is by far the most buoyant part about him. So that with ease he elevates it in the air, and invariably does so when going at his utmost speed. Besides, such is the breadth of the upper part of the front of his head, and such the tapering cut-water formation of the lower part, that by obliquely elevating his head, he thereby may be said to transform himself from a bluff-bowed sluggish galliot into a sharp-pointed New York pilot-boat. ..

Partly to show the indispensableness of this act, it may here be stated, that, in the old Dutch fishery, a mop was used to dash the running line with water; in many other ships, a wooden piggin, or bailer, is set apart for that purpose. Your hat, however, is the most convenient. ..

.. < chapter lxii 19 THE DART > A word concerning an incident in the last chapter. According to the invariable usage of the fishery, the whale-boat pushes off from the ship, with the headsman or whale-killer as temporary steersman, and the harpooneer or whale-fastener pulling the foremost oar, the one known as the harpooneer-oar. Now it needs a strong, nervous arm to strike the first iron into the fish; for often, in what is called a long dart, the heavy implement has to be flung to the distance of twenty or thirty feet. But however prolonged and exhausting the chase, the harpooneer is expected to pull his oar meanwhile to the uttermost; indeed, he is expected to set an example of superhuman activity to the rest, not only by incredible rowing, but by repeated loud and intrepid exclamations; and what it is to keep shouting at the top of one's compass, while all the other ..

muscles are strained and half started --what that is none know but those who have tried it. For one, I cannot bawl very heartily and work very recklessly at one and the same time. In this straining, bawling state, then, with his back to the fish, all at once the exhausted harpooneer hears the exciting cry -- Stand up, and give it to him! He now has to drop and secure his oar, turn round on his centre half way, seize his harpoon from the crotch, and with what little strength may remain, he essays to pitch it somehow into the whale. No wonder, taking the whole fleet of whalemen in a body, that out of fifty fair chances for a dart, not five are successful; no wonder that so many hapless harpooneers are madly cursed and disrated; no wonder that some of them actually burst their blood-vessels in the boat; no wonder that some sperm whalemen are absent four years with four barrels; no wonder that to many ship owners, whaling is but a losing concern; for it is the harpooneer that makes the voyage, and if you take the breath out of his body how can you expect to find it there when most wanted! Again, if the dart be successful, then at the second critical instant, that is, when the whale starts to run, the boat-header and harpooneer likewise start to running fore and aft, to the imminent jeopardy of themselves and every one else. It is then they change places; and the headsman, the chief officer of the little craft, takes his proper station in the bows of the boat. Now, I care not who maintains the contrary, but all this is both foolish and unnecessary. The headsman should stay in the bows from first to last; he should both dart the harpoon and the lance, and no rowing whatever should be expected of him, except under circumstances obvious to any fisherman. I know that this would sometimes involve a slight loss of speed in the chase; but long experience in various whalemen of more than one nation has convinced me that in the vast majority of failures in the fishery, it has not by any means been so much the speed of the whale as the before described exhaustion of the harpooneer that has caused them. To insure the greatest efficiency in the dart, the harpooneers of this world must start to their feet from out of idleness, and not from out of toil. ..

.. < chapter lxiii 2 THE CROTCH > Out of the trunk, the branches grow; out of them, the twigs. So, in productive subjects, grow the chapters. The crotch alluded to on a previous page deserves independent mention. It is a notched stick of a peculiar form, some two feet in length, which is perpendicularly inserted into the starboard gunwale near the bow, for the purpose of furnishing a rest for the wooden extremity of the harpoon, whose other naked, barbed end slopingly projects from the prow. Thereby the weapon is instantly at hand to its hurler, who snatches it up as readily from its rest as a backwoodsman swings his rifle from the wall. It is customary to have two harpoons reposing in the crotch, respectively called the first and second irons. But these two harpoons, each by its own cord, are both connected with the line; the object being this: to dart them both, if possible, one instantly after the other into the same whale; so that if, in the coming drag, one should draw out, the other may still retain a hold. It is a doubling of the chances. But it very often happens that owing to the instantaneous, violent, convulsive running of the whale upon receiving the first iron, it becomes impossible for the harpooneer, however lightning-like in his movements, to pitch the second iron into him. Nevertheless, as the second iron is already connected with the line, and the line is running, hence that weapon must, at all events, be anticipatingly tossed out of the boat, somehow and somewhere; else the most terrible jeopardy would involve all hands. Tumbled into the water, it accordingly is in such cases; the spare coils of box line (mentioned in a preceding chapter) making this feat, in most instances, prudently practicable. But this critical act is not always unattended with the saddest and most fatal casualties. Furthermore: you must know that when the second iron is thrown overboard, it thenceforth becomes a dangling, sharp-edged ..

terror, skittishly curvetting about both boat and whale, entangling the lines, or cutting them, and making a prodigious sensation in all directions. Nor, in general, is it possible to secure it again until the whale is fairly captured and a corpse. Consider, now, how it must be in the case of four boats all engaging one unusually strong, active, and knowing whale; when owing to these qualities in him, as well as to the thousand concurring accidents of such an audacious enterprise, eight or ten loose second irons may be simultaneously dangling about him. For, of course, each boat is supplied with several harpoons to bend on to the line should the first one be ineffectually darted without recovery. All these particulars are faithfully narrated here, as they will not fail to elucidate several most important, however intricate passages, in scenes hereafter to be painted. ..

.. < chapter lxiv 16 STUBB'S SUPPER > Stubb's whale had been killed some distance from the ship. It was a calm; so, forming a tandem of three boats, we commenced the slow business of towing the trophy to the Pequod. And now, as we eighteen men with our thirty-six arms, and one hundred and eighty thumbs and fingers, slowly toiled hour after hour upon that inert, sluggish corpse in the sea; and it seemed hardly to budge at all, except at long intervals; good evidence was hereby furnished of the enormousness of the mass we moved. For, upon the great canal of Hang-Ho, or whatever they call it, in China, four or five laborers on the foot-path will draw a bulky freighted junk at the rate of a mile an hour; but this grand argosy we towed heavily forged along, as if laden with pig-lead in bulk. Darkness came on; but three lights up and down in the Pequod's main-rigging dimly guided our way; till drawing nearer we saw Ahab dropping one of several more lanterns over the ..

bulwarks. Vacantly eyeing the heaving whale for a moment, he issued the usual orders for securing it for the night, and then handing his lantern to a seaman, went his way into the cabin, and did not come forward again until morning. Though, in overseeing the pursuit of this whale, Captain Ahab had evinced his customary activity, to call it so; yet now that the creature was dead, some vague dissatisfaction, or impatience, or despair, seemed working in him; as if the sight of that dead body reminded him that Moby Dick was yet to be slain; and though a thousand other whales were brought to his ship, all that would not one jot advance his grand, monomaniac object. Very soon you would have thought from the sound on the Pequod's decks, that all hands were preparing to cast anchor in the deep; for heavy chains are being dragged along the deck, and thrust rattling out of the port-holes. But by those clanking links, the vast corpse itself, not the ship, is to be moored. Tied by the head to the stern, and by the tail to the bows, the whale now lies with its black hull close to the vessel's, and seen through the darkness of the night, which obscured the spars and rigging aloft, the two --ship and whale, seemed yoked together like colossal bullocks, whereof one reclines while the other remains standing. If moody Ahab was now all quiescence, at least so far as could be known on deck, Stubb, his second mate, flushed with conquest, betrayed an unusual but still good-natured excitement. Such an unwonted bustle was he in that the staid Starbuck, his ..

official superior, quietly resigned to him for the time the sole management of affairs. One small, helping cause of all this liveliness in Stubb, was soon made strangely manifest. Stubb was a high liver; he was somewhat intemperately fond of the whale as a flavorish thing to his palate. A steak, a steak, ere I sleep! You, Daggoo! overboard you go, and cut me one from his small! Here be it known, that though these wild fishermen do not, as a general thing, and according to the great military maxim, make the enemy defray the current expenses of the war (at least before realizing the proceeds of the voyage), yet now and then you find some of these Nantucketers who have a genuine relish for that particular part of the Sperm Whale designated by Stubb; comprising the tapering extremity of the body. About midnight that steak was cut and cooked; and lighted by two lanterns of sperm oil, Stubb stoutly stood up to his spermaceti supper at the capstan-head, as if that capstan were a sideboard. Nor was Stubb the only banqueter on whale's flesh that night. Mingling their mumblings with his own mastications, thousands on thousands of sharks, swarming round the dead leviathan, smackingly feasted on its fatness. The few sleepers below in their bunks were often startled by the sharp slapping of their tails against the hull, within a few inches of the sleepers' hearts. Peering over the side you could just see them (as before you heard them) wallowing in the sullen, black waters, and turning over on their backs as they scooped out huge globular pieces of the whale of the bigness of a human head. This particular feat of the shark seems all but miraculous. How, at such an apparently unassailable surface, they contrive to gouge out such symmetrical mouthfuls, remains a part of the universal problem of all things. The mark they thus leave on the whale, may best be likened to the hollow made by a carpenter in countersinking for a screw. Though amid all the smoking horror and diabolism of a sea-fight, sharks will be seen longingly gazing up to the ship's decks, like hungry dogs round a table where red meat is being carved, ready to bolt down every killed man that is tossed to them; and though, while the valiant butchers over the deck-table are ..

thus cannibally carving each other's live meat with carving-knives all gilded and tasselled, the sharks, also, with their jewel-hilted mouths, are quarrelsomely carving away under the table at the dead meat; and though, were you to turn the whole affair upside down, it would still be pretty much the same thing, that is to say, a shocking sharkish business enough for all parties; and though sharks also are the invariable outriders of all slave ships crossing the Atlantic, systematically trotting alongside, to be handy in case a parcel is to be carried anywhere, or a dead slave to be decently buried; and though one or two other like instances might be set down, touching the set terms, places, and occasions, when sharks do most socially congregate, and most hilariously feast; yet is there no conceivable time or occasion when you will find them in such countless numbers, and in gayer or more jovial spirits, than around a dead sperm whale, moored by night to a whale-ship at sea. If you have never seen that sight, then suspend your decision about the propriety of devil-worship, and the expediency of conciliating the devil. But, as yet, Stubb heeded not the mumblings of the banquet that was going on so nigh him, no more than the sharks heeded the smacking of his own epicurean lips. Cook, cook! --where's that old Fleece? he cried at length, widening his legs still further, as if to form a more secure base for his supper; and, at the same time darting his fork into the dish, as if stabbing with his lance; cook, you cook! --sail this way, cook! the old black, not in any very high glee at having been previously routed from his warm hammock at a most unseasonable hour, came shambling along from his galley, for, like many old blacks, there was something the matter with his knee-pans, which he did not keep well scoured like his other pans; this old Fleece, as they called him, came shuffling and limping along, assisting his step with his tongs, which, after a clumsy fashion, were made of straightened iron hoops; this old Ebony floundered along, and in obedience to the word of command, came to a dead stop on the opposite side of Stubb's sideboard; when, ..

with both hands folded before him, and resting on his two-legged cane, he bowed his arched back still further over, at the same time sideways inclining his head, so as to bring his best ear into play. Cook, said Stubb, rapidly lifting a rather reddish morsel to his mouth, don't you think this steak is rather overdone? You've been beating this steak too much, cook; it's too tender. Don't I always say that to be good, a whale-steak must be tough? There are those sharks now over the side, don't you see they prefer it tough and rare? What a shindy they are kicking up! Cook, go and talk to 'em; tell 'em they are welcome to help themselves civilly, and in moderation, but they must keep quiet. Blast me, if I can hear my own voice. Away, cook, and deliver my message. Here, take this lantern, snatching one from his sideboard; now then, go and preach to 'em! Sullenly taking the offered lantern, old Fleece limped across the deck to the bulwarks; and then, with one hand dropping his light low over the sea, so as to get a good view of his congregation, with the other hand he solemnly flourished his tongs, and leaning far over the side in a mumbling voice began addressing the sharks, while Stubb, softly crawling behind, overheard all that was said. Fellow-critters: I'se ordered here to say dat you must stop dat dam noise dare. you hear? stop dat dam smackin' ob de lip! massa Stubb say dat you can fill your dam bellies up to de hatchings, but by Gor! you must stop dat dam racket! Cook, here interposed Stubb, accompanying the word with a sudden slap on the shoulder, -- Cook! why, damn your eyes, you mustn't swear that way when you're preaching. That's no way to convert sinners, Cook! Who dat? Den preach to him yourself, sullenly turning to go. No, Cook; go on, go on. Well, den, Belubed fellow-critters: -- Right! exclaimed Stubb, approvingly, coax 'em to it; try that, and Fleece continued. Do you is all sharks, and by natur wery woracious, yet I ..

zay to you, fellow-critters, dat dat woraciousness --'top dat dam slappin' ob de tail! How you tink to hear, 'spose you keep up such a dam slappin' and bitin' dare? Cook, cried Stubb, collaring him, I wont have that swearing. Talk to 'em gentlemanly. Once more the sermon proceeded. Your woraciousness, fellow-critters, I don't blame ye so much for; dat is natur, and can't be helped; but to gobern dat wicked natur, dat is de pint. You is sharks, sartin; but if you gobern de shark in you, why den you be angel; for all angel is not'ing more dan de shark well goberned. Now, look here, bred'ren, just try wonst to be cibil, a helping yourselbs from dat whale. Don't be tearin' de blubber out your neighbour's mout, I say. Is not one shark dood right as toder to dat whale? And, by Gor, none on you has de right to dat whale; dat whale belong to some one else. I know some o' you has berry brig mout, brigger dan oders; but den de brig mouts sometimes has de small bellies; so dat de brigness ob de mout is not to swallar wid, but to bite off de blubber for de small fry ob sharks, dat can't get into de scrouge to help demselves. Well done, old Fleece! cried Stubb, that's Christianity; go on. No use goin' on; de dam willains will keep a scrougin' and slappin' each oder, Massa Stubb; dey don't hear one word; no use a-preachin' to such dam g'uttons as you call 'em, till dare bellies is full, and dare bellies is bottomless; and when dey do get em full, dey wont hear you den; for den dey sink in de sea, go fast to sleep on de coral, and can't hear not'ing at all, no more, for eber and eber. Upon my soul, I am about of the same opinion; so give the benediction, Fleece, and I'll away to my supper. Upon this, Fleece, holding both hands over the fishy mob, raised his shrill voice, and cried -- Cussed fellow-critters! Kick up de damndest row as ever you can; fill your dam' bellies 'till dey bust --and den die. Now, cook, said Stubb, resuming his supper at the capstan; Stand just where you stood before, there, over against me, and pay particular attention. ..

All dention, said Fleece, again stooping over upon his tongs in the desired position. Well, said Stubb, helping himself freely meanwhile; I shall now go back to the subject of this steak. In the first place, how old are you, cook? What dat do wid de 'teak, said the old black, testily. Silence! How old are you, cook? 'Bout ninety, dey say, he gloomily muttered. And have you lived in this world hard upon one hundred years, cook, and don't know yet how to cook a whale-steak? rapidly bolting another mouthful at the last word, so that that morsel seemed a continuation of the question. Where were you born, cook? 'Hind de hatchway, in ferry-boat, goin' ober de Roanoke. Born in a ferry-boat! That's queer, too. But I want to know what country you were born in, cook? Didn't I say de Roanoke country? he cried, sharply. No, you didn't, cook; but I'll tell you what I'm coming to, cook. You must go home and be born over again; you don't know how to cook a whale-steak yet. Bress my soul, if I cook noder one, he growled, angrily, turning round to depart. Come back, cook; --here, hand me those tongs; --now take that bit of steak there, and tell me if you think that steak cooked as it should be? Take it, I say --holding the tongs towards him -- take it, and taste it. Faintly smacking his withered lips over it for a moment, the old negro muttered, Best cooked 'teak I eber taste; joosy, berry joosy. Cook, said Stubb, squaring himself once more; do you belong to the church? Passed one once in Cape-Down, said the old man sullenly. And you have once in your life passed a holy church in Cape-Town, where you doubtless overheard a holy parson addressing his hearers as his beloved fellow-creatures, have you, cook! And yet you come here, and tell me such a dreadful lie as you did just now, eh? said Stubb. Where do you expect to go to, cook? ..

Go to bed berry soon, he mumbled, half-turning as he spoke. Avast! heave to! I mean when you die, cook. It's an awful question. Now what's your answer? When dis old brack man dies, said the negro slowly, changing his whole air and demeanor, he hisself won't go nowhere; but some bressed angel will come and fetch him. Fetch him? How? In a coach and four, as they fetched Elijah? And fetch him where? Up dere, said Fleece, holding his tongs straight over his head, and keeping it there very solemnly. So, then, you expect to go up into our main-top, do you, cook, when you are dead? But don't you know the higher you climb, the colder it gets? Main-top, eh? Didn't say dat t'all, said Fleece, again in the sulks. You said up there, didn't you, and now look yourself, and see where your tongs are pointing. But, perhaps you expect to get into heaven by crawling through the lubber's hole, cook; but no, no, cook, you don't get there, except you go the regular way, round by the rigging. It's a ticklish business, but must be done, or else it's no go. But none of us are in heaven yet. Drop your tongs, cook, and hear my orders. Do ye hear? Hold your hat in one hand, and clap t'other a'top of your heart, when I'm giving my orders, cook. What! that your heart, there? --that's your gizzard! Aloft! aloft! --that's it --now you have it. Hold it there now, and pay attention. All 'dention, said the old black, with both hands placed as desired, vainly wriggling his grizzled head, as if to get both ears in front at one and the same time. Well then, cook; you see this whale-steak of yours was so very bad, that I have put it out of sight as soon as possible; you see that, don't you? Well, for the future, when you cook another whale-steak for my private table here, the capstan, I'll tell you what to do so as not to spoil it by overdoing. Hold the steak in one hand, and show a live coal to it with the other; that done, dish it; d'ye hear? And now to-morrow, cook, when we are cutting in the fish, be sure you stand by to get the tips of his fins; have them put in pickle. As for the ends of the flukes, have them soused, cook. There, now ye may go. ..

But Fleece had hardly got three paces off, when he was recalled. Cook, give me cutlets for supper to-morrow night in the mid-watch. D'ye hear? away you sail, then. --Halloa! stop! make a bow before you go. --Avast heaving again! Whale-balls for breakfast --don't forget. Wish, by gor! whale eat him, 'stead of him eat whale. I'm bressed if he ain't more of shark dan Massa Shark hisself, muttered the old man, limping away; with which sage ejaculation he went to his hammock. ..

A little item may as well be related here. The strongest and most reliable hold which the ship has upon the whale when moored alongside, is by the flukes or tail; and as from its greater density that part is relatively heavier than any other (excepting the side-fins), its flexibility even in death, causes it to sink low beneath the surface; so that with the hand you cannot get at it from the boat, in order to put the chain round it. But this difficulty is ingeniously overcome: a small, strong line is prepared with a wooden float at its outer end, and a weight in its middle, while the other end is secured to the ship. By adroit management the wooden float is to rise on the other side of the mass, so that now having girdled the made whale, the chain is readily made to follow suit; and being slipped along the body, is at last locked fast round the smallest part of the tail, at the point of junction with its broad flukes or lobes. ..

.. < chapter lxv 12 THE WHALE AS A DISH > That mortal man should feed upon the creature that feeds his lamp, and, like Stubb, eat him by his own light, as you may say; this seems so outlandish a thing that one must needs go a little into the history and philosophy of it. It is upon record, that three centuries ago the tongue of the Right Whale was esteemed a great delicacy in France, and commanded large prices there. Also, that in Henry VIIIth's time, a certain cook of the court obtained a handsome reward for inventing an admirable sauce to be eaten with barbacued porpoises, which, you remember, are a species of whale. Porpoises, indeed, are to this day considered fine eating. The meat is made into balls about the size of billiard balls, and being well seasoned and spiced might be taken for turtle-balls or veal balls. The old monks of Dunfermline were very fond of them. They had a great porpoise grant from the crown. The fact is, that among his hunters at least, the whale would by all hands be considered a noble dish, were there not so much of him; but when you come to sit down before a meat-pie nearly one hundred feet long, it takes away your appetite. Only the most unprejudiced of men like Stubb, nowadays partake of ..

cooked whales; but the Esquimaux are not so fastidious. We all know how they live upon whales, and have rare old vintages of prime old train oil. Zogranda, one of their most famous doctors, recommends strips of blubber for infants, as being exceedingly juicy and nourishing. And this reminds me that certain Englishmen, who long ago were accidentally left in Greenland by a whaling vessel --that these men actually lived for several months on the mouldy scraps of whales which had been left ashore after trying out the blubber. Among the Dutch whalemen these scraps are called fritters; which, indeed, they greatly resemble, being brown and crisp, and smelling something like old Amsterdam housewives' dough-nuts or oly-cooks, when fresh. They have such an eatable look that the most self-denying stranger can hardly keep his hands off. But what further depreciates the whale as a civilized dish, is his exceeding richness. He is the great prize ox of the sea, too fat to be delicately good. Look at his hump, which would be as fine eating as the buffalo's (which is esteemed a rare dish), were it not such a solid pyramid of fat. But the spermaceti itself, how bland and creamy that is; like the transparent, half-jellied, white meat of a cocoanut in the third month of its growth, yet far too rich to supply a substitute for butter. Nevertheless, many whalemen have a method of absorbing it into some other substance, and then partaking of it. In the long try watches of the night it is a common thing for the seamen to dip their ship-biscuit into the huge oil-pots and let them fry there awhile. Many a good supper have I thus made. In the case of a small Sperm Whale the brains are accounted a fine dish. The casket of the skull is broken into with an axe, and the two plump, whitish lobes being withdrawn (precisely resembling two large puddings), they are then mixed with flour, and cooked into a most delectable mess, in flavor somewhat resembling calves' head, which is quite a dish among some epicures; and every one knows that some young bucks among the epicures, by continually dining upon calves' brains, by and by get to have a little brains of their own, so as to be able to tell a calf's head from their own heads; which, indeed, requires uncommon discrimination. And that is the reason why ..

a young buck with an intelligent looking calf's head before him, is somehow one of the saddest sights you can see. The head looks a sort of reproachfully at him, with an Et tu Brute! expression. It is not, perhaps, entirely because the whale is so excessively unctuous that landsmen seem to regard the eating of him with abhorrence; that appears to result, in some way, from the consideration before mentioned: i. e. that a man should eat a newly murdered thing of the sea, and eat it too by its own light. But no doubt the first man that ever murdered an ox was regarded as a murderer; perhaps he was hung; and if he had been put on his trial by oxen, he certainly would have been; and he certainly deserved it if any murderer does. Go to the meat-market of a Saturday night and see the crowds of live bipeds staring up at the long rows of dead quadrupeds. Does not that sight take a tooth out of the cannibal's jaw? Cannibals? who is not a cannibal? I tell you it will be more tolerable for the Fejee that salted down a lean missionary in his cellar against a coming famine; it will be more tolerable for that provident Fejee, I say, in the day of judgment, than for thee, civilized and enlightened gourmand, who nailest geese to the ground and feastest on their bloated livers in thy pate-de-foie-gras. But Stubb, he eats the whale by its own light, does he? and that is adding insult to injury, is it? Look at your knife-handle, there, my civilized and enlightened gourmand dining off that roast beef, what is that handle made of? --what but the bones of the brother of the very ox you are eating? And what do you pick your teeth with, after devouring that fat goose? With a feather of the same fowl. And with what quill did the Secretary of the Society for the Suppression of Cruelty to Ganders formally indite his circulars? It is only within the last month or two that that society passed a resolution to patronize nothing but steel pens. ..

.. < chapter lxvi 2 THE SHARK MASSACRE > When in the Southern Fishery, a captured Sperm Whale, after long and weary toil, is brought alongside late at night, it is not, as a general thing at least, customary to proceed at once to the business of cutting him in. For that business is an exceedingly laborious one; is not very soon completed; and requires all hands to set about it. Therefore, the common usage is to take in all sail; lash the helm a'lee; and then send every one below to his hammock till daylight, with the reservation that, until that time, anchor-watches shall be kept; that is, two and two for an hour, each couple, the crew in rotation shall mount the deck to see that all goes well. But sometimes, especially upon the Line in the Pacific, this plan will not answer at all; because such incalculable hosts of sharks gather round the moored carcase, that were he left so for six hours, say, on a stretch, little more than the skeleton would be visible by morning. In most other parts of the ocean, however, where these fish do not so largely abound, their wondrous voracity can be at times considerably diminished, by vigorously stirring them up with sharp whaling-spades, a procedure notwithstanding, which, in some instances, only seems to tickle them into still greater activity. But it was not thus in the present case with the Pequod's sharks; though, to be sure, any man unaccustomed to such sights, to have looked over her side that night, would have almost thought the whole round sea was one huge cheese, and those sharks the maggots in it. nevertheless, upon stubb setting the anchor-watch after his supper was concluded; and when, accordingly, Queequeg and a forecastle seaman came on deck, no small excitement was created among the sharks; for immediately suspending the cutting stages over the side, and lowering three lanterns, so that they cast long gleams of light over the turbid sea, these ..

two mariners, darting their long whaling-spades, kept up an incessant murdering of the sharks, by striking the keen steel deep into their skulls, seemingly their only vital part. But in the foamy confusion of their mixed and struggling hosts, the marksmen could not always hit their mark; and this brought about new revelations of the incredible ferocity of the foe. They viciously snapped, not only at each other's disembowelments, but like flexible bows, bent round, and bit their own; till those entrails seemed swallowed over and over again by the same mouth, to be oppositely voided by the gaping wound. Nor was this all. It was unsafe to meddle with the corpses and ghosts of these creatures. A sort of generic or Pantheistic vitality seemed to lurk in their very joints and bones, after what might be called the individual life had departed. Killed and hoisted on deck for the sake of his skin, one of these sharks almost took poor Queequeg's hand off, when he tried to shut down the dead lid of his murderous jaw. Queequeg no care what god made him shark, said the savage, agonizingly lifting his hand up and down; wedder Fejee god or Nantucket god; but de god wat made shark must be one dam Ingin. ..

The whaling-spade used for cutting-in is made of the very best steel; is about the bigness of a man's spread hand; and in general shape, corresponds to the garden implement after which it is named; only its sides are perfectly flat, and its upper end considerably narrower than the lower. This weapon is always kept as sharp as possible; and when being used is occasionally honed, just like a razor. In its socket, a stiff pole, from twenty to thirty feet long, is inserted for a handle. ..

.. < chapter lxvii 23 CUTTING IN > It was a Saturday night, and such a Sabbath as followed! Ex officio professors of Sabbath breaking are all whalemen. The ivory Pequod was turned into what seemed a shamble; ..

every sailor a butcher. You would have thought we were offering up ten thousand red oxen to the sea gods. In the first place, the enormous cutting tackles, among other ponderous things comprising a cluster of blocks generally painted green, and which no single man can possibly lift --this vast bunch of grapes was swayed up to the main-top and firmly lashed to the lower mast-head, the strongest point anywhere above a ship's deck. The end of the hawser-like rope winding through these intricacies, was then conducted to the windlass, and the huge lower block of the tackles was swung over the whale; to this block the great blubber hook, weighing some one hundred pounds, was attached. And now suspended in stages over the side, Starbuck and Stubb, the mates, armed with their long spades, began cutting a hole in the body for the insertion of the hook just above the nearest of the two side-fins. This done, a broad, semicircular line is cut round the hole, the hook is inserted, and the main body of the crew striking up a wild chorus, now commence heaving in one dense crowd at the windlass. When instantly, the entire ship careens over on her side; every bolt in her starts like the nail-heads of an old house in frosty weather; she trembles, quivers, and nods her frighted mast-heads to the sky. More and more she leans over to the whale, while every gasping heave of the windlass is answered by a helping heave from the billows; till at last, a swift, startling snap is heard; with a great swash the ship rolls upwards and backwards from the whale, and the triumphant tackle rises into sight dragging after it the disengaged semicircular end of the first strip of blubber. Now as the blubber envelopes the whale precisely as the rind does an orange, so is it stripped off from the body precisely as an orange is sometimes stripped by spiralizing it. For the strain constantly kept up by the windlass continually keeps the whale rolling over and over in the water, and as the blubber in one strip uniformly peels off along the line called the scarf, simultaneously cut by the spades of Starbuck and Stubb, the mates; and just as fast as it is thus peeled off, and indeed by that very act itself, it is all the time being hoisted higher and higher aloft till its upper end grazes the main-top; the men at the windlass then cease heaving, and for a moment ..

or two the prodigious blood-dripping mass sways to and fro as if let down from the sky, and every one present must take good heed to dodge it when it swings, else it may box his ears and pitch him headlong overboard. One of the attending harpooneers now advances with a long, keen weapon called a boarding-sword, and watching his chance he dexterously slices out a considerable hole in the lower part of the swaying mass. Into this hole, the end of the second alternating great tackle is then hooked so as to retain a hold upon the blubber, in order to prepare for what follows. Whereupon, this accomplished swordsman, warning all hands to stand off, once more makes a scientific dash at the mass, and with a few sidelong, desperate, lunging slicings, severs it completely in twain; so that while the short lower part is still fast, the long upper strip, called a blanket-piece, swings clear, and is all ready for lowering. The heavers forward now resume their song, and while the one tackle is peeling and hoisting a second strip from the whale, the other is slowly slackened away, and down goes the first strip through the main hatchway right beneath, into an unfurnished parlor called the blubber-room. Into this twilight apartment sundry nimble hands keep coiling away the long blanket-piece as if it were a great live mass of plaited serpents. And thus the work proceeds; the two tackles hoisting and lowering simultaneously; both whale and windlass heaving, the heavers singing, the blubber-room gentlemen coiling, the mates scarfing, the ship straining, and all hands swearing occasionally, by way of assuaging the general friction. ..

.. < chapter lxviii 29 THE BLANKET > I have given no small attention to that not unvexed subject, the skin of the whale. I have had controversies about it with experienced whalemen afloat, and learned naturalists ashore. ..

My original opinion remains unchanged; but it is only an opinion. The question is, what and where is the skin of the whale? Already you know what his blubber is. That blubber is something of the consistence of firm, close-grained beef, but tougher, more elastic and compact, and ranges from eight or ten to twelve and fifteen inches in thickness. Now, however preposterous it may at first seem to talk of any creature's skin as being of that sort of consistence and thickness, yet in point of fact these are no arguments against such a presumption; because you cannot raise any other dense enveloping layer from the whale's body but that same blubber; and the outermost enveloping layer of any animal, if reasonably dense, what can that be but the skin? True, from the unmarred dead body of the whale, you may scrape off with your hand an infinitely thin, transparent substance, somewhat resembling the thinnest shreds of isinglass, only it is almost as flexible and soft as satin; that is, previous to being dried, when it not only contracts and thickens, but becomes rather hard and brittle. I have several such dried bits, which I use for marks in my whale-books. It is transparent, as I said before; and being laid upon the printed page, I have sometimes pleased myself with fancying it exerted a magnifying influence. At any rate, it is pleasant to read about whales through their own spectacles, as you may say. But what I am driving at here is this. That same infinitely thin, isinglass substance, which, I admit, invests the entire body of the whale, is not so much to be regarded as the skin of the creature, as the skin of the skin, so to speak; for it were simply ridiculous to say, that the proper skin of the tremendous whale is thinner and more tender than the skin of a new-born child. But no more of this. Assuming the blubber to be the skin of the whale; then, when this skin, as in the case of a very large Sperm Whale, will yield the bulk of one hundred barrels of oil; and, when it is considered that, in quantity, or rather weight, that oil, in its expressed state, is only three fourths, and not the entire substance of the coat; some idea may hence be had of the enormousness of that animated mass, a mere part of whose mere ..

integument yields such a lake of liquid as that. Reckoning ten barrels to the ton, you have ten tons for the net weight of only three quarters of the stuff of the whale's skin. In life, the visible surface of the Sperm Whale is not the least among the many marvels he presents. Almost invariably it is all over obliquely crossed and re-crossed with numberless straight marks in thick array, something like those in the finest Italian line engravings. But these marks do not seem to be impressed upon the isinglass substance above mentioned, but seem to be seen through it, as if they were engraved upon the body itself. Nor is this all. In some instances, to the quick, observant eye, those linear marks, as in a veritable engraving, but afford the ground for far other delineations. These are hieroglyphical; that is, if you call those mysterious cyphers on the walls of pyramids hieroglyphics, then that is the proper word to use in the present connexion. By my retentive memory of the hieroglyphics upon one Sperm Whale in particular, I was much struck with a plate representing the old Indian characters chiselled on the famous hieroglyphic palisades on the banks of the Upper Mississippi. Like those mystic rocks, too, the mystic-marked whale remains undecipherable. This allusion to the Indian rocks reminds me of another thing. Besides all the other phenomena which the exterior of the Sperm Whale presents, he not seldom displays the back, and more especially his flanks, effaced in great part of the regular linear appearance, by reason of numerous rude scratches, altogether of an irregular, random aspect. I should say that those New England rocks on the sea-coast, which Agassiz imagines to bear the marks of violent scraping contact with vast floating icebergs --I should say, that those rocks must not a little resemble the Sperm Whale in this particular. It also seems to me that such scratches in the whale are probably made by hostile contact with other whales; for I have most remarked them in the large, full-grown bulls of the species. A word or two more concerning this matter of the skin or blubber of the whale. It has already been said, that it is stript from him in long pieces, called blanket-pieces. Like most sea-terms, this one is very happy and significant. For the whale is ..

indeed wrapt up in his blubber as in a real blanket or counterpane; or, still better, an Indian poncho slipt over his head, and skirting his extremity. It is by reason of this cosy blanketing of his body, that the whale is enabled to keep himself comfortable in all weathers, in all seas, times, and tides. What would become of a Greenland whale, say, in those shuddering, icy seas of the north, if unsupplied with his cosy surtout? True, other fish are found exceedingly brisk in those Hyperborean waters; but these, be it observed, are your cold-blooded, lungless fish, whose very bellies are refrigerators; creatures, that warm themselves under the lee of an iceberg, as a traveller in winter would bask before an inn fire; whereas, like man, the whale has lungs and warm blood. Freeze his blood, and he dies. How wonderful is it then --except after explanation --that this great monster, to whom corporeal warmth is as indispensable as it is to man; how wonderful that he should be found at home, immersed to his lips for life in those Arctic waters! where, when seamen fall overboard, they are sometimes found, months afterwards, perpendicularly frozen into the hearts of fields of ice, as a fly is found glued in amber. But more surprising is it to know, as has been proved by experiment, that the blood of a Polar whale is warmer than that of a Borneo negro in summer. It does seem to me, that herein we see the rare virtue of a strong individual vitality, and the rare virtue of thick walls, and the rare virtue of interior spaciousness. Oh, man! admire and model thyself after the whale! Do thou, too, remain warm among ice. Do thou, too, live in this world without being of it. Be cool at the equator; keep thy blood fluid at the Pole. Like the great dome of St. Peter's, and like the great whale, retain, O man! in all seasons a temperature of thine own. But how easy and how hopeless to teach these fine things! Of erections, how few are domed like St. Peter's! of creatures, how few vast as the whale! ..

.. < chapter lxix 2 THE FUNERAL > Haul in the chains! Let the carcase go astern! The vast tackles have now done their duty. The peeled white body of the beheaded whale flashes like a marble sepulchre; though changed in hue, it has not perceptibly lost anything in bulk. it is still colossal. slowly it floats more and more away, the water round it torn and splashed by the insatiate sharks, and the air above vexed with rapacious flights of screaming fowls, whose beaks are like so many insulting poniards in the whale. The vast white headless phantom floats further and further from the ship, and every rod that it so floats, what seem square roods of sharks and cubic roods of fowls, augment the murderous din. For hours and hours from the almost stationary ship that hideous sight is seen. Beneath the unclouded and mild azure sky, upon the fair face of the pleasant sea, wafted by the joyous breezes, that great mass of death floats on and on, till lost in infinite perspectives. There's a most doleful and most mocking funeral! The sea-vultures all in pious mourning, the air-sharks all punctiliously in black or speckled. In life but few of them would have helped the whale, I ween, if peradventure he had needed it; but upon the banquet of his funeral they most piously do pounce. Oh, horrible vultureism of earth! from which not the mightiest whale is free. Nor is this the end. Desecrated as the body is, a vengeful ghost survives and hovers over it to scare. Espied by some timid man-of-war or blundering discovery-vessel from afar, when the distance obscuring the swarming fowls, nevertheless still shows the white mass floating in the sun, and the white spray heaving high against it; straightway the whale's unharming corpse, with trembling fingers is set down in the log -- shoals, rocks, and breakers hereabouts: beware! And for years afterwards, ..

perhaps, ships shun the place; leaping over it as silly sheep leap over a vacuum, because their leader originally leaped there when a stick was held. There's your law of precedents; there's your utility of traditions; there's the story of your obstinate survival of old beliefs never bottomed on the earth, and now not even hovering in the air! There's orthodoxy! Thus, while in life the great whale's body may have been a real terror to his foes, in his death his ghost becomes a powerless panic to a world. Are you a believer in ghosts, my friend? There are other ghosts than the Cock-Lane one, and far deeper men than Doctor Johnson who believe in them. ..

.. < chapter lxx 14 THE SPHYNX > It should not have been omitted that previous to completely stripping the body of the leviathan, he was beheaded. Now, the beheading of the Sperm Whale is a scientific anatomical feat, upon which experienced whale surgeons very much pride themselves; and not without reason. Consider that the whale has nothing that can properly be called a neck; on the contrary, where his head and body seem to join, there, in that very place, is the thickest part of him. Remember, also, that the surgeon must operate from above, some eight or ten feet intervening between him and his subject, and that subject almost hidden in a discolored, rolling, and oftentimes tumultuous and bursting sea. Bear in mind, too, that under these untoward circumstances he has to cut many feet deep in the flesh; and in that subterraneous manner, without so much as getting one single peep into the ever-contracting gash thus made, he must skilfully steer clear of all adjacent, interdicted parts, and exactly divide the spine at a critical point hard by its insertion into the skull. Do you not marvel, ..

then, at Stubb's boast, that he demanded but ten minutes to behead a sperm whale? When first severed, the head is dropped astern and held there by a cable till the body is stripped. That done, if it belong to a small whale it is hoisted on deck to be deliberately disposed of. But, with a full grown leviathan this is impossible; for the sperm whale's head embraces nearly one third of his entire bulk, and completely to suspend such a burden as that, even by the immense tackles of a whaler, this were as vain a thing as to attempt weighing a Dutch barn in jewellers' scales The Pequod's whale being decapitated and the body stripped, the head was hoisted against the ship's side --about half way out of the sea, so that it might yet in great part be buoyed up by its native element. And there with the strained craft steeply leaning over to it, by reason of the enormous downward drag from the lower mast-head, and every yard-arm on that side projecting like a crane over the waves; there, that blood-dripping head hung to the Pequod's waist like the giant Holofernes's from the girdle of Judith. When this last task was accomplished it was noon, and the seamen went below to their dinner. Silence reigned over the before tumultuous but now deserted deck. An intense copper calm, like a universal yellow lotus, was more and more unfolding its noiseless measureless leaves upon the sea. A short space elapsed, and up into this noiselessness came Ahab alone from his cabin. Taking a few turns on the quarter-deck, he paused to gaze over the side, then slowly getting into the main-chains he took Stubb's long spade --still remaining there after the whale's decapitation --and striking it into the lower part of the half-suspended mass, placed its other end crutch-wise under one arm, and so stood leaning over with eyes attentively fixed on this head. It was a black and hooded head; and hanging there in the midst of so intense a calm, it seemed the Sphynx's in the desert. Speak, thou vast and venerable head, muttered Ahab, which, though ungarnished with a beard, yet here and there lookest hoary with mosses; speak, mighty head, and tell us the secret thing that is in thee. Of all divers, thou hast dived the deepest. ..

that head upon which the upper sun now gleams, has moved amid this world's foundations. Where unrecorded names and navies rust, and untold hopes and anchors rot; where in her murderous hold this frigate earth is ballasted with bones of millions of the drowned; there, in that awful water-land, there was thy most familiar home. Thou hast been where bell or diver never went; hast slept by many a sailor's side, where sleepless mothers would give their lives to lay them down. Thou saw'st the locked lovers when leaping from their flaming ship; heart to heart they sank beneath the exulting wave; true to each other, when heaven seemed false to them. Thou saw'st the murdered mate when tossed by pirates from the midnight deck; for hours he fell into the deeper midnight of the insatiate maw; and his murderers still sailed on unharmed --while swift lightnings shivered the neighboring ship that would have borne a righteous husband to outstretched, longing arms. O head! thou hast seen enough to split the planets and make an infidel of Abraham, and not one syllable is thine! Sail ho! cried a triumphant voice from the main-masthead. Aye? Well, now, that's cheering, cried Ahab, suddenly erecting himself, while whole thunder-clouds swept aside from his brow. That lively cry upon this deadly calm might almost convert a better man. --Where away? Three points on the starboard bow, sir, and bringing down her breeze to us! Better and better, man. Would now St. Paul would come along that way, and to my breezelessness bring his breeze! O Nature, and O soul of man! how far beyond all utterance are your linked analogies! not the smallest atom stirs or lives on matter, but has its cunning duplicate in mind. ..

.. < chapter lxxi 2 THE JEROBOAM'S STORY > Hand in hand, ship and breeze blew on; but the breeze came faster than the ship, and soon the Pequod began to rock. By and by, through the glass the stranger's boats and manned mast-heads proved her a whale-ship. but as she was so far to windward, and shooting by, apparently making a passage to some other ground, the Pequod could not hope to reach her. So the signal was set to see what response would be made. Here be it said, that like the vessels of military marines, the ships of the American Whale Fleet have each a private signal; all which signals being collected in a book with the names of the respective vessels attached, every captain is provided with it. Thereby, the whale commanders are enabled to recognise each other upon the ocean, even at considerable distances, and with no small facility. The Pequod's signal was at last responded to by the stranger's setting her own; which proved the ship to be the Jeroboam of Nantucket. Squaring her yards, she bore down, ranged abeam under the Pequod's lee, and lowered a boat; it soon drew nigh; but, as the side-ladder was being rigged by Starbuck's order to accommodate the visiting captain, the stranger in question waved his hand from his boat's stern in token of that proceeding being entirely unnecessary. It turned out that the Jeroboam had a malignant epidemic on board, and that Mayhew, her captain, was fearful of infecting the Pequod's company. For, though himself and boat's crew remained untainted, and though his ship was half a rifle-shot off, and an incorruptible sea and air rolling and flowing between; yet conscientiously adhering to the timid quarantine of the land, he peremptorily refused to come into direct contact with the Pequod. But this did by no means prevent all communication. Preserving an interval of some few yards between itself and the ..

ship, the Jeroboam's boat by the occasional use of its oars contrived to keep parallel to the Pequod, as she heavily forged through the sea (for by this time it blew very fresh), with her main-topsail aback; though, indeed, at times by the sudden onset of a large rolling wave, the boat would be pushed some way ahead; but would be soon skilfully brought to her proper bearings again. Subject to this, and other the like interruptions now and then, a conversation was sustained between the two parties; but at intervals not without still another interruption of a very different sort. Pulling an oar in the Jeroboam's boat, was a man of a singular appearance, even in that wild whaling life where individual notabilities make up all totalities. He was a small, short, youngish man, sprinkled all over his face with freckles, and wearing redundant yellow hair. A long-skirted, cabalistically-cut coat of a faded walnut tinge enveloped him; the overlapping sleeves of which were rolled up on his wrists. A deep, settled, fanatic delirium was in his eyes. So soon as this figure had been first descried, Stubb had exclaimed -- That's he! that's he! the long-togged scaramouch the Town-Ho's company told us of! Stubb here alluded to a strange story told of the Jeroboam, and a certain man among her crew, some time previous when the Pequod spoke the Town-Ho. According to this account and what was subsequently learned, it seemed that the scaramouch in question had gained a wonderful ascendency over almost everybody in the Jeroboam. His story was this: He had been originally nurtured among the crazy society of Neskyeuna Shakers, where he had been a great prophet; in their cracked, secret meetings having several times descended from heaven by the way of a trap-door, announcing the speedy opening of the seventh vial, which he carried in his vest-pocket; but, which, instead of containing gunpowder, was supposed to be charged with laudanum. A strange, apostolic whim having seized him, he had left Neskyeuna for Nantucket, where, with that cunning peculiar to craziness, he assumed a steady, common sense exterior and offered himself as a green-hand candidate for the Jeroboam's whaling voyage. They engaged him; ..

but straightway upon the ship's getting out of sight of land, his insanity broke out in a freshet. He announced himself as the archangel Gabriel, and commanded the captain to jump overboard. He published his manifesto, whereby he set himself forth as the deliverer of the isles of the sea and vicar-general of all Oceanica. The unflinching earnestness with which he declared these things; --the dark, daring play of his sleepless, excited imagination, and all the preternatural terrors of real delirium, united to invest this Gabriel in the minds of the majority of the ignorant crew, with an atmosphere of sacredness. Moreover, they were afraid of him. As such a man, however, was not of much practical use in the ship, especially as he refused to work except when he pleased, the incredulous captain would fain have been rid of him; but apprised that that individual's intention was to land him in the first convenient port, the archangel forthwith opened all his seals and vials -- devoting the ship and all hands to unconditional perdition, in case this intention was carried out. So strongly did he work upon his disciples among the crew, that at last in a body they went to the captain and told him if Gabriel was sent from the ship, not a man of them would remain. He was therefore forced to relinquish his plan. Nor would they permit Gabriel to be any way maltreated, say or do what he would; so that it came to pass that Gabriel had the complete freedom of the ship. The consequence of all this was, that the archangel cared little or nothing for the captain and mates; and since the epidemic had broken out, he carried a higher hand than ever; declaring that the plague, as he called it, was at his sole command; nor should it be stayed but according to his good pleasure. The sailors, mostly poor devils, cringed, and some of them fawned before him; in obedience to his instructions, sometimes rendering him personal homage, as to a god. Such things may seem incredible; but, however wondrous, they are true. Nor is the history of fanatics half so striking in respect to the measureless self-deception of the fanatic himself, as his measureless power of deceiving and bedevilling so many others. But it is time to return to the Pequod. I fear not thy epidemic, man, said Ahab from the bulwarks ..

to Captain Mayhew, who stood in the boat's stern; come on board. But now Gabriel started to his feet. Think, think of the fevers, yellow and bilious! Beware of the horrible plague! Gabriel, Gabriel! cried Captain Mayhew; thou must either-- But that instant a headlong wave shot the boat far ahead, and its seethings drowned all speech. Hast thou seen the White Whale? demanded Ahab, when the boat drifted back. Think, think of thy whale-boat, stoven and sunk! Beware of the horrible tail! I tell thee again, Gabriel, that-- But again the boat tore ahead as if dragged by fiends. Nothing was said for some moments, while a succession of riotous waves rolled by, which by one of those occasional caprices of the seas were tumbling, not heaving it. Meantime, the hoisted sperm whale's head jogged about very violently, and Gabriel was seen eyeing it with rather more apprehensiveness than his archangel nature seemed to warrant. When this interlude was over, Captain Mayhew began a dark story concerning Moby Dick; not, however, without frequent interruptions from Gabriel, whenever his name was mentioned, and the crazy sea that seemed leagued with him. It seemed that the Jeroboam had not long left home, when upon speaking a whale-ship, her people were reliably apprised of the existence of Moby Dick, and the havoc he had made. Greedily sucking in this intelligence, Gabriel solemnly warned the captain against attacking the white whale, in case the monster should be seen; in his gibbering insanity, pronouncing the White Whale to be no less a being than the Shaker God incarnated; the Shakers receiving the Bible. But when, some year or two afterwards, Moby Dick was fairly sighted from the mast-heads, Macey, the chief mate, burned with ardor to encounter him; and the captain himself being not unwilling to let him have the opportunity, despite all the archangel's denunciations and forewarnings, Macey succeeded in persuading five men to man his boat. With them he pushed off; and, after ..

much weary pulling, and many perilous, unsuccessful onsets, he at last succeeded in getting one iron fast. Meantime, Gabriel, ascending to the main-royal mast-head, was tossing one arm in frantic gestures, and hurling forth prophecies of speedy doom to the sacrilegious assailants of his divinity. Now, while Macey, the mate, was standing up in his boat's bow, and with all the reckless energy of his tribe was venting his wild exclamations upon the whale, and essaying to get a fair chance for his poised lance, lo! a broad white shadow rose from the sea; by its quick, fanning motion, temporarily taking the breath out of the bodies of the oarsmen. Next instant, the luckless mate, so full of furious life, was smitten bodily into the air, and making a long arc in his descent, fell into the sea at the distance of about fifty yards. Not a chip of the boat was harmed, nor a hair of any oarsman's head; but the mate for ever sank. It is well to parenthesize here, that of the fatal accidents in the Sperm-Whale Fishery, this kind is perhaps almost as frequent as any. Sometimes, nothing is injured but the man who is thus annihilated; oftener the boat's bow is knocked off, or the thigh-board, in which the headsman stands, is torn from its place and accompanies the body. But strangest of all is the circumstance, that in more instances than one, when the body has been recovered, not a single mark of violence is discernible; the man being stark dead. The whole calamity, with the falling form of Macey, was plainly descried from the ship. Raising a piercing shriek -- The vial! the vial! Gabriel called off the terror-stricken crew from the further hunting of the whale. This terrible event clothed the archangel with added influence; because his credulous disciples believed that he had specifically fore-announced it, instead of only making a general prophecy, which any one might have done, and so have chanced to hit one of many marks in the wide margin allowed. He became a nameless terror to the ship. Mayhew having concluded his narration, Ahab put such questions to him, that the stranger captain could not forbear inquiring whether he intended to hunt the White Whale, if opportunity should offer. To which Ahab answered -- Aye. Straightway, then, Gabriel once more started to his feet, glaring ..

upon the old man, and vehemently exclaimed, with downward pointed finger -- Think, think of the blasphemer --dead, and down there! --beware of the blasphemer's end! Ahab stolidly turned aside; then said to Mayhew, Captain, I have just bethought me of my letter-bag; there is a letter for one of thy officers, if I mistake not. Starbuck, look over the bag. Every whale-ship takes out a goodly number of letters for various ships, whose delivery to the persons to whom they may be addressed, depends upon the mere chance of encountering them in the four oceans. Thus, most letters never reach their mark; and many are only received after attaining an age of two or three years or more. Soon Starbuck returned with a letter in his hand. It was sorely tumbled, damp, and covered with a dull, spotted, green mould, in consequence of being kept in a dark locker of the cabin. Of such a letter, Death himself might well have been the post-boy. Can'st not read it? cried ahab. give it me, man. aye, aye it's but a dim scrawl; --what's this? As he was studying it out, Starbuck took a long cutting-spade pole, and with his knife slightly split the end, to insert the letter there, and in that way, hand it to the boat, without its coming any closer to the ship. Meantime, Ahab holding the letter, muttered, Mr. Har--yes, Mr. Harry--(a woman's pinny hand, --the man's wife, I'll wager) -- Aye --Mr. Harry Macey, Ship Jeroboam; --why it's Macey, and he's dead! Poor fellow! poor fellow! and from his wife, sighed Mayhew; but let me have it. Nay, keep it thyself, cried Gabriel to Ahab; thou art soon going that way. Curses throttle thee! yelled Ahab. Captain Mayhew, stand by now to receive it; and taking the fatal missive from Starbuck's hands, he caught it in the slit of the pole, and reached it over towards the boat. But as he did so, the oarsmen expectantly desisted from rowing; the boat drifted a little towards the ship's stern; so that, as if by magic, the letter suddenly ranged along with Gabriel's eager hand. He clutched it in an instant, seized the boat-knife, and impaling the letter on it, sent it thus loaded back into the ship. It fell at Ahab's feet. Then Gabriel ..

shrieked out to his comrades to give way with their oars, and in that manner the mutinous boat rapidly shot away from the Pequod. As, after this interlude, the seamen resumed their work upon the jacket of the whale, many strange things were hinted in reference to this wild affair. ..

.. < chapter lxxiii 23 STUBB AND FLASK KILL A RIGHT WHALE; AND THEN HAVE > A TALK OVER HIM It must be borne in mind that all this time we have a Sperm Whale's prodigious head hanging to the Pequod's side. But we must let it continue hanging there a while till we can get a chance to attend to it. For the present other matters press, and the best we can do now for the head, is to pray heaven the tackles may hold. Now, during the past night and forenoon, the Pequod had gradually drifted into a sea, which, by its occasional patches of ..

yellow brit, gave unusual tokens of the vicinity of Right Whales, a species of the Leviathan that but few supposed to be at this particular time lurking anywhere near. And though all hands commonly disdained the capture of those inferior creatures; and though the Pequod was not commissioned to cruise for them at all, and though she had passed numbers of them near the Crozetts without lowering a boat; yet now that a Sperm Whale had been brought alongside and beheaded, to the surprise of all, the announcement was made that a Right Whale should be captured that day, if opportunity offered. Nor was this long wanting. Tall spouts were seen to leeward; and two boats, Stubb's and Flask's, were detached in pursuit. Pulling further and further away, they at last became almost invisible to the men at the mast-head. But suddenly in the distance, they saw a great heap of tumultuous white water, and soon after news came from aloft that one or both the boats must be fast. An interval passed and the boats were in plain sight, in the act of being dragged right towards the ship by the towing whale. So close did the monster come to the hull, that at first it seemed as if he meant it malice; but suddenly going down in a maelstrom, within three rods of the planks, he wholly disappeared from view, as if diving under the keel. Cut, cut! was the cry from the ship to the boats, which, for one instant, seemed on the point of being brought with a deadly dash against the vessel's side. But having plenty of line yet in the tubs, and the whale not sounding very rapidly, they paid out abundance of rope, and at the same time pulled with all their might so as to get ahead of the ship. For a few minutes the struggle was intensely critical; for while they still slacked out the tightened line in one direction, and still plied their oars in another, the contending strain threatened to take them under. But it was only a few feet advance they sought to gain. And they stuck to it till they did gain it; when instantly, a swift tremor was felt running like lightning along the keel, as the strained line, scraping beneath the ship, suddenly rose to view under her bows, snapping and quivering; and so flinging off its drippings, that the drops fell like bits of broken glass on the water, while the whale beyond also rose to sight, and once more the boats were free ..

to fly. But the fagged whale abated his speed, and blindly altering his course, went round the stern of the ship towing the two boats after him, so that they performed a complete circuit. Meantime, they hauled more and more upon their lines, till close flanking him on both sides, Stubb answered Flask with lance for lance; and thus round and round the Pequod the battle went, while the multitudes of sharks that had before swum round the Sperm Whale's body, rushed to the fresh blood that was spilled, thirstily drinking at every new gash, as the eager Israelites did at the new bursting fountains that poured from the smitten rock. At last his spout grew thick, and with a frightful roll and vomit, he turned upon his back a corpse. While the two headsmen were engaged in making fast cords to his flukes, and in other ways getting the mass in readiness for towing, some conversation ensued between them. I wonder what the old man wants with this lump of foul lard, said Stubb, not without some disgust at the thought of having to do with so ignoble a leviathan. Wants with it? said Flask, coiling some spare line in the boat's bow, did you never hear that the ship which but once has a Sperm Whale's head hoisted on her starboard side, and at the same time a Right Whale's on the larboard; did you never hear, Stubb, that that ship can never afterwards capsize? Why not? I don't know, but I heard that gamboge ghost of a Fedallah saying so, and he seems to know all about ships' charms. But I sometimes think he'll charm the ship to no good at last. I don't half like that chap, Stubb. Did you ever notice how that tusk of his is a sort of carved into a snake's head, Stubb? Sink him! I never look at him at all; but if ever I get a chance of a dark night, and he standing hard by the bulwarks, and no one by; look down there, Flask --pointing into the sea with a peculiar motion of both hands -- Aye, will I! Flask, I take that Fedallah to be the devil in disguise. Do you believe that cock and bull story about his having been stowed away on board ship? He's the devil, I say. The reason why you don't see his tail, is because he tucks it up out of sight; he carries it ..

coiled away in his pocket, I guess. Blast him! now that I think of it, he's always wanting oakum to stuff into the toes of his boots. He sleeps in his boots, don't he? He hasn't got any hammock; but I've seen him lay of nights in a coil of rigging. No doubt, and it's because of his cursed tail; he coils it down, do ye see, in the eye of the rigging. What's the old man have so much to do with him for? Striking up a swap or a bargain, I suppose. Bargain? --about what? Why, do ye see, the old man is hard bent after that White Whale, and the devil there is trying to come round him, and get him to swap away his silver watch, or his soul, or something of that sort, and then he'll surrender Moby Dick. Pooh! Stubb, you are skylarking; how can Fedallah do that? I don't know, Flask, but the devil is a curious chap, and a wicked one, I tell ye. Why, they say as how he went a sauntering into the old flag-ship once, switching his tail about devilish easy and gentlemanlike, and inquiring if the old governor was at home. Well, he was at home, and asked the devil what he wanted. The devil, switching his hoofs, up and says, "I want John." "What for?" says the old governor, "What business is that of yours," says the devil, getting mad, --"I want to use him." "Take him," says the governor --and by the Lord, Flask, if the devil didn't give John the Asiatic cholera before he got through with him, I'll eat this whale in one mouthful. But look sharp-- aint you all ready there? Well, then, pull ahead, and let's get the whale alongside. I think I remember some such story as you were telling, said Flask, when at last the two boats were slowly advancing with their burden towards the ship, but I can't remember where. Three Spaniards? Adventures of those three bloody-minded soldadoes? Did ye read it there, Flask? I guess ye did? No; never saw such a book; heard of it, though. But now, tell me, Stubb, do you suppose that that devil you was speaking of just now, was the same you say is now on board the Pequod? ..

Am I the same man that helped kill this whale? Doesn't the devil live for ever; who ever heard that the devil was dead? Did you ever see any parson a wearing mourning for the devil? And if the devil has a latch-key to get into the admiral's cabin, don't you suppose he can crawl into a port-hole? Tell me that, Mr. Flask? How old do you suppose Fedallah is, Stubb? Do you see that mainmast there? pointing to the ship; well, that's the figure one; now take all the hoops in the Pequod's hold, and string 'em along in a row with that mast, for oughts, do you see; well, that wouldn't begin to be Fedallah's age. Nor all the coopers in creation couldn't show hoops enough to make oughts enough. but see here, stubb, i thought you a little boasted just now, that you meant to give Fedallah a sea-toss, if you got a good chance. Now, if he's so old as all those hoops of yours come to, and if he is going to live for ever, what good will it do to pitch him overboard --tell me that? Give him a good ducking, anyhow. But he'd crawl back. Duck him again; and keep ducking him. Suppose he should take it into his head to duck you, though -- yes, and drown you --what then? I should like to see him try it; I'd give him such a pair of black eyes that he wouldn't dare to show his face in the admiral's cabin again for a long while, let alone down in the orlop there, where he lives, and hereabouts on the upper decks where he sneaks so much. Damn the devil, Flask; do you suppose I'm afraid of the devil? Who's afraid of him, except the old governor who daresn't catch him and put him in double-darbies, as he deserves, but lets him go about kidnapping people; aye, and signed a bond with him, that all the people the devil kidnapped, he'd roast for him? There's a governor! Do you suppose Fedallah wants to kidnap Captain Ahab? Do I suppose it? You'll know it before long, Flask. But I am going now to keep a sharp look-out on him; and if I see anything very suspicious going on, I'll just take him by the nape of his neck, and say --Look here, Beelzebub, you don't do ..

it; and if he makes any fuss, by the Lord I'll make a grab into his pocket for his tail, take it to the capstan, and give him such a wrenching and heaving, that his tail will come short off at the stump --do you see; and then, I rather guess when he finds himself docked in that queer fashion, he'll sneak off without the poor satisfaction of feeling his tail between his legs. And what will you do with the tail, Stubb? Do with it? Sell it for an ox whip when we get home; -- what else? Now, do you mean what you say, and have been saying all along, stubb? Mean or not mean, here we are at the ship. The boats were here hailed, to tow the whale on the larboard side, where fluke chains and other necessaries were already prepared for securing him. Didn't I tell you so? said Flask; yes, you'll soon see this right whale's head hoisted up opposite that parmacetti's. In good time, Flask's saying proved true. As before, the Pequod steeply leaned over towards the sperm whale's head, now, by the counterpoise of both heads, she regained her even keel; though sorely strained, you may well believe. So, when on one side you hoist in Locke's head, you go over that way; but now, on the other side, hoist in Kant's and you come back again; but in very poor plight. Thus, some minds for ever keep trimming boat. Oh, ye foolish! throw all these thunder-heads overboard, and then you will float light and right. In disposing of the body of a right whale, when brought alongside the ship, the same preliminary proceedings commonly take place as in the case of a sperm whale; only, in the latter instance, the head is cut off whole, but in the former the lips and tongue are separately removed and hoisted on deck, with all the well known black bone attached to what is called the crown-piece. But nothing like this, in the present case, had been done. The carcases of both whales had dropped astern; and the head-laden ship not a little resembled a mule carrying a pair of overburdening panniers. Meantime, Fedallah was calmly eyeing the right whale's head, and ever and anon glancing from the deep wrinkles there to the ..

lines in his own hand. And Ahab chanced so to stand, that the Parsee occupied his shadow; while, if the Parsee's shadow was there at all it seemed only to blend with, and lengthen Ahab's. As the crew toiled on, Laplandish speculations were bandied among them, concerning all these passing things. ..

.. < chapter lxxiv 7 THE SPERM WHALE'S HEAD--CONTRASTED VIEW > Here, now, are two great whales, laying their heads together; let us join them, and lay together our own. Of the grand order of folio leviathans, the Sperm Whale and the Right Whale are by far the most noteworthy. They are the only whales regularly hunted by man. To the Nantucketer, they present the two extremes of all the known varieties of the whale. As the external difference between them is mainly observable in their heads; and as a head of each is this moment hanging from the Pequod's side; and as we may freely go from one to the other, by merely stepping across the deck: --where, I should like to know, will you obtain a better chance to study practical cetology than here? In the first place, you are struck by the general contrast between these heads. Both are massive enough in all conscience; but there is a certain mathematical symmetry in the Sperm Whale's which the Right Whale's sadly lacks. There is more character in the Sperm Whale's head. As you behold it, you involuntarily yield the immense superiority to him, in point of pervading dignity. In the present instance, too, this dignity is heightened by the pepper and salt color of his head at the summit, giving token of advanced age and large experience. In short, he is what the fishermen technically call a grey-headed whale. Let us now note what is least dissimilar in these heads -- namely, the two most important organs, the eye and the ear. ..

Far back on the side of the head, and low down, near the angle of either whale's jaw, if you narrowly search, you will at last see a lashless eye, which you would fancy to be a young colt's eye; so out of all proportion is it to the magnitude of the head. Now, from this peculiar sideway position of the whale's eyes, it is plain that he can never see an object which is exactly ahead, no more than he can one exactly astern. in a word, the position of the whale's eyes corresponds to that of a man's ears; and you may fancy, for yourself, how it would fare with you, did you sideways survey objects through your ears. You would find that you could only command some thirty degrees of vision in advance of the straight side-line of sight; and about thirty more behind it. If your bitterest foe were walking straight towards you, with dagger uplifted in broad day, you would not be able to see him, any more than if he were stealing upon you from behind. In a word, you would have two backs, so to speak; but, at the same time, also, two fronts (side fronts): for what is it that makes the front of a man --what, indeed, but his eyes? Moreover, while in most other animals that I can now think of, the eyes are so planted as imperceptibly to blend their visual power, so as to produce one picture and not two to the brain; the peculiar position of the whale's eyes, effectually divided as they are by many cubic feet of solid head, which towers between them like a great mountain separating two lakes in valleys; this, of course, must wholly separate the impressions which each independent organ imparts. The whale, therefore, must see one distinct picture on this side, and another distinct picture on that side; while all between must be profound darkness and nothingness to him. Man may, in effect, be said to look out on the world from a sentry-box with two joined sashes for his window. But with the whale, these two sashes are separately inserted, making two distinct windows, but sadly impairing the view. This peculiarity of the whale's eyes is a thing always to be borne in mind in the fishery; and to be remembered by the reader in some subsequent scenes. A curious and most puzzling question might be started concerning ..

this visual matter as touching the Leviathan. But I must be content with a hint. so long as a man's eyes are open in the light, the act of seeing is involuntary; that is, he cannot then help mechanically seeing whatever objects are before him. Nevertheless, any one's experience will teach him, that though he can take in an undiscriminating sweep of things at one glance, it is quite impossible for him, attentively, and completely, to examine any two things --however large or however small --at one and the same instant of time; never mind if they lie side by side and touch each other. But if you now come to separate these two objects, and surround each by a circle of profound darkness; then, in order to see one of them, in such a manner as to bring your mind to bear on it, the other will be utterly excluded from your contemporary consciousness. How is it, then, with the whale? True, both his eyes, in themselves, must simultaneously act; but is his brain so much more comprehensive, combining, and subtle than man's, that he can at the same moment of time attentively examine two distinct prospects, one on one side of him, and the other in an exactly opposite direction? If he can, then is it as marvellous a thing in him, as if a man were able simultaneously to go through the demonstrations of two distinct problems in Euclid. Nor, strictly investigated, is there any incongruity in this comparison. It may be but an idle whim, but it has always seemed to me, that the extraordinary vacillations of movement displayed by some whales when beset by three or four boats; the timidity and liability to queer frights, so common to such whales; I think that all this indirectly proceeds from the helpless perplexity of volition, in which their divided and diametrically opposite powers of vision must involve them. But the ear of the whale is full as curious as the eye. If you are an entire stranger to their race, you might hunt over these two heads for hours, and never discover that organ. The ear has no external leaf whatever; and into the hole itself you can hardly insert a quill, so wondrously minute is it. It is lodged a little behind the eye. With respect to their ears, this important difference is to be observed between the sperm whale and the ..

right. While the ear of the former has an external opening, that of the latter is entirely and evenly covered over with a membrane, so as to be quite imperceptible from without. Is it not curious, that so vast a being as the whale should see the world through so small an eye, and hear the thunder through an ear which is smaller than a hare's? But if his eyes were broad as the lens of Herschel's great telescope; and his ears capacious as the porches of cathedrals; would that make him any longer of sight, or sharper of hearing? Not at all. -- Why then do you try to enlarge your mind? Subtilize it. Let us now with whatever levers and steam-engines we have at hand, cant over the sperm whale's head, so that it may lie bottom up; then, ascending by a ladder to the summit, have a peep down the mouth; and were it not that the body is now completely separated from it, with a lantern we might descend into the great Kentucky Mammoth Cave of his stomach. But let us hold on here by this tooth, and look about us where we are. What a really beautiful and chaste-looking mouth! from floor to ceiling, lined, or rather papered with a glistening white membrane, glossy as bridal satins. But come out now, and look at this portentous lower jaw, which seems like the long narrow lid of an immense snuff-box, with a hinge at one end, instead of one side. If you pry it up, so as to get it overhead, and expose its rows of teeth, it seems a terrific portcullis; and such, alas! it proves to many a poor wight in the fishery, upon whom these spikes fall with impaling force. But far more terrible is it to behold, when fathoms down in the sea, you see some sulky whale, floating there suspended, with his prodigious jaw, some fifteen feet long, hanging straight down at right-angles with his body, for all the world like a ship's jib-boom. This whale is not dead; he is only dispirited; out of sorts, perhaps; hypochondriac; and so supine, that the hinges of his jaw have relaxed, leaving him there in that ungainly sort of plight, a reproach to all his tribe, who must, no doubt, imprecate lock-jaws upon him. In most cases this lower jaw --being easily unhinged by a practised artist --is disengaged and hoisted on deck for the purpose of extracting the ivory teeth, and furnishing a supply of ..

that hard white whalebone with which the fishermen fashion all sorts of curious articles, including canes, umbrella-stocks, and handles to riding-whips. With a long, weary hoist the jaw is dragged on board, as if it were an anchor; and when the proper time comes --some few days after the other work --Queequeg, Daggoo, and Tashtego, being all accomplished dentists, are set to drawing teeth. With a keen cutting-spade, Queequeg lances the gums; then the jaw is lashed down to ringbolts, and a tackle being rigged from aloft, they drag out these teeth, as Michigan oxen drag stumps of old oaks out of wild wood-lands. There are generally forty-two teeth in all; in old whales, much worn down, but undecayed; nor filled after our artificial fashion. The jaw is afterwards sawn into slabs, and piled away like joists for building houses. ..

.. < chapter lxxv 17 THE RIGHT WHALE'S HEAD--CONTRASTED VIEW > Crossing the deck, let us now have a good long look at the Right Whale's head. As in general shape the noble Sperm Whale's head may be compared to a Roman war-chariot (especially in front, where it is so broadly rounded); so, at a broad view, the Right Whale's head bears a rather inelegant resemblance to a gigantic galliot-toed shoe. Two hundred years ago an old Dutch voyager likened its shape to that of a shoemaker's last. And in this same last or shoe, that old woman of the nursery tale, with the swarming brood, might very comfortably be lodged, she and all her progeny. But as you come nearer to this great head it begins to assume different aspects, according to your point of view. If you stand on its summit and look at these two f-shaped spout-holes, you would take the whole head for an enormous bass-viol, and these ..

spiracles, the apertures in its sounding-board. Then, again, if you fix your eye upon this strange, crested, comb-like incrustation on the top of the mass --this green, barnacled thing, which the Greenlanders call the crown, and the Southern fishers the bonnet of the Right Whale; fixing your eyes solely on this, you would take the head for the trunk of some huge oak, with a bird's nest in its crotch. At any rate, when you watch those live crabs that nestle here on this bonnet, such an idea will be almost sure to occur to you; unless, indeed, your fancy has been fixed by the technical term crown also bestowed upon it; in which case you will take great interest in thinking how this mighty monster is actually a diademed king of the sea, whose green crown has been put together for him in this marvellous manner. But if this whale be a king, he is a very sulky looking fellow to grace a diadem. Look at that hanging lower lip! what a huge sulk and pout is there! a sulk and pout, by carpenter's measurement, about twenty feet long and five feet deep; a sulk and pout that will yield you some 500 gallons of oil and more. A great pity, now, that this unfortunate whale should be hare-lipped. The fissure is about a foot across. Probably the mother during an important interval was sailing down the Peruvian coast, when earthquakes caused the beach to gape. Over this lip, as over a slippery threshold, we now slide into the mouth. Upon my word were I at Mackinaw, I should take this to be the inside of an Indian wigwam. Good Lord! is this the road that Jonah went? The roof is about twelve feet high, and runs to a pretty sharp angle, as if there were a regular ridge-pole there; while these ribbed, arched, hairy sides, present us with those wondrous, half vertical, scimetar-shaped slats of whale-bone, say three hundred on a side, which depending from the upper part of the head or crown bone, form those Venetian blinds which have elsewhere been cursorily mentioned. The edges of these bones are fringed with hairy fibres, through which the Right Whale strains the water, and in whose intricacies he retains the small fish, when open-mouthed he goes through the seas of brit in feeding time. In the central blinds of bone, as they stand in their natural order, there are certain curious marks, curves, hollows, and ridges, whereby some whalemen calculate ..

the creature's age, as the age of an oak by its circular rings. Though the certainty of this criterion is far from demonstrable, yet it has the savor of analogical probability. At any rate, if we yield to it, we must grant a far greater age to the Right Whale than at first glance will seem reasonable. In old times, there seem to have prevailed the most curious fancies concerning these blinds. One voyager in Purchas calls them the wondrous whiskers inside of the whale's mouth; another, hogs' bristles; a third old gentleman in Hackluyt uses the following elegant language: There are about two hundred and fifty fins growing on each side of his upper chop, which arch over his tongue on each side of his mouth. As every one knows, these same hogs' bristles, fins, whiskers, blinds, or whatever you please, furnish to the ladies their busks and other stiffening contrivances. But in this particular, the demand has long been on the decline. It was in Queen Anne's time that the bone was in its glory, the farthingale being then all the fashion. And as those ancient dames moved about gaily, though in the jaws of the whale, as you may say; even so, in a shower, with the like thoughtlessness, do we nowadays fly under the same jaws for protection; the umbrella being a tent spread over the same bone. But now forget all about blinds and whiskers for a moment, and, standing in the Right Whale's mouth, look around you afresh. Seeing all these colonnades of bone so methodically ranged about, would you not think you were inside the great Haarlem organ, and gazing upon its thousand pipes? For a carpet to the organ we have a rug of the softest Turkey --the tongue, which is glued, as it were, to the floor of the mouth. It is very fat and tender, and apt to tear in pieces in hoisting it on deck. This particular tongue now before us; at a passing glance I should say it was a six-barreler; that is, it will yield you about that amount of oil. Ere this, you must have plainly seen the truth of what I ..

started with --that the Sperm Whale and the Right Whale have almost entirely different heads. To sum up, then; in the Right Whale's there is no great well of sperm; no ivory teeth at all; no long, slender mandible of a lower jaw, like the Sperm Whale's. Nor in the Sperm Whale are there any of those blinds of bone; no huge lower lip; and scarcely anything of a tongue. Again, the Right Whale has two external spout-holes, the Sperm Whale only one. Look your last, now, on these venerable hooded heads, while they yet lie together; for one will soon sink, unrecorded, in the sea; the other will not be very long in following. Can you catch the expression of the Sperm Whale's there? It is the same he died with, only some of the longer wrinkles in the forehead seem now faded away. I think his broad brow to be full of a prairie-like placidity, born of a speculative indifference as to death. But mark the other head's expression. See that amazing lower lip, pressed by accident against the vessel's side, so as firmly to embrace the jaw. Does not this whole head seem to speak of an enormous practical resolution in facing death? This Right Whale I take to have been a Stoic; the Sperm Whale, a Platonian, who might have taken up Spinoza in his latter years. ..

This reminds us that the Right Whale really has a sort of whisker, or rather a moustache, consisting of a few scattered white hairs on the upper part of the outer end of the lower jaw. Sometimes these tufts impart a rather brigandish expression to his otherwise solemn countenance. ..

.. < chapter lxxvi 24 THE BATTERING-RAM > Ere quitting, for the nonce, the Sperm Whale's head, I would have you, as a sensible physiologist, simply --particularly remark its front aspect, in all its compacted collectedness. I would have you investigate it now with the sole view of forming to yourself some unexaggerated, intelligent estimate of whatever battering-ram power may be lodged there. Here is a vital point; for you must either satisfactorily settle this matter with yourself, or for ever remain an infidel as to one of the most appalling, ..

but not the less true events, perhaps anywhere to be found in all recorded history. You observe that in the ordinary swimming position of the Sperm Whale, the front of his head presents an almost wholly vertical plane to the water; you observe that the lower part of that front slopes considerably backwards, so as to furnish more of a retreat for the long socket which receives the boom-like lower jaw; you observe that the mouth is entirely under the head, much in the same way, indeed, as though your own mouth were entirely under your chin. Moreover you observe that the whale has no external nose; and that what nose he has --his spout hole --is on the top of his head; you observe that his eyes and ears are at the sides of his head, nearly one third of his entire length from the front. Wherefore, you must now have perceived that the front of the Sperm Whale's head is a dead, blind wall, without a single organ or tender prominence of any sort whatsoever. Furthermore, you are now to consider that only in the extreme, lower, backward sloping part of the front of the head, is there the slightest vestige of bone; and not till you get near twenty feet from the forehead do you come to the full cranial development. So that this whole enormous boneless mass is as one wad. Finally, though, as will soon be revealed, its contents partly comprise the most delicate oil; yet, you are now to be apprised of the nature of the substance which so impregnably invests all that apparent effeminacy. In some previous place I have described to you how the blubber wraps the body of the whale, as the rind wraps an orange. Just so with the head; but with this difference: about the head this envelope, though not so thick, is of a boneless toughness, inestimable by any man who has not handled it. The severest pointed harpoon, the sharpest lance darted by the strongest human arm, impotently rebounds from it. It is as though the forehead of the Sperm Whale were paved with horses' hoofs. I do not think that any sensation lurks in it. Bethink yourself also of another thing. When two large, loaded Indiamen chance to crowd and crush towards each other in the docks, what do the sailors do? They do not suspend between them, at the point of coming contact, any merely hard substance, ..

like iron or wood. No, they hold there a large, round wad of tow and cork, enveloped in the thickest and toughest of ox-hide. That bravely and uninjured takes the jam which would have snapped all their oaken handspikes and iron crowbars. By itself this sufficiently illustrates the obvious fact I drive at. But supplementary to this, it has hypothetically occurred to me, that as ordinary fish possess what is called a swimming bladder in them, capable, at will, of distension or contraction; and as the Sperm Whale, as far as I know, has no such provision in him; considering, too, the otherwise inexplicable manner in which he now depresses his head altogether beneath the surface, and anon swims with it high elevated out of the water; considering the unobstructed elasticity of its envelop; considering the unique interior of his head; it has hypothetically occurred to me, I say, that those mystical lung-celled honeycombs there may possibly have some hitherto unknown and unsuspected connexion with the outer air, so as to be susceptible to atmospheric distension and contraction. If this be so, fancy the irresistibleness of that might, to which the most impalpable and destructive of all elements contributes. Now, mark. Unerringly impelling this dead, impregnable, uninjurable wall, and this most buoyant thing within; there swims behind it all a mass of tremendous life, only to be adequately estimated as piled wood is --by the cord; and all obedient to one volition, as the smallest insect. So that when I shall hereafter detail to you all the specialities and concentrations of potency everywhere lurking in this expansive monster; when I shall show you some of his more inconsiderable braining feats; I trust you will have renounced all ignorant incredulity, and be ready to abide by this; that though the Sperm Whale stove a passage through the Isthmus of Darien, and mixed the Atlantic with the Pacific, you would not elevate one hair of your eye-brow. For unless you own the whale, you are but a provincial and sentimentalist in Truth. But clear Truth is a thing for salamander giants only to encounter; how small the chances for the provincials then? What befel the weakling youth lifting the dread goddess's veil at Sais? ..

.. < chapter lxxvii 2 THE GREAT HEIDELBURGH TUN > Now comes the Baling of the Case. But to comprehend it aright, you must know something of the curious internal structure of the thing operated upon. Regarding the Sperm whale's head as a solid oblong, you may, on an inclined plane, sideways divide it into two quoins, whereof the lower is the bony structure, forming the cranium and jaws, and the upper an unctuous mass wholly free from bones; its broad forward end forming the expanded vertical apparent forehead of the whale. At the middle of the forehead horizontally subdivide this upper quoin, and then you have two almost equal parts, which before were naturally divided by an internal wall of a thick tendinous substance. The lower subdivided part, called the junk, is one immense honeycomb of oil, formed by the crossing and re-crossing, into ten thousand infiltrated cells, of tough elastic white fibres throughout its whole extent. The upper part, known as the Case, may be regarded as the great Heidelburgh Tun of the Sperm Whale. And as that famous great tierce is mystically carved in front, so the whale's vast plaited forehead forms innumerable strange devices for the emblematical adornment of his wondrous tun. Moreover, as that of Heidelburgh was always replenished with the most excellent of the wines of the Rhenish valleys, so the tun of the whale contains by far the most precious of all his oily vintages; namely, the highly-prized spermaceti, in its absolutely pure, limpid, and odoriferous state. Nor is this precious substance found unalloyed in any other part of the creature. Though in life it remains perfectly fluid, yet, upon ..

exposure to the air, after death, it soon begins to concrete; sending forth beautiful crystalline shoots, as when the first thin delicate ice is just forming in water. A large whale's case generally yields about five hundred gallons of sperm, though from unavoidable circumstances, considerable of it is spilled, leaks, and dribbles away, or is otherwise irrevocably lost in the ticklish business of securing what you can. I know not with what fine and costly material the heidelburgh Tun was coated within, but in superlative richness that coating could not possibly have compared with the silken pearl-colored membrane, like the line of a fine pelisse, forming the inner surface of the Sperm Whale's case. It will have been seen that the Heidelburgh Tun of the Sperm Whale embraces the entire length of the entire top of the head; and since --as has been elsewhere set forth --the head embraces one third of the whole length of the creature, then setting that length down at eighty feet for a good sized whale, you have more than twenty-six feet for the depth of the tun, when it is lengthwise hoisted up and down against a ship's side. As in decapitating the whale, the operator's instrument is brought close to the spot where an entrance is subsequently forced into the spermaceti magazine; he has, therefore, to be uncommonly heedful, lest a careless, untimely stroke should invade the sanctuary and wastingly let out its invaluable contents. It is this decapitated end of the head, also, which is at last elevated out of the water, and retained in that position by the enormous cutting tackles, whose hempen combinations, on one side, make quite a wilderness of ropes in that quarter. Thus much being said, attend now, I pray you, to that marvellous and --in this particular instance --almost fatal operation whereby the Sperm Whale's great Heidelburgh Tun is tapped. ..

Quoin is not a Euclidean term. It belongs to the pure nautical mathematics. I know not that it has been defined before. A quoin is a solid which differs from a wedge in having its sharp end formed by the steep inclination of one side, instead of the mutual tapering of both sides. ..

.. < chapter lxxviii 2 CISTERN AND BUCKETS > Nimble as a cat, Tashtego mounts aloft; and without altering his erect posture, runs straight out upon the overhanging main-yard-arm, to the part where it exactly projects over the hoisted Tun. He has carried with him a light tackle called a whip, consisting of only two parts, travelling through a single-sheaved block. Securing this block, so that it hangs down from the yard-arm, he swings one end of the rope, till it is caught and firmly held by a hand on deck. Then, hand-over-hand, down the other part, the Indian drops through the air, till dexterously he lands on the summit of the head. There --still high elevated above the rest of the company, to whom he vivaciously cries --he seems some Turkish Muezzin calling the good people to prayers from the top of a tower. A short-handled sharp spade being sent up to him, he diligently searches for the proper place to begin breaking into the Tun. In this business he proceeds very heedfully, like a treasure-hunter in some old house, sounding the walls to find where the gold is masoned in. By the time this cautious search is over, a stout iron-bound bucket, precisely like a well-bucket, has been attached to one end of the whip; while the other end, being stretched across the deck, is there held by two or three alert hands. These last now hoist the bucket within grasp of the Indian, to whom another person has reached up a very long pole. Inserting this pole into the bucket, Tashtego downward guides the bucket into the Tun, till it entirely disappears; then giving the word to the seamen at the whip, up comes the bucket again, all bubbling like a dairy-maid's pail of new milk. Carefully lowered from its height, the full-freighted vessel is caught by an appointed hand, and quickly emptied into a large tub. Then re-mounting aloft, it again goes through the same round until the deep cistern will yield no more. Towards the end, Tashtego has to ram his long pole harder and ..

harder, and deeper and deeper into the Tun, until some twenty feet of the pole have gone down. Now, the people of the Pequod had been baling some time in this way; several tubs had been filled with the fragrant sperm; when all at once a queer accident happened. Whether it was that Tashtego, that wild Indian, was so heedless and reckless as to let go for a moment his one-handed hold on the great cabled tackles suspending the head; or whether the place where he stood was so treacherous and oozy; or whether the Evil One himself would have it to fall out so, without stating his particular reasons; how it was exactly, there is no telling now; but, on a sudden, as the eightieth or ninetieth bucket came suckingly up --my God! poor Tashtego --like the twin reciprocating bucket in a veritable well, dropped head-foremost down into this great Tun of Heidelburgh, and with a horrible oily gurgling, went clean out of sight! Man overboard! cried Daggoo, who amid the general consternation first came to his senses. Swing the bucket this way! and putting one foot into it, so as the better to secure his slippery hand-hold on the whip itself, the hoisters ran him high up to the top of the head, almost before Tashtego could have reached its interior bottom. Meantime, there was a terrible tumult. Looking over the side, they saw the before lifeless head throbbing and heaving just below the surface of the sea, as if that moment seized with some momentous idea; whereas it was only the poor Indian unconsciously revealing by those struggles the perilous depth to which he had sunk. At this instant, while Daggoo, on the summit of the head, was clearing the whip --which had somehow got foul of the great cutting tackles --a sharp cracking noise was heard; and to the unspeakable horror of all, one of the two enormous hooks suspending the head tore out, and with a vast vibration the enormous mass sideways swung, till the drunk ship reeled and shook as if smitten by an iceberg. The one remaining hook, upon which the entire strain now depended, seemed every instant to be on the point of giving way; an event still more likely from the violent motions of the head. Come down, come down! yelled the seamen to Daggoo, but ..

with one hand holding on to the heavy tackles, so that if the head should drop, he would still remain suspended; the negro having cleared the foul line, rammed down the bucket into the now collapsed well, meaning that the buried harpooneer should grasp it, and so be hoisted out. In heaven's name, man, cried Stubb, are you ramming home a cartridge there? --Avast! How will that help him; jamming that iron-bound bucket on top of his head? Avast, will ye! Stand clear of the tackle! cried a voice like the bursting of a rocket. Almost in the same instant, with a thunder-boom, the enormous mass dropped into the sea, like Niagara's Table-Rock into the whirlpool; the suddenly relieved hull rolled away from it, to far down her glittering copper; and all caught their breath, as half swinging --now over the sailors' heads, and now over the water --Daggoo, through a thick mist of spray, was dimly beheld clinging to the pendulous tackles, while poor, buried-alive Tashtego was sinking utterly down to the bottom of the sea! But hardly had the blinding vapor cleared away, when a naked figure with a boarding-sword in its hand, was for one swift moment seen hovering over the bulwarks. The next, a loud splash announced that my brave Queequeg had dived to the rescue. One packed rush was made to the side, and every eye counted every ripple, as moment followed moment, and no sign of either the sinker or the diver could be seen. Some hands now jumped into a boat alongside, and pushed a little off from the ship. Ha! ha! cried Daggoo, all at once, from his now quiet, swinging perch overhead; and looking further off from the side, we saw an arm thrust upright from the blue waves; a sight strange to see, as an arm thrust forth from the grass over a grave. both! both! --it is both! --cried daggoo again with a joyful shout; and soon after, Queequeg was seen boldly striking out with one hand, and with the other clutching the long hair of the Indian. Drawn into the waiting boat, they were quickly brought to the deck; but Tashtego was long in coming to, and Queequeg did not look very brisk. ..

Now, how had this noble rescue been accomplished? Why, diving after the slowly descending head, Queequeg with his keen sword had made side lunges near its bottom, so as to scuttle a large hole there; then dropping his sword, had thrust his long arm far inwards and upwards, and so hauled out our poor Tash by the head. He averred, that upon first thrusting in for him, a leg was presented; but well knowing that that was not as it ought to be, and might occasion great trouble; -- he had thrust back the leg, and by a dexterous heave and toss, had wrought a somerset upon the Indian; so that with the next trial, he came forth in the good old way --head foremost. As for the great head itself, that was doing as well as could be expected. And thus, through the courage and great skill in obstetrics of Queequeg, the deliverance, or rather, delivery of Tashtego, was successfully accomplished, in the teeth, too, of the most untoward and apparently hopeless impediments; which is a lesson by no means to be forgotten. Midwifery should be taught in the same course with fencing and boxing, riding and rowing. I know that this queer adventure of the Gay-Header's will be sure to seem incredible to some landsmen, though they themselves may have either seen or heard of some one's falling into a cistern ashore; an accident which not seldom happens, and with much less reason too than the Indian's, considering the exceeding slipperiness of the curb of the Sperm Whale's well. But, peradventure, it may be sagaciously urged, how is this? We thought the tissued, infiltrated head of the Sperm Whale, was the lightest and most corky part about him; and yet thou makest it sink in an element of a far greater specific gravity than itself. We have thee there. Not at all, but I have ye; for at the time poor Tash fell in, the case had been nearly emptied of its lighter contents, leaving little but the dense tendinous wall of the well --a double welded, hammered substance, as I have before said, much heavier than the sea water, and a lump of which sinks in it like lead almost. But the tendency to rapid sinking in this substance was in the present instance materially counteracted by the other parts of the head remaining undetached from it, so that it sank very slowly and deliberately indeed, affording Queequeg a fair chance for performing his agile ..

obstetrics on the run, as you may say. Yes, it was a running delivery, so it was. Now, had Tashtego perished in that head, it had been a very precious perishing; smothered in the very whitest and daintiest of fragrant spermaceti; coffined, hearsed, and tombed in the secret inner chamber and sanctum sanctorum of the whale. Only one sweeter end can readily be recalled --the delicious death of an Ohio honey-hunter, who seeking honey in the crotch of a hollow tree, found such exceeding store of it, that leaning too far over, it sucked him in, so that he died embalmed. How many, think ye, have likewise fallen into Plato's honey head, and sweetly perished there? ..

.. < chapter lxxix 14 THE PRAIRE > To scan the lines of his face, or feel the bumps on the head of this Leviathan; this is a thing which no Physiognomist or Phrenologist has as yet undertaken. Such an enterprise would seem almost as hopeful as for Lavater to have scrutinized the wrinkles on the Rock of Gibraltar, or for Gall to have mounted a ladder and manipulated the Dome of the Pantheon. Still, in that famous work of his, Lavater not only treats of the various faces of men, but also attentively studies the faces of horses, birds, serpents, and fish; and dwells in detail upon the modifications of expression discernible therein. Nor have Gall and his disciple Spurzheim failed to throw out some hints touching the phrenological characteristics of other beings than man. Therefore, though I am but ill qualified for a pioneer, in the application of these two semi-sciences to the whale, I will do my endeavor. I try all things; I achieve what I can. Physiognomically regarded, the Sperm Whale is an anomalous creature. He has no proper nose. And since the nose is the central and most conspicuous of the features; and since it perhaps ..

most modifies and finally controls their combined expression; hence it would seem that its entire absence, as an external appendage, must very largely affect the countenance of the whale. For as in landscape gardening, a spire, cupola, monument, or tower of some sort, is deemed almost indispensable to the completion of the scene; so no face can be physiognomically in keeping without the elevated open-work belfry of the nose. Dash the nose from Phidias's marble Jove, and what a sorry remainder! Nevertheless, Leviathan is of so mighty a magnitude, all his proportions are so stately, that the same deficiency which in the sculptured Jove were hideous, in him is no blemish at all. Nay, it is an added grandeur. A nose to the whale would have been impertinent. As on your physiognomical voyage you sail round his vast head in your jolly-boat, your noble conceptions of him are never insulted by the reflection that he has a nose to be pulled. A pestilent conceit, which so often will insist upon obtruding even when beholding the mightiest royal beadle on his throne. In some particulars, perhaps, the most imposing physiognomical view to be had of the Sperm Whale, is that of the full front of his head. This aspect is sublime. In thought a fine human brow is like the east when troubled with the morning. in the repose of the pasture, the curled brow of the bull has a touch of the grand in it. Pushing heavy cannon up mountain defiles, the elephant's brow is majestic. Human or animal, the mystical brow is as that great golden seal affixed by the German emperors to their decrees. It signifies God: done this day by my hand. But in most creatures, nay in man himself, very often the brow is but a mere strip of alpine land lying along the snow line. Few are the foreheads which like Shakespeare's or Melancthon's rise so high, and descend so low, that the eyes themselves seem clear, eternal, tideless mountain lakes; and all above them in the forehead's wrinkles, you seem to track the antlered thoughts descending there to drink, as the Highland hunters track the snow prints of the deer. But in the great Sperm Whale, this high and mighty god-like dignity inherent in the brow is so immensely amplified, that gazing on it, in that full front view, you feel the Deity and the dread powers ..

more forcibly than in beholding any other object in living nature. For you see no one point precisely; not one distinct feature is revealed; no nose, eyes, ears, or mouth; no face; he has none, proper; nothing but that one broad firmament of a forehead, pleated with riddles; dumbly lowering with the doom of boats, and ships, and men. Nor, in profile, does this wondrous brow diminish; though that way viewed, its grandeur does not domineer upon you so. In profile, you plainly perceive that horizontal, semi-crescentic depression in the forehead's middle, which, in man, is Lavater's mark of genius. But how? Genius in the Sperm Whale? Has the Sperm Whale ever written a book, spoken a speech? No, his great genius is declared in his doing nothing particular to prove it. It is moreover declared in his pyramidical silence. And this reminds me that had the great Sperm Whale been known to the young Orient World, he would have been deified by their child-magian thoughts. they deified the crocodile of the nile, because the crocodile is tongueless; and the Sperm Whale has no tongue, or as least it is so exceedingly small, as to be incapable of protrusion. If hereafter any highly cultured, poetical nation shall lure back to their birth-right, the merry May-day gods of old; and livingly enthrone them again in the now egotistical sky; in the now unhaunted hill; then be sure, exalted to Jove's high seat, the great Sperm Whale shall lord it. Champollion deciphered the wrinkled granite hieroglyphics. But there is no Champollion to decipher the Egypt of every man's and every being's face. Physiognomy, like every other human science, is but a passing fable. If then, Sir William Jones, who read in thirty languages, could not read the simplest peasant's face, in its profounder and more subtle meanings, how may unlettered Ishmael hope to read the awful Chaldee of the Sperm Whale's brow? I but put that brow before you. Read if it you can. ..

.. < chapter lxxx 2 THE NUT > If the Sperm Whale be physiognomically a Sphinx, to the phrenologist his brain seems that geometrical circle which it is impossible to square. In the full-grown creature the skull will measure at least twenty feet in length. Unhinge the lower jaw, and the side view of this skull is as the side view of a moderately inclined plane resting throughout on a level base. But in life --as we have elsewhere seen --this inclined plane is angularly filled up, and almost squared by the enormous superincumbent mass of the junk and sperm. At the high end the skull forms a crater to bed that part of the mass; while under the long floor of this crater -- in another cavity seldom exceeding ten inches in length and as many in depth --reposes the mere handful of this monster's brain. The brain is at least twenty feet from his apparent forehead in life; it is hidden away behind its vast outworks, like the innermost citadel within the amplified fortifications of Quebec. So like a choice casket is it secreted in him, that I have known some whalemen who peremptorily deny that the Sperm Whale has any other brain than that palpable semblance of one formed by the cubic-yards of his sperm magazine. Lying in strange folds, courses, and convolutions, to their apprehensions, it seems more in keeping with the idea of his general might to regard that mystic part of him as the seat of his intelligence. It is plain, then, that phrenologically the head of this Leviathan, in the creature's living intact state, is an entire delusion. As for his true brain, you can then see no indications of it, nor feel any. The whale, like all things that are mighty, wears a false brow to the common world. If you unload his skull of its spermy heaps and then take a rear view of its rear end, which is the high end, you will be ..

struck by its resemblance to the human skull, beheld in the same situation, and from the same point of view. Indeed, place this reversed skull (scaled down to the human magnitude) among a plate of men's skulls, and you would involuntarily confound it with them; and remarking the depressions on one part of its summit, in phrenological phrase you would say --This man had no self-esteem, and no veneration. And by those negations, considered along with the affirmative fact of his prodigious bulk and power, you can best form to yourself the truest, though not the most exhilarating conception of what the most exalted potency is. But if from the comparative dimensions of the whale's proper brain, you deem it incapable of being adequately charted, then I have another idea for you. If you attentively regard almost any quadruped's spine, you will be struck with the resemblance of its vertebrae to a strung necklace of dwarfed skulls, all bearing rudimental resemblance to the skull proper. It is a German conceit, that the vertebrae are absolutely undeveloped skulls. But the curious external resemblance, I take it the Germans were not the first men to perceive. A foreign friend once pointed it out to me, in the skeleton of a foe he had slain, and with the vertebrae of which he was inlaying, in a sort of basso-relievo, the beaked prow of his canoe. Now, I consider that the phrenologists have omitted an important thing in not pushing their investigations from the cerebellum through the spinal canal. For I believe that much of a man's character will be found betokened in his backbone. I would rather feel your spine than your skull, whoever you are. A thin joist of a spine never yet upheld a full and noble soul. I rejoice in my spine, as in the firm audacious staff of that flag which I fling half out to the world. Apply this spinal branch of phrenology to the Sperm Whale. His cranial cavity is continuous with the first neck-vertebra; and in that vertebra the bottom of the spinal canal will measure ten inches across, being eight in height, and of a triangular figure with the base downwards. As it passes through the remaining vertebrae the canal tapers in size, but for a considerable distance remains of large capacity. Now, of course, this ..

canal is filled with much the same strangely fibrous substance -- the spinal cord --as the brain; and directly communicates with the brain. And what is still more, for many feet after emerging from the brain's cavity, the spinal cord remains of an undecreasing girth, almost equal to that of the brain. Under all these circumstances, would it be unreasonable to survey and map out the whale's spine phrenologically? For, viewed in this light, the wonderful comparative smallness of his brain proper is more than compensated by the wonderful comparative magnitude of his spinal cord. But leaving this hint to operate as it may with the phrenologists, I would merely assume the spinal theory for a moment, in reference to the sperm whale's hump. This august hump, if I mistake not, rises over one of the larger vertebrae, and is, therefore, in some sort, the outer convex mould of it. From its relative situation then, I should call this high hump the organ of firmness or indomitableness in the Sperm Whale. And that the great monster is indomitable, you will yet have reason to know. ..

.. < chapter lxxxi 21 THE PEQUOD MEETS THE VIRGIN > The predestinated day arrived, and we duly met the ship Jungfrau, Derick De Deer, master, of Bremen. At one time the greatest whaling people in the world, the Dutch and Germans are now among the least; but here and there at very wide intervals of latitude and longitude, you still occasionally meet with their flag in the Pacific. For some reason, the Jungfrau seemed quite eager to pay her respects. While yet some distance from the Pequod, she rounded to, and dropping a boat, her captain was impelled towards us, impatiently standing in the bows instead of the stern. ..

What has he in his hand there? cried Starbuck, pointing to something wavingly held by the German. Impossible! --a lamp-feeder! Not that, said Stubb, no, no, it's a coffee-pot, Mr. Starbuck; he's coming off to make us our coffee, is the Yarman; don't you see that big tin can there alongside of him? --that's his boiling water. Oh! he's all right, is the Yarman. Go along with you, cried Flask, it's a lamp-feeder and an oil-can. He's out of oil, and has come a-begging. However curious it may seem for an oil-ship to be borrowing oil on the whale-ground, and however much it may invertedly contradict the old proverb about carrying coals to Newcastle, yet sometimes such a thing really happens; and in the present case Captain Derick De Deer did indubitably conduct a lamp-feeder as Flask did declare. As he mounted the deck, ahab abruptly accosted him, without at all heeding what he had in his hand; but in his broken lingo, the German soon evinced his complete ignorance of the White Whale; immediately turning the conversation to his lamp-feeder and oil can, with some remarks touching his having to turn into his hammock at night in profound darkness --his last drop of Bremen oil being gone, and not a single flying-fish yet captured to supply the deficiency; concluding by hinting that his ship was indeed what in the Fishery is technically called a clean one (that is, an empty one), well deserving the name of Jungfrau or the Virgin. His necessities supplied, Derick departed; but he had not gained his ship's side, when whales were almost simultaneously raised from the mast-heads of both vessels; and so eager for the chase was Derick, that without pausing to put his oil-can and lamp-feeder aboard, he slewed round his boat and made after the leviathan lamp-feeders. Now, the game having risen to leeward, he and the other three German boats that soon followed him, had considerably the start of the Pequod's keels. There were eight whales, an average pod. Aware of their danger, they were going all abreast with great speed straight before the wind, rubbing their flanks as closely as so many spans of horses in harness. They left a ..

great, wide wake, as though continually unrolling a great wide parchment upon the sea. Full in this rapid wake, and many fathoms in the rear, swam a huge, humped old bull, which by his comparatively slow progress, as well as by the unusual yellowish incrustations overgrowing him, seemed afflicted with the jaundice, or some other infirmity. Whether this whale belonged to the pod in advance, seemed questionable; for it is not customary for such venerable leviathans to be at all social. Nevertheless, he stuck to their wake, though indeed their back water must have retarded him, because the white-bone or swell at his broad muzzle was a dashed one, like the swell formed when two hostile currents meet. His spout was short, slow, and laborious; coming forth with a choking sort of gush, and spending itself in torn shreds, followed by strange subterranean commotions in him, which seemed to have egress at his other buried extremity, causing the waters behind him to upbubble. Who's got some paregoric? said Stubb, he has the stomach-ache, I'm afraid. Lord, think of having half an acre of stomach-ache! Adverse winds are holding mad Christmas in him, boys. It's the first foul wind I ever knew to blow from astern; but look, did ever whale yaw so before? it must be, he's lost his tiller. As an overladen Indiaman bearing down the Hindostan coast with a deck load of frightened horses, careens, buries, rolls, and wallows on her way; so did this old whale heave his aged bulk, and now and then partly turning over on his cumbrous rib-ends, expose the cause of his devious wake in the unnatural stump of his starboard fin. Whether he had lost that fin in battle, or had been born without it, it were hard to say. Only wait a bit, old chap, and I'll give ye a sling for that wounded arm, cried cruel Flask, pointing to the whale-line near him. Mind he don't sling thee with it, cried Starbuck. Give way, or the German will have him. With one intent all the combined rival boats were pointed for this one fish, because not only was he the largest, and therefore the most valuable whale, but he was nearest to them, and the other whales were going with such great velocity, moreover, ..

as almost to defy pursuit for the time. At this juncture, the Pequod's keel had shot by the three German boats last lowered; but from the great start he had had, Derick's boat still led the chase, though every moment neared by his foreign rivals. The only thing they feared, was, that from being already so nigh to his mark, he would be enabled to dart his iron before they could completely overtake and pass him. as for derick, he seemed quite confident that this would be the case, and occasionally with a deriding gesture shook his lamp-feeder at the other boats. The ungracious and ungrateful dog! cried Starbuck; he mocks and dares me with the very poor-box I filled for him not five minutes ago! --then in his old intense whisper -- give way, greyhounds! Dog to it! I tell ye what it is, men --cried Stubb to his crew -- It's against my religion to get mad; but I'd like to eat that villanous Yarman --Pull--won't ye? Are ye going to let that rascal beat ye? Do ye love brandy? A hogshead of brandy, then, to the best man. Come, why don't some of ye burst a blood-vessel? Who's that been dropping an anchor overboard --we don't budge an inch --we're becalmed. Halloo, here's grass growing in the boat's bottom --and by the Lord, the mast there's budding. This won't do, boys. Look at that Yarman! The short and long of it is, men, will ye spit fire or not? Oh! see the suds he makes! cried Flask, dancing up and down -- What a hump --Oh, do pile on the beef --lays like a log! Oh! my lads, do spring --slap-jacks and quohogs for supper, you know, my lads --baked clams and muffins --oh, do, do spring --he's a hundred barreler --don't lose him now --don't oh, don't! -- see that Yarman --Oh! won't ye pull for your duff, my lads --such a sog! such a sogger! Don't ye love sperm? There goes three thousand dollars, men! --a bank! --a whole bank! The bank of England! --Oh, do, do, do! --What's that Yarman about now? At this moment Derick was in the act of pitching his lamp-feeder at the advancing boats, and also his oil-can; perhaps with the double view of retarding his rivals' way, and at the same time economically accelerating his own by the momentary impetus of the backward toss. The unmannerly Dutch dogger! cried Stubb. Pull now, ..

men, like fifty thousand line-of-battle-ship loads of red-haired devils. What d'ye say, Tashtego; are you the man to snap your spine in two-and-twenty pieces for the honor of old Gay-head? What d'ye say? I say, pull like god-dam, --cried the Indian. Fiercely, but evenly incited by the taunts of the German, the Pequod's three boats now began ranging almost abreast; and, so disposed, momentarily neared him. In that fine, loose, chivalrous attitude of the headsman when drawing near to his prey, the three mates stood up proudly, occasionally backing the after oarsman with an exhilarating cry of, There she slides, now! Hurrah for the white-ash breeze! Down with the Yarman! Sail over him! But so decided an original start had Derick had, that spite of all their gallantry, he would have proved the victor in this race, had not a righteous judgment descended upon him in a crab which caught the blade of his midship oarsman. While this clumsy lubber was striving to free his white-ash, and while, in consequence, Derick's boat was nigh to capsizing, and he thundering away at his men in a mighty rage; --that was a good time for Starbuck, Stubb, and Flask. With a shout, they took a mortal start forwards, and slantingly ranged up on the German's quarter. An instant more, and all four boats were diagonically in the whale's immediate wake, while stretching from them, on both sides, was the foaming swell that he made. It was a terrific, most pitiable, and maddening sight. The whale was now going head out, and sending his spout before him in a continual tormented jet; while his one poor fin beat his side in an agony of fright. Now to this hand, now to that, he yawed in his faltering flight, and still at every billow that he broke, he spasmodically sank in the sea, or sideways rolled towards the sky his one beating fin. So have I seen a bird with clipped wing, making affrighted broken circles in the air, vainly striving to escape the piratical hawks. But the bird has a voice, and with plaintive cries will make known her fear; but the fear of this vast dumb brute of the sea, was chained up and enchanted in him; he had no voice, save that choking respiration through his spiracle, and this made the sight of him unspeakably ..

pitiable; while still, in his amazing bulk, portcullis jaw, and omnipotent tail, there was enough to appal the stoutest man who so pitied. Seeing now that but a very few moments more would give the Pequod's boats the advantage, and rather than be thus foiled of his game, Derick chose to hazard what to him must have seemed a most unusually long dart, ere the last chance would for ever escape. But no sooner did his harpooneer stand up for the stroke, than all three tigers --Queequeg, Tashtego, Daggoo -- instinctively sprang to their feet, and standing in a diagonal row, simultaneously pointed their barbs; and darted over the head of the German harpooneer, their three Nantucket irons entered the whale. Blinding vapors of foam and white-fire! The three boats, in the first fury of the whale's headlong rush, bumped the German's aside with such force, that both Derick and his baffled harpooneer were spilled out, and sailed over by the three flying keels. Don't be afraid, my butter-boxes, cried Stubb, casting a passing glance upon them as he shot by; ye'll be picked up presently --all right --I saw some sharks astern --St. Bernard's dogs, you know --relieve distressed travellers. Hurrah! this is the way to sail now. Every keel a sun-beam! Hurrah! --Here we go like three tin kettles at the tail of a mad cougar! This puts me in mind of fastening to an elephant in a tilbury on a plain --makes the wheel-spokes fly, boys, when you fasten to him that way; and there's danger of being pitched out too, when you strike a hill. Hurrah! this is the way a fellow feels when he's going to Davy Jones --all a rush down an endless inclined plane! Hurrah! this whale carries the everlasting mail! But the monster's run was a brief one. Giving a sudden gasp, he tumultuously sounded. With a grating rush, the three lines flew round the loggerheads with such a force as to gouge deep grooves in them; while so fearful were the harpooneers that this rapid sounding would soon exhaust the lines, that using all their dexterous might, they caught repeated smoking turns with the rope to hold on; till at last --owing to the perpendicular strain from the lead-lined chocks of the boats, whence the three ..

ropes went straight down into the blue --the gunwales of the bows were almost even with the water, while the three sterns tilted high in the air. And the whale soon ceasing to sound, for some time they remained in that attitude, fearful of expending more line, though the position was a little ticklish. But though boats have been taken down and lost in this way, yet it is this holding on, as it is called; this hooking up by the sharp barbs of his live flesh from the back; this it is that often torments the Leviathan into soon rising again to meet the sharp lance of his foes. Yet not to speak of the peril of the thing, it is to be doubted whether this course is always the best; for it is but reasonable to presume, that the longer the stricken whale stays under water, the more he is exhausted. Because, owing to the enormous surface of him --in a full grown sperm whale something less than square feet --the pressure of the water is immense. We all know what an astonishing atmospheric weight we ourselves stand up under; even here, above-ground, in the air; how vast, then, the burden of a whale, bearing on his back a column of two hundred fathoms of ocean! It must at least equal the weight of fifty atmospheres. One whaleman has estimated it at the weight of twenty line-of-battle ships, with all their guns, and stores, and men on board. As the three boats lay there on that gently rolling sea, gazing down into its eternal blue noon; and as not a single groan or cry of any sort, nay, not so much as a ripple or a bubble came up from its depths; what landsman would have thought, that beneath all that silence and placidity, the utmost monster of the seas was writhing and wrenching in agony! Not eight inches of perpendicular rope were visible at the bows. Seems it credible that by three such thin threads the great Leviathan was suspended like the big weight to an eight day clock. Suspended? and to what? To three bits of board. Is this the creature of whom it was once so triumphantly said -- Canst thou fill his skin with barbed irons? or his head with fish-spears? The sword of him that layeth at him cannot hold, the spear, the dart, nor the habergeon: he esteemeth iron as straw; the arrow cannot make him flee; darts are counted as stubble; he laugheth at the shaking of a spear! This the creature? this he? Oh! that unfulfilments ..

should follow the prophets. For with the strength of a thousand thighs in his tail, Leviathan had run his head under the mountains of the sea, to hide him from the Pequod's fish-spears! In that sloping afternoon sunlight, the shadows that the three boats sent down beneath the surface, must have been long enough and broad enough to shade half Xerxes' army. Who can tell how appalling to the wounded whale must have been such huge phantoms flitting over his head! Stand by, men; he stirs, cried Starbuck, as the three lines suddenly vibrated in the water, distinctly conducting upwards to them, as by magnetic wires, the life and death throbs of the whale, so that every oarsman felt them in his seat. The next moment, relieved in a great part from the downward strain at the bows, the boats gave a sudden bounce upwards, as a small ice-field will, when a dense herd of white bears are scared from it into the sea. Haul in! Haul in! cried Starbuck again; he's rising. The lines, of which, hardly an instant before, not one hand's breadth could have been gained, were now in long quick coils flung back all dripping into the boats, and soon the whale broke water within two ship's lengths of the hunters. His motions plainly denoted his extreme exhaustion. In most land animals there are certain valves or flood-gates in many of their veins, whereby when wounded, the blood is in some degree at least instantly shut off in certain directions. Not so with the whale; one of whose peculiarities it is, to have an entire nonvalvular structure of the blood-vessels, so that when pierced even by so small a point as a harpoon, a deadly drain is at once begun upon his whole arterial system; and when this is heightened by the extraordinary pressure of water at a great distance below the surface, his life may be said to pour from him in incessant streams. Yet so vast is the quantity of blood in him, and so distant and numerous its interior fountains, that he will keep thus bleeding and bleeding for a considerable period; even as in a drought a river will flow, whose source is in the well-springs of far-off and undiscernible hills. Even now, when the boats pulled upon this whale, and perilously drew over his swaying ..

flukes, and the lances were darted into him, they were followed by steady jets from the new made wound, which kept continually playing, while the natural spout-hole in his head was only at intervals, however rapid, sending its affrighted moisture into the air. From this last vent no blood yet came, because no vital part of him had thus far been struck. His life, as they significantly call it, was untouched. As the boats now more closely surrounded him, the whole upper part of his form, with much of it that is ordinarily submerged, was plainly revealed. His eyes, or rather the places where his eyes had been, were beheld. As strange misgrown masses gather in the knot-holes of the noblest oaks when prostrate, so from the points which the whale's eyes had once occupied, now protruded blind bulbs, horribly pitiable to see. but pity there was none. For all his old age, and his one arm, and his blind eyes, he must die the death and be murdered, in order to light the gay bridals and other merry-makings of men, and also to illuminate the solemn churches that preach unconditional inoffensiveness by all to all. Still rolling in his blood, at last he partially disclosed a strangely discolored bunch or protuberance, the size of a bushel, low down on the flank. A nice spot, cried Flask; just let me prick him there once. Avast! cried Starbuck, there's no need of that! But humane Starbuck was too late. At the instant of the dart an ulcerous jet shot from this cruel wound, and goaded by it into more than sufferable anguish, the whale now spouting thick blood, with swift fury blindly darted at the craft, bespattering them and their glorying crews all over with showers of gore, capsizing Flask's boat and marring the bows. It was his death stroke. For, by this time, so spent was he by loss of blood, that he helplessly rolled away from the wreck he had made; lay panting on his side, impotently flapped with his stumped fin, then over and over slowly revolved like a waning world; turned up the white secrets of his belly; lay like a log, and died. It was most piteous, that last expiring spout. As when by unseen hands the water is gradually drawn off from some mighty fountain, and with half-stifled melancholy gurglings the spray-column lowers and lowers to the ground --so the last long dying spout of the whale. ..

Soon, while the crews were awaiting the arrival of the ship, the body showed symptoms of sinking with all its treasures unrifled. Immediately, by Starbuck's orders, lines were secured to it at different points, so that ere long every boat was a buoy; the sunken whale being suspended a few inches beneath them by the cords. By very heedful management, when the ship drew nigh, the whale was transferred to her side, and was strongly secured there by the stiffest fluke-chains, for it was plain that unless artificially upheld, the body would at once sink to the bottom. It so chanced that almost upon first cutting into him with the spade, the entire length of a corroded harpoon was found imbedded in his flesh, on the lower part of the bunch before described. But as the stumps of harpoons are frequently found in the dead bodies of captured whales, with the flesh perfectly healed around them, and no prominence of any kind to denote their place; therefore, there must needs have been some other unknown reason in the present case fully to account for the ulceration alluded to. But still more curious was the fact of a lance-head of stone being found in him, not far from the buried iron, the flesh perfectly firm about it. Who had darted that stone lance? And when? It might have been darted by some Nor' West Indian long before America was discovered. What other marvels might have been rummaged out of this monstrous cabinet there is no telling. But a sudden stop was put to further discoveries, by the ship's being unprecedentedly dragged over sideways to the sea, owing to the body's immensely increasing tendency to sink. However, Starbuck, who had the ordering of affairs, hung on to it to the last; hung on to it so resolutely, indeed, that when at length the ship would have been capsized, if still persisting in locking arms with the body; then, when the command was given to break clear from it, such was the immovable strain upon the timber-heads to which the fluke-chains and cables were fastened, that it was impossible to cast them off. Meantime everything in the Pequod was aslant. To cross to the other side of the deck was like walking up the steep gabled roof of a house. The ship groaned and gasped. Many of the ivory inlayings of her bulwarks and cabins were started from their places, by the unnatural dislocation. In ..

vain handspikes and crows were brought to bear upon the immovable fluke-chains, to pry them adrift from the timber-heads; and so low had the whale now settled that the submerged ends could not be at all approached, while every moment whole tons of ponderosity seemed added to the sinking bulk, and the ship seemed on the point of going over. Hold on, hold on, won't ye? cried Stubb to the body, don't be in such a devil of a hurry to sink! By thunder, men, we must do something or go for it. No use prying there; avast, I say with your handspikes, and run one of ye for a prayer book and a pen-knife, and cut the big chains. Knife? Aye, aye, cried Queequeg, and seizing the carpenter's heavy hatchet, he leaned out of a porthole, and steel to iron, began slashing at the largest fluke-chains. But a few strokes, full of sparks, were given, when the exceeding strain effected the rest. With a terrific snap, every fastening went adrift; the ship righted, the carcase sank. Now, this occasional inevitable sinking of the recently killed Sperm Whale is a very curious thing; nor has any fisherman yet adequately accounted for it. Usually the dead Sperm Whale floats with great buoyancy, with its side or belly considerably elevated above the surface. If the only whales that thus sank were old, meagre, and broken-hearted creatures, their pads of lard diminished and all their bones heavy and rheumatic; then you might with some reason assert that this sinking is caused by an uncommon specific gravity in the fish so sinking, consequent upon this absence of buoyant matter in him. But it is not so. For young whales, in the highest health, and swelling with noble aspirations, prematurely cut off in the warm flush and May of life, with all their panting lard about them; even these brawny, buoyant heroes do sometimes sink. Be it said, however, that the Sperm Whale is far less liable to this accident than any other species. Where one of that sort go down, twenty Right Whales do. This difference in the species is no doubt imputable in no small degree to the greater quantity of bone in the Right Whale; his Venetian blinds alone sometimes weighing more than a ton; from this incumbrance the Sperm Whale is wholly free. But there are instances where, ..

after the lapse of many hours or several days, the sunken whale again rises, more buoyant than in life. But the reason of this is obvious. Gases are generated in him; he swells to a prodigious magnitude; becomes a sort of animal balloon. A line-of-battle ship could hardly keep him under then. In the Shore Whaling, on soundings, among the Bays of New Zealand, when a Right Whale gives token of sinking, they fasten buoys to him, with plenty of rope; so that when the body has gone down, they know where to look for it when it shall have ascended again. It was not long after the sinking of the body that a cry was heard from the Pequod's mast-heads, announcing that the Jungfrau was again lowering her boats; though the only spout in sight was that of a Fin-Back, belonging to the species of uncapturable whales, because of its incredible power of swimming. Nevertheless, the Fin-Back's spout is so similar to the Sperm Whale's, that by unskilful fishermen it is often mistaken for it. And consequently Derick and all his host were now in valiant chase of this unnearable brute. The Virgin crowding all sail, made after her four young keels, and thus they all disappeared far to leeward, still in bold, hopeful chase. Oh! many are the Fin-Backs, and many are the Dericks, my friend. ..

.. < chapter lxxxii 24 THE HONOR AND GLORY OF WHALING > There are some enterprises in which a careful disorderliness is the true method. The more I dive into this matter of whaling, and push my researches up to the very spring-head of it, so much the more am I impressed with its great honorableness and antiquity; and especially when I find so many great demi-gods and heroes, prophets of all sorts, who one way or other have shed distinction upon it, I am transported with the reflection that I myself ..

belong, though but subordinately, to so emblazoned a fraternity. The gallant Perseus, a son of Jupiter, was the first whaleman; and to the eternal honor of our calling be it said, that the first whale attacked by our brotherhood was not killed with any sordid intent. Those were the knightly days of our profession, when we only bore arms to succor the distressed, and not to fill men's lamp-feeders. Every one knows the fine story of Perseus and Andromeda; how the lovely Andromeda, the daughter of a king, was tied to a rock on the sea-coast, and as Leviathan was in the very act of carrying her off, Perseus, the prince of whalemen, intrepidly advancing, harpooned the monster, and delivered and married the maid. It was an admirable artistic exploit, rarely achieved by the best harpooneers of the present day; inasmuch as this Leviathan was slain at the very first dart. And let no man doubt this Arkite story; for in the ancient Joppa, now Jaffa, on the Syrian coast, in one of the Pagan temples, there stood for many ages the vast skeleton of a whale, which the city's legends and all the inhabitants asserted to be the identical bones of the monster that Perseus slew. When the Romans took Joppa, the same skeleton was carried to Italy in triumph. What seems most singular and suggestively important in this story, is this: it was from Joppa that Jonah set sail. Akin to the adventure of Perseus and Andromeda --indeed, by some supposed to be indirectly derived from it --is that famous story of St. George and the Dragon; which dragon I maintain to have been a whale; for in many old chronicles whales and dragons are strangely jumbled together, and often stand for each other. Thou art as a lion of the waters, and as a dragon of the sea, saith ezekiel; hereby, plainly meaning a whale; in truth, some versions of the Bible use that word itself. Besides, it would much subtract from the glory of the exploit had St. George but encountered a crawling reptile of the land, instead of doing battle with the great monster of the deep. Any man may kill a snake, but only a Perseus, a St. George, a Coffin, have the heart in them to march boldly up to a whale. Let not the modern paintings of this scene mislead us; for though the creature encountered by that valiant whaleman of old is vaguely represented of a griffin-like shape, and though ..

the battle is depicted on land and the saint on horseback, yet considering the great ignorance of those times, when the true form of the whale was unknown to artists; and considering that as in Perseus' case, St. George's whale might have crawled up out of the sea on the beach; and considering that the animal ridden by St. George might have been only a large seal, or sea-horse; bearing all this in mind, it will not appear altogether incompatible with the sacred legend and the ancientest draughts of the scene, to hold this so-called dragon no other than the great Leviathan himself. In fact, placed before the strict and piercing truth, this whole story will fare like that fish, flesh, and fowl idol of the Philistines, Dagon by name; who being planted before the ark of Israel, his horse's head and both the palms of his hands fell off from him, and only the stump or fishy part of him remained. Thus, then, one of our own noble stamp, even a whaleman, is the tutelary guardian of England; and by good rights, we harpooneers of Nantucket should be enrolled in the most noble order of St. George. And therefore, let not the knights of that honorable company (none of whom, I venture to say, have ever had to do with a whale like their great patron), let them never eye a Nantucketer with disdain, since even in our woollen frocks and tarred trowsers we are much better entitled to st. george's decoration than they. Whether to admit Hercules among us or not, concerning this I long remained dubious: for though according to the Greek mythologies, that antique Crockett and Kit Carson --that brawny doer of rejoicing good deeds, was swallowed down and thrown up by a whale; still, whether that strictly makes a whaleman of him, that might be mooted. It nowhere appears that he ever actually harpooned his fish, unless, indeed, from the inside. Nevertheless, he may be deemed a sort of involuntary whaleman; at any rate the whale caught him, if he did not the whale. I claim him for one of our clan. But, by the best contradictory authorities, this Grecian story of Hercules and the whale is considered to be derived from the still more ancient Hebrew story of Jonah and the whale; and vice versa; certainly they are very similar. If I claim the demigod then, why not the prophet? ..

Nor do heroes, saints, demigods, and prophets alone comprise the whole roll of our order. Our grand master is still to be named; for like royal kings of old times, we find the headwaters of our fraternity in nothing short of the great gods themselves. That wondrous oriental story is now to be rehearsed from the Shaster, which gives us the dread Vishnoo, one of the three persons in the godhead of the Hindoos; gives us this divine Vishnoo himself for our Lord; --Vishnoo, who, by the first of his ten earthly incarnations, has for ever set apart and sanctified the whale. When Brahma, or the God of Gods, saith the Shaster, resolved to recreate the world after one of its periodical dissolutions, he gave birth to Vishnoo, to preside over the work; but the Vedas, or mystical books, whose perusal would seem to have been indispensable to Vishnoo before beginning the creation, and which therefore must have contained something in the shape of practical hints to young architects, these Vedas were lying at the bottom of the waters; so Vishnoo became incarnate in a whale, and sounding down in him to the uttermost depths, rescued the sacred volumes. Was not this Vishnoo a whaleman, then? even as a man who rides a horse is called a horseman? Perseus, St. George, Hercules, Jonah, and Vishnoo! there's a member-roll for you! What club but the whaleman's can head off like that? ..

.. < chapter lxxxiii 26 JONAH HISTORICALLY REGARDED > Reference was made to the historical story of Jonah and the whale in the preceding chapter. Now some Nantucketers rather distrust this historical story of Jonah and the whale. But then there were some sceptical Greeks and Romans, who, standing out from the orthodox pagans of their times, equally doubted the story of Hercules and the whale, and Arion and the dolphin; ..

and yet their doubting those traditions did not make those traditions one whit the less facts, for all that. One old Sag-Harbor whaleman's chief reason for questioning the Hebrew story was this: --He had one of those quaint old-fashioned Bibles, embellished with curious, unscientific plates; one of which represented Jonah's whale with two spouts in his head --a peculiarity only true with respect to a species of the Leviathan (the Right Whale, and the varieties of that order), concerning which the fishermen have this saying, A penny roll would choke him; his swallow is so very small. But, to this, Bishop Jebb's anticipative answer is ready. It is not necessary, hints the Bishop, that we consider Jonah as tombed in the whale's belly, but as temporarily lodged in some part of his mouth. And this seems reasonable enough in the good Bishop. For truly, the Right Whale's mouth would accommodate a couple of whist tables, and comfortably seat all the players. Possibly, too, Jonah might have ensconced himself in a hollow tooth; but, on second thoughts, the Right Whale is toothless. Another reason which Sag-Harbor (he went by that name) urged for his want of faith in this matter of the prophet, was something obscurely in reference to his incarcerated body and the whale's gastric juices. But this objection likewise falls to the ground, because a German exegetist supposes that Jonah must have taken refuge in the floating body of a dead whale -- even as the French soldiers in the Russian campaign turned their dead horses into tents, and crawled into them. Besides, it has been divined by other continental commentators, that when Jonah was thrown overboard from the Joppa ship, he straightway effected his escape to another vessel near by, some vessel with a whale for a figure-head; and, I would add, possibly called The Whale, as some craft are nowadays christened the Shark, the Gull, the Eagle. Nor have there been wanting learned exegetists who have opined that the whale mentioned in the book of Jonah merely meant a life-preserver --an inflated bag of wind --which the endangered prophet swam to, and so was saved from a watery doom. Poor Sag-Harbor, therefore, seems worsted all round. But he had still another reason for his want of faith. It was this, if I remember right: Jonah was ..

swallowed by the whale in the Mediterranean Sea, and after three days he was vomited up somewhere within three days' journey of Nineveh, a city on the Tigris, very much more than three days' journey across from the nearest point of the Mediterranean coast. How is that? But was there no other way for the whale to land the prophet within that short distance of Nineveh? Yes. He might have carried him round by the way of the Cape of Good Hope. But not to speak of the passage through the whole length of the Mediterranean, and another passage up the Persian Gulf and Red Sea, such a supposition would involve the complete circumnavigation of all Africa in three days, not to speak of the Tigris waters, near the site of Nineveh, being too shallow for any whale to swim in. Besides, this idea of Jonah's weathering the Cape of Good Hope at so early a day would wrest the honor of the discovery of that great headland from Bartholomew Diaz, its reputed discoverer, and so make modern history a liar. But all these foolish arguments of old Sag-Harbor only evinced his foolish pride of reason --a thing still more reprehensible in him, seeing that he had but little learning except what he had picked up from the sun and the sea. I say it only shows his foolish, impious pride, and abominable, devilish rebellion against the reverend clergy. For by a Portuguese Catholic priest, this very idea of Jonah's going to Nineveh via the Cape of Good Hope was advanced as a signal magnification of the general miracle. And so it was. Besides, to this day, the highly enlightened Turks devoutly believe in the historical story of Jonah. And some three centuries ago, an English traveller in old Harris's Voyages, speaks of a Turkish Mosque built in honor of Jonah, in which mosque was a miraculous lamp that burnt without any oil. ..

.. < chapter lxxxiv 2 PITCHPOLING > To make them run easily and swiftly, the axles of carriages are anointed; and for much the same purpose, some whalers perform an analogous operation upon their boat; they grease the bottom. Nor is it to be doubted that as such a procedure can do no harm, it may possibly be of no contemptible advantage; considering that oil and water are hostile; that oil is a sliding thing, and that the object in view is to make the boat slide bravely. Queequeg believed strongly in anointing his boat, and one morning not long after the German ship Jungfrau disappeared, took more than customary pains in that occupation; crawling under its bottom, where it hung over the side, and rubbing in the unctuousness as though diligently seeking to insure a crop of hair from the craft's bald keel. He seemed to be working in obedience to some particular presentiment. Nor did it remain unwarranted by the event. Towards noon whales were raised; but so soon as the ship sailed down to them, they turned and fled with swift precipitancy; a disordered flight, as of Cleopatra's barges from Actium. Nevertheless, the boats pursued, and Stubb's was foremost. By great exertion, Tashtego at last succeeded in planting one iron; but the stricken whale, without at all sounding, still continued his horizontal flight, with added fleetness. Such unintermitted strainings upon the planted iron must sooner or later inevitably extract it. It became imperative to lance the flying whale, or be content to lose him. But to haul the boat up to his flank was impossible, he swam so fast and furious. What then remained? Of all the wondrous devices and dexterities, the sleights of hand and countless subtleties, to which the veteran whaleman is so often forced, none exceed that fine manoeuvre with the lance called pitchpoling. Small sword, or broad sword, in all its ..

exercises boasts nothing like it. It is only indispensable with an inveterate running whale; its grand fact and feature is the wonderful distance to which the long lance is accurately darted from a violently rocking, jerking boat, under extreme headway. Steel and wood included, the entire spear is some ten or twelve feet in length; the staff is much slighter than that of the harpoon, and also of a lighter material--pine. It is furnished with a small rope called a warp, of considerable length, by which it can be hauled back to the hand after darting. But before going further, it is important to mention here, that though the harpoon may be pitchpoled in the same way with the lance, yet it is seldom done; and when done, is still less frequently successful, on account of the greater weight and inferior length of the harpoon as compared with the lance, which in effect become serious drawbacks. As a general thing, therefore, you must first get fast to a whale, before any pitchpoling comes into play. Look now at Stubb; a man who from his humorous, deliberate coolness and equanimity in the direst emergencies, was specially qualified to excel in pitchpoling. Look at him; he stands upright in the tossed bow of the flying boat; wrapt in fleecy foam, the towing whale is forty feet ahead. Handling the long lance lightly, glancing twice or thrice along its length to see if it be exactly straight, Stubb whistlingly gathers up the coil of the warp in one hand, so as to secure its free end in his grasp, leaving the rest unobstructed. Then holding the lance full before his waistband's middle, he levels it at the whale; when, covering him with it, he steadily depresses the butt-end in his hand, thereby elevating the point till the weapon stands fairly balanced upon his palm, fifteen feet in the air. He minds you somewhat of a juggler, balancing a long staff on his chin. Next moment with a rapid, nameless impulse, in a superb lofty arch the bright steel spans the foaming distance, and quivers in the life spot of the whale. Instead of sparkling water, he now spouts red blood. That drove the spigot out of him! cries Stubb. 'Tis July's immortal Fourth; all fountains must run wine to-day! Would now, it were old Orleans whiskey, or old Ohio, or unspeakable ..

old Monongahela! Then, Tashtego, lad, I'd have ye hold a canakin to the jet, and we'd drink round it! Yea, verily, hearts alive, we'd brew choice punch in the spread of his spout-hole there, and from that live punch-bowl quaff the living stuff! Again and again to such gamesome talk, the dexterous dart is repeated, the spear returning to its master like a greyhound held in skilful leash. The agonized whale goes into his flurry; the tow-line is slackened, and the pitchpoler dropping astern, folds his hands, and mutely watches the monster die. ..

.. < chapter lxxxv 11 THE FOUNTAIN > That for six thousand years --and no one knows how many millions of ages before --the great whales should have been spouting all over the sea, and sprinkling and mistifying the gardens of the deep, as with so many sprinkling or mistifying pots; and that for some centuries back, thousands of hunters should have been close by the fountain of the whale, watching these sprinklings and spoutings --that all this should be, and yet, that down to this blessed minute (fifteen and a quarter minutes past one o'clock P. M. of this sixteenth day of December, A. D. ), it should still remain a problem, whether these spoutings are, after all, really water, or nothing but vapor --this is surely a noteworthy thing. Let us, then, look at this matter, along with some interesting items contingent. Every one knows that by the peculiar cunning of their gills, the finny tribes in general breathe the air which at all times is combined with the element in which they swim, hence, a herring or a cod might live a century, and never once raise its head above the surface. But owing to his marked internal structure which gives him regular lungs, like a human being's, the whale can only live by inhaling the disengaged air in the open atmosphere. Wherefore the necessity ..

for his periodical visits to the upper world. But he cannot in any degree breathe through his mouth, for, in his ordinary attitude, the Sperm Whale's mouth is buried at least eight feet beneath the surface; and what is still more, his windpipe has no connexion with his mouth. No, he breathes through his spiracle alone; and this is on the top of his head. If I say, that in any creature breathing is only a function indispensable to vitality, inasmuch as it withdraws from the air a certain element, which being subsequently brought into contact with the blood imparts to the blood its vivifying principle, I do not think I shall err; though I may possibly use some superfluous scientific words. Assume it, and it follows that if all the blood in a man could be aerated with one breath, he might then seal up his nostrils and not fetch another for a considerable time. That is to say, he would then live without breathing. Anomalous as it may seem, this is precisely the case with the whale, who systematically lives, by intervals, his full hour and more (when at the bottom) without drawing a single breath, or so much as in any way inhaling a particle of air; for, remember, he has no gills. How is this? Between his ribs and on each side of his spine he is supplied with a remarkable involved Cretan labyrinth of vermicelli-like vessels, which vessels, when he quits the surface, are completely distended with oxygenated blood. So that for an hour or more, a thousand fathoms in the sea, he carries a surplus stock of vitality in him, just as the camel crossing the waterless desert carries a surplus supply of drink for future use in its four supplementary stomachs. The anatomical fact of this labyrinth is indisputable; and that the supposition founded upon it is reasonable and true, seems the more cogent to me, when I consider the otherwise inexplicable obstinacy of that leviathan in having his spoutings out, as the fishermen phrase it. This is what I mean. If unmolested, upon rising to the surface, the Sperm Whale will continue there for a period of time exactly uniform with all his other unmolested risings. Say he stays eleven minutes, and jets seventy times, that is, respires seventy breaths; then whenever he rises again, he will be sure to have his seventy breaths over again, to a minute. Now, if after he fetches a few ..

breaths you alarm him, so that he sounds, he will be always dodging up again to make good his regular allowance of air. And not till those seventy breaths are told, will he finally go down to stay out his full term below. Remark, however, that in different individuals these rates are different; but in any one they are alike. Now, why should the whale thus insist upon having his spoutings out, unless it be to replenish his reservoir of air, ere descending for good? How obvious is it, too, that this necessity for the whale's rising exposes him to all the fatal hazards of the chase. For not by hook or by net could this vast leviathan be caught, when sailing a thousand fathoms beneath the sunlight. Not so much thy skill, then, O hunter, as the great necessities that strike the victory to thee! In man, breathing is incessantly going on --one breath only serving for two or three pulsations; so that whatever other business he has to attend to, waking or sleeping, breathe he must, or die he will. But the Sperm Whale only breathes about one seventh or Sunday of his time. It has been said that the whale only breathes through his spout-hole; if it could truthfully be added that his spouts are mixed with water, then I opine we should be furnished with the reason why his sense of smell seems obliterated in him; for the only thing about him that at all answers to his nose is that identical spout-hole; and being so clogged with two elements, it could not be expected to have the power of smelling. But owing to the mystery of the spout --whether it be water or whether it be vapor --no absolute certainty can as yet be arrived at on this head. Sure it is, nevertheless, that the Sperm Whale has no proper olfactories. But what does he want of them? No roses, no violets, no Cologne-water in the sea. Furthermore, as his windpipe solely opens into the tube of his spouting canal, and as that long canal --like the grand Erie Canal --is furnished with a sort of locks (that open and shut) for the downward retention of air or the upward exclusion of water, therefore the whale has no voice; unless you insult him by saying, that when he so strangely rumbles, he talks through his nose. But then again, what has the whale to say? Seldom have I known any profound being that had anything to say to this ..

world, unless forced to stammer out something by way of getting a living. Oh! happy that the world is such an excellent listener! Now, the spouting canal of the Sperm Whale, chiefly intended as it is for the conveyance of air, and for several feet laid along, horizontally, just beneath the upper surface of his head, and a little to one side; this curious canal is very much like a gas-pipe laid down in a city on one side of a street. But the question returns whether this gas-pipe is also a water-pipe; in other words, whether the spout of the Sperm Whale is the mere vapor of the exhaled breath, or whether that exhaled breath is mixed with water taken in at the mouth, and discharged through the spiracle. It is certain that the mouth indirectly communicates with the spouting canal; but it cannot be proved that this is for the purpose of discharging water through the spiracle. Because the greatest necessity for so doing would seem to be, when in feeding he accidentally takes in water. But the Sperm Whale's food is far beneath the surface, and there he cannot spout even if he would. Besides, if you regard him very closely, and time him with your watch, you will find that when unmolested, there is an undeviating rhyme between the periods of his jets and the ordinary periods of respiration. But why pester one with all this reasoning on the subject? Speak out! You have seen him spout; then declare what the spout is; can you not tell water from air? My dear sir, in this world it is not so easy to settle these plain things. I have ever found your plain things the knottiest of all. And as for this whale spout, you might almost stand in it, and yet be undecided as to what it is precisely. The central body of it is hidden in the snowy sparkling mist enveloping it; and how can you certainly tell whether any water falls from it, when, always, when you are close enough to a whale to get a close view of his spout, he is in a prodigious commotion, the water cascading all around him. And if at such times you should think that you really perceived drops of moisture in the spout, how do you know that they are not merely condensed from its vapor; or how do you know that they are not those identical drops superficially lodged in the spout-hole fissure, which is countersunk into the summit of the whale's head? For even when tranquilly swimming through the mid-day ..

sea in a calm, with his elevated hump sun-dried as a dromedary's in the desert; even then, the whale always carries a small basin of water on his head, as under a blazing sun you will sometimes see a cavity in a rock filled up with rain. Nor is it at all prudent for the hunter to be over curious touching the precise nature of the whale spout. It will not do for him to be peering into it, and putting his face in it. You cannot go with your pitcher to this fountain and fill it, and bring it away. For even when coming into slight contact with the outer, vapory shreds of the jet, which will often happen, your skin will feverishly smart, from the acridness of the thing so touching it. And I know one, who coming into still closer contact with the spout, whether with some scientific object in view, or otherwise, I cannot say, the skin peeled off from his cheek and arm. Wherefore, among whalemen, the spout is deemed poisonous; they try to evade it. Another thing; I have heard it said, and I do not much doubt it, that if the jet is fairly spouted into your eyes, it will blind you. The wisest thing the investigator can do then, it seems to me, is to let this deadly spout alone. Still, we can hypothesize, even if we cannot prove and establish. My hypothesis is this: that the spout is nothing but mist. And besides other reasons, to this conclusion I am impelled, by considerations touching the great inherent dignity and sublimity of the Sperm Whale; I account him no common, shallow being, inasmuch as it is an undisputed fact that he is never found on soundings, or near shores; all other whales sometimes are. He is both ponderous and profound. And I am convinced that from the heads of all ponderous profound beings, such as Plato, Pyrrho, the Devil, Jupiter, Dante, and so on, there always goes up a certain semi-visible steam, while in the act of thinking deep thoughts. While composing a little treatise on Eternity, I had the curiosity to place a mirror before me; and ere long saw reflected there, a curious involved worming and undulation in the atmosphere over my head. The invariable moisture of my hair, while plunged in deep thought, after six cups of hot tea in my thin shingled attic, of an August noon; this seems an additional argument for the above supposition. And how nobly it raises our conceit of the mighty, misty ..

monster, to behold him solemnly sailing through a calm tropical sea; his vast, mild head overhung by a canopy of vapor, engendered by his incommunicable contemplations, and that vapor --as you will sometimes see it --glorified by a rainbow, as if Heaven itself had put its seal upon his thoughts. For, d'ye see, rainbows do not visit the clear air; they only irradiate vapor. And so, through all the thick mists of the dim doubts in my mind, divine intuitions now and then shoot, enkindling my fog with a heavenly ray. And for this I thank God; for all have doubts; many deny; but doubts or denials, few along with them, have intuitions. Doubts of all things earthly, and intuitions of some things heavenly; this combination makes neither believer nor infidel, but makes a man who regards them both with equal eye. ..

.. < chapter lxxxvi 16 THE TAIL > Other poets have warbled the praises of the soft eye of the antelope, and the lovely plumage of the bird that never alights; less celestial, I celebrate a tail. Reckoning the largest sized Sperm Whale's tail to begin at that point of the trunk where it tapers to about the girth of a man, it comprises upon its upper surface alone, an area of at least fifty square feet. The compact round body of its root expands into two broad, firm, flat palms or flukes, gradually shoaling away to less than an inch in thickness. At the crotch or junction, these flukes slightly overlap, then sideways recede from each other like wings, leaving a wide vacancy between. In no living thing are the lines of beauty more exquisitely defined than in the crescentic borders of these flukes. At its utmost expansion in the full grown whale, the tail will considerably exceed twenty feet across. The entire member seems a dense webbed bed of welded ..

sinews; but cut into it, and you find that three distinct strata compose it: --upper, middle, and lower. The fibres in the upper and lower layers, are long and horizontal; those of the middle one, very short, and running crosswise between the outside layers. This triune structure, as much as anything else, imparts power to the tail. To the student of old Roman walls, the middle layer will furnish a curious parallel to the thin course of tiles always alternating with the stone in those wonderful relics of the antique, and which undoubtedly contribute so much to the great strength of the masonry. But as if this vast local power in the tendinous tail were not enough, the whole bulk of the leviathan is knit over with a warp and woof of muscular fibres and filaments, which passing on either side the loins and running down into the flukes, insensibly blend with them, and largely contribute to their might; so that in the tail the confluent measureless force of the whole whale seems concentrated to a point. Could annihilation occur to matter, this were the thing to do it. Nor does this --its amazing strength, at all tend to cripple the graceful flexion of its motions; where infantileness of ease undulates through a Titanism of power. On the contrary, those motions derive their most appalling beauty from it. Real strength never impairs beauty or harmony, but it often bestows it; and in everything imposingly beautiful, strength has much to do with the magic. Take away the tied tendons that all over seem bursting from the marble in the carved Hercules, and its charm would be gone. As devout Eckerman lifted the linen sheet from the naked corpse of Goethe, he was overwhelmed with the massive chest of the man, that seemed as a Roman triumphal arch. When Angelo paints even God the Father in human form, mark what robustness is there. And whatever they may reveal of the divine love in the Son, the soft, curled, hermaphroditical Italian pictures, in which his idea has been most successfully embodied; these pictures, so destitute as they are of all brawniness, hint nothing of any power, but the mere negative, feminine one of submission and endurance, which on all hands it is conceded, form the peculiar practical virtues of his teachings. Such is the subtle elasticity of the organ I treat of, that ..

whether wielded in sport, or in earnest, or in anger, whatever be the mood it be in, its flexions are invariably marked by exceeding grace. Therein no fairy's arm can transcend it. Five great motions are peculiar to it. First, when used as a fin for progression; Second, when used as a mace in battle; Third, in sweeping; Fourth, in lobtailing; Fifth, in peaking flukes. First: Being horizontal in its position, the Leviathan's tail acts in a different manner from the tails of all other sea creatures. It never wriggles. In man or fish, wriggling is a sign of inferiority. To the whale, his tail is the sole means of propulsion. Scroll-wise coiled forwards beneath the body, and then rapidly sprung backwards, it is this which gives that singular darting, leaping motion to the monster when furiously swimming. His side-fins only serve to steer by. Second: It is a little significant, that while one sperm whale only fights another sperm whale with his head and jaw, nevertheless, in his conflicts with man, he chiefly and contemptuously uses his tail. In striking at a boat, he swiftly curves away his flukes from it, and the blow is only inflicted by the recoil. If it be made in the unobstructed air, especially if it descend to its mark, the stroke is then simply irresistible. No ribs of man or boat can withstand it. Your only salvation lies in eluding it; but if it comes sideways through the opposing water, then partly owing to the light buoyancy of the whaleboat, and the elasticity of its materials, a cracked rib or a dashed plank or two, a sort of stitch in the side, is generally the most serious result. These submerged side blows are so often received in the fishery, that they are accounted mere child's play. Some one strips off a frock, and the hole is stopped. Third: I cannot demonstrate it, but it seems to me, that in the whale the sense of touch is concentrated in the tail; for in this respect there is a delicacy in it only equalled by the daintiness of the elephant's trunk. This delicacy is chiefly evinced in the action of sweeping, when in maidenly gentleness the whale with a certain soft slowness moves his immense flukes from side to side upon the surface of the sea; and if he feel but a sailor's whisker, woe to that sailor, whiskers and all. ..

What tenderness there is in that preliminary touch! Had this tail any prehensile power, I should straightway bethink me of Darmonodes' elephant that so frequented the flower-market, and with low salutations presented nosegays to damsels, and then caressed their zones. On more accounts than one, a pity it is that the whale does not possess this prehensile virtue in his tail; for I have heard of yet another elephant, that when wounded in the fight, curved round his trunk and extracted the dart. Fourth: Stealing unawares upon the whale in the fancied security of the middle of solitary seas, you find him unbent from the vast corpulence of his dignity, and kitten-like, he plays on the ocean as if it were a hearth. But still you see his power in his play. The broad palms of his tail are flirted high into the air; then smiting the surface, the thunderous concussion resounds for miles. You would almost think a great gun had been discharged; and if you noticed the light wreath of vapor from the spiracle at his other extremity, you would think that that was the smoke from the touch-hole. Fifth: As in the ordinary floating posture of the leviathan the flukes lie considerably below the level of his back, they are then completely out of sight beneath the surface; but when he is about to plunge into the deeps, his entire flukes with at least thirty feet of his body are tossed erect in the air, and so remain vibrating a moment, till they downwards shoot out of view. Excepting the sublime breach --somewhere else to be described --this peaking of the whale's flukes is perhaps the grandest sight to be seen in all animated nature. Out of the bottomless profundities the gigantic tail seems spasmodically snatching at the highest heaven. So in dreams, have I seen majestic Satan thrusting forth his tormented colossal claw from the flame Baltic of Hell. But in gazing at such scenes, it is all in all what mood you are in; if in the Dantean, the devils will occur to you; if in that of Isaiah, the archangels. Standing at the mast-head of my ship during a sunrise that crimsoned sky and sea, I once saw a large herd of whales in the east, all heading towards the sun, and for a moment vibrating in concert with peaked flukes. As it seemed to me at the time, such a grand ..

embodiment of adoration of the gods was never beheld, even in Persia, the home of the fire worshippers. As Ptolemy Philopater testified of the African elephant, I then testified of the whale, pronouncing him the most devout of all beings. For according to King Juba, the military elephants of antiquity often hailed the morning with their trunks uplifted in the profoundest silence. The chance comparison in this chapter, between the whale and the elephant, so far as some aspects of the tail of the one and the trunk of the other are concerned, should not tend to place those two opposite organs on an equality, much less the creatures to which they respectively belong. For as the mightiest elephant is but a terrier to Leviathan, so, compared with Leviathan's tail, his trunk is but the stalk of a lily. The most direful blow from the elephant's trunk were as the playful tap of a fan, compared with the measureless crush and crash of the sperm whale's ponderous flukes, which in repeated instances have one after the other hurled entire boats with all their oars and crews into the air, very much as an Indian juggler tosses his balls. The more I consider this mighty tail, the more do I deplore my inability to express it. At times there are gestures in it, which, though they would well grace the hand of man, remain wholly inexplicable. In an extensive herd, so remarkable, occasionally, are these mystic gestures, that I have heard hunters who have declared them akin to Free-Mason signs and symbols; that the whale, indeed, by these methods intelligently conversed with the world. Nor are there wanting other motions of the whale in his general body, full of strangeness, and unaccountable to his most experienced assailant. Dissect him how I may, then, I but go skin deep; I know him not, and never will. But if I know not even the tail of this whale, how understand his head? much more, how comprehend his face, when face he has none? ..

Thou shalt see my back parts, my tail, he seems to say, but my face shall not be seen. But I cannot completely make out his back parts; and hint what he will about his face, I say again he has no face. ..

Though all comparison in the way of general bulk between the whale and the elephant is preposterous, inasmuch as in that particular the elephant stands in much the same respect to the whale that a dog does to the elephant; nevertheless, there are not wanting some points of curious similitude; among these is the spout. It is well known that the elephant will often draw up water or dust in his trunk, and then elevating it, jet it forth in a stream. ..

.. < chapter lxxxvii 6 THE GRAND ARMADA > The long and narrow peninsula of Malacca, extending south-eastward from the territories of Birmah, forms the most southerly point of all Asia. In a continuous line from that peninsula stretch the long islands of Sumatra, Java, Bally, and Timor; which, with many others, form a vast mole, or rampart, lengthwise connecting Asia with Australia, and dividing the long unbroken Indian ocean from the thickly studded oriental archipelagoes. This rampart is pierced by several sally-ports for the convenience of ships and whales; conspicuous among which are the straits of Sunda and Malacca. By the straits of Sunda, chiefly, vessels bound to China from the west, emerge into the China seas. Those narrow straits of Sunda divide Sumatra from Java; and standing midway in that vast rampart of islands, buttressed by that bold green promontory, known to seamen as Java Head; they not a little correspond to the central gateway opening into some vast walled empire: and considering the inexhaustible wealth of spices, and silks, and jewels, and gold, and ivory, with which the thousand islands of that oriental sea are enriched, it seems a significant provision of nature, that such treasures, by the very formation of the land, should at least bear the appearance, however ineffectual, of being guarded from the all-grasping western world. The shores of the Straits of Sunda are unsupplied with those domineering fortresses which guard the entrances to the Mediterranean, the Baltic, and the Propontis. Unlike the Danes, these Orientals do not demand the obsequious homage of lowered top-sails from the endless procession of ships ..

before the wind, which for centuries past, by night and by day, have passed between the islands of Sumatra and Java, freighted with the costliest cargoes of the east. But while they freely waive a ceremonial like this, they do by no means renounce their claim to more solid tribute. Time out of mind the piratical proas of the Malays, lurking among the low shaded coves and islets of Sumatra, have sallied out upon the vessels sailing through the straits, fiercely demanding tribute at the point of their spears. Though by the repeated bloody chastisements they have received at the hands of European cruisers, the audacity of these corsairs has of late been somewhat repressed; yet, even at the present day, we occasionally hear of English and American vessels, which, in those waters, have been remorselessly boarded and pillaged. With a fair, fresh wind, the Pequod was now drawing nigh to these straits; Ahab purposing to pass through them into the Javan sea, and thence, cruising northwards, over waters known to be frequented here and there by the Sperm whale, sweep inshore by the Philippine Islands, and gain the far coast of Japan, in time for the great whaling season there. By these means, the circumnavigating Pequod would sweep almost all the known Sperm Whale cruising grounds of the world, previous to descending upon the Line in the Pacific; where Ahab, though everywhere else foiled in his pursuit, firmly counted upon giving battle to Moby Dick, in the sea he was most known to frequent; and at a season when he might most reasonably be presumed to be haunting it. But how now? in this zoned quest, does Ahab touch no land? does his crew drink air? Surely, he will stop for water. Nay. For a long time, now, the circus-running sun has raced within his fiery ring, and needs no sustenance but what's in himself. So Ahab. Mark this, too, in the whaler. While other hulls are loaded down with alien stuff, to be transferred to foreign wharves; the world-wandering whale-ship carries no cargo but herself and crew, their weapons and their wants. She has a whole lake's contents bottled in her ample hold. She is ballasted with utilities; not altogether with unusable pig-lead and kentledge. She carries years' water in her. Clear old prime Nantucket water; which, when three years afloat, the Nantucketer, ..

in the Pacific, prefers to drink before the brackish fluid, but yesterday rafted off in casks, from the Peruvian or Indian streams. Hence it is, that, while other ships may have gone to China from New York, and back again, touching at a score of ports, the whale-ship, in all that interval, may not have sighted one grain of soil; her crew having seen no man but floating seamen like themselves. So that did you carry them the news that another flood had come; they would only answer -- Well, boys, here's the ark! Now, as many Sperm Whales had been captured off the western coast of Java, in the near vicinity of the straits of Sunda; indeed, as most of the ground, roundabout, was generally recognised by the fishermen as an excellent spot for cruising; therefore, as the Pequod gained more and more upon Java Head, the look-outs were repeatedly hailed, and admonished to keep wide awake. But though the green palmy cliffs of the land soon loomed on the starboard bow, and with delighted nostrils the fresh cinnamon was snuffed in the air, yet not a single jet was descried. Almost renouncing all thought of falling in with any game hereabouts, the ship had well nigh entered the straits, when the customary cheering cry was heard from aloft, and ere long a spectacle of singular magnificence saluted us. But here be it premised, that owing to the unwearied activity with which of late they have been hunted over all four oceans, the Sperm Whales, instead of almost invariably sailing in small detached companies, as in former times, are now frequently met with in extensive herds, sometimes embracing so great a multitude, that it would almost seem as if numerous nations of them had sworn solemn league and covenant for mutual assistance and protection. To this aggregation of the Sperm Whale into such immense caravans, may be imputed the circumstance that even in the best cruising grounds, you may now sometimes sail for weeks and months together, without being greeted by a single spout; and then be suddenly saluted by what sometimes seems thousands on thousands. Broad on both bows, at the distance of some two or three miles, and forming a great semicircle, embracing one half of the level horizon, a continuous chain of whale-jets were up-playing and sparkling in the noon-day air. Unlike the straight perpendicular ..

twin-jets of the Right Whale, which, dividing at top, falls over in two branches, like the cleft drooping boughs of a willow, the single forward-slanting spout of the Sperm Whale presents a thick curled bush of white mist, continually rising and falling away to leeward. Seen from the Pequod's deck, then, as she would rise on a high hill of the sea, this host of vapory spouts, individually curling up into the air, and beheld through a blending atmosphere of bluish haze, showed like the thousand cheerful chimneys of some dense metropolis, descried of a balmy autumnal morning, by some horseman on a height. As marching armies approaching an unfriendly defile in the mountains, accelerate their march, all eagerness to place that perilous passage in their rear, and once more expand in comparative security upon the plain; even so did this vast fleet of whales now seem hurrying forward through the straits; gradually contracting the wings of their semicircle, and swimming on, in one solid, but still crescentic centre. Crowding all sail the Pequod pressed after them; the harpooneers handling their weapons, and loudly cheering from the heads of their yet suspended boats. If the wind only held, little doubt had they, that chased through these Straits of Sunda, the vast host would only deploy into the Oriental seas to witness the capture of not a few of their number. And who could tell whether, in that congregated caravan, Moby Dick himself might not temporarily be swimming, like the worshipped white-elephant in the coronation procession of the Siamese! So with stun-sail piled on stun-sail, we sailed along, driving these leviathans before us; when, of a sudden, the voice of Tashtego was heard, loudly directing attention to something in our wake. Corresponding to the crescent in our van, we beheld another in our rear. It seemed formed of detached white vapors, rising and falling something like the spouts of the whales; only they did not so completely come and go; for they constantly hovered, without finally disappearing. Levelling his glass at this sight, ahab quickly revolved in his pivot-hole, crying, aloft there, and rig whips and buckets to wet the sails; --Malays, sir, and after us! ..

As if too long lurking behind the headlands, till the Pequod should fairly have entered the straits, these rascally Asiatics were now in hot pursuit, to make up for their over-cautious delay. But when the swift Pequod, with a fresh leading wind, was herself in hot chase; how very kind of these tawny philanthropists to assist in speeding her on to her own chosen pursuit, -- mere riding-whips and rowels to her, that they were. As with glass under arm, Ahab to-and-fro paced the deck; in his forward turn beholding the monsters he chased, and in the after one the bloodthirsty pirates chasing him; some such fancy as the above seemed his. And when he glanced upon the green walls of the watery defile in which the ship was then sailing, and bethought him that through that gate lay the route to his vengeance, and beheld, how that through that same gate he was now both chasing and being chased to his deadly end; and not only that, but a herd of remorseless wild pirates and inhuman atheistical devils were infernally cheering him on with their curses; --when all these conceits had passed through his brain, Ahab's brow was left gaunt and ribbed, like the black sand beach after some stormy tide has been gnawing it, without being able to drag the firm thing from its place. But thoughts like these troubled very few of the reckless crew; and when, after steadily dropping and dropping the pirates astern, the Pequod at last shot by the vivid green Cockatoo Point on the Sumatra side, emerging at last upon the broad waters beyond; then, the harpooneers seemed more to grieve that the swift whales had been gaining upon the ship, than to rejoice that the ship had so victoriously gained upon the Malays. But still driving on in the wake of the whales, at length they seemed abating their speed; gradually the ship neared them; and the wind now dying away, word was passed to spring to the boats. But no sooner did the herd, by some presumed wonderful instinct of the Sperm Whale, become notified of the three keels that were after them, --though as yet a mile in their rear, --than they rallied again, and forming in close ranks and battalions, so that their spouts all looked like flashing lines of stacked bayonets, moved on with redoubled velocity. Stripped to our shirts and drawers, we sprang to the white-ash, ..

and after several hours' pulling were almost disposed to renounce the chase, when a general pausing commotion among the whales gave animating token that they were now at last under the influence of that strange perplexity of inert irresolution, which, when the fishermen perceive it in the whale, they say he is gallied. The compact martial columns in which they had been hitherto rapidly and steadily swimming, were now broken up in one measureless rout; and like King Porus' elephants in the Indian battle with Alexander, they seemed going mad with consternation. In all directions expanding in vast irregular circles, and aimlessly swimming hither and thither, by their short thick spoutings, they plainly betrayed their distraction of panic. This was still more strangely evinced by those of their number, who, completely paralysed as it were, helplessly floated like water-logged dismantled ships on the sea. Had these leviathans been but a flock of simple sheep, pursued over the pasture by three fierce wolves, they could not possibly have evinced such excessive dismay. But this occasional timidity is characteristic of almost all herding creatures. Though banding together in tens of thousands, the lion-maned buffaloes of the West have fled before a solitary horseman. Witness, too, all human beings, how when herded together in the sheepfold of a theatre's pit, they will, at the slightest alarm of fire, rush helter-skelter for the outlets, crowding, trampling, jamming, and remorselessly dashing each other to death. Best, therefore, withhold ..

any amazement at the strangely gallied whales before us, for there is no folly of the beasts of the earth which is not infinitely outdone by the madness of men. Though many of the whales, as has been said, were in violent motion, yet it is to be observed that as a whole the herd neither advanced nor retreated, but collectively remained in one place. As is customary in those cases, the boats at once separated, each making for some one lone whale on the outskirts of the shoal. In about three minutes' time, Queequeg's harpoon was flung; the stricken fish darted blinding spray in our faces, and then running away with us like light, steered straight for the heart of the herd. Though such a movement on the part of the whale struck under such circumstances, is in no wise unprecedented; and indeed is almost always more or less anticipated; yet does it present one of the more perilous vicissitudes of the fishery. For as the swift monster drags you deeper and deeper into the frantic shoal, you bid adieu to circumspect life and only exist in a delirious throb. As, blind and deaf, the whale plunged forward, as if by sheer power of speed to rid himself of the iron leech that had fastened to him; as we thus tore a white gash in the sea, on all sides menaced as we flew, by the crazed creatures to and fro rushing about us; our beset boat was like a ship mobbed by ice-isles in a tempest, and striving to steer through their complicated channels and straits, knowing not at what moment it may be locked in and crushed. But not a bit daunted, Queequeg steered us manfully; now sheering off from this monster directly across our route in advance; now edging away from that, whose colossal flukes were suspended overhead, while all the time, Starbuck stood up in the bows, lance in hand, pricking out of our way whatever whales he could reach by short darts, for there was no time to make long ones. Nor were the oarsmen quite idle, though their wonted duty was now altogether dispensed with. They chiefly attended to the shouting part of the business. Out of the way, Commodore! cried one, to a great dromedary that of a sudden rose bodily to the surface, and for an instant threatened to swamp us. Hard down with your tail, there! cried a second ..

to another, which, close to our gunwale, seemed calmly cooling himself with his own fan-like extremity. All whaleboats carry certain curious contrivances, originally invented by the Nantucket Indians, called druggs. Two thick squares of wood of equal size are stoutly clenched together, so that they cross each other's grain at right angles; a line of considerable length is then attached to the middle of this block, and the other end of the line being looped, it can in a moment be fastened to a harpoon. It is chiefly among gallied whales that this drugg is used. For then, more whales are close round you than you can possibly chase at one time. But sperm whales are not every day encountered; while you may, then, you must kill all you can. And if you cannot kill them all at once, you must wing them, so that they can be afterwards killed at your leisure. Hence it is, that at times like these the drugg comes into requisition. Our boat was furnished with three of them. The first and second were successfully darted, and we saw the whales staggeringly running off, fettered by the enormous sidelong resistance of the towing drugg. They were cramped like malefactors with the chain and ball. But upon flinging the third, in the act of tossing overboard the clumsy wooden block, it caught under one of the seats of the boat, and in an instant tore it out and carried it away, dropping the oarsman in the boat's bottom as the seat slid from under him. On both sides the sea came in at the wounded planks, but we stuffed two or three drawers and shirts in, and so stopped the leaks for the time. It had been next to impossible to dart these drugged-harpoons, were it not that as we advanced into the herd, our whale's way greatly diminished; moreover, that as we went still further and further from the circumference of commotion, the direful disorders seemed waning. So that when at last the jerking harpoon drew out, and the towing whale sideways vanished; then, with the tapering force of his parting momentum, we glided between two whales into the innermost heart of the shoal, as if from some mountain torrent we had slid into a serene valley lake. Here the storms in the roaring glens between the outermost whales, were heard but not felt. In this central expanse the sea presented that smooth satin-like surface, called a sleek, produced ..

by the subtle moisture thrown off by the whale in his more quiet moods. Yes, we were now in that enchanted calm which they say lurks at the heart of every commotion. And still in the distracted distance we beheld the tumults of the outer concentric circles, and saw successive pods of whales, eight or ten in each, swiftly going round and round, like multiplied spans of horses in a ring; and so closely shoulder to shoulder, that a Titanic circus-rider might easily have over-arched the middle ones, and so have gone round on their backs. Owing to the density of the crowd of reposing whales, more immediately surrounding the embayed axis of the herd, no possible chance of escape was at present afforded us. We must watch for a breach in the living wall that hemmed us in; the wall that had only admitted us in order to shut us up. Keeping at the centre of the lake, we were occasionally visited by small tame cows and calves; the women and children of this routed host. Now, inclusive of the occasional wide intervals between the revolving outer circles, and inclusive of the spaces between the various pods in any one of those circles, the entire area at this juncture, embraced by the whole multitude, must have contained at least two or three square miles. At any rate --though indeed such a test at such a time might be deceptive --spoutings might be discovered from our low boat that seemed playing up almost from the rim of the horizon. I mention this circumstance, because, as if the cows and calves had been purposely locked up in this innermost fold; and as if the wide extent of the herd had hitherto prevented them from learning the precise cause of its stopping; or, possibly, being so young, unsophisticated, and every way innocent and inexperienced; however it may have been, these smaller whales --now and then visiting our becalmed boat from the margin of the lake --evinced a wondrous fearlessness and confidence, or else a still becharmed panic which it was impossible not to marvel at. Like household dogs they came snuffling round us, right up to our gunwales, and touching them; till it almost seemed that some spell had suddenly domesticated them. Queequeg patted their foreheads; Starbuck scratched their backs with his lance; but fearful of the consequences, for the time refrained from darting it. ..

But far beneath this wondrous world upon the surface, another and still stranger world met our eyes as we gazed over the side. For, suspended in those watery vaults, floated the forms of the nursing mothers of the whales, and those that by their enormous girth seemed shortly to become mothers. The lake, as I have hinted, was to a considerable depth exceedingly transparent; and as human infants while suckling will calmly and fixedly gaze away from the breast, as if leading two different lives at the time; and while yet drawing mortal nourishment, be still spiritually feasting upon some unearthly reminiscence; --even so did the young of these whales seem looking up towards us, but not at us, as if we were but a bit of Gulf-weed in their new-born sight. floating on their sides, the mothers also seemed quietly eyeing us. One of these little infants, that from certain queer tokens seemed hardly a day old, might have measured some fourteen feet in length, and some six feet in girth. He was a little frisky; though as yet his body seemed scarce yet recovered from that irksome position it had so lately occupied in the maternal reticule; where, tail to head, and all ready for the final spring, the unborn whale lies bent like a Tartar's bow. The delicate side-fins, and the palms of his flukes, still freshly retained the plaited crumpled appearance of a baby's ears newly arrived from foreign parts. Line! line! cried Queequeg, looking over the gunwale; him fast! him fast! --Who line him! Who struck? Two whale; one big, one little! What ails ye, man? cried Starbuck. Look-e here, said Queequeg pointing down. As when the stricken whale, that from the tub has reeled out hundreds of fathoms of rope; as, after deep sounding, he floats up again, and shows the slackened curling line buoyantly rising and spiralling towards the air; so now, Starbuck saw long coils of the umbilical cord of Madame Leviathan, by which the young cub seemed still tethered to its dam. Not seldom in the rapid vicissitudes of the chase, this natural line, with the maternal end loose, becomes entangled with the hempen one, so that the cub is thereby trapped. Some of the subtlest secrets of the seas ..

seemed divulged to us in this enchanted pond. We saw young Leviathan amours in the deep. And thus, though surrounded by circle upon circle of consternations and affrights, did these inscrutable creatures at the centre freely and fearlessly indulge in all peaceful concernments; yea, serenely revelled in dalliance and delight. But even so, amid the tornadoed Atlantic of my being, do I myself still for ever centrally disport in mute calm; and while ponderous planets of unwaning woe revolve round me, deep down and deep inland there i still bathe me in eternal mildness of joy. Meanwhile, as we thus lay entranced, the occasional sudden frantic spectacles in the distance evinced the activity of the other boats, still engaged in drugging the whales on the frontier of the host; or possibly carrying on the war within the first circle, where abundance of room and some convenient retreats were afforded them. But the sight of the enraged drugged whales now and then blindly darting to and fro across the circles, was nothing to what at last met our eyes. It is sometimes the custom when fast to a whale more than commonly powerful and alert, to seek to hamstring him, as it were, by sundering or maiming his gigantic tail-tendon. It is done by darting a short-handled cutting-spade, to which is attached a rope for hauling it back again. A whale wounded (as we afterwards learned) in this part, but not effectually, as it seemed, had broken away from the boat, carrying along with him half of the harpoon line; and in the extraordinary agony of the wound, he was now dashing among the revolving circles like the lone mounted desperado ..

Arnold, at the battle of Saratoga, carrying dismay wherever he went. But agonizing as was the wound of this whale, and an appalling spectacle enough, any way; yet the peculiar horror with which he seemed to inspire the rest of the herd, was owing to a cause which at first the intervening distance obscured from us. But at length we perceived that by one of the unimaginable accidents of the fishery, this whale had become entangled in the harpoon-line that he towed; he had also run away with the cutting-spade in him; and while the free end of the rope attached to that weapon, had permanently caught in the coils of the harpoon-line round his tail, the cutting-spade itself had worked loose from his flesh. So that tormented to madness, he was now churning through the water, violently flailing with his flexible tail, and tossing the keen spade about him, wounding and murdering his own comrades. this terrific object seemed to recall the whole herd from their stationary fright. First, the whales forming the margin of our lake began to crowd a little, and tumble against each other, as if lifted by half spent billows from afar; then the lake itself began faintly to heave and swell; the submarine bridal-chambers and nurseries vanished; in more and more contracting orbits the whales in the more central circles began to swim in thickening clusters. Yes, the long calm was departing. A low advancing hum was soon heard; and then like to the tumultuous masses of block-ice when the great river Hudson breaks up in Spring, the entire host of whales came tumbling upon their inner centre, as if to pile themselves up in one common mountain. Instantly Starbuck and Queequeg changed places; Starbuck taking the stern. Oars! Oars! he intensely whispered, seizing the helm -- gripe your oars, and clutch your souls, now! My God, men, stand by! Shove him off, you Queequeg --the whale there! --prick him! --hit him! Stand up --stand up, and stay so! Spring, men -- pull, men; never mind their backs --scrape them! --scrape away! The boat was now all but jammed between two vast black bulks, leaving a narrow Dardanelles between their long lengths. But by desperate endeavor we at last shot into a temporary ..

opening; then giving way rapidly, and at the same time earnestly watching for another outlet. After many similar hair-breadth escapes, we at last swiftly glided into what had just been one of the outer circles, but now crossed by random whales, all violently making for one centre. This lucky salvation was cheaply purchased by the loss of Queequeg's hat, who, while standing in the bows to prick the fugitive whales, had his hat taken clean from his head by the air-eddy made by the sudden tossing of a pair of broad flukes close by. Riotous and disordered as the universal commotion now was, it soon resolved itself into what seemed a systematic movement; for having clumped together at last in one dense body, they then renewed their onward flight with augmented fleetness. Further pursuit was useless; but the boats still lingered in their wake to pick up what drugged whales might be dropped astern, and likewise to secure one which Flask had killed and waifed. The waif is a pennoned pole, two or three of which are carried by every boat; and which, when additional game is at hand, are inserted upright into the floating body of a dead whale, both to mark its place on the sea, and also as token of prior possession, should the boats of any other ship draw near. The result of this lowering was somewhat illustrative of that sagacious saying in the Fishery, --the more whales the less fish. Of all the drugged whales only one was captured. The rest contrived to escape for the time, but only to be taken, as will hereafter be seen, by some other craft than the Pequod. ..

To gally, or gallow, is to frighten excessively --to confound with fright. It is an old Saxon word. It occurs once in Shakespeare: -- The wrathful skies Gallow the very wanderers of the dark And make them keep their caves. To common language, the word is now completely obsolete. When the polite landsman first hears it from the gaunt Nantucketer, he is apt to set it down as one of the whaleman's self-derived savageries. Much the same is it with many other sinewy Saxonisms of this sort, which emigrated to New-England rocks with the noble brawn of the old English emigrants in the time of the Commonwealth. Thus, some of the best and furthest-descended English words --the etymological Howards and Percys --are now democratised, nay, plebeianised --so to speak --in the New World. ..

The sperm whale, as with all other species of the Leviathan, but unlike most other fish, breeds indifferently at all seasons; after a gestation which may probably be set down at nine months, producing but one at a time; though in some few known instances giving birth to an Esau and Jacob: -- a contingency provided for in suckling by two teats, curiously situated, one on each side of the anus; but the breasts themselves extend upwards from that. When by chance these precious parts in a nursing whale are cut by the hunter's lance, the mother's pouring milk and blood rivallingly discolor the sea for rods. The milk is very sweet and rich; it has been tasted by man; it might do well with strawberries. When overflowing with mutual esteem, the whales salute more hominum. ..

.. < chapter lxxxviii 28 SCHOOLS AND SCHOOLMASTERS > The previous chapter gave account of an immense body or herd of Sperm Whales, and there was also then given the probable cause inducing those vast aggregations. Now, though such great bodies are at times encountered, yet, ..

as must have been seen, even at the present day, small detached bands are occasionally observed, embracing from twenty to fifty individuals each. Such bands are known as schools. They generally are of two sorts; those composed almost entirely of females, and those mustering none but young vigorous males, or bulls, as they are familiarly designated. In cavalier attendance upon the school of females, you invariably see a male of full grown magnitude, but not old; who, upon any alarm, evinces his gallantry by falling in the rear and covering the flight of his ladies. In truth, this gentleman is a luxurious Ottoman, swimming about over the watery world, surroundingly accompanied by all the solaces and endearments of the harem. The contrast between this Ottoman and his concubines is striking; because, while he is always of the largest leviathanic proportions, the ladies, even at full growth, are not more than one third of the bulk of an average-sized male. They are comparatively delicate, indeed; I dare say, not to exceed half a dozen yards round the waist. Nevertheless, it cannot be denied, that upon the whole they are hereditarily entitled to en bon point. It is very curious to watch this harem and its lord in their indolent ramblings. Like fashionables, they are for ever on the move in leisurely search of variety. You meet them on the Line in time for the full flower of the Equatorial feeding season, having just returned, perhaps, from spending the summer in the Northern seas, and so cheating summer of all unpleasant weariness and warmth. By the time they have lounged up and down the promenade of the Equator awhile, they start for the Oriental waters in anticipation of the cool season there, and so evade the other excessive temperature of the year. When serenely advancing on one of these journeys, if any strange suspicious sights are seen, my lord whale keeps a wary eye on his interesting family. Should any unwarrantably pert young Leviathan coming that way, presume to draw confidentially close to one of the ladies, with what prodigious fury the Bashaw assails him, and chases him away! High times, indeed, if unprincipled young rakes like him are to be permitted to invade the sanctity of domestic bliss; though do what the Bashaw will, he cannot keep the most notorious Lothario out ..

of his bed; for, alas! all fish bed in common. As ashore, the ladies often cause the most terrible duels among their rival admirers; just so with the whales, who sometimes come to deadly battle, and all for love. They fence with their long lower jaws, sometimes locking them together, and so striving for the supremacy like elks that warringly interweave their antlers. Not a few are captured having the deep scars of these encounters, --furrowed heads, broken teeth, scolloped fins; and in some instances, wrenched and dislocated mouths. but supposing the invader of domestic bliss to betake himself away at the first rush of the harem's lord, then is it very diverting to watch that lord. Gently he insinuates his vast bulk among them again and revels there awhile, still in tantalizing vicinity to young Lothario, like pious Solomon devoutly worshipping among his thousand concubines. Granting other whales to be in sight, the fishermen will seldom give chase to one of these Grand Turks; for these Grand Turks are too lavish of their strength, and hence their unctuousness is small. As for the sons and the daughters they beget, why, those sons and daughters must take care of themselves; at least, with only the maternal help. For like certain other omnivorous roving lovers that might be named, my Lord Whale has no taste for the nursery, however much for the bower; and so, being a great traveller, he leaves his anonymous babies all over the world; every baby an exotic. In good time, nevertheless, as the ardor of youth declines; as years and dumps increase; as reflection lends her solemn pauses; in short, as a general lassitude overtakes the sated Turk; then a love of ease and virtue supplants the love for maidens; our Ottoman enters upon the impotent, repentant, admonitory stage of life, forswears, disbands the harem, and grown to an exemplary, sulky old soul, goes about all alone among the meridians and parallels saying his prayers, and warning each young Leviathan from his amorous errors. Now, as the harem of whales is called by the fishermen a school, so is the lord and master of that school technically known as the schoolmaster. It is therefore not in strict character, however admirably satirical, that after going to school himself, he should then go abroad inculcating not what he learned there, but the folly of it. His title, schoolmaster, would very naturally ..

seem derived from the name bestowed upon the harem itself, but some have surmised that the man who first thus entitled this sort of Ottoman whale, must have read the memoirs of Vidocq, and informed himself what sort of a country-schoolmaster that famous Frenchman was in his younger days, and what was the nature of those occult lessons he inculcated into some of his pupils. The same secludedness and isolation to which the schoolmaster whale betakes himself in his advancing years, is true of all aged Sperm Whales. Almost universally, a lone whale --as a solitary Leviathan is called --proves an ancient one. Like venerable moss-bearded Daniel Boone, he will have no one near him but Nature herself; and her he takes to wife in the wilderness of waters, and the best of wives she is, though she keeps so many moody secrets. The schools composing none but young and vigorous males, previously mentioned, offer a strong contrast to the harem schools. For while those female whales are characteristically timid, the young males, or forty-barrel-bulls, as they call them, are by far the most pugnacious of all Leviathans, and proverbially the most dangerous to encounter; excepting those wondrous grey-headed, grizzled whales, sometimes met, and these will fight you like grim fiends exasperated by a penal gout. The Forty-barrel-bull schools are larger than the harem schools. Like a mob of young collegians, they are full of fight, fun, and wickedness, tumbling round the world at such a reckless, rollicking rate, that no prudent underwriter would insure them any more than he would a riotous lad at Yale or Harvard. They soon relinquish this turbulence though, and when about three fourths grown, break up, and separately go about in quest of settlements, that is, harems. Another point of difference between the male and female schools is still more characteristic of the sexes. Say you strike a Forty-barrel-bull --poor devil! all his comrades quit him. But strike a member of the harem school, and her companions swim around her with every token of concern, sometimes lingering so near her and so long, as themselves to fall a prey. ..

.. < chapter lxxxix 2 FAST-FISH AND LOOSE-FISH > The allusion to the waifs and waif-poles in the last chapter but one, necessitates some account of the laws and regulations of the whale fishery, of which the waif may be deemed the grand symbol and badge. It frequently happens that when several ships are cruising in company, a whale may be struck by one vessel, then escape, and be finally killed and captured by another vessel; and herein are indirectly comprised many minor contingencies, all partaking of this one grand feature. For example, --after a weary and perilous chase and capture of a whale, the body may get loose from the ship by reason of a violent storm; and drifting far away to leeward, be retaken by a second whaler, who, in a calm, snugly tows it alongside, without risk of life or line. Thus the most vexatious and violent disputes would often arise between the fishermen, were there not some written or unwritten, universal, undisputed law applicable to all cases. Perhaps the only formal whaling code authorized by legislative enactment, was that of Holland. It was decreed by the States-General in A. D. . But though no other nation has ever had any written whaling law, yet the American fishermen have been their own legislators and lawyers in this matter. They have provided a system which for terse comprehensiveness surpasses Justinian's Pandects and the By-laws of the Chinese Society for the Suppression of Meddling with other People's Business. Yes; these laws might be engraven on a Queen Anne's farthing, or the barb of a harpoon, and worn round the neck, so small are they. I. A Fast-Fish belongs to the party fast to it. II. A Loose-Fish is fair game for anybody who can soonest catch it. But what plays the mischief with this masterly code is the ..

admirable brevity of it, which necessitates a vast volume of commentaries to expound it. First: What is a Fast-Fish? Alive or dead a fish is technically fast, when it is connected with an occupied ship or boat, by any medium at all controllable by the occupant or occupants, -- a mast, an oar, a nine-inch cable, a telegraph wire, or a strand of cobweb, it is all the same. Likewise a fish is technically fast when it bears a waif, or any other recognised symbol of possession; so long as the party waifing it plainly evince their ability at any time to take it alongside, as well as their intention so to do. These are scientific commentaries; but the commentaries of the whalemen themselves sometimes consist in hard words and harder knocks --the Coke-upon-Littleton of the fist. True, among the more upright and honorable whalemen allowances are always made for peculiar cases, where it would be an outrageous moral injustice for one party to claim possession of a whale previously chased or killed by another party. But others are by no means so scrupulous. Some fifty years ago there was a curious case of whale-trover litigated in England, wherein the plaintiffs set forth that after a hard chase of a whale in the Northern seas; and when indeed they (the plaintiffs) had succeeded in harpooning the fish; they were at last, through peril of their lives, obliged to forsake not only their lines, but their boat itself. Ultimately the defendants (the crew of another ship) came up with the whale, struck, killed, seized, and finally appropriated it before the very eyes of the plaintiffs. And when those defendants were remonstrated with, their captain snapped his fingers in the plaintiffs' teeth, and assured them that by way of doxology to the deed he had done, he would now retain their line, harpoons, and boat, which had remained attached to the whale at the time of the seizure. Wherefore the plaintiffs now sued for the recovery of the value of their whale, line, harpoons, and boat. Mr. Erskine was counsel for the defendants; Lord Ellenborough was the judge. In the course of the defence, the witty Erskine went on to illustrate his position, by alluding to a recent crim. con. case, wherein a gentleman, after in vain trying to bridle his wife's viciousness, had at last abandoned her upon ..

the seas of life; but in the course of years, repenting of that step, he instituted an action to recover possession of her. Erskine was on the other side; and he then supported it by saying, that though the gentleman had originally harpooned the lady, and had once had her fast, and only by reason of the great stress of her plunging viciousness, had as last abandoned her; yet abandon her he did, so that she became a loose-fish; and therefore when a subsequent gentleman re-harpooned her, the lady then became that subsequent gentleman's property, along with whatever harpoon might have been found sticking in her. Now in the present case Erskine contended that the examples of the whale and the lady were reciprocally illustrative of each other. These pleadings, and the counter pleadings, being duly heard, the very learned judge in set terms decided, to wit, --That as for the boat, he awarded it to the plaintiffs, because they had merely abandoned it to save their lives; but that with regard to the controverted whale, harpoons, and line, they belonged to the defendants; the whale, because it was a Loose-Fish at the time of the final capture; and the harpoons and line because when the fish made off with them, it (the fish) acquired a property in those articles; and hence anybody who afterwards took the fish had a right to them. Now the defendants afterwards took the fish; ergo, the aforesaid articles were theirs. A common man looking at this decision of the very learned Judge, might possibly object to it. But ploughed up to the primary rock of the matter, the two great principles laid down in the twin whaling laws previously quoted, and applied and elucidated by Lord Ellenborough in the above cited case; these two laws touching Fast-Fish and Loose-Fish, I say, will, on reflection, be found the fundamentals of all human jurisprudence; For notwithstanding its complicated tracery of sculpture, the Temple of the Law, like the Temple of the Philistines, has but two props to stand on. Is it not a saying in every one's mouth, Possession is half of the law: that is, regardless of how the thing came into possession? But often possession is the whole of the law. What are the sinews and souls of Russian serfs and Republican slaves ..

but Fast-Fish, whereof possession is the whole of the law? What to the rapacious landlord is the widow's last mite but a Fast-Fish? What is yonder undetected villain's marble mansion with a door-plate for a waif; what is that but a Fast-Fish? What is the ruinous discount which Mordecai, the broker, gets from poor Woebegone, the bankrupt, on a loan to keep Woebegone's family from starvation; what is that ruinous discount but a Fast-Fish? What is the archbishop of Savesoul's income of 100,000 pounds seized from the scant bread and cheese of hundreds of thousands of broken-backed laborers (all sure of heaven without any of Savesoul's help) what is that globular 100,000 but a Fast-Fish? What are the Duke of Dunder's hereditary towns and hamlets but Fast-Fish? What to that redoubted harpooneer, John Bull, is poor Ireland, but a Fast-Fish? What to that apostolic lancer, Brother Jonathan, is Texas but a Fast-Fish? And concerning all these, is not Possession the whole of the law? But if the doctrine of Fast-Fish be pretty generally applicable, the kindred doctrine of Loose-Fish is still more widely so. That is internationally and universally applicable. What was America in but a loose-fish, in which Columbus struck the Spanish standard by way of waifing it for his royal master and mistress? What was Poland to the Czar? What Greece to the Turk? What India to England? What at last will Mexico be to the United States? All Loose-Fish. What are the Rights of Man and the Liberties of the World but Loose-Fish? What all men's minds and opinions but Loose-Fish? What is the principle of religious belief in them but a Loose-Fish? What to the ostentatious smuggling verbalists are the thoughts of thinkers but Loose-Fish? What is the great globe itself but a Loose-Fish? And what are you, reader, but a Loose-Fish and a Fast-Fish, too? ..

.. < chapter xc 2 HEADS OR TAILS > De balena vero sufficit, si rex habeat caput, et regina caudam. Bracton, l 3. c. 3. Latin from the books of the Laws of England, which taken along with the context, means, that of all whales captured by anybody on the coast of that land, the King, as Honorary Grand Harpooneer, must have the head, and the Queen be respectfully presented with the tail. A division which, in the whale, is much like halving an apple; there is no intermediate remainder. Now as this law, under a modified form, is to this day in force in England; and as it offers in various respects a strange anomaly touching the general law of Fast and Loose-Fish, it is here treated of in a separate chapter, on the same courteous principle that prompts the English railways to be at the expense of a separate car, specially reserved for the accommodation of royalty. In the first place, in curious proof of the fact that the above-mentioned law is still in force, I proceed to lay before you a circumstance that happened within the last two years. It seems that some honest mariners of Dover, or Sandwich, or some one of the Cinque Ports, had after a hard chase succeeded in killing and beaching a fine whale which they had originally descried afar off from the shore. Now the Cinque Ports are partially or somehow under the jurisdiction of a sort of policeman or beadle, called a Lord Warden. Holding the office directly from the crown, I believe, all the royal emoluments incident to the Cinque Port territories become by assignment his. By some writers this office is called a sinecure. But not so. Because the Lord Warden is busily employed at times in fobbing his perquisites; which are his chiefly by virtue of that same fobbing of them. Now when these poor sun-burnt mariners, bare-footed, and ..

with their trowsers rolled high up on their eely legs, had wearily hauled their fat fish high and dry, promising themselves a good 150 pounds from the precious oil and bone; and in fantasy sipping rare tea with their wives, and good ale with their cronies, upon the strength of their respective shares; up steps a very learned and most Christian and charitable gentleman, with a copy of Blackstone under his arm; and laying it upon the whale's head, he says -- Hands off! this fish, my masters, is a Fast-Fish. I seize it as the Lord Warden's. Upon this the poor mariners in their respectful consternation --so truly English --knowing not what to say, fall to vigorously scratching their heads all round; meanwhile ruefully glancing from the whale to the stranger. But that did in nowise mend the matter, or at all soften the hard heart of the learned gentleman with the copy of Blackstone. At length one of them, after long scratching about for his ideas, made bold to speak. Please, sir, who is the Lord Warden? The Duke. But the duke had nothing to do with taking this fish? It is his. We have been at great trouble, and peril, and some expense, and is all that to go to the Duke's benefit; we getting nothing at all for our pains but our blisters? It is his. Is the duke so very poor as to be forced to this desperate mode of getting a livelihood? It is his. I thought to relieve my old bed-ridden mother by part of my share of this whale. It is his. Won't the Duke be content with a quarter or a half? It is his. In a word, the whale was seized and sold, and his Grace the Duke of Wellington received the money. Thinking that viewed in some particular lights, the case might by a bare possibility in some small degree be deemed, under the circumstances, a rather hard one, an honest clergyman of the town respectfully addressed a note to his Grace, begging him to take the case of those unfortunate ..

mariners into full consideration. To which my Lord Duke in substance replied (both letters were published) that he had already done so, and received the money, and would be obliged to the reverend gentleman if for the future he (the reverend gentleman) would decline meddling with other people's business. Is this the still militant old man, standing at the corners of the three kingdoms, on all hands coercing alms of beggars? It will readily be seen that in this case the alleged right of the Duke to the whale was a delegated one from the Sovereign. We must needs inquire then on what principle the Sovereign is originally invested with that right. The law itself has already been set forth. But Plowdon gives us the reason for it. Says Plowdon, the whale so caught belongs to the King and Queen, because of its superior excellence. And by the soundest commentators this has ever been held a cogent argument in such matters. But why should the King have the head, and the Queen the tail? A reason for that, ye lawyers! In his treatise on Queen-Gold, or Queen-pinmoney, an old King's Bench author, one William Prynne, thus discourseth: Ye tail is ye Queen's, that ye Queen's wardrobe may be supplied with ye whalebone. Now this was written at a time when the black limber bone of the Greenland or Right whale was largely used in ladies' bodices. But this same bone is not in the tail; it is in the head, which is a sad mistake for a sagacious lawyer like Prynne. But is the Queen a mermaid, to be presented with a tail? An allegorical meaning may lurk here. There are two royal fish so styled by the English law writers -- the whale and the sturgeon; both royal property under certain limitations, and nominally supplying the tenth branch of the crown's ordinary revenue. I know not that any other author has hinted of the matter; but by inference it seems to me that the sturgeon must be divided in the same way as the whale, the King receiving the highly dense and elastic head peculiar to that fish, which, symbolically regarded, may possibly be humorously grounded upon some presumed congeniality. And thus there seems a reason in all things, even in law. ..

.. < chapter xci 2 THE PEQUOD MEETS THE ROSE-BUD > In vain it was to rake for Ambergriese in the paunch of this Leviathan, insufferable fetor denying not inquiry. Sir T. Browne, V. E. It was a week or two after the last whaling scene recounted, and when we were slowly sailing over a sleepy, vapory, mid-day sea, that the many noses on the Pequod's deck proved more vigilant discoverers than the three pairs of eyes aloft. A peculiar and not very pleasant smell was smelt in the sea. I will bet something now, said Stubb, that somewhere hereabouts are some of those drugged whales we tickled the other day. I thought they would keel up before long. Presently, the vapors in advance slid aside; and there in the distance lay a ship, whose furled sails betokened that some sort of whale must be alongside. As we glided nearer, the stranger showed French colors from his peak; and by the eddying cloud of vulture sea-fowl that circled, and hovered, and swooped around him, it was plain that the whale alongside must be what the fishermen call a blasted whale, that is, a whale that has died unmolested on the sea, and so floated an unappropriated corpse. It may well be conceived, what an unsavory odor such a mass must exhale; worse than an Assyrian city in the plague, when the living are incompetent to bury the departed. So intolerable indeed is it regarded by some, that no cupidity could persuade them to moor alongside of it. Yet are there those who will still do it; notwithstanding the fact that the oil obtained from such subjects is of a very inferior quality, and by no means of the nature of attar-of-rose. Coming still nearer with the expiring breeze, we saw that the Frenchman had a second whale alongside; and this second whale seemed even more of a nosegay than the first. In truth, it turned out to be one of those problematical whales that seem ..

to dry up and die with a sort of prodigious dyspepsia, or indigestion; leaving their defunct bodies almost entirely bankrupt of anything like oil. Nevertheless, in the proper place we shall see that no knowing fisherman will ever turn up his nose at such a whale as this, however much he may shun blasted whales in general. The Pequod had now swept so nigh to the stranger, that Stubb vowed he recognized his cutting spade-pole entangled in the lines that were knotted round the tail of one of these whales. There's a pretty fellow, now, he banteringly laughed, standing in the ship's bows, there's a jackal for ye! I well know that these Crappoes of Frenchmen are but poor devils in the fishery; sometimes lowering their boats for breakers, mistaking them for Sperm Whale spouts; yes, and sometimes sailing from their port with their hold full of boxes of tallow candles, and cases of snuffers, foreseeing that all the oil they will get won't be enough to dip the Captain's wick into; aye, we all know these things; but look ye, here's a Crappo that is content with our leavings, the drugged whale there, I mean; aye, and is content too with scraping the dry bones of that other precious fish he has there. Poor devil! I say, pass round a hat, some one, and let's make him a present of a little oil for dear charity's sake. For what oil he'll get from that drugged whale there, wouldn't be fit to burn in a jail; no, not in a condemned cell. And as for the other whale, why, I'll agree to get more oil by chopping up and trying out these three masts of ours, than he'll get from that bundle of bones; though, now that I think of it, it may contain something worth a good deal more than oil; yes, ambergris. I wonder now if our old man has thought of that. It's worth trying. Yes, I'm for it; and so saying he started for the quarter-deck. By this time the faint air had become a complete calm; so that whether or no, the Pequod was now fairly entrapped in the smell, with no hope of escaping except by its breezing up again. Issuing from the cabin, Stubb now called his boat's crew, and pulled off for the stranger. Drawing across her bow, he perceived that in accordance with the fanciful French taste, the upper part of her stem-piece was carved in the likeness of a ..

huge drooping stalk, was painted green, and for thorns had copper spikes projecting from it here and there; the whole terminating in a symmetrical folded bulb of a bright red color. Upon her head boards, in large gilt letters, he read Bouton de Rose, --Rose-button, or Rose-bud; and this was the romantic name of this aromatic ship. Though Stubb did not understand the Bouton part of the inscription, yet the word rose, and the bulbous figure-head put together, sufficiently explained the whole to him. A wooden rose-bud, eh? he cried with his hand to his nose, that will do very well; but how like all creation it smells! Now in order to hold direct communication with the people on deck, he had to pull round the bows to the starboard side, and thus come close to the blasted whale; and so talk over it. Arrived then at this spot, with one hand still to his nose, he bawled -- Bouton-de-Rose, ahoy! are there any of you Bouton-de-Roses that speak English? Yes, rejoined a Guernsey-man from the bulwarks, who turned out to be the chief-mate. Well, then, my Bouton-de-Rose-bud, have you seen the White Whale? What whale? The White Whale --a Sperm Whale --Moby Dick, have ye seen him? Never heard of such a whale. Cachalot Blanche! White Whale --no. Very good, then; good bye now, and I'll call again in a minute. Then rapidly pulling back towards the Pequod, and seeing Ahab leaning over the quarter-deck rail awaiting his report, he moulded his two hands into a trumpet and shouted -- No, Sir! No! Upon which Ahab retired, and Stubb returned to the Frenchman. He now perceived that the Guernsey-man, who had just got into the chains, and was using a cutting-spade, had slung his nose in a sort of bag. What's the matter with your nose, there? said Stubb. Broke it? ..

I wish it was broken, or that I didn't have any nose at all! answered the Guernsey-man, who did not seem to relish the job he was at very much. But what are you holding yours for? Oh, nothing! It's a wax nose; I have to hold it on. Fine day, aint it? Air rather gardenny, I should say; throw us a bunch of posies, will ye, Bouton-de-Rose? What in the devil's name do you want here? roared the Guernsey-man, flying into a sudden passion. Oh! keep cool--cool? yes, that's the word; why don't you pack those whales in ice while you're working at 'em? But joking aside, though; do you know, Rose-bud, that it's all nonsense trying to get any oil out of such whales? As for that dried up one, there, he hasn't a gill in his whole carcase. I know that well enough; but, d'ye see, the Captain here won't believe it; this is his first voyage; he was a Cologne manufacturer before. But come aboard, and mayhap he'll believe you, if he won't me; and so I'll get out of this dirty scrape. Anything to oblige ye, my sweet and pleasant fellow, rejoined Stubb, and with that he soon mounted to the deck. There a queer scene presented itself. The sailors, in tasselled caps of red worsted, were getting the heavy tackles in readiness for the whales. But they worked rather slow and talked very fast, and seemed in anything but a good humor. All their noses upwardly projected from their faces like so many jib-booms. Now and then pairs of them would drop their work, and run up to the mast-head to get some fresh air. Some thinking they would catch the plague, dipped oakum in coal-tar, and at intervals held it to their nostrils. Others having broken the stems of their pipes almost short off at the bowl, were vigorously puffing tobacco-smoke, so that it constantly filled their olfactories. Stubb was struck by a shower of outcries and anathemas proceeding from the Captain's round-house abaft; and looking in that direction saw a fiery face thrust from behind the door, which was held ajar from within. This was the tormented surgeon, who, after in vain remonstrating against the proceedings of the day, had betaken himself to the Captain's round-house ( cabinet he called it) to avoid the pest; but still, could not help yelling out his entreaties and indignations at times. ..

Marking all this, Stubb argued well for his scheme, and turning to the Guernsey-man had a little chat with him, during which the stranger mate expressed his detestation of his Captain as a conceited ignoramus, who had brought them all into so unsavory and unprofitable a pickle. Sounding him carefully, Stubb further perceived that the Guernsey-man had not the slightest suspicion concerning the ambergris. He therefore held his peace on that head, but otherwise was quite frank and confidential with him, so that the two quickly concocted a little plan for both circumventing and satirizing the Captain, without his at all dreaming of distrusting their sincerity. According to this little plan of theirs, the Guernsey-man, under cover of an interpreter's office, was to tell the Captain what he pleased, but as coming from Stubb; and as for Stubb, he was to utter any nonsense that should come uppermost in him during the interview. By this time their destined victim appeared from his cabin. He was a small and dark, but rather delicate looking man for a sea-captain, with large whiskers and moustache, however; and wore a red cotton velvet vest with watch-seals at his side. To this gentleman, Stubb was now politely introduced by the Guernsey-man, who at once ostentatiously put on the aspect of interpreting between them. What shall I say to him first? said he. Why, said Stubb, eyeing the velvet vest and the watch and seals, you may as well begin by telling him that he looks a sort of babyish to me, though I don't pretend to be a judge. He says, Monsieur, said the Guernsey-man, in French, turning to his captain, that only yesterday his ship spoke a vessel, whose captain and chief-mate, with six sailors, had all died of a fever caught from a blasted whale they had brought alongside. Upon this the captain started, and eagerly desired to know more. What now? said the Guernsey-man to Stubb. Why, since he takes it so easy, tell him that now I have eyed him carefully, I'm quite certain that he's no more fit to command a whale-ship than a St. Jago monkey. In fact, tell him from me he's a baboon. ..

He vows and declares, Monsieur, that the other whale, the dried one, is far more deadly than the blasted one; in fine, Monsieur, he conjures us, as we value our lives, to cut loose from these fish. Instantly the captain ran forward, and in a loud voice commanded his crew to desist from hoisting the cutting-tackles, and at once cast loose the cables and chains confining the whales to the ship. What now? said the Guernsey-man, when the captain had returned to them. Why, let me see; yes, you may as well tell him now that -- that --in fact, tell him I've diddled him, and (aside to himself) perhaps somebody else. He says, Monsieur, that he's very happy to have been of any service to us. Hearing this, the captain vowed that they were the grateful parties (meaning himself and mate) and concluded by inviting Stubb down into his cabin to drink a bottle of Bordeaux. He wants you to take a glass of wine with him, said the interpreter. Thank him heartily; but tell him it's against my principles to drink with the man I've diddled. In fact, tell him I must go. He says, Monsieur, that his principles won't admit of his drinking; but that if Monsieur wants to live another day to drink, then Monsieur had best drop all four boats, and pull the ship away from these whales, for it's so calm they won't drift. By this time Stubb was over the side, and getting into his boat, hailed the Guernsey-man to this effect, --that having a long tow-line in his boat, he would do what he could to help them, by pulling out the lighter whale of the two from the ship's side. While the Frenchman's boats, then, were engaged in towing the ship one way, Stubb benevolently towed away at his whale the other way, ostentatiously slacking out a most unusually long tow-line. Presently a breeze sprang up; Stubb feigned to cast off from the whale; hoisting his boats, the Frenchman soon increased his distance, while the Pequod slid in between him and Stubb's whale. Whereupon Stubb quickly pulled to the floating body, ..

and hailing the pequod to give notice of his intentions, at once proceeded to reap the fruit of his unrighteous cunning. Seizing his sharp boat-spade, he commenced an excavation in the body, a little behind the side fin. You would almost have thought he was digging a cellar there in the sea; and when at length his spade struck against the gaunt ribs, it was like turning up old Roman tiles and pottery buried in fat English loam. His boat's crew were all in high excitement, eagerly helping their chief, and looking as anxious as gold-hunters. And all the time numberless fowls were diving, and ducking, and screaming, and yelling, and fighting around them. Stubb was beginning to look disappointed, especially as the horrible nosegay increased, when suddenly from out the very heart of this plague, there stole a faint stream of perfume, which flowed through the tide of bad smells without being absorbed by it, as one river will flow into and then along with another, without at all blending with it for a time. I have it, I have it, cried Stubb, with delight, striking something in the subterranean regions, a purse! a purse! Dropping his spade, he thrust both hands in, and drew out handfuls of something that looked like ripe Windsor soap, or rich mottled old cheese; very unctuous and savory withal. You might easily dent it with your thumb; it is of a hue between yellow and ash color. And this, good friends, is ambergris, worth a gold guinea an ounce to any druggist. Some six handfuls were obtained; but more was unavoidably lost in the sea, and still more, perhaps, might have been secured were it not for impatient Ahab's loud command to Stubb to desist, and come on board, else the ship would bid them good bye. ..

.. < chapter xcii 31 AMBERGRIS > Now this ambergris is a very curious substance, and so important as an article of commerce, that in a certain Nantucket-born ..

Captain Coffin was examined at the bar of the English House of Commons on that subject. for at that time, and indeed until a comparatively late day, the precise origin of ambergris remained, like amber itself, a problem to the learned. Though the word ambergris is but the French compound for grey amber, yet the two substances are quite distinct. For amber, though at times found on the sea-coast, is also dug up in some far inland soils, whereas ambergris is never found except upon the sea. Besides, amber is a hard, transparent, brittle, odorless substance, used for mouth-pieces to pipes, for beads and ornaments; but ambergris is soft, waxy, and so highly fragrant and spicy, that it is largely used in perfumery, in pastiles, precious candles, hair-powders, and pomatum. The Turks use it in cooking, and also carry it to Mecca, for the same purpose that frankincense is carried to St. Peter's in Rome. Some wine merchants drop a few grains into claret, to flavor it. Who would think, then, that such fine ladies and gentlemen should regale themselves with an essence found in the inglorious bowels of a sick whale! Yet so it is. By some, ambergris is supposed to be the cause, and by others the effect, of the dyspepsia in the whale. How to cure such a dyspepsia it were hard to say, unless by administering three or four boat loads of Brandreth's pills, and then running out of harm's way, as laborers do in blasting rocks. I have forgotten to say that there were found in this ambergris, certain hard, round, bony plates, which at first Stubb thought might be sailors' trousers buttons; but it afterwards turned out that they were nothing more than pieces of small squid bones embalmed in that manner. Now that the incorruption of this most fragrant ambergris should be found in the heart of such decay; is this nothing? Bethink thee of that saying of St. Paul in Corinthians, about corruption and incorruption; how that we are sown in dishonor, but raised in glory. And likewise call to mind that saying of paracelsus about what it is that maketh the best musk. Also forget not the strange fact that of all things of ill-savor, Cologne-water, in its rudimental manufacturing stages, is the worst. I should like to conclude the chapter with the above appeal, but cannot, owing to my anxiety to repel a charge often made ..

against whalemen, and which, in the estimation of some already biased minds, might be considered as indirectly substantiated by what has been said of the Frenchman's two whales. Elsewhere in this volume the slanderous aspersion has been disproved, that the vocation of whaling is throughout a slatternly, untidy business. But there is another thing to rebut. They hint that all whales always smell bad. Now how did this odious stigma originate? I opine, that it is plainly traceable to the first arrival of the Greenland whaling ships in London, more than two centuries ago. Because those whalemen did not then, and do not now, try out their oil at sea as the Southern ships have always done; but cutting up the fresh blubber in small bits, thrust it through the bung holes of large casks, and carry it home in that manner; the shortness of the season in those Icy Seas, and the sudden and violent storms to which they are exposed, forbidding any other course. The consequence is, that upon breaking into the hold, and unloading one of these whale cemeteries, in the Greenland dock, a savor is given forth somewhat similar to that arising from excavating an old city grave-yard, for the foundations of a Lying-in Hospital. I partly surmise also, that this wicked charge against whalers may be likewise imputed to the existence on the coast of Greenland, in former times, of a Dutch village called Schmerenburgh or Smeerenberg, which latter name is the one used by the learned Fogo Von Slack, in his great work on Smells, a textbook on that subject. As its name imports (smeer, fat; berg, to put up), this village was founded in order to afford a place for the blubber of the dutch whale fleet to be tried out, without being taken home to Holland for that purpose. It was a collection of furnaces, fat-kettles, and oil sheds; and when the works were in full operation certainly gave forth no very pleasant savor. But all this is quite different from a South Sea Sperm Whaler; which in a voyage of four years perhaps, after completely filling her hold with oil, does not, perhaps, consume fifty days in the business of boiling out; and in the state that it is casked, the oil is nearly scentless. The truth is, that living or dead, if but decently treated, whales as a species are by no ..

means creatures of ill odor; nor can whalemen be recognised, as the people of the middle ages affected to detect a Jew in the company, by the nose. Nor indeed can the whale possibly be otherwise than fragrant, when, as a general thing, he enjoys such high health; taking abundance of exercise; always out of doors; though, it is true, seldom in the open air. I say, that the motion of a Sperm Whale's flukes above water dispenses a perfume, as when a musk-scented lady rustles her dress in a warm parlor. What then shall I liken the Sperm Whale to for fragrance, considering his magnitude? Must it not be to that famous elephant, with jewelled tusks, and redolent with myrrh, which was led out of an Indian town to do honor to Alexander the Great? ..

.. < chapter xciii 15 THE CASTAWAY > It was but some few days after encountering the Frenchman, that a most significant event befell the most insignificant of the Pequod's crew; an event most lamentable; and which ended in providing the sometimes madly merry and predestinated craft with a living and ever accompanying prophecy of whatever shattered sequel might prove her own. Now, in the whale ship, it is not every one that goes in the boats. Some few hands are reserved called ship-keepers, whose province it is to work the vessel while the boats are pursuing the whale. As a general thing, these ship-keepers are as hardy fellows as the men comprising the boats' crews. But if there happen to be an unduly slender, clumsy, or timorous wight in the ship, that wight is certain to be made a ship-keeper. It was so in the Pequod with the little negro Pippin by nick-name, Pip by abbreviation. Poor Pip! ye have heard of him before; ye must remember his tambourine on that dramatic midnight, so gloomy-jolly. ..

In outer aspect, Pip and Dough-Boy made a match, like a black pony and a white one, of equal developments, though of dissimilar color, driven in one eccentric span. But while hapless Dough-Boy was by nature dull and torpid in his intellects, Pip, though over tender-hearted, was at bottom very bright, with that pleasant, genial, jolly brightness peculiar to his tribe; a tribe, which ever enjoy all holidays and festivities with finer, freer relish than any other race. For blacks, the year's calendar should show naught but three hundred and sixty-five Fourth of Julys and New Year's Days. Nor smile so, while I write that this little black was brilliant, for even blackness has its brilliancy; behold yon lustrous ebony, panelled in king's cabinets. But Pip loved life, and all life's peaceable securities; so that the panic-striking business in which he had somehow unaccountably become entrapped, had most sadly blurred his brightness; though, as ere long will be seen, what was thus temporarily subdued in him, in the end was destined to be luridly illumined by strange wild fires, that fictitiously showed him off to ten times the natural lustre with which in his native Tolland County in Connecticut, he had once enlivened many a fiddler's frolic on the green; and at melodious even-tide, with his gay ha-ha! had turned the round horizon into one star-belled tambourine. So, though in the clear air of day, suspended against a blue-veined neck, the pure-watered diamond drop will healthful glow; yet, when the cunning jeweller would show you the diamond in its most impressive lustre, he lays it against a gloomy ground, and then lights it up, not by the sun, but by some unnatural gases. Then come out those fiery effulgences, infernally superb; then the evil-blazing diamond, once the divinest symbol of the crystal skies, looks like some crown-jewel stolen from the King of Hell. But let us to the story. It came to pass, that in the ambergris affair Stubb's after-oarsman chanced so to sprain his hand, as for a time to become quite maimed; and, temporarily, Pip was put into his place. The first time Stubb lowered with him, Pip evinced much nervousness; but happily, for that time, escaped close contact with the whale; and therefore came off not altogether discreditably; though Stubb observing him, took care, afterwards, ..

to exhort him to cherish his courageousness to the utmost, for he might often find it needful. Now upon the second lowering, the boat paddled upon the whale; and as the fish received the darted iron, it gave its customary rap, which happened, in this instance, to be right under poor Pip's seat. The involuntary consternation of the moment caused him to leap, paddle in hand, out of the boat; and in such a way, that part of the slack whale line coming against his chest, he breasted it overboard with him, so as to become entangled in it, when at last plumping into the water. That instant the stricken whale started on a fierce run, the line swiftly straightened; and presto! poor Pip came all foaming up to the chocks of the boat, remorselessly dragged there by the line, which had taken several turns around his chest and neck. Tashtego stood in the bows. He was full of the fire of the hunt. He hated Pip for a poltroon. Snatching the boat-knife from its sheath, he suspended its sharp edge over the line, and turning towards Stubb, exclaimed interrogatively, cut? meantime pip's blue, choked face plainly looked, Do, for God's sake! All passed in a flash. In less than half a minute, this entire thing happened. Damn him, cut! roared Stubb; and so the whale was lost and Pip was saved. So soon as he recovered himself, the poor little negro was assailed by yells and execrations from the crew. Tranquilly permitting these irregular cursings to evaporate, Stubb then in a plain, business-like, but still half humorous manner, cursed Pip officially; and that done, unofficially gave him much wholesome advice. The substance was, Never jump from a boat, Pip, except --but all the rest was indefinite, as the soundest advice ever is. Now, in general, Stick to the boat, is your true motto in whaling; but cases will sometimes happen when Leap from the boat, is still better. Moreover, as if perceiving at last that if he should give undiluted conscientious advice to Pip, he would be leaving him too wide a margin to jump in for the future; Stubb suddenly dropped all advice, and concluded with a peremptory command, Stick to the boat, Pip, or by the Lord, I wont pick you up if you jump; mind that. We can't afford ..

to lose whales by the likes of you; a whale would sell for thirty times what you would, Pip, in Alabama. Bear that in mind, and don't jump any more. Hereby perhaps Stubb indirectly hinted, that though man loved his fellow, yet man is a money-making animal, which propensity too often interferes with his benevolence. But we are all in the hands of the Gods; and Pip jumped again. It was under very similar circumstances to the first performance; but this time he did not breast out the line; and hence, when the whale started to run, Pip was left behind on the sea, like a hurried traveller's trunk. Alas! Stubb was but too true to his word. It was a beautiful, bounteous, blue day; the spangled sea calm and cool, and flatly stretching away, all round, to the horizon, like gold-beater's skin hammered out to the extremest. Bobbing up and down in that sea, Pip's ebon head showed like a head of cloves. No boat-knife was lifted when he fell so rapidly astern. Stubb's inexorable back was turned upon him; and the whale was winged. In three minutes, a whole mile of shoreless ocean was between Pip and Stubb. Out from the centre of the sea, poor Pip turned his crisp, curling, black head to the sun, another lonely castaway, though the loftiest and the brightest. Now, in calm weather, to swim in the open ocean is as easy to the practised swimmer as to ride in a spring-carriage ashore. But the awful lonesomeness is intolerable. The intense concentration of self in the middle of such a heartless immensity, my God! who can tell it? Mark, how when sailors in a dead calm bathe in the open sea --mark how closely they hug their ship and only coast along her sides. But had Stubb really abandoned the poor little negro to his fate? No; he did not mean to, at least. Because there were two boats in his wake, and he supposed, no doubt, that they would of course come up to Pip very quickly, and pick him up; though, indeed, such considerations towards oarsmen jeopardized through their own timidity, is not always manifested by the hunters in all similar instances; and such instances not unfrequently occur; almost invariably in the fishery, a coward, so called, is marked with the same ruthless detestation peculiar to military navies and armies. ..

But it so happened, that those boats, without seeing Pip, suddenly spying whales close to them on one side, turned, and gave chase; and Stubb's boat was now so far away, and he and all his crew so intent upon his fish, that Pip's ringed horizon began to expand around him miserably. By the merest chance the ship itself at last rescued him; but from that hour the little negro went about the deck an idiot; such, at least, they said he was. The sea had jeeringly kept his finite body up, but drowned the infinite of his soul. Not drowned entirely, though. Rather carried down alive to wondrous depths, where strange shapes of the unwarped primal world glided to and fro before his passive eyes; and the miser-merman, Wisdom, revealed his hoarded heaps; and among the joyous, heartless, ever-juvenile eternities, Pip saw the multitudinous, God-omnipresent, coral insects, that out of the firmament of waters heaved the colossal orbs. He saw God's foot upon the treadle of the loom, and spoke it; and therefore his shipmates called him mad. So man's insanity is heaven's sense; and wandering from all mortal reason, man comes at last to that celestial thought, which, to reason, is absurd and frantic; and weal or woe, feels then uncompromised, indifferent as his God. For the rest, blame not Stubb too hardly. The thing is common in that fishery; and in the sequel of the narrative, it will then be seen what like abandonment befell myself. ..

.. < chapter xciv 26 A SQUEEZE OF THE HAND > That whale of Stubb's so dearly purchased, was duly brought to the Pequod's side, where all those cutting and hoisting operations previously detailed, were regularly gone through, even to the baling of the Heidelburgh Tun, or Case. While some were occupied with this latter duty, others were employed in dragging away the larger tubs, so soon as filled with the sperm; and when the proper time arrived, this same ..

sperm was carefully manipulated ere going to the try-works, of which anon. It had cooled and crystallized to such a degree, that when, with several others, I sat down before a large Constantine's bath of it, I found it strangely concreted into lumps, here and there rolling about in the liquid part. It was our business to squeeze these lumps back into fluid. A sweet and unctuous duty! no wonder that in old times this sperm was such a favorite cosmetic. Such a clearer! such a sweetener! such a softener! such a delicious mollifier! After having my hands in it for only a few minutes, my fingers felt like eels, and began, as it were, to serpentine and spiralize. As I sat there at my ease, cross-legged on the deck; after the bitter exertion at the windlass; under a blue tranquil sky; the ship under indolent sail, and gliding so serenely along; as I bathed my hands among those soft, gentle globules of infiltrated tissues, woven almost within the hour; as they richly broke to my fingers, and discharged all their opulence, like fully ripe grapes their wine; as I snuffed up that uncontaminated aroma, --literally and truly, like the smell of spring violets; I declare to you, that for the time I lived as in a musky meadow; I forgot all about our horrible oath; in that inexpressible sperm, I washed my hands and my heart of it; I almost began to credit the old Paracelsan superstition that sperm is of rare virtue in allaying the heat of anger: while bathing in that bath, I felt divinely free from all ill-will, or petulence, or malice, of any sort whatsoever. Squeeze! squeeze! squeeze! all the morning long; I squeezed that sperm till I myself almost melted into it; I squeezed that sperm till a strange sort of insanity came over me; and I found myself unwittingly squeezing my co-laborers' hands in it, mistaking their hands for the gentle globules. Such an abounding, affectionate, friendly, loving feeling did this avocation beget; that at last I was continually squeezing their hands, and looking up into their eyes sentimentally; as much as to say, --Oh! my dear fellow beings, why should we longer cherish any social acerbities, or know the slightest ill-humor or envy! Come; let us squeeze hands all round; nay, let us all squeeze ourselves ..

into each other; let us squeeze ourselves universally into the very milk and sperm of kindness. Would that I could keep squeezing that sperm for ever! For now, since by many prolonged, repeated experiences, I have perceived that in all cases man must eventually lower, or at least shift, his conceit of attainable felicity; not placing it anywhere in the intellect or the fancy; but in the wife, the heart, the bed, the table, the saddle, the fire-side, the country; now that I have perceived all this, I am ready to squeeze case eternally. In thoughts of the visions of the night, I saw long rows of angels in paradise, each with his hands in a jar of spermaceti. Now, while discoursing of sperm, it behooves to speak of other things akin to it, in the business of preparing the sperm whale for the try-works. First comes white-horse, so called, which is obtained from the tapering part of the fish, and also from the thicker portions of his flukes. It is tough with congealed tendons --a wad of muscle --but still contains some oil. After being severed from the whale, the white-horse is first cut into portable oblongs ere going to the mincer. They look much like blocks of Berkshire marble. Plum-pudding is the term bestowed upon certain fragmentary parts of the whale's flesh, here and there adhering to the blanket of blubber, and often participating to a considerable degree in its unctuousness. It is a most refreshing, convivial, beautiful object to behold. As its name imports, it is of an exceedingly rich, mottled tint, with a bestreaked snowy and golden ground, dotted with spots of the deepest crimson and purple. It is plums of rubies, in pictures of citron. Spite of reason, it is hard to keep yourself from eating it. I confess, that once I stole behind the foremast to try it. It tasted something as I should conceive a royal cutlet from the thigh of Louis le Gros might have tasted, supposing him to have been killed the first day after the venison season, and that particular venison season contemporary with an unusually fine vintage of the vineyards of Champagne. ..

There is another substance, and a very singular one, which turns up in the course of this business, but which I feel it to be very puzzling adequately to describe. It is called slobgollion; an appellation original with the whalemen, and even so is the nature of the substance. It is an ineffably oozy, stringy affair, most frequently found in the tubs of sperm, after a prolonged squeezing, and subsequent decanting. I hold it to be the wondrously thin, ruptured membranes of the case, coalescing. Gurry, so called, is a term properly belonging to right whalemen, but sometimes incidentally used by the sperm fishermen. It designates the dark, glutinous substance which is scraped off the back of the Greenland or right whale, and much of which covers the decks of those inferior souls who hunt that ignoble Leviathan. Nippers. Strictly this word is not indigenous to the whale's vocabulary. But as applied by whalemen, it becomes so. A whaleman's nipper is a short firm strip of tendinous stuff cut from the tapering part of Leviathan's tail: it averages an inch in thickness, and for the rest, is about the size of the iron part of a hoe. Edgewise moved along the oily deck, it operates like a leathern squilgee; and by nameless blandishments, as of magic, allures along with it all impurities. But to learn all about these recondite matters, your best way is at once to descend into the blubber-room, and have a long talk with its inmates. This place has previously been mentioned as the receptacle for the blanket-pieces, when stript and hoisted from the whale. When the proper time arrives for cutting up its contents, this apartment is a scene of terror to all tyros, especially by night. On one side, lit by a dull lantern, a space has been left clear for the workmen. They generally go in pairs, --a pike-and-gaff-man and a spade-man. The whaling-pike is similar to a frigate's boarding-weapon of the same name. The gaff is something like a boat-hook. With his gaff, the gaffman hooks on to a sheet of blubber, and strives to hold it from slipping, as the ship pitches and lurches about. Meanwhile, the spade-man stands on the sheet itself, perpendicularly chopping it into the portable horse-pieces. This spade is sharp as hone can make it; the spademan's feet are shoeless; the thing ..

he stands on will sometimes irresistibly slide away from him, like a sledge. If he cuts off one of his own toes, or one of his assistants', would you be very much astonished? Toes are scarce among veteran blubber-room men. ..

.. < chapter xcv 6 THE CASSOCK > Had you stepped on board the Pequod at a certain juncture of this post-mortemizing of the whale; and had you strolled forward nigh the windlass, pretty sure am I that you would have scanned with no small curiosity a very strange, enigmatical object, which you would have seen there, lying along lengthwise in the lee scuppers. Not the wondrous cistern in the whale's huge head; not the prodigy of his unhinged lower jaw; not the miracle of his symmetrical tail; none of these would so surprise you, as half a glimpse of that unaccountable cone, -- longer than a Kentuckian is tall, nigh a foot in diameter at the base, and jet-black as Yojo, the ebony idol of Queequeg. And an idol, indeed, it is; or, rather, in old times, its likeness was. Such an idol as that found in the secret groves of Queen Maachah in Judea; and for worshipping which, king Asa, her son, did depose her, and destroyed the idol, and burnt it for an abomination at the brook Kedron, as darkly set forth in the 15th chapter of the first book of Kings. Look at the sailor, called the mincer, who now comes along, and assisted by two allies, heavily backs the grandissimus, as the mariners call it, and with bowed shoulders, staggers off with it as if he were a grenadier carrying a dead comrade from the field. extending it upon the forecastle deck, he now proceeds cylindrically to remove its dark pelt, as an African hunter the pelt of a boa. This done he turns the pelt inside out, like a pantaloon leg; gives it a good stretching, so as almost to double its diameter; and at last hangs it, well spread, in the ..

rigging, to dry. Ere long, it is taken down; when removing some three feet of it, towards the pointed extremity, and then cutting two slits for arm-holes at the other end, he lengthwise slips himself bodily into it. The mincer now stands before you invested in the full canonicals of his calling. Immemorial to all his order, this investiture alone will adequately protect him, while employed in the peculiar functions of his office. That office consists in mincing the horse-pieces of blubber for the pots; an operation which is conducted at a curious wooden horse, planted endwise against the bulwarks, and with a capacious tub beneath it, into which the minced pieces drop, fast as the sheets from a rapt orator's desk. Arrayed in decent black; occupying a conspicuous pulpit; intent on bible leaves; what a candidate for an archbishoprick, what a lad for a Pope were this mincer! ..

Bible leaves! Bible leaves! This is the invariable cry from the mates to the mincer. It enjoins him to be careful, and cut his work into as thin slices as possible, inasmuch as by so doing the business of boiling out the oil is much accelerated, and its quantity considerably increased, besides perhaps improving it in quality. ..

.. < chapter xcvi 17 THE TRY-WORKS > Besides her hoisted boats, an American whaler is outwardly distinguished by her try-works. She presents the curious anomaly of the most solid masonry joining with oak and hemp in constituting the completed ship. it is as if from the open field a brick-kiln were transported to her planks. The try-works are planted between the foremast and main-mast, the most roomy part of the deck. The timbers beneath are of a peculiar strength, fitted to sustain the weight of an almost solid mass of brick and mortar, some ten feet by eight square, and five in height. The foundation does not penetrate the deck, but the masonry is firmly secured to the surface by ..

ponderous knees of iron bracing it on all sides, and screwing it down to the timbers. On the flanks it is cased with wood, and at top completely covered by a large, sloping, battened hatchway. Removing this hatch we expose the great try-pots, two in number, and each of several barrels' capacity. When not in use, they are kept remarkably clean. Sometimes they are polished with soapstone and sand, till they shine within like silver punch-bowls. During the night-watches some cynical old sailors will crawl into them and coil themselves away there for a nap. While employed in polishing them --one man in each pot, side by side --many confidential communications are carried on, over the iron lips. It is a place also for profound mathematical meditation. It was in the left hand try-pot of the Pequod, with the soapstone diligently circling round me, that I was first indirectly struck by the remarkable fact, that in geometry all bodies gliding along the cycloid, my soapstone for example, will descend from any point in precisely the same time. Removing the fire-board from the front of the try-works, the bare masonry of that side is exposed, penetrated by the two iron mouths of the furnaces, directly underneath the pots. These mouths are fitted with heavy doors of iron. The intense heat of the fire is prevented from communicating itself to the deck, by means of a shallow reservoir extending under the entire inclosed surface of the works. By a tunnel inserted at the rear, this reservoir is kept replenished with water as fast as it evaporates. There are no external chimneys; they open direct from the rear wall. And here let us go back for a moment. It was about nine o'clock at night that the Pequod's try-works were first started on this present voyage. It belonged to Stubb to oversee the business. All ready there? Off hatch, then, and start her. You cook, fire the works. This was an easy thing, for the carpenter had been thrusting his shavings into the furnace throughout the passage. Here be it said that in a whaling voyage the first fire in the try-works has to be fed for a time with wood. After that no wood is used, except as a means of quick ignition to the staple fuel. In a word, after being tried out, the crisp, shrivelled ..

blubber, now called scraps or fritters, still contains considerable of its unctuous properties. These fritters feed the flames. Like a plethoric burning martyr, or a self-consuming misanthrope, once ignited, the whale supplies his own fuel and burns by his own body. Would that he consumed his own smoke! for his smoke is horrible to inhale, and inhale it you must, and not only that, but you must live in it for the time. It has an unspeakable, wild, Hindoo odor about it, such as may lurk in the vicinity of funereal pyres. It smells like the left wing of the day of judgment; it is an argument for the pit. By midnight the works were in full operation. We were clear from the carcase; sail had been made; the wind was freshening; the wild ocean darkness was intense. But that darkness was licked up by the fierce flames, which at intervals forked forth from the sooty flues, and illuminated every lofty rope in the rigging, as with the famed Greek fire. The burning ship drove on, as if remorselessly commissioned to some vengeful deed. So the pitch and sulphur-freighted brigs of the bold Hydriote, Canaris, issuing from their midnight harbors, with broad sheets of flame for sails, bore down upon the turkish frigates, and folded them in conflagrations. The hatch, removed from the top of the works, now afforded a wide hearth in front of them. Standing on this were the Tartarean shapes of the pagan harpooneers, always the whale-ship's stokers. With huge pronged poles they pitched hissing masses of blubber into the scalding pots, or stirred up the fires beneath, till the snaky flames darted, curling, out of the doors to catch them by the feet. The smoke rolled away in sullen heaps. To every pitch of the ship there was a pitch of the boiling oil, which seemed all eagerness to leap into their faces. Opposite the mouth of the works, on the further side of the wide wooden hearth, was the windlass. This served for a sea-sofa. Here lounged the watch, when not otherwise employed, looking into the red heat of the fire, till their eyes felt scorched in their heads. Their tawny features, now all begrimed with smoke and sweat, their matted beards, and the contrasting barbaric brilliancy of their teeth, all these were strangely revealed in the capricious emblazonings of the works. As they ..

narrated to each other their unholy adventures, their tales of terror told in words of mirth; as their uncivilized laughter forked upwards out of them, like the flames from the furnace; as to and fro, in their front, the harpooneers wildly gesticulated with their huge pronged forks and dippers; as the wind howled on, and the sea leaped, and the ship groaned and dived, and yet steadfastly shot her red hell further and further into the blackness of the sea and the night, and scornfully champed the white bone in her mouth, and viciously spat round her on all sides; then the rushing Pequod, freighted with savages, and laden with fire, and burning a corpse, and plunging into that blackness of darkness, seemed the material counterpart of her monomaniac commander's soul. So seemed it to me, as I stood at her helm, and for long hours silently guided the way of this fire-ship on the sea. Wrapped, for that interval, in darkness myself, I but the better saw the redness, the madness, the ghastliness of others. The continual sight of the fiend shapes before me, capering half in smoke and half in fire, these at last begat kindred visions in my soul, so soon as I began to yield to that unaccountable drowsiness which ever would come over me at a midnight helm. But that night, in particular, a strange (and ever since inexplicable) thing occurred to me. Starting from a brief standing sleep, I was horribly conscious of something fatally wrong. The jaw-bone tiller smote my side, which leaned against it; in my ears was the low hum of sails, just beginning to shake in the wind; I thought my eyes were open; I was half conscious of putting my fingers to the lids and mechanically stretching them still further apart. But, spite of all this, I could see no compass before me to steer by; though it seemed but a minute since I had been watching the card, by the steady binnacle lamp illuminating it. Nothing seemed before me but a jet gloom, now and then made ghastly by flashes of redness. Uppermost was the impression, that whatever swift, rushing thing I stood on was not so much bound to any haven ahead as rushing from all havens astern. A stark, bewildered feeling, as of death, came over me. Convulsively my hands grasped the tiller, but with the crazy conceit that the tiller was, somehow, ..

in some enchanted way, inverted. My God! what is the matter with me? thought I. Lo! in my brief sleep I had turned myself about, and was fronting the ship's stern, with my back to her prow and the compass. In an instant I faced back, just in time to prevent the vessel from flying up into the wind, and very probably capsizing her. How glad and how grateful the relief from this unnatural hallucination of the night, and the fatal contingency of being brought by the lee! look not too long in the face of the fire, O man! Never dream with thy hand on the helm! Turn not thy back to the compass; accept the first hint of the hitching tiller; believe not the artificial fire, when its redness makes all things look ghastly. To-morrow, in the natural sun, the skies will be bright; those who glared like devils in the forking flames, the morn will show in far other, at least gentler, relief; the glorious, golden, glad sun, the only true lamp --all others but liars! Nevertheless the sun hides not Virginia's Dismal Swamp, nor Rome's accursed Campagna, nor wide Sahara, nor all the millions of miles of deserts and of griefs beneath the moon. The sun hides not the ocean, which is the dark side of this earth, and which is two thirds of this earth. So, therefore, that mortal man who hath more of joy than sorrow in him, that mortal man cannot be true --not true, or undeveloped. With books the same. The truest of all men was the Man of Sorrows, and the truest of all books is Solomon's, and Ecclesiastes is the fine hammered steel of woe. All is vanity. ALL. This wilful world hath not got hold of unchristian Solomon's wisdom yet. But he who dodges hospitals and jails, and walks fast crossing grave-yards, and would rather talk of operas than hell; calls Cowper, Young, Pascal, Rousseau, poor devils all of sick men; and throughout a care-free lifetime swears by Rabelais as passing wise, and therefore jolly; --not that man is fitted to sit down on tomb-stones, and break the green damp mould with unfathomably wondrous Solomon. But even Solomon, he says, the man that wandereth out of the way of understanding shall remain ( i. e. even while living) in the congregation of the dead. Give not thyself up, then, to fire, lest it invert thee, deaden thee; as for the time it did me. ..

There is a wisdom that is woe; but there is a woe that is madness. And there is a Catskill eagle in some souls that can alike dive down into the blackest gorges, and soar out of them again and become invisible in the sunny spaces. And even if he for ever flies within the gorge, that gorge is in the mountains; so that even in his lowest swoop the mountain eagle is still higher than other birds upon the plain, even though they soar. ..

.. < chapter xcvii 9 THE LAMP > Had you descended from the Pequod's try-works to the Pequod's forecastle, where the off duty watch were sleeping, for one single moment you would have almost thought you were standing in some illuminated shrine of canonized kings and counsellors. There they lay in their triangular oaken vaults, each mariner a chiselled muteness; a score of lamps flashing upon his hooded eyes. In merchantmen, oil for the sailor is more scarce than the milk of queens. To dress in the dark, and eat in the dark, and stumble in darkness to his pallet, this is his usual lot. But the whaleman, as he seeks the food of light, so he lives in light. He makes his berth an Aladdin's lamp, and lays him down in it; so that in the pitchiest night the ship's black hull still houses an illumination. See with what entire freedom the whaleman takes his handful of lamps --often but old bottles and vials, though --to the copper cooler at the try-works, and replenishes them there, as mugs of ale at a vat. He burns, too, the purest of oil, in its unmanufactured, and, therefore, unvitiated state; a fluid unknown to solar, lunar, or astral contrivances ashore. It is sweet as early grass butter in April. He goes and hunts for his oil, so as to be sure of its freshness and genuineness, even as the traveller on the prairie hunts up his own supper of game. ..

.. < chapter xcviii 2 STOWING DOWN AND CLEARING UP > Already has it been related how the great leviathan is afar off descried from the mast-head; how he is chased over the watery moors, and slaughtered in the valleys of the deep; how he is then towed alongside and beheaded; and how (on the principle which entitled the headsman of old to the garments in which the beheaded was killed) his great padded surtout becomes the property of his executioner; how, in due time, he is condemned to the pots, and, like Shadrach, Meshach, and Abednego, his spermaceti, oil, and bone pass unscathed through the fire; --but now it remains to conclude the last chapter of this part of the description by rehearsing --singing, if I may -- the romantic proceeding of decanting off his oil into the casks and striking them down into the hold, where once again leviathan returns to his native profundities, sliding along beneath the surface as before; but, alas! never more to rise and blow. While still warm, the oil, like hot punch, is received into the six-barrel casks; and while, perhaps, the ship is pitching and rolling this way and that in the midnight sea, the enormous casks are slewed round and headed over, end for end, and sometimes perilously scoot across the slippery deck, like so many land slides, till at last man-handled and stayed in their course; and all round the hoops, rap, rap, go as many hammers as can play upon them, for now, ex officio, every sailor is a cooper. At length, when the last pint is casked, and all is cool, then the great hatchways are unsealed, the bowels of the ship are thrown open, and down go the casks to their final rest in the sea. This done, the hatches are replaced, and hermetically closed, like a closet walled up. In the sperm fishery, this is perhaps one of the most remarkable incidents in all the business of whaling. One day the planks stream with freshets of blood and oil; on the sacred ..

quarter-deck enormous masses of the whale's head are profanely piled; great rusty casks lie about, as in a brewery yard; the smoke from the try-works has besooted all the bulwarks; the mariners go about suffused with unctuousness; the entire ship seems great leviathan himself; while on all hands the din is deafening. But a day or two after, you look about you, and prick your ears in this self-same ship; and were it not for the tell-tale boats and try-works, you would all but swear you trod some silent merchant vessel, with a most scrupulously neat commander. The unmanufactured sperm oil possesses a singularly cleansing virtue. This is the reason why the decks never look so white as just after what they call an affair of oil. Besides, from the ashes of the burned scraps of the whale, a potent ley is readily made; and whenever any adhesiveness from the back of the whale remains clinging to the side, that ley quickly exterminates it. Hands go diligently along the bulwarks, and with buckets of water and rags restore them to their full tidiness. The soot is brushed from the lower rigging. All the numerous implements which have been in use are likewise faithfully cleansed and put away. The great hatch is scrubbed and placed upon the try-works, completely hiding the pots; every cask is out of sight; all tackles are coiled in unseen nooks; and when by the combined and simultaneous industry of almost the entire ship's company, the whole of this conscientious duty is at last concluded, then the crew themselves proceed to their own ablutions; shift themselves from top to toe; and finally issue to the immaculate deck, fresh and all aglow, as bridegrooms new-leaped from out the daintiest Holland. Now, with elated step, they pace the planks in twos and threes, and humorously discourse of parlors, sofas, carpets, and fine cambrics; propose to mat the deck; think of having hangings to the top; object not to taking tea by moonlight on the piazza of the forecastle. To hint to such musked mariners of oil, and bone, and blubber, were little short of audacity. They know not the thing you distantly allude to. Away, and bring us napkins! But mark: aloft there, at the three mast heads, stand three ..

men intent on spying out more whales, which, if caught, infallibly will again soil the old oaken furniture, and drop at least one small grease-spot somewhere. Yes; and many is the time, when, after the severest uninterrupted labors, which know no night; continuing straight through for ninety-six hours; when from the boat, where they have swelled their wrists with all day rowing on the Line, --they only step to the deck to carry vast chains, and heave the heavy windlass, and cut and slash, yea, and in their very sweatings to be smoked and burned anew by the combined fires of the equatorial sun and the equatorial try-works; when, on the heel of all this, they have finally bestirred themselves to cleanse the ship, and make a spotless dairy room of it; many is the time the poor fellows, just buttoning the necks of their clean frocks, are startled by the cry of There she blows! and away they fly to fight another whale, and go through the whole weary thing again. Oh! my friends, but this is man-killing! Yet this is life. For hardly have we mortals by long toilings extracted from the world's vast bulk its small but valuable sperm; and then, with weary patience, cleansed ourselves from its defilements, and learned to live here in clean tabernacles of the soul; hardly is this done, when -- There she blows! --the ghost is spouted up, and away we sail to fight some other world, and go through young life's old routine again. Oh! the metempsychosis! Oh! Pythagoras, that in bright Greece, two thousand years ago, did die, so good, so wise, so mild; I sailed with thee along the Peruvian coast last voyage -- and, foolish as I am, taught thee, a green simple boy, how to splice a rope! ..

.. < chapter xcix 30 THE DOUBLOON > Ere now it has been related how Ahab was wont to pace his quarter-deck, taking regular turns at either limit, the binnacle ..

and mainmast; but in the multiplicity of other things requiring narration it has not been added how that sometimes in these walks, when most plunged in his mood, he was wont to pause in turn at each spot, and stand there strangely eyeing the particular object before him. When he halted before the binnacle, with his glance fastened on the pointed needle in the compass, that glance shot like a javelin with the pointed intensity of his purpose; and when resuming his walk he again paused before the mainmast, then, as the same riveted glance fastened upon the riveted gold coin there, he still wore the same aspect of nailed firmness, only dashed with a certain wild longing, if not hopefulness. But one morning, turning to pass the doubloon, he seemed to be newly attracted by the strange figures and inscriptions stamped on it, as though now for the first time beginning to interpret for himself in some monomaniac way whatever significance might lurk in them. And some certain significance lurks in all things, else all things are little worth, and the round world itself but an empty cipher, except to sell by the cartload, as they do hills about Boston, to fill up some morass in the Milky Way. Now this doubloon was of purest, virgin gold, raked somewhere out of the heart of gorgeous hills, whence, east and west, over golden sands, the head-waters of many a Pactolus flows. And though now nailed amidst all the rustiness of iron bolts and the verdigris of copper spikes, yet, untouchable and immaculate to any foulness, it still preserved its Quito glow. Nor, though placed amongst a ruthless crew and every hour passed by ruthless hands, and through the livelong nights shrouded with thick darkness which might cover any pilfering approach, nevertheless every sunrise found the doubloon where the sunset left it last. For it was set apart and sanctified to one awe-striking end; and however wanton in their sailor ways, one and all, the mariners revered it as the white whale's talisman. Sometimes they talked it over in the weary watch by night, wondering whose it was to be at last, and whether he would ever live to spend it. Now those noble golden coins of South America are as ..

medals of the sun and tropic token-pieces. Here palms, alpacas, and volcanoes; sun's disks and stars; ecliptics, horns-of-plenty, and rich banners waving, are in luxuriant profusion stamped; so that the precious gold seems almost to derive an added preciousness and enhancing glories, by passing through those fancy mints, so Spanishly poetic. It so chanced that the doubloon of the Pequod was a most wealthy example of these things. On its round border it bore the letters, REPUBLICA DEL ECUADOR: QUITO. So this bright coin came from a country planted in the middle of the world, and beneath the great equator, and named after it; and it had been cast midway up the Andes, in the unwaning clime that knows no autumn. Zoned by those letters you saw the likeness of three Andes' summits; from one a flame; a tower on another; on the third a crowing cock; while arching over all was a segment of the partitioned zodiac, the signs all marked with their usual cabalistics, and the keystone sun entering the equinoctial point at Libra. Before this equatorial coin, Ahab, not unobserved by others, was now pausing. There's something ever egotistical in mountain-tops and towers, and all other grand and lofty things; look here, --three peaks as proud as Lucifer. The firm tower, that is Ahab; the volcano, that is Ahab; the courageous, the undaunted, and victorious fowl, that, too, is Ahab; all are Ahab; and this round gold is but the image of the rounder globe, which, like a magician's glass, to each and every man in turn but mirrors back his own mysterious self. Great pains, small gains for those who ask the world to solve them; it cannot solve itself. Methinks now this coined sun wears a ruddy face; but see! aye, he enters the sign of storms, the equinox! and but six months before he wheeled out of a former equinox at Aries! From storm to storm! So be it, then. Born in throes, 't is fit that man should live in pains and die in pangs! So be it, then! Here's stout stuff for woe to work on. So be it, then. No fairy fingers can have pressed the gold, but devil's claws must have left their mouldings there since yesterday, murmured Starbuck to himself, leaning against the bulwarks. The old ..

man seems to read Belshazzar's awful writing. I have never marked the coin inspectingly. He goes below; let me read. A dark valley between three mighty, heaven-abiding peaks, that almost seem the Trinity, in some faint earthly symbol. So in this vale of Death, God girds us round; and over all our gloom, the sun of Righteousness still shines a beacon and a hope. If we bend down our eyes, the dark vale shows her mouldy soil; but if we lift them, the bright sun meets our glance half way, to cheer. Yet, oh, the great sun is no fixture; and if, at midnight, we would fain snatch some sweet solace from him, we gaze for him in vain! This coin speaks wisely, mildly, truly, but still sadly to me. I will quit it, lest Truth shake me falsely. There now's the old Mogul, soliloquized Stubb by the try-works, he's been twigging it; and there goes Starbuck from the same, and both with faces which I should say might be somewhere within nine fathoms long. And all from looking at a piece of gold, which did I have it now on Negro Hill or in Corlaer's Hook, I'd not look at it very long ere spending it. Humph! in my poor, insignificant opinion, I regard this as queer. I have seen doubloons before now in my voyagings; your doubloons of old Spain, your doubloons of Peru, your doubloons of Chili, your doubloons of Bolivia, your doubloons of Popayan; with plenty of gold moidores and pistoles, and joes, and half joes, and quarter joes. what then should there be in this doubloon of the Equator that is so killing wonderful? By Golconda! let me read it once. Halloa! here's signs and wonders truly! That, now, is what old Bowditch in his Epitome calls the zodiac, and what my almanack below calls ditto. I'll get the almanack and as I have heard devils can be raised with Daboll's arithmetic, I'll try my hand at raising a meaning out of these queer curvicues here with the Massachusetts calendar. Here's the book. Let's see now. Signs and wonders; and the sun, he's always among 'em. Hem, hem, hem; here they are --here they go --all alive: --Aries, or the Ram; Taurus, or the Bull and Jimimi! here's Gemini himself, or the Twins. Well; the sun he wheels among 'em. Aye, here on the coin he's just crossing the threshold between two of twelve sitting-rooms all in a ring. Book! you lie there; the fact is, you books must know your ..

places. You'll do to give us the bare words and facts, but we come in to supply the thoughts. That's my small experience, so far as the Massachusetts calendar, and Bowditch's navigator, and Daboll's arithmetic go. Signs and wonders, eh? Pity if there is nothing wonderful in signs, and significant in wonders! There's a clue somewhere; wait a bit; hist--hark! By Jove, I have it! Look you, Doubloon, your zodiac here is the life of man in one round chapter; and now I'll read it off, straight out of the book. Come, Almanack! To begin: there's Aries, or the Ram --lecherous dog, he begets us; then, Taurus, or the Bull --he bumps us the first thing; then Gemini, or the Twins -- that is, Virtue and Vice; we try to reach Virtue, when lo! comes Cancer the Crab, and drags us back; and here, going from Virtue, Leo, a roaring Lion, lies in the path --he gives a few fierce bites and surly dabs with his paw; we escape, and hail Virgo, the Virgin! that's our first love; we marry and think to be happy for aye, when pop comes Libra, or the Scales --happiness weighed and found wanting; and while we are very sad about that, Lord! how we suddenly jump, as Scorpio, or the Scorpion, stings us in rear; we are curing the wound, when whang come the arrows all round; Sagittarius, or the Archer, is amusing himself. As we pluck out the shafts, stand aside; here's the battering-ram, Capricornus, or the Goat; full tilt, he comes rushing, and headlong we are tossed; when Aquarius, or the Water-bearer, pours out his whole deluge and drowns us; and to wind up with Pisces, or the Fishes, we sleep. There's a sermon now, writ in high heaven, and the sun goes through it every year, and yet comes out of it all alive and hearty. Jollily he, aloft there, wheels through toil and trouble; and so, alow here, does jolly Stubb. Oh, jolly's the word for aye! Adieu, Doubloon! But stop; here comes little King-Post; dodge round the try-works, now, and let's hear what he'll have to say. There; he's before it; he'll out with something presently. So, so; he's beginning. I see nothing here, but a round thing made of gold, and whoever raises a certain whale, this round thing belongs to him. So, what's all this staring been about? It is worth sixteen dollars, that's true; and at two cents the cigar, that's nine hundred and ..

sixty cigars. I wont smoke dirty pipes like Stubb, but I like cigars, and here's nine hundred and sixty of them; so here goes Flask aloft to spy 'em out. Shall I call that wise or foolish, now; if it be really wise it has a foolish look to it; yet, if it be really foolish, then has it a sort of wiseish look to it. But, avast; here comes our old Manxman --the old hearse-driver, he must have been, that is, before he took to the sea. He luffs up before the doubloon; halloa, and goes round on the other side of the mast; why, there's a horse-shoe nailed on that side; and now he's back again; what does that mean? Hark! he's muttering --voice like an old worn-out coffee-mill. Prick ears, and listen! If the White Whale be raised, it must be in a month and a day, when the sun stands in some one of these signs. I've studied signs, and know their marks; they were taught me two score years ago, by the old witch in Copenhagen. Now, in what sign will the sun then be? The horse-shoe sign; for there it is, right opposite the gold. And what's the horse-shoe sign? The lion is the horse-shoe sign --the roaring and devouring lion. Ship, old ship! my old head shakes to think of thee. There's another rendering now; but still one text. All sorts of men in one kind of world, you see. Dodge again! here comes Queequeg --all tattooing --looks like the signs of the Zodiac himself. What says the Cannibal? As I live he's comparing notes; looking at his thigh bone; thinks the sun is in the thigh, or in the calf, or in the bowels, I suppose, as the old women talk Surgeon's Astronomy in the back country. And by Jove, he's found something there in the vicinity of his thigh --I guess it's Sagittarius, or the Archer. No: he don't know what to make of the doubloon; he takes it for an old button off some king's trowsers. But, aside again! here comes that ghost-devil, Fedallah; tail coiled out of sight as usual, oakum in the toes of his pumps as usual. What does he say, with that look of his? Ah, only makes a sign to the sign and bows himself; there is a sun on the coin --fire worshipper, depend upon it. Ho! more and more. This way comes Pip --poor boy! would he had died, or I; he's half horrible to me. He too has been watching all of these interpreters --myself included --and look now, he comes to read, ..

with that unearthly idiot face. stand away again and hear him. hark! I look, you look, he looks; we look, ye look, they look. Upon my soul, he's been studying Murray's Grammar! Improving his mind, poor fellow! But what's that he says now -- hist! I look, you look, he looks; we look, ye look, they look. Why, he's getting it by heart --hist! again. I look, you look, he looks; we look, ye look, they look. Well, that's funny. And I, you, and he; and we, ye, and they, are all bats; and I'm a crow, especially when I stand a'top of this pine tree here. Caw! caw! caw! caw! caw! caw! Ain't I a crow? And where's the scare-crow? There he stands; two bones stuck into a pair of old trowsers, and two more poked into the sleeves of an old jacket. Wonder if he means me? --complimentary! --poor lad! --I could go hang myself. Any way, for the present, I'll quit Pip's vicinity. I can stand the rest, for they have plain wits; but he's too crazy-witty for my sanity. So, so, I leave him muttering. Here's the ship's navel, this doubloon here, and they are all on fire to unscrew it. But, unscrew your navel, and what's the consequence? Then again, if it stays here, that is ugly, too, for when aught's nailed to the mast it's a sign that things grow desperate. Ha, ha! old Ahab! the White Whale; he'll nail ye! This is a pine tree. My father, in old Tolland county, cut down a pine tree once, and found a silver ring grown over in it; some old darkey's wedding ring. How did it get there? And so they'll say in the resurrection, when they come to fish up this old mast, and find a doubloon lodged in it, with bedded oysters for the shaggy bark. Oh, the gold! the precious, precious gold! --the green miser 'll hoard ye soon! Hish! hish! God goes 'mong the worlds blackberrying. Cook! ho, cook! and cook us! Jenny! hey, hey, hey, hey, hey, Jenny, Jenny! and get your hoe-cake done! ..

.. < chapter c 2 LEG AND ARM THE PEQUOD, OF NANTUCKET, MEETS THE SAMUEL > ENDERBY, OF LONDON Ship, ahoy! Hast seen the White Whale? So cried Ahab, once more hailing a ship showing English colors, bearing down under the stern. Trumpet to mouth, the old man was standing in his hoisted quarter-boat, his ivory leg plainly revealed to the stranger captain, who was carelessly reclining in his own boat's bow. He was a darkly-tanned, burly, good-natured, fine-looking man, of sixty or thereabouts, dressed in a spacious roundabout, that hung round him in festoons of blue pilot-cloth; and one empty arm of this jacket streamed behind him like the broidered arm of a huzzar's surcoat. Hast seen the White Whale? See you this? and withdrawing it from the fold that had hidden it, he held up a white arm of sperm whale bone, terminating in a wooden head like a mallet. Man my boat! cried Ahab, impetuously, and tossing about the oars near him -- Stand by to lower! In less than a minute, without quitting his little craft, he and his crew were dropped to the water, and were soon alongside of the stranger. But here a curious difficulty presented itself. In the excitement of the moment, Ahab had forgotten that since the loss of his leg he had never once stepped on board of any vessel at sea but his own, and then it was always by an ingenious and very handy mechanical contrivance peculiar to the Pequod, and a thing not to be rigged and shipped in any other vessel at a moment's warning. Now, it is no very easy matter for anybody --except those who are almost hourly used to it, like whalemen --to clamber up a ship's side from a boat on the open sea; for the great swells now lift the boat high up towards ..

the bulwarks, and then instantaneously drop it half way down to the kelson. so, deprived of one leg, and the strange ship of course being altogether unsupplied with the kindly invention, Ahab now found himself abjectly reduced to a clumsy landsman again; hopelessly eyeing the uncertain changeful height he could hardly hope to attain. It has before been hinted, perhaps, that every little untoward circumstance that befel him, and which indirectly sprang from his luckless mishap, almost invariably irritated or exasperated Ahab. And in the present instance, all this was heightened by the sight of the two officers of the strange ship, leaning over the side, by the perpendicular ladder of nailed cleets there, and swinging towards him a pair of tastefully-ornamented man-ropes; for at first they did not seem to bethink them that a one-legged man must be too much of a cripple to use their sea bannisters. But this awkwardness only lasted a minute, because the strange captain, observing at a glance how affairs stood, cried out, I see, I see! --avast heaving there! Jump, boys, and swing over the cutting-tackle. As good luck would have it, they had had a whale alongside a day or two previous, and the great tackles were still aloft, and the massive curved blubber-hook, now clean and dry, was still attached to the end. This was quickly lowered to Ahab, who at once comprehending it all, slid his solitary thigh into the curve of the hook (it was like sitting in the fluke of an anchor, or the crotch of an apple tree), and then giving the word, held himself fast, and at the same time also helped to hoist his own weight, by pulling hand-over-hand upon one of the running parts of the tackle. Soon he was carefully swung inside the high bulwarks, and gently landed upon the capstan head. With his ivory arm frankly thrust forth in welcome, the other captain advanced, and Ahab, putting out his ivory leg, and crossing the ivory arm (like two sword-fish blades) cried out in his walrus way, Aye, aye, hearty! let us shake bones together! --an arm and a leg! --an arm that never can shrink, d'ye see; and a leg that never can run. Where did'st thou see the White Whale? --how long ago? The White Whale, said the Englishman, pointing his ivory ..

arm towards the East, and taking a rueful sight along it, as if it had been a telescope; There I saw him, on the Line, last season. And he took that arm off, did he? asked Ahab, now sliding down from the capstan, and resting on the Englishman's shoulder, as he did so. Aye, he was the cause of it, at least; and that leg, too? Spin me the yarn, said Ahab; how was it? It was the first time in my life that I ever cruised on the Line, began the Englishman. I was ignorant of the White Whale at that time. Well, one day we lowered for a pod of four or five whales, and my boat fastened to one of them; a regular circus horse he was, too, that went milling and milling round so, that my boat's crew could only trim dish, by sitting all their sterns on the outer gunwale. Presently up breaches from the bottom of the sea a bouncing great whale, with a milky-white head and hump, all crows' feet and wrinkles. It was he, it was he! cried Ahab, suddenly letting out his suspended breath. And harpoons sticking in near his starboard fin. Aye, aye --they were mine -- my irons, cried Ahab, exultingly -- but on! Give me a chance, then, said the Englishman, good-humoredly. Well, this old great-grandfather, with the white head and hump, runs all afoam into the pod, and goes to snapping furiously at my fast-line. Aye, I see! --wanted to part it; free the fast-fish --an old trick --I know him. How it was exactly, continued the one-armed commander, I do not know; but in biting the line, it got foul of his teeth, caught there somehow; but we didn't know it then; so that when we afterwards pulled on the line, bounce we came plump on to his hump! instead of the other whale's that went off to windward, all fluking. Seeing how matters stood, and what a noble great whale it was --the noblest and biggest I ever saw, sir, in my life --I resolved to capture him, spite of the boiling rage he seemed to be in. And thinking the hap-hazard line would get loose, or the tooth it was tangled to might draw (for I have ..

a devil of a boat's crew for a pull on a whale-line); seeing all this, I say, I jumped into my first mate's boat --Mr. Mounttop's here (by the way, Captain --Mounttop; Mounttop--the captain); --as I was saying, I jumped into Mounttop's boat, which, d'ye see, was gunwale and gunwale with mine, then; and snatching the first harpoon, let this old great-grandfather have it. But, Lord, look you, sir --hearts and souls alive, man --the next instant, in a jiff, I was blind as a bat --both eyes out --all befogged and bedeadened with black foam --the whale's tail looming straight up out of it, perpendicular in the air, like a marble steeple. No use sterning all, then; but as I was groping at midday, with a blinding sun, all crown-jewels; as I was groping, I say, after the second iron, to toss it overboard --down comes the tail like a Lima tower, cutting my boat in two, leaving each half in splinters; and, flukes first, the white hump backed through the wreck, as though it was all chips. We all struck out. To escape his terrible flailings, I seized hold of my harpoon-pole sticking in him, and for a moment clung to that like a sucking fish. But a combing sea dashed me off, and at the same instant, the fish, taking one good dart forwards, went down like a flash; and the barb of that cursed second iron towing along near me caught me here (clapping his hand just below his shoulder); yes, caught me just here, I say, and bore me down to Hell's flames, I was thinking; when, when, all of a sudden, thank the good God, the barb ript its way along the flesh --clear along the whole length of my arm --came out nigh my wrist, and up i floated; --and that gentleman there will tell you the rest (by the way, captain --Dr. Bunger, ship's surgeon: Bunger, my lad, -- the captain). Now, Bunger boy, spin your part of the yarn. The professional gentleman thus familiarly pointed out, had been all the time standing near them, with nothing specific visible, to denote his gentlemanly rank on board. His face was an exceedingly round but sober one; he was dressed in a faded blue woollen frock or shirt, and patched trowsers; and had thus far been dividing his attention between a marlingspike he held in one hand, and a pill-box held in the other, occasionally casting a critical glance at the ivory limbs of the two crippled captains. But, at his superior's introduction of him to Ahab, he ..

politely bowed, and straightway went on to do his captain's bidding. It was a shocking bad wound, began the whale-surgeon; and, taking my advice, Captain Boomer here, stood our old Sammy-- Samuel Enderby is the name of my ship, interrupted the one-armed captain, addressing Ahab; go on, boy. Stood our old Sammy off to the northward, to get out of the blazing hot weather there on the Line. But it was no use --I did all I could; sat up with him nights; was very severe with him in the matter of diet-- Oh, very severe! chimed in the patient himself; then suddenly altering his voice, Drinking hot rum toddies with me every night, till he couldn't see to put on the bandages; and sending me to bed, half seas over, about three o'clock in the morning. Oh, ye stars! he sat up with me indeed, and was very severe in my diet. Oh! a great watcher, and very dietetically severe, is Dr. Bunger. (Bunger, you dog, laugh out! why don't ye? You know you're a precious jolly rascal.) But, heave ahead, boy, I'd rather be killed by you than kept alive by any other man. My captain, you must have ere this perceived, respected sir --said the imperturbable godly-looking Bunger, slightly bowing to Ahab -- is apt to be facetious at times; he spins us many clever things of that sort. But I may as well say --en passant, as the French remark --that I myself --that is to say, Jack Bunger, late of the reverend clergy --am a strict total abstinence man; I never drink-- Water! cried the captain; he never drinks it; it's a sort of fits to him; fresh water throws him into the hydrophobia; but go on --go on with the arm story. Yes, I may as well, said the surgeon, coolly. I was about observing, sir, before Captain Boomer's facetious interruption, that spite of my best and severest endeavors, the wound kept getting worse and worse; the truth was, sir, it was as ugly gaping wound as surgeon ever saw; more than two feet and several inches long. I measured it with the lead line. In short, it grew black; I knew what was threatened, and off it came. ..

But I had no hand in shipping that ivory arm there; that thing is against all rule --pointing at it with the marlingspike -- that is the captain's work, not mine; he ordered the carpenter to make it; he had that club-hammer there put to the end, to knock some one's brains out with, I suppose, as he tried mine once. He flies into diabolical passions sometimes. Do ye see this dent, sir --removing his hat, and brushing aside his hair, and exposing a bowl-like cavity in his skull, but which bore not the slightest scarry trace, or any token of ever having been a wound -- Well, the captain there will tell you how that came here; he knows. No, I don't, said the captain, but his mother did; he was born with it. Oh, you solemn rogue, you --you Bunger! was there ever such another Bunger in the watery world? Bunger, when you die, you ought to die in pickle, you dog; you should be preserved to future ages, you rascal. What became of the White Whale? now cried Ahab, who thus far had been impatiently listening to this bye-play between the two Englishmen. Oh! cried the one-armed captain, Oh, yes! Well; after he sounded, we didn't see him again for some time; in fact, as I before hinted, I didn't then know what whale it was that had served me such a trick, till some time afterwards, when coming back to the Line, we heard about Moby Dick --as some call him --and then I knew it was he. Did'st thou cross his wake again? Twice. But could not fasten? Didn't want to try to: ain't one limb enough? What should I do without this other arm? And I'm thinking Moby Dick doesn't bite so much as he swallows. Well, then, interrupted Bunger, give him your left arm for bait to get the right. Do you know, gentlemen --very gravely and mathematically bowing to each Captain in succession -- Do you know, gentlemen, that the digestive organs of the whale are so inscrutably constructed by Divine Providence, that it is quite impossible for him to completely digest even a ..

man's arm? And he knows it too. So that what you take for the White Whale's malice is only his awkwardness. For he never means to swallow a single limb; he only thinks to terrify by feints. But sometimes he is like the old juggling fellow, formerly a patient of mine in Ceylon, that making believe swallow jack-knives, once upon a time let one drop into him in good earnest, and there it stayed for a twelvemonth or more; when I gave him an emetic, and he heaved it up in small tacks, d'ye see. No possible way for him to digest that jack-knife, and fully incorporate it into his general bodily system. Yes, Captain Boomer, if you are quick enough about it, and have a mind to pawn one arm for the sake of the privilege of giving decent burial to the other, why in that case the arm is yours; only let the whale have another chance at you shortly, that's all. No, thank ye, Bunger, said the english captain, he's welcome to the arm he has, since I can't help it, and didn't know him then; but not to another one. No more White Whales for me; I've lowered for him once, and that has satisfied me. There would be great glory in killing him, I know that; and there is a ship-load of precious sperm in him, but, hark ye, he's best let alone; don't you think so, Captain? --glancing at the ivory leg. He is. But he will still be hunted, for all that. What is best let alone, that accursed thing is not always what least allures. He's all a magnet! How long since thou saw'st him last? Which way heading? Bless my soul, and curse the foul fiend's, cried Bunger, stoopingly walking round Ahab, and like a dog, strangely snuffing; this man's blood --bring the thermometer; --it's at the boiling point! --his pulse makes these planks beat! --sir! --taking a lancet from his pocket, and drawing near to Ahab's arm. Avast! roared Ahab, dashing him against the bulwarks -- Man the boat! Which way heading? Good God! cried the English Captain, to whom the question was put. What's the matter? He was heading east, I think. --Is your Captain crazy? whispering Fedallah. But Fedallah, putting a finger on his lip, slid over the bulwarks ..

to take the boat's steering oar, and Ahab, swinging the cutting-tackle towards him, commanded the ship's sailors to stand by to lower. In a moment he was standing in the boat's stern, and the Manilla men were springing to their oars. In vain the English Captain hailed him. With back to the stranger ship, and face set like a flint to his own, Ahab stood upright till alongside of the Pequod. ..

.. < chapter ci 10 THE DECANTER > Ere the English ship fades from sight, be it set down here, that she hailed from London, and was named after the late Samuel Enderby, merchant of that city, the original of the famous whaling house of enderby and sons; a house which in my poor whaleman's opinion, comes not far behind the united royal houses of the Tudors and Bourbons, in point of real historical interest. How long, prior to the year of our Lord 0083 , this great whaling house was in existence, my numerous fish-documents do not make plain; but in that year ( ) it fitted out the first English ships that ever regularly hunted the Sperm Whale; though for some score of years previous (ever since ) our valiant Coffins and Maceys of Nantucket and the Vineyard had in large fleets pursued that Leviathan, but only in the North and South Atlantic: not elsewhere. Be it distinctly recorded here, that the Nantucketers were the first among mankind to harpoon with civilized steel the great Sperm Whale; and that for half a century they were the only people of the whole globe who so harpooned him. In , a fine ship, the Amelia, fitted out for the express purpose, and at the sole charge of the vigorous Enderbys, boldly rounded Cape Horn, and was the first among the nations to lower a whale-boat of any sort in the great South Sea. The ..

voyage was a skilful and lucky one; and returning to her berth with her hold full of the precious sperm, the Amelia's example was soon followed by other ships, English and American, and thus the vast Sperm Whale grounds of the Pacific were thrown open. But not content with this good deed, the indefatigable house again bestirred itself: Samuel and all his Sons --how many, their mother only knows --and under their immediate auspices, and partly, I think, at their expense, the British government was induced to send the sloop-of-war Rattler on a whaling voyage of discovery into the South Sea. Commanded by a naval Post-Captain, the Rattler made a rattling voyage of it, and did some service; how much does not appear. But this is not all. In 0084 , the same house fitted out a discovery whale ship of their own, to go on a tasting cruise to the remote waters of Japan. That ship --well called the Syren --made a noble experimental cruise; and it was thus that the great Japanese Whaling Ground first became generally known. The Syren in this famous voyage was commanded by a Captain Coffin, a Nantucketer. All honor to the Enderbies, therefore, whose house, I think, exists to the present day; though doubtless the original Samuel must long ago have slipped his cable for the great South Sea of the other world. The ship named after him was worthy of the honor, being a very fast sailer and a noble craft every way. I boarded her once at midnight somewhere off the Patagonian coast, and drank good flip down in the forecastle. It was a fine gam we had, and they were all trumps --every soul on board. A short life to them, and a jolly death. And that fine gam I had --long, very long after old Ahab touched her planks with his ivory heel -- it minds me of the noble, solid, Saxon hospitality of that ship; and may my parson forget me, and the devil remember me, if I ever lose sight of it. Flip? Did I say we had flip? Yes, and we flipped it at the rate of ten gallons the hour; and when the squall came (for it's squally off there by Patagonia), and all hands --visitors and all --were called to reef topsails, we were so top-heavy that we had to swing each other aloft in bowlines; and we ignorantly furled the skirts of our jackets into ..

the sails, so that we hung there, reefed fast in the howling gale, a warning example to all drunken tars. However, the masts did not go overboard; and by and bye we scrambled down, so sober, that we had to pass the flip again, though the savage salt spray bursting down the forecastle scuttle, rather too much diluted and pickled it to my taste. The beef was fine --tough, but with body in it. They said it was bull-beef; others, that it was dromedary beef; but i do not know, for certain, how that was. they had dumplings too; small, but substantial, symmetrically globular, and indestructible dumplings. I fancied that you could feel them, and roll them about in you after they were swallowed. If you stooped over too far forward, you risked their pitching out of you like billiard-balls. The bread --but that couldn't be helped; besides, it was an anti-scorbutic; in short, the bread contained the only fresh fare they had. But the forecastle was not very light, and it was very easy to step over into a dark corner when you ate it. But all in all, taking her from truck to helm, considering the dimensions of the cook's boilers, including his own live parchment boilers; fore and aft, I say, the Samuel Enderby was a jolly ship; of good fare and plenty; fine flip and strong; crack fellows all, and capital from boot heels to hat-band. But why was it, think ye, that the Samuel Enderby, and some other English whalers I know of --not all though --were such famous, hospitable ships; that passed round the beef, and the bread, and the can, and the joke; and were not soon weary of eating, and drinking, and laughing? I will tell you. The abounding good cheer of these English whalers is matter for historical research. Nor have I been at all sparing of historical whale research, when it has seemed needed. The English were preceded in the whale fishery by the Hollanders, Zealanders, and Danes; from whom they derived many terms still extant in the fishery; and what is yet more, their fat old fashions, touching plenty to eat and drink. For, as a general thing, the English merchant-ship scrimps her crew; but not so the English whaler. Hence, in the English, this thing of whaling good cheer is not normal and natural, but incidental and particular; and, therefore, must have some special origin, ..

which is here pointed out, and will be still further elucidated. During my researches in the leviathanic histories, I stumbled upon an ancient Dutch volume, which, by the musty whaling smell of it, I knew must be about whalers. The title was, Dan Coopman, wherefore I concluded that this must be the invaluable memoirs of some Amsterdam cooper in the fishery, as every whale ship must carry its cooper. I was reinforced in this opinion by seeing that it was the production of one Fitz Swackhammer. But my friend Dr. Snodhead, a very learned man, professor of Low Dutch and High German in the college of Santa Claus and St. Pott's, to whom I handed the work for translation, giving him a box of sperm candles for his trouble -- this same Dr. Snodhead, so soon as he spied the book, assured me that Dan Coopman did not mean The Cooper, but The Merchant. In short, this ancient and learned Low Dutch book treated of the commerce of Holland; and, among other subjects, contained a very interesting account of its whale fishery. And in this chapter it was, headed Smeer, or Fat, that I found a long detailed list of the outfits for the larders and cellars of 180 sail of Dutch whalemen; from which list, as translated by Dr. Snodhead. I transcribe the following: 0084400,000 lbs. of beef. 60,000 lbs. Friesland pork. 150,000 lbs. of stock fish. 550,000 lbs. of biscuit. 72,000 lbs. of soft bread. 2,800 firkins of butter. 20,000 lbs. of Texel and Leyden cheese. 144,000 lbs. cheese (probably an inferior article). 550 ankers of Geneva. 10,800 barrels of beer. Most statistical tables are parchingly dry in the reading; not so in the present case, however, where the reader is flooded with whole pipes, barrels, quarts, and gills of good gin and good cheer. At the time, I devoted three days to the studious digesting of all this beer, beef, and bread, during which many profound ..

thoughts were incidentally suggested to me, capable of a transcendental and Platonic application; and, furthermore, I compiled supplementary tables of my own, touching the probable quantity of stock-fish, etc., consumed by every Low Dutch harpooneer in that ancient Greenland and Spitzbergen whale fishery. In the first place, the amount of butter, and Texel and Leyden cheese consumed, seems amazing. I impute it, though, to their naturally unctuous natures, being rendered still more unctuous by the nature of their vocation, and especially by their pursuing their game in those frigid Polar Seas, on the very coasts of that Esquimaux country where the convivial natives pledge each other in bumpers of train oil. The quantity of beer, too, is very large, 10,800 barrels. Now, as those polar fisheries could only be prosecuted in the short summer of that climate, so that the whole cruise of one of these Dutch whalemen, including the short voyage to and from the Spitzbergen sea, did not much exceed three months, say, and reckoning 30 men to each of their fleet of 180 sail, we have 5,400 Low Dutch seamen in all; therefore, I say, we have precisely two barrels of beer per man, for a twelve weeks' allowance, exclusive of his fair proportion of that 550 ankers of gin. Now, whether these gin and beer harpooneers, so fuddled as one might fancy them to have been, were the right sort of men to stand up in a boat's head, and take good aim at flying whales; this would seem somewhat improbable. Yet they did aim at them, and hit them too. But this was very far North, be it remembered, where beer agrees well with the constitution; upon the Equator, in our southern fishery, beer would be apt to make the harpooneer sleepy at the mast-head and boozy in his boat; and grievous loss might ensue to Nantucket and New Bedford. But no more; enough has been said to show that the old Dutch whalers of two or three centuries ago were high livers; and that the English whalers have not neglected so excellent an example. For, say they, when cruising in an empty ship, if you can get nothing better out of the world, get a good dinner out of it, at least. And this empties the decanter. ..

.. < chapter cii 2 A BOWER IN THE ARSACIDES > Hitherto, in descriptively treating of the Sperm Whale, I have chiefly dwelt upon the marvels of his outer aspect; or separately and in detail upon some few interior structural features. But to a large and thorough sweeping comprehension of him, it behoves me now to unbutton him still further, and untagging the points of his hose, unbuckling his garters, and casting loose the hooks and the eyes of the joints of his innermost bones, set him before you in his ultimatum; that is to say, in his unconditional skeleton. But how now, Ishmael? How is it, that you, a mere oarsman in the fishery, pretend to know aught about the subterranean parts of the whale? Did erudite Stubb, mounted upon your capstan, deliver lectures on the anatomy of the Cetacea; and by help of the windlass, hold up a specimen rib for exhibition? Explain thyself, Ishmael. Can you land a full-grown whale on your deck for examination, as a cook dishes a roast-pig? Surely not. A veritable witness have you hitherto been, Ishmael; but have a care how you seize the privilege of Jonah alone; the privilege of discoursing upon the joists and beams; the rafters, ridge-pole, sleepers, and under-pinnings, making up the frame-work of leviathan; and belike of the tallow-vats, dairy-rooms, butteries, and cheeseries in his bowels. I confess, that since Jonah, few whalemen have penetrated very far beneath the skin of the adult whale; nevertheless, I have been blessed with an opportunity to dissect him in miniature. In a ship I belonged to, a small cub Sperm Whale was once bodily hoisted to the deck for his poke or bag, to make sheaths for the barbs of the harpoons, and for the heads of the lances. Think you I let that chance go, without using my boat-hatchet and jack-knife, and breaking the seal and reading all the contents of that young cub? ..

And as for my exact knowledge of the bones of the leviathan in their gigantic, full grown development, for that rare knowledge I am indebted to my late royal friend Tranquo, king of Tranque, one of the Arsacides. For being at Tranque, years ago, when attached to the trading-ship Dey of Algiers, I was invited to spend part of the Arsacidean holidays with the lord of Tranque, at his retired palm villa at Pupella; a sea-side glen not very far distant from what our sailors called Bamboo-Town, his capital. Among many other fine qualities, my royal friend Tranquo, being gifted with a devout love for all matters of barbaric vertu, had brought together in Pupella whatever rare things the more ingenious of his people could invent; chiefly carved woods of wonderful devices, chiselled shells, inlaid spears, costly paddles, aromatic canoes; and all these distributed among whatever natural wonders, the wonder-freighted, tribute-rendering waves had cast upon his shores. Chief among these latter was a great Sperm Whale, which, after an unusually long raging gale, had been found dead and stranded, with his head against a cocoa-nut tree, whose plumage-like, tufted droopings seemed his verdant jet. When the vast body had at last been stripped of its fathom-deep enfoldings, and the bones become dust dry in the sun, then the skeleton was carefully transported up the Pupella glen, where a grand temple of lordly palms now sheltered it. The ribs were hung with trophies; the vertebrae were carved with Arsacidean annals, in strange hieroglyphics; in the skull, the priests kept up an unextinguished aromatic flame, so that the mystic head again sent forth its vapory spout; while, suspended from a bough, the terrific lower jaw vibrated over all the devotees, like the hair-hung sword that so affrighted damocles. it was a wondrous sight. the wood was green as mosses of the icy Glen; the trees stood high and haughty, feeling their living sap; the industrious earth beneath was as a weaver's loom, with a gorgeous carpet on it, whereof the ground-vine tendrils formed the warp and woof, and the living flowers the figures. All the trees, with all their laden branches; all the shrubs, and ferns, and grasses; the message-carrying air; all ..

these unceasingly were active. Through the lacings of the leaves, the great sun seemed a flying shuttle weaving the unwearied verdure. Oh, busy weaver! unseen weaver! --pause! --one word! -- whither flows the fabric? what palace may it deck? wherefore all these ceaseless toilings? Speak, weaver! --stay thy hand! -- but one single word with thee! Nay --the shuttle flies --the figures float from forth the loom; the freshet-rushing carpet for ever slides away. The weaver-god, he weaves; and by that weaving is he deafened, that he hears no mortal voice; and by that humming, we, too, who look on the loom are deafened; and only when we escape it shall we hear the thousand voices that speak through it. For even so it is in all material factories. The spoken words that are inaudible among the flying spindles; those same words are plainly heard without the walls, bursting from the opened casements. Thereby have villanies been detected. Ah, mortal! then, be heedful; for so, in all this din of the great world's loom, thy subtlest thinkings may be overheard afar. Now, amid the green, life-restless loom of that Arsacidean wood, the great, white, worshipped skeleton lay lounging --a gigantic idler! Yet, as the ever-woven verdant warp and woof intermixed and hummed around him, the mighty idler seemed the cunning weaver; himself all woven over with the vines; every month assuming greener, fresher verdure; but himself a skeleton. Life folded Death; Death trellised Life; the grim god wived with youthful Life, and begat him curly-headed glories. Now, when with royal Tranquo I visited this wondrous whale, and saw the skull an altar, and the artificial smoke ascending from where the real jet had issued, I marvelled that the king should regard a chapel as an object of vertu. He laughed. But more I marvelled that the priests should swear that smoky jet of his was genuine. To and fro I paced before this skeleton --brushed the vines aside --broke through the ribs --and with a ball of Arsacidean twine, wandered, eddied long amid its many winding, shaded collonades and arbors. But soon my line was out; and following it back, I emerged from the opening where I entered. I saw no living thing within; naught was there but bones. ..

Cutting me a green measuring-rod, I once more dived within the skeleton. From their arrow-slit in the skull, the priests perceived me taking the altitude of the final rib. How now! they shouted; Dar'st thou measure this our god! That's for us. Aye, priests --well, how long do ye make him, then? But hereupon a fierce contest rose among them, concerning feet and inches; they cracked each other's sconces with their yard-sticks -- the great skull echoed --and seizing that lucky chance, I quickly concluded my own admeasurements. These admeasurements I now propose to set before you. But first, be it recorded, that, in this matter, I am not free to utter any fancied measurement I please. Because there are skeleton authorities you can refer to, to test my accuracy. There is a Leviathanic Museum, they tell me, in Hull, England, one of the whaling ports of that country, where they have some fine specimens of fin-backs and other whales. Likewise, I have heard that in the museum of Manchester, in New Hampshire, they have what the proprietors call the only perfect specimen of a Greenland or River Whale in the United States. Moreover, at a place in Yorkshire, England, Burton constable by name, a certain sir clifford constable has in his possession the skeleton of a Sperm Whale, but of moderate size, by no means of the full-grown magnitude of my friend King Tranquo's. In both cases, the stranded whales to which these two skeletons belonged, were originally claimed by their proprietors upon similar grounds. King Tranquo seizing his because he wanted it; and Sir Clifford, because he was lord of the seignories of those parts. Sir Clifford's whale has been articulated throughout; so that, like a great chest of drawers, you can open and shut him, in all his bony cavities --spread out his ribs like a gigantic fan --and swing all day upon his lower jaw. Locks are to be put upon some of his trap-doors and shutters; and a footman will show round future visitors with a bunch of keys at his side. Sir Clifford thinks of charging twopence for a peep at the whispering gallery in the spinal column; threepence to hear the echo in the hollow of his cerebellum; and sixpence for the unrivalled view from his forehead. The skeleton dimensions I shall now proceed to set down are ..

copied verbatim from my right arm, where I had them tattooed; as in my wild wanderings at that period, there was no other secure way of preserving such valuable statistics. But as I was crowded for space, and wished the other parts of my body to remain a blank page for a poem I was then composing --at least, what untattooed parts might remain --I did not trouble myself with the odd inches; nor, indeed, should inches at all enter into a congenial admeasurement of the whale. ..

.. < chapter ciii 10 MEASUREMENT OF THE WHALE'S SKELETON > In the first place, I wish to lay before you a particular, plain statement, touching the living bulk of this leviathan, whose skeleton we are briefly to exhibit. Such a statement may prove useful here. According to a careful calculation I have made, and which I partly base upon Captain Scoresby's estimate, of seventy tons for the largest sized Greenland whale of sixty feet in length; according to my careful calculation, I say, a Sperm Whale of the largest magnitude, between eighty-five and ninety feet in length, and something less than forty feet in its fullest circumference, such a whale will weigh at least ninety tons; so that reckoning thirteen men to a ton, he would considerably outweigh the combined population of a whole village of one thousand one hundred inhabitants. Think you not then that brains, like yoked cattle, should be put to this leviathan, to make him at all budge to any landsman's imagination? Having already in various ways put before you his skull, spout-hole, jaw, teeth, tail, forehead, fins, and divers other parts, I shall now simply point out what is most interesting in the general bulk of his unobstructed bones. But as the colossal skull embraces so very large a proportion of the entire extent ..

of the skeleton; as it is by far the most complicated part; and as nothing is to be repeated concerning it in this chapter, you must not fail to carry it in your mind, or under your arm, as we proceed, otherwise you will not gain a complete notion of the general structure we are about to view. In length, the Sperm Whale's skeleton at Tranque measured seventy-two feet; so that when fully invested and extended in life, he must have been ninety feet long; for in the whale, the skeleton loses about one fifth in length compared with the living body. Of this seventy-two feet, his skull and jaw comprised some twenty feet, leaving some fifty feet of plain back-bone. Attached to this back-bone, for something less than a third of its length, was the mighty circular basket of ribs which once enclosed his vitals. To me this vast ivory-ribbed chest, with the long, unrelieved spine, extending far away from it in a straight line, not a little resembled the hull of a great ship new-laid upon the stocks, when only some twenty of her naked bow-ribs are inserted, and the keel is otherwise, for the time, but a long, disconnected timber. The ribs were ten on a side. The first, to begin from the neck, was nearly six feet long; the second, third, and fourth were each successively longer, till you came to the climax of the fifth, or one of the middle ribs, which measured eight feet and some inches. From that part, the remaining ribs diminished, till the tenth and last only spanned five feet and some inches. In general thickness, they all bore a seemly correspondence to their length. The middle ribs were the most arched. In some of the Arsacides they are used for beams whereon to lay foot-path bridges over small streams. In considering these ribs, I could not but be struck anew with the circumstance, so variously repeated in this book, that the skeleton of the whale is by no means the mould of his invested form. The largest of the Tranque ribs, one of the middle ones, occupied that part of the fish which, in life, is greatest in depth. Now, the greatest depth of the invested body of this particular whale must have been at least sixteen feet; whereas, the corresponding rib measured but little more than eight feet. So that this rib only conveyed half of the true notion of the living ..

magnitude of that part. Besides, for some way, where I now saw but a naked spine, all that had been once wrapped round with tons of added bulk in flesh, muscle, blood, and bowels. Still more, for the ample fins, I here saw but a few disordered joints; and in place of the weighty and majestic, but boneless flukes, an utter blank! How vain and foolish, then, thought I, for timid untravelled man to try to comprehend aright this wondrous whale, by merely poring over his dead attenuated skeleton, stretched in this peaceful wood. no. only in the heart of quickest perils; only when within the eddyings of his angry flukes; only on the profound unbounded sea, can the fully invested whale be truly and livingly found out. But the spine. For that, the best way we can consider it is, with a crane, to pile its bones high up on end. No speedy enterprise. But now it's done, it looks much like Pompey's Pillar. There are forty and odd vertebrae in all, which in the skeleton are not locked together. They mostly lie like the great knobbed blocks on a Gothic spire, forming solid courses of heavy masonry. The largest, a middle one, is in width something less than three feet, and in depth more than four. The smallest, where the spine tapers away into the tail, is only two inches in width, and looks something like a white billiard-ball. I was told that there were still smaller ones, but they had been lost by some little cannibal urchins, the priest's children, who had stolen them to play marbles with. Thus we see how that the spine of even the hugest of living things tapers off at last into simple child's play. ..

.. < chapter civ 30 THE FOSSIL WHALE > From his mighty bulk the whale affords a most congenial theme whereon to enlarge, amplify, and generally expatiate. Would you, you could not compress him. By good rights he ..

should only be treated of in imperial folio. Not to tell over again his furlongs from spiracle to tail, and the yards he measures about the waist; only think of the gigantic involutions of his intestines, where they lie in him like great cables and hausers coiled away in the subterranean orlop-deck of a line-of-battle-ship. Since I have undertaken to manhandle this Leviathan, it behoves me to approve myself omnisciently exhaustive in the enterprise; not overlooking the minutest seminal germs of his blood, and spinning him out to the uttermost coil of his bowels. Having already described him in most of his present habitatory and anatomical peculiarities, it now remains to magnify him in an archaeological, fossiliferous, and antediluvian point of view. Applied to any other creature than the Leviathan --to an ant or a flea --such portly terms might justly be deemed unwarrantably grandiloquent. But when Leviathan is the text, the case is altered. Fain am I to stagger to this emprise under the weightiest words of the dictionary. And here be it said, that whenever it has been convenient to consult one in the course of these dissertations, I have invariably used a huge quarto edition of Johnson, expressly purchased for that purpose; because that famous lexicographer's uncommon personal bulk more fitted him to compile a lexicon to be used by a whale author like me. One often hears of writers that rise and swell with their subject, though it may seem but an ordinary one. How, then, with me, writing of this Leviathan? Unconsciously my chirography expands into placard capitals. Give me a condor's quill! Give me Vesuvius' crater for an inkstand! Friends, hold my arms! For in the mere act of penning my thoughts of this Leviathan, they weary me, and make me faint with their out-reaching comprehensiveness of sweep, as if to include the whole circle of the sciences, and all the generations of whales, and men, and mastodons, past, present, and to come, with all the revolving panoramas of empire on earth, and throughout the whole universe, not excluding its suburbs. Such, and so magnifying, is the virtue of a large and liberal theme! We expand to its bulk. To produce a mighty book, you must choose a ..

mighty theme. No great and enduring volume can ever be written on the flea, though many there be who have tried it. Ere entering upon the subject of Fossil Whales, I present my credentials as a geologist, by stating that in my miscellaneous time i have been a stone-mason, and also a great digger of ditches, canals, and wells, wine-vaults, cellars, and cisterns of all sorts. Likewise, by way of preliminary, I desire to remind the reader, that while in the earlier geological strata there are found the fossils of monsters now almost completely extinct; the subsequent relics discovered in what are called the Tertiary formations seem the connecting, or at any rate intercepted links, between the antichronical creatures, and those whose remote posterity are said to have entered the Ark; all the Fossil Whales hitherto discovered belong to the Tertiary period, which is the last preceding the superficial formations. And though none of them precisely answer to any known species of the present time, they are yet sufficiently akin to them in general respects, to justify their taking ranks as Cetacean fossils. Detached broken fossils of pre-adamite whales, fragments of their bones and skeletons, have within thirty years past, at various intervals, been found at the base of the Alps, in Lombardy, in France, in England, in Scotland, and in the States of Louisiana, Mississippi, and Alabama. Among the more curious of such remains is part of a skull, which in the year was disinterred in the Rue Dauphine in Paris, a short street opening almost directly upon the palace of the Tuileries; and bones disinterred in excavating the great docks of Antwerp, in Napoleon's time. Cuvier pronounced these fragments to have belonged to some utterly unknown Leviathanic species. But by far the most wonderful of all cetacean relics was the almost complete vast skeleton of an extinct monster, found in the year , on the plantation of Judge Creagh, in Alabama. The awe-stricken credulous slaves in the vicinity took it for the bones of one of the fallen angels. The Alabama doctors declared it a huge reptile, and bestowed upon it the name of Basilosaurus. But some specimen bones of it being taken across the sea to owen, the english anatomist, it turned out that this alleged reptile was a whale, though of a departed species. ..

A significant illustration of the fact, again and again repeated in this book, that the skeleton of the whale furnishes but little clue to the shape of his fully invested body. So Owen rechristened the monster Zeuglodon; and in his paper read before the London Geological Society, pronounced it, in substance, one of the most extraordinary creatures which the mutations of the globe have blotted out of existence. When I stand among these mighty Leviathan skeletons, skulls, tusks, jaws, ribs, and vertebrae, all characterized by partial resemblances to the existing breeds of sea-monsters; but at the same time bearing on the other hand similar affinities to the annihilated antichronical Leviathans, their incalculable seniors; I am, by a flood, borne back to that wondrous period, ere time itself can be said to have begun; for time began with man. Here Saturn's grey chaos rolls over me, and I obtain dim, shuddering glimpses into those Polar eternities; when wedged bastions of ice pressed hard upon what are now the Tropics; and in all the 25,000 miles of this world's circumference, not an inhabitable hand's breadth of land was visible. Then the whole world was the whale's; and, king of creation, he left his wake along the present lines of the Andes and the Himmalehs. Who can show a pedigree like Leviathan? Ahab's harpoon had shed older blood than the Pharaoh's. Methuselah seems a school-boy. I look round to shake hands with Shem. I am horror-struck at this antemosaic, unsourced existence of the unspeakable terrors of the whale, which, having been before all time, must needs exist after all humane ages are over. But not alone has this Leviathan left his pre-adamite traces in the stereotype plates of nature, and in limestone and marl bequeathed his ancient bust; but upon Egyptian tablets, whose antiquity seems to claim for them an almost fossiliferous character, we find the unmistakable print of his fin. In an apartment of the great temple of Denderah, some fifty years ago, there was discovered upon the granite ceiling a sculptured and painted planisphere, abounding in centaurs, griffins, and dolphins, similar to the grotesque figures on the celestial globe of the moderns. Gliding among them, old Leviathan swam as of yore; was there swimming in that planisphere, centuries before Solomon was cradled. ..

Nor must there be omitted another strange attestation of the antiquity of the whale, in his own osseous post-diluvian reality, as set down by the venerable John Leo, the old Barbary traveller. Not far from the Sea-side, they have a Temple, the Rafters and Beams of which are made of Whale-Bones; for Whales of a monstrous size are oftentimes cast up dead upon that shore. The Common People imagine, that by a secret Power bestowed by God upon the Temple, no Whale can pass it without immediate death. But the truth of the Matter is, that on either side of the Temple, there are Rocks that shoot two Miles into the Sea, and wound the Whales when they light upon 'em. They keep a Whale's Rib of an incredible length for a Miracle, which lying upon the Ground with its convex part uppermost, makes an Arch, the Head of which cannot be reached by a Man upon a Camel's Back. This Rib (says John Leo) is said to have layn there a hundred Years before I saw it. Their Historians affirm, that a Prophet who prophesy'd of Mahomet, came from this Temple, and some do not stand to assert, that the Prophet Jonas was cast forth by the Whale at the Base of the Temple. In this Afric Temple of the Whale I leave you, reader, and if you be a Nantucketer, and a whaleman, you will silently worship there. ..

.. < chapter cv 24 DOES THE WHALE'S MAGNITUDE DIMINISH? WILL HE PERISH? > Inasmuch, then, as this Leviathan comes floundering down upon us from the head-waters of the Eternities, it may be fitly inquired, whether, in the long course of his generations, he has not degenerated from the original bulk of his sires. But upon investigation we find, that not only are the whales of the present day superior in magnitude to those whose fossil remains are found in the Tertiary system (embracing a distinct geological period prior to man), but of the whales found in that ..

Tertiary system, those belonging to its latter formations exceed in size those of its earlier ones. Of all the pre-adamite whales yet exhumed, by far the largest is the Alabama one mentioned in the last chapter, and that was less than seventy feet in length in the skeleton. Whereas, we have already seen, that the tape-measure gives seventy-two feet for the skeleton of a large sized modern whale. And I have heard, on whalemen's authority, that Sperm Whales have been captured near a hundred feet long at the time of capture. But may it not be, that while the whales of the present hour are an advance in magnitude upon those of all previous geological periods; may it not be, that since Adam's time they have degenerated? Assuredly, we must conclude so, if we are to credit the accounts of such gentlemen as Pliny, and the ancient naturalists generally. For Pliny tells us of whales that embraced acres of living bulk, and Aldrovandus of others which measured eight hundred feet in length --Rope Walks and Thames Tunnels of Whales! And even in the days of Banks and Solander, Cooke's naturalists, we find a Danish member of the Academy of Sciences setting down certain Iceland Whales (reydan-siskur, or Wrinkled Bellies) at one hundred and twenty yards; that is, three hundred and sixty feet. And Lacepede, the French naturalist, in his elaborate history of whales, in the very beginning of his work (page 3), sets down the Right Whale at one hundred metres, three hundred and twenty-eight feet. And this work was published so late as A. D. . But will any whaleman believe these stories? No. The whale of to-day is as big as his ancestors in Pliny's time. And if ever I go where Pliny is, I, a whaleman (more than he was), will make bold to tell him so. Because I cannot understand how it is, that while the Egyptian mummies that were buried thousands of years before even Pliny was born, do not measure so much in their coffins as a modern Kentuckian in his socks; and while the cattle and other animals sculptured on the oldest Egyptian and Nineveh tablets, by the relative proportions in which they are drawn, just as plainly prove that the high-bred, stall-fed, prize cattle of Smithfield, not only equal, but far exceed in magnitude the fattest of Pharaoh's fat kine; in the face of ..

all this, I will not admit that of all animals the whale alone should have degenerated. But still another inquiry remains; one often agitated by the more recondite Nantucketers. Whether owing to the almost omniscient look-outs at the mast-heads of the whale-ships, now penetrating even through Behring's straits, and into the remotest secret drawers and lockers of the world; and the thousand harpoons and lances darted along all continental coasts; the moot point is, whether Leviathan can long endure so wide a chase, and so remorseless a havoc; whether he must not at last be exterminated from the waters, and the last whale, like the last man, smoke his last pipe, and then himself evaporate in the final puff. Comparing the humped herds of whales with the humped herds of buffalo, which, not forty years ago, overspread by tens of thousands the prairies of Illinois and Missouri, and shook their iron manes and scowled with their thunder-clotted brows upon the sites of populous river-capitals, where now the polite broker sells you land at a dollar an inch; in such a comparison an irresistible argument would seem furnished, to show that the hunted whale cannot now escape speedy extinction. But you must look at this matter in every light. Though so short a period ago --not a good life-time --the census of the buffalo in Illinois exceeded the census of men now in London, and though at the present day not one horn or hoof of them remains in all that region; and though the cause of this wondrous extermination was the spear of man; yet the far different nature of the whale-hunt peremptorily forbids so inglorious an end to the Leviathan. Forty men in one ship hunting the Sperm Whale for forty-eight months think they have done extremely well, and thank God, if at last they carry home the oil of forty fish. Whereas, in the days of the old Canadian and Indian hunters and trappers of the West, when the far west (in whose sunset suns still rise) was a wilderness and a virgin, the same number of moccasined men, for the same number of months, mounted on horse instead of sailing in ships, would have slain not forty, but forty thousand and more buffaloes; a fact that, if need were, could be statistically stated. Nor, considered aright, does it seem any argument in favor ..

of the gradual extinction of the Sperm Whale, for example, that in former years (the latter part of the last century, say) these Leviathans, in small pods, were encountered much oftener than at present, and, in consequence, the voyages were not so prolonged, and were also much more remunerative. Because, as has been elsewhere noticed, those whales, influenced by some views to safety, now swim the seas in immense caravans, so that to a large degree the scattered solitaries, yokes, and pods, and schools of other days are now aggregated into vast but widely separated, unfrequent armies. That is all. And equally fallacious seems the conceit, that because the so-called whale-bone whales no longer haunt many grounds in former years abounding with them, hence that species also is declining. For they are only being driven from promontory to cape; and if one coast is no longer enlivened with their jets, then, be sure, some other and remoter strand has been very recently startled by the unfamiliar spectacle. Furthermore: concerning these last mentioned Leviathans, they have two firm fortresses, which, in all human probability, will for ever remain impregnable. And as upon the invasion of their valleys, the frosty Swiss have retreated to their mountains; so, hunted from the savannas and glades of the middle seas, the whale-bone whales can at last resort to their Polar citadels, and diving under the ultimate glassy barriers and walls there, come up among icy fields and floes; and in a charmed circle of everlasting December, bid defiance to all pursuit from man. But as perhaps fifty of these whale-bone whales are harpooned for one cachalot, some philosophers of the forecastle have concluded that this positive havoc has already very seriously diminished their battalions. But though for some time past a number of these whales, not less than 13,000 have been annually slain on the nor' west coast by the Americans alone; yet there are considerations which render even this circumstance of little or no account as an opposing argument in this matter. Natural as it is to be somewhat incredulous concerning the populousness of the more enormous creatures of the globe, yet what shall we say to Harto, the historian of Goa, when he tells us that at one hunting the King of Siam took elephants; ..

that in those regions elephants are numerous as droves of cattle in the temperate climes. And there seems no reason to doubt that if these elephants, which have now been hunted for thousands of years, by Semiramis, by Porus, by hannibal, and by all the successive monarchs of the East --if they still survive there in great numbers, much more may the great whale outlast all hunting, since he has a pasture to expatiate in, which is precisely twice as large as all Asia, both Americas, Europe and Africa, New Holland, and all the Isles of the sea combined. Moreover: we are to consider, that from the presumed great longevity of whales, their probably attaining the age of a century and more, therefore at any one period of time, several distinct adult generations must be contemporary. And what that is, we may soon gain some idea of, by imagining all the grave-yards, cemeteries, and family vaults of creation yielding up the live bodies of all the men, women, and children who were alive seventy-five years ago; and adding this countless host to the present human population of the globe. Wherefore, for all these things, we account the whale immortal in his species, however perishable in his individuality. He swam the seas before the continents broke water; he once swam over the site of the Tuileries, and Windsor Castle, and the Kremlin. In Noah's flood, he despised Noah's Ark; and if ever the world is to be again flooded, like the Netherlands, to kill off its rats, then the eternal whale will still survive, and rearing upon the topmost crest of the equatorial flood, spout his frothed defiance to the skies. ..

.. < chapter cvi 29 AHAB'S LEG > The precipitating manner in which Captain Ahab had quitted the Samuel Enderby of London, had not been unattended with some small violence to his own person. He had lighted with such energy upon a thwart of his boat that his ivory leg had ..

received a half-splintering shock. And when after gaining his own deck, and his own pivot-hole there, he so vehemently wheeled round with an urgent command to the steersman (it was, as ever, something about his not steering inflexibly enough); then, the already shaken ivory received such an additional twist and wrench, that though it still remained entire, and to all appearances lusty, yet Ahab did not deem it entirely trustworthy. And, indeed, it seemed small matter for wonder, that for all his pervading, mad recklessness, Ahab did at times give careful heed to the condition of that dead bone upon which he partly stood. For it had not been very long prior to the Pequod's sailing from Nantucket, that he had been found one night lying prone upon the ground, and insensible; by some unknown, and seemingly inexplicable, unimaginable casualty, his ivory limb having been so violently displaced, that it had stake-wise smitten, and all but pierced his groin; nor was it without extreme difficulty that the agonizing wound was entirely cured. Nor, at the time, had it failed to enter his monomaniac mind, that all the anguish of that then present suffering was but the direct issue of a former woe; and he too plainly seemed to see, that as the most poisonous reptile of the marsh perpetuates his kind as inevitably as the sweetest songster of the grove; so, equally with every felicity, all miserable events do naturally beget their like. Yea, more than equally, thought Ahab; since both the ancestry and posterity of Grief go further than the ancestry and posterity of Joy. For, not to hint of this: that it is an inference from certain canonic teachings, that while some natural enjoyments here shall have no children born to them for the other world, but, on the contrary, shall be followed by the joy-childlessness of all hell's despair; whereas, some guilty mortal miseries shall still fertilely beget to themselves an eternally progressive progeny of griefs beyond the grave; not at all to hint of this, there still seems an inequality in the deeper analysis of the thing. For, thought Ahab, while even the highest earthly felicities ever have a certain unsignifying pettiness lurking in them, but, at bottom, all heart-woes, a mystic significance, and, in some men, an archangelic grandeur; so do their diligent tracings-out not belie the obvious deduction. To trail the genealogies ..

of these high mortal miseries, carries us at last among the sourceless primogenitures of the gods; so that, in the face of all the glad, hay-making suns, and soft-cymballing, round harvest-moons, we must needs give in to this: that the gods themselves are not for ever glad. The ineffaceable, sad birth-mark in the brow of man, is but the stamp of sorrow in the signers. Unwittingly here a secret has been divulged, which perhaps might more properly, in set way, have been disclosed before. With many other particulars concerning Ahab, always had it remained a mystery to some, why it was, that for a certain period, both before and after the sailing of the Pequod, he had hidden himself away with such Grand-Lama-like exclusiveness; and, for that one interval, sought speechless refuge, as it were, among the marble senate of the dead. Captain Peleg's bruited reason for this thing appeared by no means adequate; though, indeed, as touching all Ahab's deeper part, every revelation partook more of significant darkness than of explanatory light. But, in the end, it all came out; this one matter did, at least. That direful mishap was at the bottom of his temporary recluseness. And not only this, but to that ever-contracting, dropping circle ashore, who, for any reason, possessed the privilege of a less banned approach to him; to that timid circle the above hinted casualty --remaining, as it did, moodily unaccounted for by Ahab --invested itself with terrors, not entirely underived from the land of spirits and of wails. So that, through their zeal for him, they had all conspired, so far as in them lay, to muffle up the knowledge of this thing from others; and hence it was, that not till a considerable interval had elapsed, did it transpire upon the Pequod's decks. But be all this as it may; let the unseen, ambiguous synod in the air, or the vindictive princes and potentates of fire, have to do or not with earthly Ahab, yet, in this present matter of his leg, he took plain practical procedures; --he called the carpenter. And when that functionary appeared before him, he bade him without delay set about making a new leg, and directed the mates to see him supplied with all the studs and joists of jaw-ivory (Sperm Whale) which had thus far been accumulated ..

on the voyage, in order that a careful selection of the stoutest, clearest-grained stuff might be secured. This done, the carpenter received orders to have the leg completed that night; and to provide all the fittings for it, independent of those pertaining to the distrusted one in use. Moreover, the ship's forge was ordered to be hoisted out of its temporary idleness in the hold; and, to accelerate the affair, the blacksmith was commanded to proceed at once to the forging of whatever iron contrivances might be needed. ..

.. < chapter cvii 11 THE CARPENTER > Seat thyself sultanically among the moons of Saturn, and take high abstracted man alone; and he seems a wonder, a grandeur, and a woe. But from the same point, take mankind in mass, and for the most part, they seem a mob of unnecessary duplicates, both contemporary and hereditary. But most humble though he was, and far from furnishing an example of the high, humane abstraction; the Pequod's carpenter was no duplicate; hence, he now comes in person on this stage. Like all sea-going ship carpenters, and more especially those belonging to whaling vessels, he was, to a certain off-handed, practical extent, alike experienced in numerous trades and callings collateral to his own; the carpenter's pursuit being the ancient and outbranching trunk of all those numerous handicrafts which more or less have to do with wood as an auxiliary material. but, besides the application to him of the generic remark above, this carpenter of the Pequod was singularly efficient in those thousand nameless mechanical emergencies continually recurring in a large ship, upon a three or four years' voyage, in uncivilized and far-distant seas. For not to speak of his readiness in ordinary duties: --repairing stove boats, sprung spars, reforming the shape of clumsy-bladed oars, inserting bull's ..

eyes in the deck, or new tree-nails in the side planks, and other miscellaneous matters more directly pertaining to his special business; he was moreover unhesitatingly expert in all manner of conflicting aptitudes, both useful and capricious. The one grand stage where he enacted all his various parts so manifold, was his vice-bench; a long rude ponderous table furnished with several vices, of different sizes, and both of iron and of wood. At all times except when whales were alongside, this bench was securely lashed athwartships against the rear of the Try-works. A belaying pin is found too large to be easily inserted into its hole: the carpenter claps it into one of his ever-ready vices, and straightway files it smaller. A lost land-bird of strange plumage strays on board, and is made a captive: out of clean shaved rods of right-whale bone, and cross-beams of sperm whale ivory, the carpenter makes a pagoda-looking cage for it. An oarsman sprains his wrist: the carpenter concocts a soothing lotion. Stubb longed for vermillion stars to be painted upon the blade of his every oar; screwing each oar in his big vice of wood, the carpenter symmetrically supplies the constellation. A sailor takes a fancy to wear shark-bone ear-rings: the carpenter drills his ears. Another has the toothache: the carpenter out pincers, and clapping one hand upon his bench bids him be seated there; but the poor fellow unmanageably winces under the unconcluded operation; whirling round the handle of his wooden vice, the carpenter signs him to clap his jaw in that, if he would have him draw the tooth. Thus, this carpenter was prepared at all points, and alike indifferent and without respect in all. Teeth he accounted bits of ivory; heads he deemed but top-blocks; men themselves he lightly held for capstans. But while now upon so wide a field thus variously accomplished, and with such liveliness of expertness in him, too; all this would seem to argue some uncommon vivacity of intelligence. But not precisely so. For nothing was this man more remarkable, than for a certain impersonal stolidity as it were; impersonal, I say; for it so shaded off into the surrounding infinite of things, that it seemed one with the general stolidity discernible in the whole visible world; which while ..

pauselessly active in uncounted modes, still eternally holds its peace, and ignores you, though you dig foundations for cathedrals. Yet was this half-horrible stolidity in him, involving, too, as it appeared, an all-ramifying heartlessness; --yet was it oddly dashed at times, with an old, crutch-like, antediluvian, wheezing humorousness, not unstreaked now and then with a certain grizzled wittiness; such as might have served to pass the time during the midnight watch on the bearded forecastle of Noah's ark. Was it that this old carpenter had been a life-long wanderer, whose much rolling, to and fro, not only had gathered no moss; but what is more, had rubbed off whatever small outward clingings might have originally pertained to him? He was a stript abstract; an unfractioned integral; uncompromised as a new-born babe; living without premeditated reference to this world or the next. You might almost say, that this strange uncompromisedness in him involved a sort of unintelligence; for in his numerous trades, he did not seem to work so much by reason or by instinct, or simply because he had been tutored to it, or by any intermixture of all these, even or uneven; but merely by a kind of deaf and dumb, spontaneous literal process. He was a pure manipulator; his brain, if he had ever had one, must have early oozed along into the muscles of his fingers. He was like one of those unreasoning but still highly useful, multum in parvo, Sheffield contrivances, assuming the exterior -- though a little swelled --of a common pocket knife; but containing, not only blades of various sizes, but also screw-drivers, cork-screws, tweezers, awls, pens, rulers, nail-filers, counter-sinkers. So, if his superiors wanted to use the carpenter for a screw-driver, all they had to do was to open that part of him, and the screw was fast: or if for tweezers, take him up by the legs, and there they were. Yet, as previously hinted, this omnitooled, open-and-shut carpenter, was, after all, no mere machine of an automaton. If he did not have a common soul in him, he had a subtle something that somehow anomalously did its duty. What that was, whether essence of quicksilver, or a few drops of hartshorn, there is no telling. But there it was; and there it had abided for now some sixty years or more. And this it was, this same ..

unaccountable, cunning life-principle in him; this it was, that kept him a great part of the time soliloquizing; but only like an unreasoning wheel, which also hummingly soliloquizes; or rather, his body was a sentry-box and this soliloquizer on guard there, and talking all the time to keep himself awake. ..

.. < chapter cviii 7 AHAB AND THE CARPENTER THE DECK--FIRST NIGHT WATCH > (Carpenter standing before his vice-bench, and by the light of two lanterns busily filing the ivory joist for the leg, which joist is firmly fixed in the vice. Slabs of ivory, leather straps, pads, screws, and various tools of all sorts lying about the bench. Forward, the red flame of the forge is seen, where the blacksmith is at work.) Drat the file, and drat the bone! That is hard which should be soft, and that soft which should be hard. So we go, who file old jaws and shinbones. Let's try another. Aye, now, this works better ( sneezes). Halloa, this bone dust is ( sneezes)-- why it's ( sneezes)--yes it's ( sneezes)--bless my soul, it won't let me speak! This is what an old fellow gets now for working in dead lumber. Saw a live tree, and you don't get this dust; amputate a live bone, and you don't get it ( sneezes). Come, come, you old Smut, there, bear a hand, and let's have that ferule and buckle-screw; I'll be ready for them presently. Lucky now ( sneezes) there's no knee-joint to make; that might puzzle a little; but a mere shinbone --why it's easy as making hop-poles; only I should like to put a good finish on. Time, time; if I but only had the time, I could turn him out as neat a leg now as ever ( sneezes) scraped to a lady in a parlor. Those buckskin legs and calves of legs I've seen in shop windows wouldn't compare at all. They soak water, they do; and of ..

course get rheumatic, and have to be doctored ( sneezes) with washes and lotions, just like live legs. There; before I saw it off, now, I must call his old Mogulship, and see whether the length will be all right; too short, if anything, I guess. Ha! that's the heel; we are in luck; here he comes, or it's somebody else, that's certain. Ahab ( advancing). (During the ensuing scene, the carpenter continues sneezing at times). Well, manmaker! Just in time, sir. If the captain pleases, I will now mark the length. Let me measure, sir. Measured for a leg! good. Well, it's not the first time. About it! There; keep thy finger on it. This is a cogent vice thou hast here, carpenter; let me feel its grip once. so, so; it does pinch some. Oh, sir, it will break bones--beware, beware! No fear; I like a good grip; I like to feel something in this slippery world that can hold, man. What's Prometheus about there? --the blacksmith, I mean --what's he about? He must be forging the buckle-screw, sir, now. Right. It's a partnership; he supplies the muscle part. He makes a fierce red flame there! Aye, sir; he must have the white heat for this kind of fine work. Um-m. So he must. I do deem it now a most meaning thing, that that old Greek, Prometheus, who made men, they say, should have been a blacksmith, and animated them with fire; for what's made in fire must properly belong to fire; and so hell's probable. How the soot flies! This must be the remainder the Greek made the Africans of. Carpenter, when he's through with that buckle, tell him to forge a pair of steel shoulder-blades; there's a pedlar aboard with a crushing pack. Sir? Hold; while Prometheus is about it, I'll order a complete man after a desirable pattern. Imprimis, fifty feet high in his socks; then, chest modelled after the Thames Tunnel; then, legs with roots to 'em, to stay in one place; then, arms three ..

feet through the wrist; no heart at all, brass forehead, and about a quarter of an acre of fine brains; and let me see --shall I order eyes to see outwards? No, but put a sky-light on top of his head to illuminate inwards. There, take the order, and away. Now, what's he speaking about, and who's he speaking to, I should like to know? Shall I keep standing here? ( aside). 'Tis but indifferent architecture to make a blind dome; here's one. No, no, no; I must have a lantern. Ho, ho! That's it, hey? Here are two, sir; one will serve my turn. What art thou thrusting that thief-catcher into my face for, man? thrusted light is worse than presented pistols. i thought, sir, that you spoke to carpenter. Carpenter? why that's --but no; --a very tidy, and, I may say, an extremely gentlemanlike sort of business thou art in here, carpenter; --or would'st thou rather work in clay? Sir? --Clay? clay, sir? That's mud; we leave clay to ditchers, sir. The fellow's impious! What art thou sneezing about? Bone is rather dusty, sir. Take the hint, then; and when thou art dead, never bury thyself under living people's noses. Sir? --oh! ah! --I guess so; so; --yes, yes --oh dear! Look ye, carpenter, I dare say thou callest thyself a right good workmanlike workman, eh! Well, then, will it speak thoroughly well for thy work, if, when I come to mount this leg thou makest, I shall nevertheless feel another leg in the same identical place with it; that is, carpenter, my old lost leg; the flesh and blood one, I mean. Canst thou not drive that old Adam away? Truly, sir, I begin to understand somewhat now. Yes, I have heard something curious on that score, sir; how that a dismasted man never entirely loses the feeling of his old spar, but it will be still pricking him at times. May I humbly ask if it be really so, sir? It is, man. Look, put thy live leg here in the place where mine once was; so, now, here is only one distinct leg to the eye, ..

yet two to the soul. Where thou feelest tingling life; there, exactly there, there to a hair, do I. Is't a riddle? I should humbly call it a poser, sir. Hist, then. How dost thou know that some entire, living, thinking thing may not be invisibly and uninterpenetratingly standing precisely where thou now standest; aye, and standing there in thy spite? In thy most solitary hours, then, dost thou not fear eavesdroppers? Hold, don't speak! And if I still feel the smart of my crushed leg, though it be now so long dissolved; then, why mayest not thou, carpenter, feel the fiery pains of hell for ever, and without a body? Hah! Good Lord! Truly, sir, if it comes to that, I must calculate over again; I think I didn't carry a small figure, sir. Look ye, pudding-heads should never grant premises. --How long before this leg is done? Perhaps an hour, sir. Bungle away at it then, and bring it to me (turns to go). Oh, Life! Here I am, proud as Greek god, and yet standing debtor to this blockhead for a bone to stand on! Cursed be that mortal inter-indebtedness which will not do away with ledgers. I would be free as air; and I'm down in the whole world's books. I am so rich, I could have given bid for bid with the wealthiest Praetorians at the auction of the Roman empire (which was the world's); and yet I owe for the flesh in the tongue I brag with. By heavens! I'll get a crucible, and into it, and dissolve myself down to one small, compendious vertebra. So. Carpenter ( resuming his work). Well, well, well! Stubb knows him best of all, and Stubb always says he's queer; says nothing but that one sufficient little word queer; he's queer, says Stubb; he's queer--queer, queer; and keeps dinning it into Mr. Starbuck all the time -- queer, sir --queer, queer, very queer. And here's his leg! Yes, now that I think of it, here's his bedfellow! has a stick of whale's jaw-bone for a wife! And this is his leg; he'll stand on this. What was that now about one leg standing in three places, and all three places standing in one hell --how was that? Oh! I don't wonder he looked so scornful at me! I'm a sort of strange-thoughted ..

sometimes, they say; but that's only haphazard-like. Then, a short, little old body like me, should never undertake to wade out into deep waters with tall, heron-built captains; the water chucks you under the chin pretty quick, and there's a great cry for life-boats. And here's the heron's leg! long and slim, sure enough! Now, for most folks one pair of legs lasts a lifetime, and that must be because they use them mercifully, as a tender-hearted old lady uses her roly-poly old coach-horses. But Ahab; oh he's a hard driver. Look, driven one leg to death, and spavined the other for life, and now wears out bone legs by the cord. Halloa, there, you Smut! bear a hand there with those screws, and let's finish it before the resurrection fellow comes a-calling with his horn for all legs, true or false, as brewery-men go round collecting old beer barrels, to fill 'em up again. What a leg this is! It looks like a real live leg, filed down to nothing but the core; he'll be standing on this to-morrow; he'll be taking altitudes on it. Halloa! I almost forgot the little oval slate, smoothed ivory, where he figures up the latitude. So, so; chisel, file, and sand-paper, now! ..

.. < chapter cix 21 AHAB AND STARBUCK IN THE CABIN > According to usage they were pumping the ship next morning; and lo! no inconsiderable oil came up with the water; the casks below must have sprung a bad leak. Much concern was shown; and Starbuck went down into the cabin to report this unfavorable affair. ..

Now, from the South and West the Pequod was drawing nigh to Formosa and the Bashee Isles, between which lies one of the tropical outlets from the China waters into the Pacific. And so Starbuck found Ahab with a general chart of the oriental archipelagoes spread before him; and another separate one representing the long eastern coasts of the Japanese islands -- Niphon, Matsmai, and Sikoke. With his snow-white new ivory leg braced against the screwed leg of his table, and with a long pruning-hook of a jack-knife in his hand, the wondrous old man, with his back to the gangway door, was wrinkling his brow, and tracing his old courses again. Who's there? hearing the footstep at the door, but not turning round to it. On deck! Begone! captain ahab mistakes; it is I. The oil in the hold is leaking, sir. We must up Burtons and break out. Up Burtons and break out? Now that we are nearing Japan; heave-to here for a week to tinker a parcel of old hoops? Either do that, sir, or waste in one day more oil than we may make good in a year. What we come twenty thousand miles to get is worth saving, sir. So it is, so it is; if we get it. I was speaking of the oil in the hold, sir. And I was not speaking or thinking of that at all. Begone! Let it leak! I'm all aleak myself. Aye! leaks in leaks! not only full of leaky casks, but those leaky casks are in a leaky ship; and that's a far worse plight than the Pequod's, man. Yet I don't stop to plug my leak; for who can find it in the deep-loaded hull; or how hope to plug it, even if found, in this life's howling gale? Starbuck! I'll not have the Burtons hoisted. What will the owners say, sir? Let the owners stand on Nantucket beach and outyell the Typhoons. What cares Ahab? Owners, owners? Thou art always prating to me, Starbuck, about those miserly owners, as if the owners were my conscience. But look ye, the only real owner of anything is its commander; and hark ye, my conscience is in this ship's keel. --On deck! Captain Ahab, said the reddening mate, moving further into the cabin, with a daring so strangely respectful and cautious that ..

it almost seemed not only every way seeking to avoid the slightest outward manifestation of itself, but within also seemed more than half distrustful of itself; A better man than I might well pass over in thee what he would quickly enough resent in a younger man; aye! and in a happier, Captain Ahab. Devils! Dost thou then so much as dare to critically think of me? --On deck! Nay, sir, not yet; I do entreat. And I do dare, sir --to be forbearing! Shall we not understand each other better than hitherto, Captain ahab? ahab seized a loaded musket from the rack (forming part of most South-Sea-men's cabin furniture), and pointing it towards Starbuck, exclaimed: There is one God that is Lord over the earth, and one Captain that is lord over the Pequod. --On deck! For an instant in the flashing eyes of the mate, and his fiery cheeks, you would have almost thought that he had really received the blaze of the levelled tube. But, mastering his emotion, he half calmly rose, and as he quitted the cabin, paused for an instant and said: Thou hast outraged, not insulted me, Sir; but for that I ask thee not to beware of Starbuck; thou wouldst but laugh; but let Ahab beware of Ahab; beware of thyself, old man. He waxes brave, but nevertheless obeys; most careful bravery that! murmured Ahab, as Starbuck disappeared. What's that he said --Ahab beware of Ahab --there's something there! Then unconsciously using the musket for a staff, with an iron brow he paced to and fro in the little cabin; but presently the thick plaits of his forehead relaxed, and returning the gun to the rack, he went to the deck. Thou art but too good a fellow, Starbuck, he said lowly to the mate; then raising his voice to the crew: Furl the t'gallant-sails and close-reef the top-sails, fore and aft; back the main-yard; up Burtons, and break out in the main-hold. It were perhaps vain to surmise exactly why it was, that as respecting Starbuck, Ahab thus acted. It may have been a flash of honesty in him; or mere prudential policy which, under the circumstance, imperiously forbade the slightest symptom of open disaffection, however transient, in the important chief ..

officer of his ship. However it was, his orders were executed; and the Burtons were hoisted. ..

In Sperm-whalemen with any considerable quantity of oil on board, it is a regular semi-weekly duty to conduct a hose into the hold, and drench the casks with sea-water; which afterwards, at varying intervals, is removed by the ship's pumps. Hereby the casks are sought to be kept damply tight; while by the changed character of the withdrawn water, the mariners readily detect any serious leakage in the precious cargo. ..

.. < chapter cx 4 QUEEQUEG IN HIS COFFIN > Upon searching, it was found that the casks last struck into the hold were perfectly sound, and that the leak must be further off. So, it being calm weather, they broke out deeper and deeper, disturbing the slumbers of the huge ground-tier butts; and from that black midnight sending those gigantic moles into the daylight above. So deep did they go; and so ancient, and corroded, and weedy the aspect of the lowermost puncheons, that you almost looked next for some mouldy corner-stone cask containing coins of Captain Noah, with copies of the posted placards, vainly warning the infatuated old world from the flood. Tierce after tierce, too, of water, and bread, and beef, and shooks of staves, and iron bundles of hoops, were hoisted out, till at last the piled decks were hard to get about; and the hollow hull echoed under foot, as if you were treading over empty catacombs, and reeled and rolled in the sea like an air-freighted demijohn. Top-heavy was the ship as a dinnerless student with all Aristotle in his head. Well was it that the Typhoons did not visit them then. Now, at this time it was that my poor pagan companion, and fast bosom-friend, Queequeg, was seized with a fever, which brought him nigh to his endless end. Be it said, that in this vocation of whaling, sinecures are unknown; dignity and danger go hand in hand; till you get to be Captain, the higher you rise the harder you toil. So with poor Queequeg, who, as harpooneer, must not only face all the rage of the living whale, but --as we have elsewhere seen -- mount his dead back in a rolling sea; and finally descend into the gloom of the hold, and bitterly sweating all day in that ..

subterraneous confinement, resolutely manhandle the clumsiest casks and see to their stowage. To be short, among whalemen, the harpooneers are the holders, so called. Poor Queequeg! when the ship was about half disembowelled, you should have stooped over the hatchway, and peered down upon him there; where, stripped to his woollen drawers, the tattooed savage was crawling about amid that dampness and slime, like a green spotted lizard at the bottom of a well. And a well, or an ice-house, it somehow proved to him, poor pagan; where, strange to say, for all the heat of his sweatings, he caught a terrible chill which lapsed into a fever; and at last, after some days' suffering, laid him in his hammock, close to the very sill of the door of death. How he wasted and wasted away in those few long-lingering days, till there seemed but little left of him but his frame and tattooing. But as all else in him thinned, and his cheek-bones grew sharper, his eyes, nevertheless, seemed growing fuller and fuller; they became of a strange softness of lustre; and mildly but deeply looked out at you there from his sickness, a wondrous testimony to that immortal health in him which could not die, or be weakened. And like circles on the water, which, as they grow fainter, expand; so his eyes seemed rounding and rounding, like the rings of Eternity. An awe that cannot be named would steal over you as you sat by the side of this waning savage, and saw as strange things in his face, as any beheld who were bystanders when Zoroaster died. For whatever is truly wondrous and fearful in man, never yet was put into words or books. And the drawing near of Death, which alike levels all, alike impresses all with a last revelation, which only an author from the dead could adequately tell. So that --let us say it again --no dying Chaldee or Greek had higher and holier thoughts than those, whose mysterious shades you saw creeping over the face of poor Queequeg, as he quietly lay in his swaying hammock, and the rolling sea seemed gently rocking him to his final rest, and the ocean's invisible flood-tide lifted him higher and higher towards his destined heaven. Not a man of the crew but gave him up; and, as for Queequeg himself, what he thought of his case was forcibly shown by a curious favor he asked. He called one to him in the grey ..

morning watch, when the day was just breaking, and taking his hand, said that while in Nantucket he had chanced to see certain little canoes of dark wood, like the rich war-wood of his native isle; and upon inquiry, he had learned that all whalemen who died in Nantucket, were laid in those same dark canoes, and that the fancy of being so laid had much pleased him; for it was not unlike the custom of his own race, who, after embalming a dead warrior, stretched him out in his canoe, and so left him to be floated away to the starry archipelagoes; for not only do they believe that the stars are isles, but that far beyond all visible horizons, their own mild, uncontinented seas, interflow with the blue heavens; and so form the white breakers of the milky way. He added, that he shuddered at the thought of being buried in his hammock, according to the usual sea-custom, tossed like something vile to the death-devouring sharks. No: he desired a canoe like those of Nantucket, all the more congenial to him, being a whaleman, that like a whale-boat these coffin-canoes were without a keel; though that involved but uncertain steering, and much lee-way adown the dim ages. Now, when this strange circumstance was made known aft, the carpenter was at once commanded to do Queequeg's bidding, whatever it might include. There was some heathenish, coffin-colored old lumber aboard, which, upon a long previous voyage, had been cut from the aboriginal groves of the Lackaday islands, and from these dark planks the coffin was recommended to be made. No sooner was the carpenter apprised of the order, than taking his rule, he forthwith with all the indifferent promptitude of his character, proceeded into the forecastle and took Queequeg's measure with great accuracy, regularly chalking Queequeg's person as he shifted the rule. Ah! poor fellow! he'll have to die now, ejaculated the Long Island sailor. Going to his vice-bench, the carpenter for convenience' sake and general reference, now transferringly measured on it the exact length the coffin was to be, and then made the transfer permanent by cutting two notches at its extremities. This done, he marshalled the planks and his tools, and to work. ..

When the last nail was driven, and the lid duly planed and fitted, he lightly shouldered the coffin and went forward with it, inquiring whether they were ready for it yet in that direction. Overhearing the indignant but half-humorous cries with which the people on deck began to drive the coffin away, Queequeg, to every one's consternation, commanded that the thing should be instantly brought to him, nor was there any denying him; seeing that, of all mortals, some dying men are the most tyrannical; and certainly, since they will shortly trouble us so little for evermore, the poor fellows ought to be indulged. Leaning over in his hammock, Queequeg long regarded the coffin with an attentive eye. He then called for his harpoon, had the wooden stock drawn from it, and then had the iron part placed in the coffin along with one of the paddles of his boat. All by his own request, also, biscuits were then ranged round the sides within: a flask of fresh water was placed at the head, and a small bag of woody earth scraped up in the hold at the foot; and a piece of sail-cloth being rolled up for a pillow, Queequeg now entreated to be lifted into his final bed, that he might make trial of its comforts, if any it had. He lay without moving a few minutes, then told one to go to his bag and bring out his little god, Yojo. Then crossing his arms on his breast with Yojo between, he called for the coffin lid (hatch he called it) to be placed over him. The head part turned over with a leather hinge, and there lay Queequeg in his coffin with little but his composed countenance in view. Rarmai (it will do; it is easy), he murmured at last, and signed to be replaced in his hammock. But ere this was done, Pip, who had been slily hovering near by all this while, drew nigh to him where he lay, and with soft sobbings, took him by the hand; in the other, holding his tambourine. Poor rover! will ye never have done with all this weary roving? Where go ye now? But if the currents carry ye to those sweet Antilles where the beaches are only beat with water-lilies, will ye do one little errand for me? Seek out one Pip, who's now been missing long: I think he's in those far Antilles. If ye find him, then comfort him; for he must be very sad; for look! ..

he's left his tambourine behind; --I found it. Rig-a-dig, dig, dig! Now, Queequeg, die; and I'll beat ye your dying march. I have heard, murmured Starbuck, gazing down the scuttle, that in violent fevers, men, all ignorance, have talked in ancient tongues; and that when the mystery is probed, it turns out always that in their wholly forgotten childhood those ancient tongues had been really spoken in their hearing by some lofty scholars. So, to my fond faith, poor Pip, in this strange sweetness of his lunacy, brings heavenly vouchers of all our heavenly homes. Where learned he that, but there? --Hark! he speaks again: but more wildly now. Form two and two! Let's make a General of him! Ho, where's his harpoon? Lay it across here. --Rig-a-dig, dig, dig! huzza! Oh for a game cock now to sit upon his head and crow! queequeg dies game! --mind ye that; queequeg dies game! -- take ye good heed of that; Queequeg dies game! I say; game, game, game! but base little Pip, he died a coward; died all a'shiver; --out upon Pip! Hark ye; if ye find Pip, tell all the Antilles he's a runaway; a coward, a coward, a coward! Tell them he jumped from a whale-boat! I'd never beat my tambourine over base Pip, and hail him General, if he were once more dying here. No, no! shame upon all cowards --shame upon them! Let 'em go drown like Pip, that jumped from a whale-boat. Shame! shame! During all this, Queequeg lay with closed eyes, as if in a dream. Pip was led away, and the sick man was replaced in his hammock. But now that he had apparently made every preparation for death; now that his coffin was proved a good fit, Queequeg suddenly rallied; soon there seemed no need of the carpenter's box: and thereupon, when some expressed their delighted surprise, he, in substance, said, that the cause of his sudden convalescence was this; --at a critical moment, he had just recalled a little duty ashore, which he was leaving undone; and therefore had changed his mind about dying: he could not die yet, he averred. They asked him, then, whether to live or die was a matter of his own sovereign will and pleasure. He answered, certainly. In a word, it was Queequeg's conceit, that if a man ..

made up his mind to live, mere sickness could not kill him: nothing but a whale, or a gale, or some violent, ungovernable, unintelligent destroyer of that sort. Now, there is this noteworthy difference between savage and civilized; that while a sick, civilized man may be six months convalescing, generally speaking, a sick savage is almost half-well again in a day. So, in good time my Queequeg gained strength; and at length after sitting on the windlass for a few indolent days (but eating with a vigorous appetite) he suddenly leaped to his feet, threw out arms and legs, gave himself a good stretching, yawned a little bit, and then springing into the head of his hoisted boat, and poising a harpoon, pronounced himself fit for a fight. With a wild whimsiness, he now used his coffin for a sea-chest; and emptying into it his canvas bag of clothes, set them in order there. Many spare hours he spent, in carving the lid with all manner of grotesque figures and drawings; and it seemed that hereby he was striving, in his rude way, to copy parts of the twisted tattooing on his body. And this tattooing, had been the work of a departed prophet and seer of his island, who, by those hieroglyphic marks, had written out on his body a complete theory of the heavens and the earth, and a mystical treatise on the art of attaining truth; so that Queequeg in his own proper person was a riddle to unfold; a wondrous work in one volume; but whose mysteries not even himself could read, though his own live heart beat against them; and these mysteries were therefore destined in the end to moulder away with the living parchment whereon they were inscribed, and so be unsolved to the last. And this thought it must have been which suggested to Ahab that wild exclamation of his, when one morning turning away from surveying poor Queequeg -- Oh, devilish tantalization of the gods! ..

.. < chapter cxi 2 THE PACIFIC > When gliding by the Bashee isles we emerged at last upon the great South Sea; were it not for other things, I could have greeted my dear Pacific with uncounted thanks, for now the long supplication of my youth was answered; that serene ocean rolled eastwards from me a thousand leagues of blue. There is, one knows not what sweet mystery about this sea, whose gently awful stirrings seem to speak of some hidden soul beneath; like those fabled undulations of the Ephesian sod over the buried Evangelist St. John. And meet it is, that over these sea-pastures, wide-rolling watery prairies and Potters' Fields of all four continents, the waves should rise and fall, and ebb and flow unceasingly; for here, millions of mixed shades and shadows, drowned dreams, somnambulisms, reveries; all that we call lives and souls, lie dreaming, dreaming, still; tossing like slumberers in their beds; the ever-rolling waves but made so by their restlessness. To any meditative Magian rover, this serene Pacific, once beheld, must ever after be the sea of his adoption. It rolls the midmost waters of the world, the Indian ocean and Atlantic being but its arms. The same waves wash the moles of the new-built Californian towns, but yesterday planted by the recentest race of men, and lave the faded but still gorgeous skirts of Asiatic lands, older than Abraham; while all between float milky-ways of coral isles, and low-lying, endless, unknown Archipelagoes, and impenetrable Japans. Thus this mysterious, divine Pacific zones the world's whole bulk about; makes all coasts one bay to it; seems the tide-beating heart of earth. Lifted by those eternal swells, you needs must own the seductive god, bowing your head to Pan. But few thoughts of Pan stirred Ahab's brain, as standing like an iron statue at his accustomed place beside the mizen ..

rigging, with one nostril he unthinkingly snuffed the sugary musk from the Bashee isles (in whose sweet woods mild lovers must be walking), and with the other consciously inhaled the salt breath of the new found sea; that sea in which the hated White Whale must even then be swimming. Launched at length upon these almost final waters, and gliding towards the Japanese cruising-ground, the old man's purpose intensified itself. His firm lips met like the lips of a vice; the Delta of his forehead's veins swelled like overladen brooks; in his very sleep, his ringing cry ran through the vaulted hull, Stern all! the White Whale spouts thick blood! ..

.. < chapter cxii 13 THE BLACKSMITH > The blacksmith availing himself of the mild, summer-cool weather that now reigned in these latitudes, and in preparation for the peculiarly active pursuits shortly to be anticipated, Perth, the begrimed, blistered old blacksmith, had not removed his portable forge to the hold again, after concluding his contributory work for Ahab's leg, but still retained it on deck, fast lashed to ringbolts by the foremast; being now almost incessantly invoked by the headsmen, and harpooneers, and bowsmen to do some little job for them; altering, or repairing, or new shaping their various weapons and boat furniture. Often he would be surrounded by an eager circle, all waiting to be served; holding boat-spades, pike-heads, harpoons, and lances, and jealously watching his every sooty movement, as he toiled. Nevertheless, this old man's was a patient hammer wielded by a patient arm. No murmur, no impatience, no petulence did come from him. Silent, slow, and solemn; bowing over still further his chronically broken back, he toiled away, as if toil were life itself, and the heavy beating of his hammer the heavy beating of his heart. And so it was. --Most miserable! ..

A peculiar walk in this old man, a certain slight but painful appearing yawing in his gait, had at an early period of the voyage excited the curiosity of the mariners. And to the importunity of their persisted questionings he had finally given in; and so it came to pass that every one now knew the shameful story of his wretched fate. Belated, and not innocently, one bitter winter's midnight, on the road running between two country towns, the blacksmith half-stupidly felt the deadly numbness stealing over him, and sought refuge in a leaning, dilapidated barn. The issue was, the loss of the extremities of both feet. Out of this revelation, part by part, at last came out the four acts of the gladness, and the one long, and as yet uncatastrophied fifth act of the grief of his life's drama. He was an old man, who, at the age of nearly sixty, had postponedly encountered that thing in sorrow's technicals called ruin. He had been an artisan of famed excellence, and with plenty to do; owned a house and garden; embraced a youthful, daughter-like, loving wife, and three blithe, ruddy children; every Sunday went to a cheerful-looking church, planted in a grove. But one night, under cover of darkness, and further concealed in a most cunning disguisement, a desperate burglar slid into his happy home, and robbed them all of everything. And darker yet to tell, the blacksmith himself did ignorantly conduct this burglar into his family's heart. It was the Bottle Conjuror! Upon the opening of that fatal cork, forth flew the fiend, and shrivelled up his home. Now, for prudent, most wise, and economic reasons, the blacksmith's shop was in the basement of his dwelling, but with a separate entrance to it; so that always had the young and loving healthy wife listened with no unhappy nervousness, but with vigorous pleasure, to the stout ringing of her young-armed old husband's hammer; whose reverberations, muffled by passing through the floors and walls, came up to her, not unsweetly, in her nursery; and so, to stout Labor's iron lullaby, the blacksmith's infants were rocked to slumber. Oh, woe on woe! Oh, Death, why canst thou not sometimes be timely? Hadst thou taken this old blacksmith to thyself ere his full ruin came upon him, then had the young widow had a ..

delicious grief, and her orphans a truly venerable, legendary sire to dream of in their after years; and all of them a care-killing competency. But Death plucked down some virtuous elder brother, on whose whistling daily toil solely hung the responsibilities of some other family, and left the worse than useless old man standing, till the hideous rot of life should make him easier to harvest. Why tell the whole? The blows of the basement hammer every day grew more and more between; and each blow every day grew fainter than the last; the wife sat frozen at the window, with tearless eyes, glitteringly gazing into the weeping faces of her children; the bellows fell; the forge choked up with cinders; the house was sold; the mother dived down into the long church-yard grass; her children twice followed her thither; and the houseless, familyless old man staggered off a vagabond in crape; his every woe unreverenced; his grey head a scorn to flaxen curls! Death seems the only desirable sequel for a career like this; but Death is only a launching into the region of the strange Untried; it is but the first salutation to the possibilities of the immense Remote, the Wild, the Watery, the Unshored; therefore, to the death-longing eyes of such men, who still have left in them some interior compunctions against suicide, does the all-contributed and all-receptive ocean alluringly spread forth his whole plain of unimaginable, taking terrors, and wonderful, new-life adventures; and from the hearts of infinite Pacifics, the thousand mermaids sing to them -- Come hither, broken-hearted; here is another life without the guilt of intermediate death; here are wonders supernatural, without dying for them. Come hither! bury thyself in a life which, to your now equally abhorred and abhorring, landed world, is more oblivious than death. Come hither! put up thy grave-stone, too, within the churchyard, and come hither, till we marry thee! Hearkening to these voices, East and West, by early sun-rise, and by fall of eve, the blacksmith's soul responded, Aye, I come! And so Perth went a-whaling. ..

.. < chapter cxiii 2 THE FORGE > With matted beard, and swathed in a bristling shark-skin apron, about mid-day, Perth was standing between his forge and anvil, the latter placed upon an iron-wood log, with one hand holding a pike-head in the coals, and with the other at his forge's lungs, when captain ahab came along, carrying in his hand a small rusty-looking leathern bag. While yet a little distance from the forge, moody Ahab paused; till at last, Perth, withdrawing his iron from the fire, began hammering it upon the anvil --the red mass sending off the sparks in thick hovering flights, some of which flew close to Ahab. Are these thy Mother Carey's chickens, Perth? they are always flying in thy wake; birds of good omen, too, but not to all; --look here, they burn; but thou--thou liv'st among them without a scorch. Because I am scorched all over, Captain Ahab, answered Perth, resting for a moment on his hammer; I am past scorching; not easily can'st thou scorch a scar. Well, well; no more. Thy shrunk voice sounds too calmly, sanely woful to me. In no Paradise myself, I am impatient of all misery in others that is not mad. Thou should'st go mad, blacksmith; say, why dost thou not go mad? How can'st thou endure without being mad? Do the heavens yet hate thee, that thou can'st not go mad? --What wert thou making there? Welding an old pike-head, sir; there were seams and dents in it. And can'st thou make it all smooth, again, blacksmith, after such hard usage as it had? I think so, sir. And I suppose thou can'st smoothe almost any seams and dents; never mind how hard the metal, blacksmith? Aye, sir, I think I can; all seams and dents but one. ..

Look ye here, then, cried Ahab, passionately advancing, and leaning with both hands on Perth's shoulders; look ye here -- here --can ye smoothe out a seam like this, blacksmith, sweeping one hand across his ribbed brow;;if thou could'st, blacksmith, glad enough would I lay my head upon thy anvil, and feel thy heaviest hammer between my eyes. Answer! Can'st thou smoothe this seam? Oh! that is the one, sir! Said I not all seams and dents but one? aye, blacksmith, it is the one; aye, man, it is unsmoothable; for though thou only see'st it here in my flesh, it has worked down into the bone of my skull -- that is all wrinkles! But, away with child's play; no more gaffs and pikes to-day. Look ye here! jingling the leathern bag, as if it were full of gold coins. I, too, want a harpoon made; one that a thousand yoke of fiends could not part, Perth; something that will stick in a whale like his own fin-bone. There's the stuff, flinging the pouch upon the anvil. Look ye, blacksmith, these are the gathered nail-stubbs of the steel shoes of racing horses. Horse-shoe stubbs, sir? Why, Captain Ahab, thou hast here, then, the best and stubbornest stuff we blacksmiths ever work. I know it, old man; these stubbs will weld together like glue from the melted bones of murderers. Quick! forge me the harpoon. And forge me first, twelve rods for its shank; then wind, and twist, and hammer these twelve together like the yarns and strands of a tow-line. Quick! I'll blow the fire. When at last the twelve rods were made, Ahab tried them, one by one, by spiralling them, with his own hand, round a long, heavy iron bolt. A flaw! rejecting the last one. Work that over again, Perth. This done, Perth was about to begin welding the twelve into one, when Ahab stayed his hand, and said he would weld his own iron. As, then, with regular, gasping hems, he hammered on the anvil, Perth passing to him the glowing rods, one after the other, and the hard pressed forge shooting up its intense straight flame, the Parsee passed silently, and bowing over his head towards the fire, seemed invoking some curse or some blessing on the toil. But, as Ahab looked up, he slid aside. ..

What's that bunch of lucifers dodging about there for? muttered Stubb, looking on from the forecastle. That Parsee smells fire like a fusee; and smells of it himself, like a hot musket's powder-pan. At last the shank, in one complete rod, received its final heat; and as perth, to temper it, plunged it all hissing into the cask of water near by, the scalding steam shot up into Ahab's bent face. Would'st thou brand me, Perth? wincing for a moment with the pain; have I been but forging my own branding-iron, then? Pray God, not that; yet I fear something, Captain Ahab. Is not this harpoon for the White Whale? For the white fiend! But now for the barbs; thou must make them thyself, man. Here are my razors --the best of steel; here, and make the barbs sharp as the needle-sleet of the Icy Sea. For a moment, the old blacksmith eyed the razors as though he would fain not use them. Take them, man, I have no need for them; for I now neither shave, sup, nor pray till --but here --to work! Fashioned at last into an arrowy shape, and welded by Perth to the shank, the steel soon pointed the end of the iron; and as the blacksmith was about giving the barbs their final heat, prior to tempering them, he cried to Ahab to place the water-cask near. No, no --no water for that; I want it of the true death-temper. Ahoy, there! Tashtego, Queequeg, Daggoo! What say ye, pagans! Will ye give me as much blood as will cover this barb? holding it high up. A cluster of dark nods replied, Yes. Three punctures were made in the heathen flesh, and the White Whale's barbs were then tempered. Ego non baptizo te in nomine patris, sed in nomine diaboli! deliriously howled Ahab, as the malignant iron scorchingly devoured the baptismal blood. Now, mustering the spare poles from below, and selecting one of hickory, with the bark still investing it, Ahab fitted the end to the socket of the iron. A coil of new tow-line was then unwound, and some fathoms of it taken to the windlass, and ..

stretched to a great tension. Pressing his foot upon it, till the rope hummed like a harp-string, then eagerly bending over it, and seeing no strandings, ahab exclaimed, good! and now for the seizings. At one extremity the rope was unstranded, and the separate spread yarns were all braided and woven round the socket of the harpoon; the pole was then driven hard up into the socket; from the lower end the rope was traced half way along the pole's length, and firmly secured so, with intertwistings of twine. This done, pole, iron, and rope --like the Three Fates --remained inseparable, and Ahab moodily stalked away with the weapon; the sound of his ivory leg, and the sound of the hickory pole, both hollowly ringing along every plank. But ere he entered his cabin, a light, unnatural, half-bantering, yet most piteous sound was heard. Oh, Pip! thy wretched laugh, thy idle but unresting eye; all thy strange mummeries not unmeaningly blended with the black tragedy of the melancholy ship, and mocked it! ..

.. < chapter cxiv 20 THE GILDER > Penetrating further and further into the heart of the Japanese cruising ground, the Pequod was soon all astir in the fishery. Often, in mild, pleasant weather, for twelve, fifteen, eighteen, and twenty hours on the stretch, they were engaged in the boats, steadily pulling, or sailing, or paddling after the whales, or for an interlude of sixty or seventy minutes calmly awaiting their uprising; though with but small success for their pains. At such times, under an abated sun; afloat all day upon smooth, slow heaving swells; seated in his boat, light as a birch canoe; and so sociably mixing with the soft waves themselves, that like hearth-stone cats they purr against the gunwale; these are the times of dreamy quietude, when beholding the tranquil ..

beauty and brilliancy of the ocean's skin, one forgets the tiger heart that pants beneath it; and would not willingly remember, that this velvet paw but conceals a remorseless fang. These are the times, when in his whale-boat the rover softly feels a certain filial, confident, land-like feeling towards the sea; that he regards it as so much flowery earth; and the distant ship revealing only the tops of her masts, seems struggling forward, not though high rolling waves, but through the tall grass of a rolling prairie: as when the western emigrants' horses only show their erected ears, while their hidden bodies widely wade through the amazing verdure. The long-drawn virgin vales; the mild blue hill-sides; as over these there steals the hush, the hum; you almost swear that play-wearied children lie sleeping in these solitudes, in some glad May-time, when the flowers of the woods are plucked. And all this mixes with your most mystic mood; so that fact and fancy, half-way meeting, interpenetrate, and form one seamless whole. Nor did such soothing scenes, however temporary, fail of at least as temporary an effect on Ahab. But if these secret golden keys did seem to open in him his own secret golden treasuries, yet did his breath upon them prove but tarnishing. Oh, grassy glades! oh, ever vernal endless landscapes in the soul; in ye, --though long parched by the dead drought of the earthy life, --in ye, men yet may roll, like young horses in new morning clover; and for some few fleeting moments, feel the cool dew of the life immortal on them. Would to God these blessed calms would last. But the mingled, mingling threads of life are woven by warp and woof: calms crossed by storms, a storm for every calm. There is no steady unretracing progress in this life; we do not advance through fixed gradations, and at the last one pause: --through infancy's unconscious spell, boyhood's thoughtless faith, adolescence' doubt (the common doom), then scepticism, then disbelief, resting at last in manhood's pondering repose of If. But once gone through, we trace the round again; and are infants, boys, and men, and Ifs eternally. Where lies the final harbor, whence we unmoor no more? in what rapt ether sails the world, of which the weariest will ..

never weary? Where is the foundling's father hidden? Our souls are like those orphans whose unwedded mothers die in bearing them: the secret of our paternity lies in their grave, and we must there to learn it. And that same day, too, gazing far down from his boat's side into that same golden sea, Starbuck lowly murmured: -- Loveliness unfathomable, as ever lover saw in his young bride's eye! --Tell me not of thy teeth-tiered sharks, and thy kidnapping cannibal ways. Let faith oust fact; let fancy oust memory; I look deep down and do believe. And Stubb, fish-like, with sparkling scales, leaped up in that same golden light: -- I am Stubb, and Stubb has his history; but here Stubb takes oaths that he has always been jolly! ..

.. < chapter cxv 16 THE PEQUOD MEETS THE BACHELOR > And jolly enough were the sights and the sounds that came bearing down before the wind, some few weeks after Ahab's harpoon had been welded. It was a Nantucket ship, the Bachelor, which had just wedged in her last cask of oil, and bolted down her bursting hatches; and now, in glad holiday apparel, was joyously, though somewhat vain-gloriously, sailing round among the widely-separated ships on the ground, previous to pointing her prow for home. The three men at her mast-head wore long streamers of narrow red bunting at their hats; from the stern, a whale-boat was suspended, bottom down; and hanging captive from the bowsprit was seen the long lower jaw of the last whale they had slain. Signals, ensigns, and jacks of all colors were flying from her rigging, on every side. Sideways lashed in each of her three basketed tops were two barrels of sperm; above which, in her top-mast cross-trees, you saw slender breakers of the ..

same precious fluid; and nailed to her main truck was a brazen lamp. As was afterwards learned, the bachelor had met with the most surprising success; all the more wonderful, for that while cruising in the same seas numerous other vessels had gone entire months without securing a single fish. Not only had barrels of beef and bread been given away to make room for the far more valuable sperm, but additional supplemental casks had been bartered for, from the ships she had met; and these were stowed along the deck, and in the captain's and officers' staterooms. Even the cabin table itself had been knocked into kindling-wood; and the cabin mess dined off the broad head of an oil-butt, lashed down to the floor for a centrepiece. In the forecastle, the sailors had actually caulked and pitched their chests, and filled them; it was humorously added, that the cook had clapped a head on his largest boiler, and filled it; that the steward had plugged his spare coffee-pot and filled it; that the harpooneers had headed the sockets of their irons and filled them; that indeed everything was filled with sperm, except the captain's pantaloons pockets, and those he reserved to thrust his hands into, in self-complacent testimony of his entire satisfaction. As this glad ship of good luck bore down upon the moody Pequod, the barbarian sound of enormous drums came from her forecastle; and drawing still nearer, a crowd of her men were seen standing round her huge try-pots, which, covered with the parchment-like poke or stomach skin of the black fish, gave forth a loud roar to every stroke of the clenched hands of the crew. On the quarter-deck, the mates and harpooneers were dancing with the olive-hued girls who had eloped with them from the Polynesian Isles; while suspended in an ornamented boat, firmly secured aloft between the foremast and mainmast, three Long Island negroes, with glittering fiddle-bows of whale ivory, were presiding over the hilarious jig. Meanwhile, others of the ship's company were tumultuously busy at the masonry of the try-works, from which the huge pots had been removed. You would have almost thought they were pulling down the cursed Bastile, such wild cries they raised, as the now useless brick and mortar were being hurled into the sea. ..

Lord and master over all this scene, the captain stood erect on the ship's elevated quarter-deck, so that the whole rejoicing drama was full before him, and seemed merely contrived for his own individual diversion. And Ahab, he too was standing on his quarter-deck, shaggy and black, with a stubborn gloom; and as the two ships crossed each other's wakes --one all jubilations for things passed, the other all forebodings as to things to come --their two captains in themselves impersonated the whole striking contrast of the scene. Come aboard, come aboard! cried the gay Bachelor's commander, lifting a glass and a bottle in the air. Hast seen the White Whale? gritted Ahab in reply. No; only heard of him; but don't believe in him at all, said the other good-humoredly. Come aboard! Thou are too damned jolly. Sail on. Hast lost any men? Not enough to speak of --two islanders, that's all; --but come aboard, old hearty, come along. I'll soon take that black from your brow. Come along, will ye (merry's the play); a full ship and homeward-bound. How wondrous familiar is a fool! muttered Ahab; then aloud, Thou art a full ship and homeward bound, thou sayest; well, then, call me an empty ship, and outward-bound. So go thy ways, and I will mine. Forward there! Set all sail, and keep her to the wind! And thus, while the one ship went cheerily before the breeze, the other stubbornly fought against it; and so the two vessels parted; the crew of the Pequod looking with grave, lingering glances towards the receding Bachelor; but the Bachelor's men never heeding their gaze for the lively revelry they were in. And as Ahab, leaning over the taffrail, eyed the homeward-bound craft, he took from his pocket a small vial of sand, and then looking from the ship to the vial, seemed thereby bringing two remote associations together, for that vial was filled with Nantucket soundings. ..

.. < chapter cxvi 2 THE DYING WHALE > Not seldom in this life, when, on the right side, fortune's favorites sail close by us, we, though all adroop before, catch somewhat of the rushing breeze, and joyfully feel our bagging sails fill out. So seemed it with the Pequod. For next day after encountering the gay Bachelor, whales were seen and four were slain; and one of them by Ahab. It was far down the afternoon; and when all the spearings of the crimson fight were done: and floating in the lovely sunset sea and sky, sun and whale both stilly died together; then, such a sweetness and such plaintiveness, such inwreathing orisons curled up in that rosy air, that it almost seemed as if far over from the deep green convent valleys of the Manilla isles, the Spanish land-breeze, wantonly turned sailor, had gone to sea, freighted with these vesper hymns. Soothed again, but only soothed to deeper gloom, Ahab, who had sterned off from the whale, sat intently watching his final wanings from the now tranquil boat. For that strange spectacle observable in all sperm whales dying --the turning sunwards of the head, and so expiring --that strange spectacle, beheld of such a placid evening, somehow to Ahab conveyed a wondrousness unknown before. He turns and turns him to it, --how slowly, but how steadfastly, his homage-rendering and invoking brow, with his last dying motions. He too worships fire; most faithful, broad, baronial vassal of the sun! --Oh that these too-favoring eyes should see these too-favoring sights. Look! here, far water-locked; beyond all hum of human weal or woe; in these most candid and impartial seas; where to traditions no rocks furnish tablets; where for long Chinese ages, the billows have still rolled on speechless and unspoken to, as stars that shine upon the Niger's unknown source; here, too, life dies sunwards full of ..

faith; but see! no sooner dead, than death whirls round the corpse, and it heads some other way. -- Oh, thou dark Hindoo half of nature, who of drowned bones hast builded thy separate throne somewhere in the heart of these unverdured seas; thou art an infidel, thou queen, and too truly speakest to me in the wide-slaughtering Typhoon, and the hushed burial of its after calm. Nor has this thy whale sunwards turned his dying head, and then gone round again, without a lesson to me. Oh, trebly hooped and welded hip of power! Oh, high aspiring, rainbowed jet! --that one strivest, this one jettest all in vain! In vain, oh whale, dost thou seek intercedings with yon all-quickening sun, that only calls forth life, but gives it not again. Yet dost thou, darker half, rock me with a prouder, if a darker faith. All thy unnamable imminglings, float beneath me here; I am buoyed by breaths of once living things, exhaled as air, but water now. Then hail, for ever hail, O sea, in whose eternal tossings the wild fowl finds his only rest. Born of earth, yet suckled by the sea; though hill and valley mothered me, ye billows are my foster-brothers! ..

.. < chapter cxvii 23 THE WHALE WATCH > The four whales slain that evening had died wide apart; one, far to windward; one, less distant, to leeward; one ahead; one astern. These last three were brought alongside ere nightfall; but the windward one could not be reached till morning; and the boat that had killed it lay by its side all night; and that boat was Ahab's. The waif-pole was thrust upright into the dead whale's spout-hole; and the lantern hanging from its top, cast a troubled flickering glare upon the black, glossy back, and far out upon the ..

midnight waves, which gently chafed the whale's broad flank, like soft surf upon a beach. Ahab and all his boat's crew seemed asleep but the Parsee; who crouching in the bow, sat watching the sharks, that spectrally played round the whale, and tapped the light cedar planks with their tails. A sound like the moaning in squadrons over Asphaltites of unforgiven ghosts of Gomorrah, ran shuddering through the air. Started from his slumbers, Ahab, face to face, saw the Parsee; and hooped round by the gloom of the night they seemed the last men in a flooded world. I have dreamed it again, said he. Of the hearses? Have I not said, old man, that neither hearse nor coffin can be thine? And who are hearsed that die on the sea? But I said, old man, that ere thou couldst die on this voyage, two hearses must verily be seen by thee on the sea; the first not made by mortal hands; and the visible wood of the last one must be grown in America. Aye, aye! a strange sight that, Parsee: --a hearse and its plumes floating over the ocean with the waves for the pall-bearers. Ha! Such a sight we shall not soon see. Believe it or not, thou canst not die till it be seen, old man. And what was that saying about thyself? Though it come to the last, I shall still go before thee thy pilot. And when thou art so gone before --if that ever befall --then ere I can follow, thou must still appear to me, to pilot me still? --Was it not so? Well, then, did I believe all ye say, oh my pilot! I have here two pledges that I shall yet slay Moby Dick and survive it. Take another pledge, old man, said the Parsee, as his eyes lighted up like fire-flies in the gloom, -- Hemp only can kill thee. The gallows, ye mean. --I am immortal then, on land and on sea, cried Ahab, with a laugh of derision; -- Immortal on land and on sea! Both were silent again, as one man. The grey dawn came on, and the slumbering crew arose from the boat's bottom, and ere noon the dead whale was brought to the ship. ..

.. < chapter cxviii 2 THE QUADRANT > The season for the Line at length drew near; and every day when Ahab, coming from his cabin, cast his eyes aloft, the vigilant helmsman would ostentatiously handle his spokes, and the eager mariners quickly run to the braces, and would stand there with all their eyes centrally fixed on the nailed doubloon; impatient for the order to point the ship's prow for the equator. In good time the order came. It was hard upon high noon; and Ahab, seated in the bows of his high-hoisted boat, was about taking his wonted daily obervation of the sun to determine his latitude. Now, in that Japanese sea, the days in summer are as freshets of effulgences. That unblinkingly vivid Japanese sun seems the blazing focus of the glassy ocean's immeasureable burning-glass. The sky looks lacquered; clouds there are none; the horizon floats; and this nakedness of unrelieved radiance is as the insufferable splendors of God's throne. Well that Ahab's quadrant was furnished with colored glasses, through which to take sight of that solar fire. So, swinging his seated form to the roll of the ship, and with his astrological-looking instrument placed to his eye, he remained in that posture for some moments to catch the precise instant when the sun should gain its precise meridian. Meantime while his whole attention was absorbed, the Parsee was kneeling beneath him on the ship's deck, and with face thrown up like Ahab's, was eyeing the same sun with him; only the lids of his eyes half hooded their orbs, and his wild face was subdued to an earthly passionlessness. At length the desired observation was taken; and with his pencil upon his ivory leg, Ahab soon calculated what his latitude must be at that precise instant. Then falling into a moment's revery, he again looked up towards the sun and murmured to himself: Thou sea-mark! thou high and mighty Pilot! thou tellest me truly ..

where I am --but canst thou cast the least hint where I shall be? Or canst thou tell where some other thing besides me is this moment living? Where is Moby Dick? This instant thou must be eyeing him. These eyes of mine look into the very eye that is even now beholding him; aye, and into the eye that is even now equally beholding the objects on the unknown, thither side of thee, thou sun! Then gazing at his quadrant, and handling, one after the other, its numerous cabalistical contrivances, he pondered again, and muttered: Foolish toy! babies' plaything of haughty Admirals, and Commodores, and Captains; the world brags of thee, of thy cunning and might; but what after all canst thou do, but tell the poor, pitiful point, where thou thyself happenest to be on this wide planet, and the hand that holds thee: no! not one jot more! Thou canst not tell where one drop of water or one grain of sand will be to-morrow noon; and yet with thy impotence thou insultest the sun! Science! Curse thee, thou vain toy; and cursed be all the things that cast man's eyes aloft to that heaven, whose live vividness but scorches him, as these old eyes are even now scorched with thy light, O sun! Level by nature to this earth's horizon are the glances of man's eyes; not shot from the crown of his head, as if God had meant him to gaze on his firmament. Curse thee, thou quadrant! dashing it to the deck, no longer will I guide my earthly way by thee; the level ship's compass, and the level dead-reckoning, by log and by line; these shall conduct me, and show me my place on the sea. Aye, lighting from the boat to the deck, thus I trample on thee, thou paltry thing that feebly pointest on high; thus I split and destroy thee! As the frantic old man thus spoke and thus trampled with his live and dead feet, a sneering triumph that seemed meant for Ahab, and a fatalistic despair that seemed meant for himself --these passed over the mute, motionless Parsee's face. Unobserved he rose and glided away; while, awestruck by the aspect of their commander, the seamen clustered together on the forecastle, till Ahab, troubledly pacing the deck, shouted out -- To the braces! Up helm! --square in! In an instant the yards swung round; and as the ship half-wheeled ..

upon her heel, her three firm-seated graceful masts erectly poised upon her long, ribbed hull, seemed as the three Horatii pirouetting on one sufficient steed. Standing between the knight-heads, Starbuck watched the Pequod's tumultuous way, and Ahab's also, as he went lurching along the deck. I have sat before the dense coal fire and watched it all aglow, full of its tormented flaming life; and I have seen it wane at last, down, down, to dumbest dust. Old man of oceans! of all this fiery life of thine, what will at length remain but one little heap of ashes! Aye, cried Stubb, but sea-coal ashes --mind ye that, Mr. Starbuck --sea-coal, not your common charcoal. Well, well; I heard Ahab mutter, "Here some one thrusts these cards into these old hands of mine; swears that I must play them, and no others." And damn me, Ahab, but thou actest right; live in the game, and die it! ..

.. < chapter cxix 19 THE CANDLES > Warmest climes but nurse the cruellest fangs: the tiger of Bengal crouches in spiced groves of ceaseless verdure. Skies the most effulgent but basket the deadliest thunders: gorgeous Cuba knows tornadoes that never swept tame northern lands. So, too, it is, that in these resplendent Japanese seas the mariner encounters the direst of all storms, the Typhoon. It will sometimes burst from out that cloudless sky, like an exploding bomb upon a dazed and sleepy town. Towards evening of that day, the Pequod was torn of her canvas, and bare-poled was left to fight a Typhoon which had struck her directly ahead. When darkness came on, sky and sea roared and split with the thunder, and blazed with the lightning, that showed the disabled masts fluttering here and there with ..

the rags which the first fury of the tempest had left for its after sport. Holding by a shroud, Starbuck was standing on the quarter-deck; at every flash of the lightning glancing aloft, to see what additional disaster might have befallen the intricate hamper there; while Stubb and Flask were directing the men in the higher hoisting and firmer lashing of the boats. But all their pains seemed naught. Though lifted to the very top of the cranes, the windward quarter boat (Ahab's) did not escape. A great rolling sea, dashing high up against the reeling ship's high tetering side, stove in the boat's bottom at the stern, and left it again, all dripping through like a sieve. Bad work, bad work! Mr. Starbuck, said Stubb, regarding the wreck, but the sea will have its way. Stubb, for one, can't fight it. You see, Mr. Starbuck, a wave has such a great long start before it leaps, all round the world it runs, and then comes the spring! But as for me, all the start I have to meet it, is just across the deck here. But never mind; it's all in fun: so the old song says; --( sings.) Oh! jolly is the gale, And a joker is the whale, A' flourishin' his tail, -- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! The scud all a flyin' That's his flip only foamin'; When he stirs in the spicin', -- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! Thunder splits the ships, But he only smacks his lips, A tastin' of this flip, -- Such a funny, sporty, gamy, jesty, joky, hoky-poky lad, is the Ocean, oh! Avast Stubb, cried Starbuck, let the Typhoon sing, and strike his harp here in our rigging; but if thou art a brave man thou wilt hold thy peace. But I am not a brave man; never said i was a brave man; I am a coward; and I sing to keep up my spirits. And I tell you what it is, Mr. Starbuck, there's no way to stop my singing ..

in this world but to cut my throat. And when that's done, ten to one I sing ye the doxology for a wind-up. Madman! look through my eyes if thou hast none of thine own. What! how can you see better of a dark night than anybody else, never mind how foolish? Here! cried Starbuck, seizing Stubb by the shoulder, and pointing his hand towards the weather bow, markest thou not that the gale comes from the eastward, the very course Ahab is to run for Moby Dick? the very course he swung to this day noon? now mark his boat there; where is that stove? In the stern-sheets, man; where he is wont to stand --his stand-point is stove, man! Now jump overboard, and sing away, if thou must! I don't half understand ye: what's in the wind? Yes, yes, round the Cape of Good Hope is the shortest way to Nantucket, soliloquized Starbuck suddenly, heedless of Stubb's question. The gale that now hammers at us to stave us, we can turn it into a fair wind that will drive us towards home. Yonder, to windward, all is blackness of doom; but to leeward, homeward --I see it lightens up there; but not with the lightning. At that moment in one of the intervals of profound darkness, following the flashes, a voice was heard at his side; and almost at the same instant a volley of thunder peals rolled overhead. Who's there? Old Thunder! said Ahab, groping his way along the bulwarks to his pivot-hole; but suddenly finding his path made plain to him by elbowed lances of fire. Now, as the lightning rod to a spire on shore is intended to carry off the perilous fluid into the soil; so the kindred rod which at sea some ships carry to each mast, is intended to conduct it into the water. But as this conductor must descend to considerable depth, that its end may avoid all contact with the hull; and as moreover, if kept constantly towing there, it would be liable to many mishaps, besides interfering not a little with some of the rigging, and more or less impeding the vessel's way in the water; because of all this, the lower parts of a ship's ..

lightning-rods are not always overboard; but are generally made in long slender links, so as to be the more readily hauled up into the chains outside, or thrown down into the sea, as occasion may require. The rods! the rods! cried Starbuck to the crew, suddenly admonished to vigilance by the vivid lightning that had just been darting flambeaux, to light Ahab to his post. Are they overboard? drop them over, fore and aft. Quick! Avast! cried Ahab; let's have fair play here, though we be the weaker side. Yet I'll contribute to raise rods on the Himmalehs and Andes, that all the world may be secured; but out on privileges! Let them be, sir. Look aloft! cried Starbuck. The corpusants! the corpusants! All the yard-arms were tipped with a pallid fire; and touched at each tri-pointed lightning-rod-end with three tapering white flames, each of the three tall masts was silently burning in that sulphurous air, like three gigantic wax tapers before an altar. Blast the boat! let it go! cried Stubb at this instant, as a swashing sea heaved up under his own little craft, so that its gunwale violently jammed his hand, as he was passing a lashing. Blast it! --but slipping backward on the deck, his uplifted eyes caught the flames; and immediately shifting his tone, he cried -- The corpusants have mercy on us all! To sailors, oaths are household words; they will swear in the trance of the calm, and in the teeth of the tempest; they will imprecate curses from the topsail-yard-arms, when most they teter over to a seething sea; but in all my voyagings, seldom have I heard a common oath when God's burning finger has been laid on the ship; when his mene, mene, Tekel Upharsin has been woven into the shrouds and the cordage. While this pallidness was burning aloft, few words were heard from the enchanted crew; who in one thick cluster stood on the forecastle, all their eyes gleaming in that pale phosphorescence, like a far away constellation of stars. Relieved against the ghostly light, the gigantic jet negro, Daggoo, loomed up to thrice his real stature, and seemed the black cloud from which the thunder had come. The parted mouth of Tashtego revealed his shark-white teeth, which strangely gleamed as if they too ..

had been tipped by corpusants; while lit up by the preternatural light, Queequeg's tattooing burned like Satanic blue flames on his body. The tableau all waned at last with the pallidness aloft; and once more the Pequod and every soul on her decks were wrapped in a pall. A moment or two passed, when Starbuck, going forward, pushed against some one. It was Stubb. What thinkest thou now, man; I heard thy cry; it was not the same in the song. No, no, it wasn't; I said the corpusants have mercy on us all; and I hope they will, still. But do they only have mercy on long faces? --have they no bowels for a laugh? And look ye, Mr. Starbuck --but it's too dark to look. Hear me, then: I take that mast-head flame we saw for a sign of good luck; for those masts are rooted in a hold that is going to be chock a' block with sperm-oil, d'ye see; and so, all that sperm will work up into the masts, like sap in a tree. Yes, our three masts will yet be as three spermaceti candles --that's the good promise we saw. At that moment Starbuck caught sight of Stubb's face slowly beginning to glimmer into sight. Glancing upwards, he cried: See! see! and once more the high tapering flames were beheld with what seemed redoubled supernaturalness in their pallor. The corpusants have mercy on us all, cried Stubb, again. At the base of the mainmast, full beneath the doubloon and the flame, the parsee was kneeling in Ahab's front, but with his head bowed away from him; while near by, from the arched and overhanging rigging, where they had just been engaged securing a spar, a number of the seamen, arrested by the glare, now cohered together, and hung pendulous, like a knot of numbed wasps from a drooping, orchard twig. In various enchanted attitudes, like the standing, or stepping, or running skeletons in Herculaneum, others remained rooted to the deck; but all their eyes upcast. Aye, aye, men! cried Ahab. Look up at it; mark it well; the white flame but lights the way to the White Whale! Hand me those main-mast links there; I would fain feel this pulse, and let mine beat against it; blood against fire! So. ..

Then turning --the last link held fast in his left hand, he put his foot upon the Parsee; and with fixed upward eye, and high-flung right arm, he stood erect before the lofty tri-pointed trinity of flames. Oh! thou clear spirit of clear fire, whom on these seas I as Persian once did worship, till in the sacramental act so burned by thee, that to this hour I bear the scar; I now know thee, thou clear spirit, and I now know that thy right worship is defiance. To neither love nor reverence wilt thou be kind; and e'en for hate thou canst but kill; and all are killed. No fearless fool now fronts thee. I own thy speechless, placeless power; but to the last gasp of my earthquake life will dispute its unconditional, unintegral mastery in me. In the midst of the personified impersonal, a personality stands here. Though but a point at best; whencesoe'er I came; wheresoe'er I go; yet while I earthly live, the queenly personality lives in me, and feels her royal rights. But war is pain, and hate is woe. Come in thy lowest form of love, and I will kneel and kiss thee; but at thy highest, come as mere supernal power; and though thou launchest navies of full-freighted worlds, there's that in here that still remains indifferent. Oh, thou clear spirit, of thy fire thou madest me, and like a true child of fire, I breathe it back to thee. [Sudden, repeated flashes of lightning; the nine flames leap lengthwise to thrice their previous height; Ahab, with the rest, closes his eyes, his right hand pressed hard upon them.] I own thy speechless, placeless power; said I not so? Nor was it wrung from me; nor do I now drop these links. Thou canst blind; but I can then grope. Thou canst consume; but I can then be ashes. Take the homage of these poor eyes, and shutter-hands. I would not take it. The lightning flashes through my skull; mine eye-balls ache and ache; my whole beaten brain seems as beheaded, and rolling on some stunning ground. Oh, oh! Yet blindfold, yet will I talk to thee. Light though thou be, thou leapest out of darkness; but I am darkness leaping out of light, leaping out of thee! The javelins cease; open eyes; see, or not? There burn the flames! Oh, thou magnanimous! now do I glory in my genealogy. But thou art but my fiery father; my sweet mother, I know not. Oh, cruel! what hast ..

thou done with her? There lies my puzzle; but thine is greater. Thou knowest not how came ye, hence callest thyself unbegotten; certainly knowest not thy beginning, hence callest thyself unbegun. I know that of me, which thou knowest not of thyself, oh, thou omnipotent. There is some unsuffusing thing beyond thee, thou clear spirit, to whom all thy eternity is but time, all thy creativeness mechanical. Through thee, thy flaming self, my scorched eyes do dimly see it. Oh, thou foundling fire, thou hermit immemorial, thou too hast thy incommunicable riddle, thy unparticipated grief. Here again with haughty agony, i read my sire. leap! leap up, and lick the sky! I leap with thee; I burn with thee; would fain be welded with thee; defyingly I worship thee! The boat! the boat! cried Starbuck, look at thy boat, old man! Ahab's harpoon, the one forged at Perth's fire, remained firmly lashed in its conspicuous crotch, so that it projected beyond his whale-boat's bow; but the sea that had stove its bottom had caused the loose leather sheath to drop off; and from the keen steel barb there now came a levelled flame of pale, forked fire. As the silent harpoon burned there like a serpent's tongue, Starbuck grasped Ahab by the arm -- God, God is against thee, old man; forbear! t'is an ill voyage! ill begun, ill continued; let me square the yards, while we may, old man, and make a fair wind of it homewards, to go on a better voyage than this. Overhearing Starbuck, the panic-stricken crew instantly ran to the braces --though not a sail was left aloft. For the moment all the aghast mate's thoughts seemed theirs; they raised a half mutinous cry. But dashing the rattling lightning links to the deck, and snatching the burning harpoon, Ahab waved it like a torch among them; swearing to transfix with it the first sailor that but cast loose a rope's end. Petrified by his aspect, and still more shrinking from the fiery dart that he held, the men fell back in dismay, and Ahab again spoke: -- All your oaths to hunt the White Whale are as binding as mine; and heart, soul, and body, lungs and life, old Ahab is bound. And that ye may know to what tune this heart beats; ..

look ye here; thus I blow out the last fear! And with one blast of his breath he extinguished the flame. As in the hurricane that sweeps the plain, men fly the neighborhood of some lone, gigantic elm, whose very height and strength but render it so much the more unsafe, because so much the more a mark for thunderbolts; so at those last words of ahab's many of the mariners did run from him in a terror of dismay. ..

.. < chapter cxx 10 THE DECK TOWARDS THE END OF THE FIRST NIGHT WATCH > Ahab standing by the helm. Starbuck approaching him. We must send down the main-top-sail yard, sir. The band is working loose, and the lee lift is half-stranded. Shall I strike it, sir? Strike nothing; lash it. If I had sky-sail poles, I'd sway them up now. Sir? --in God's name! --sir? Well. The anchors are working, sir. Shall I get them inboard? Strike nothing, and stir nothing, but lash everything. The wind rises, but it has not got up to my table-lands yet. Quick, and see to it. --By masts and keels! he takes me for the hunch-backed skipper of some coasting smack. Send down my main-top-sail yard! Ho, gluepots! Loftiest trucks were made for wildest winds, and this brain-truck of mine now sails amid the cloud-scud. Shall I strike that? Oh, none but cowards send down their brain-trucks in tempest time. What a hooroosh aloft there! I would e'en take it for sublime, did I not know that the colic is a noisy malady. Oh, take medicine, take medicine! ..

.. < chapter cxxi 2 MIDNIGHT--THE FORECASTLE BULWARKS > Stubb and Flask mounted on them, and passing additional lashings over the anchors there hanging. No, Stubb; you may pound that knot there as much as you please, but you will never pound into me what you were just now saying. And how long ago is it since you said the very contrary? Didn't you once say that whatever ship Ahab sails in, that ship should pay something extra on its insurance policy, just as though it were loaded with powder barrels aft and boxes of lucifers forward? Stop, now; didn't you say so? Well, suppose I did? What then? i've part changed my flesh since that time, why not my mind? Besides, supposing we are loaded with powder barrels aft and lucifers forward; how the devil could the lucifers get afire in this drenching spray here? Why, my little man, you have pretty red hair, but you couldn't get afire now. Shake yourself; you're Aquarius, or the water-bearer, Flask; might fill pitchers at your coat collar. Don't you see, then, that for these extra risks the Marine Insurance companies have extra guarantees? Here are hydrants, Flask. But hark, again, and I'll answer ye the other thing. First take your leg off from the crown of the anchor here, though, so I can pass the rope; now listen. What's the mighty difference between holding a mast's lightning-rod in the storm, and standing close by a mast that hasn't got any lightning-rod at all in a storm? Don't you see, you timber-head, that no harm can come to the holder of the rod, unless the mast is first struck? What are you talking about, then? Not one ship in a hundred carries rods, and Ahab, --aye, man, and all of us, --were in no more danger then, in my poor opinion, than all the crews in ten thousand ships now sailing the seas. Why, you King-Post, you, I suppose you would have every man in the world go about ..

with a small lightning-rod running up the corner of his hat, like a militia officer's skewered feather, and trailing behind like his sash. Why don't ye be sensible, Flask? it's easy to be sensible; why don't ye, then? any man with half an eye can be sensible. I don't know that, Stubb. You sometimes find it rather hard. Yes, when a fellow's soaked through, it's hard to be sensible, that's a fact. And I am about drenched with this spray. Never mind; catch the turn there, and pass it. Seems to me we are lashing down these anchors now as if they were never going to be used again. tying these two anchors here, Flask, seems like tying a man's hands behind him. And what big generous hands they are, to be sure. These are your iron fists, hey? What a hold they have, too! I wonder, Flask, whether the world is anchored anywhere; if she is, she swings with an uncommon long cable, though. There, hammer that knot down, and we've done. So; next to touching land, lighting on deck is the most satisfactory. I say, just wring out my jacket skirts, will ye? Thank ye. They laugh at long-togs so, Flask; but seems to me, a long tailed coat ought always to be worn in all storms afloat. The tails tapering down that way, serve to carry off the water, d'ye see. Same with cocked hats; the cocks form gable-end eave-troughs, Flask. No more monkey-jackets and tarpaulins for me; I must mount a swallow-tail, and drive down a beaver; so. Halloa! whew! there goes my tarpaulin overboard; Lord, Lord, that the winds that come from heaven should be so unmannerly! This is a nasty night, lad. ..

.. < chapter cxxiii 10 THE MUSKET > During the most violent shocks of the Typhoon, the man at the Pequod's jaw-bone tiller had several times been reelingly hurled to the deck by its spasmodic motions, even though preventer tackles had been attached to it --for they were slack -- because some play to the tiller was indispensable. In a severe gale like this, while the ship is but a tossed shuttle-cock to the blast, it is by no means uncommon to see the needles in the compasses, at intervals, go round and round. It was thus with the Pequod's; at almost every shock the helmsman had not failed to notice the whirling velocity with which they revolved upon the cards; it is a sight that hardly any one can behold without some sort of unwonted emotion. Some hours after midnight, the Typhoon abated so much, that through the strenuous exertions of Starbuck and Stubb --one engaged forward and the other aft --the shivered remnants of the jib and fore and main-top-sails were cut adrift from the spars, and went eddying away to leeward, like the feathers of ..

an albatross, which sometimes are cast to the winds when that storm-tossed bird is on the wing. The three corresponding new sails were now bent and reefed, and a storm-trysail was set further aft; so that the ship soon went through the water with some precision again; and the course --for the present, East-south-east --which he was to steer, if practicable, was once more given to the helmsman. For during the violence of the gale, he had only steered according to its vicissitudes. But as he was now bringing the ship as near her course as possible, watching the compass meanwhile, lo! a good sign! the wind seemed coming round astern; aye! the foul breeze became fair! Instantly the yards were squared, to the lively song of Ho! the fair wind! oh-he-yo, cheerly, men! the crew singing for joy, that so promising an event should so soon have falsified the evil portents preceding it. In compliance with the standing order of his commander -- to report immediately, and at any one of the twenty-four hours, any decided change in the affairs of the deck, --Starbuck had no sooner trimmed the yards to the breeze --however reluctantly and gloomily, --than he mechanically went below to apprise Captain Ahab of the circumstance. Ere knocking at his state-room, he involuntarily paused before it a moment. The cabin lamp --taking long swings this way and that --was burning fitfully, and casting fitful shadows upon the old man's bolted door, --a thin one, with fixed blinds inserted, in place of upper panels. The isolated subterraneousness of the cabin made a certain humming silence to reign there, though it was hooped round by all the roar of the elements. The loaded muskets in the rack were shiningly revealed, as they stood upright against the forward bulkhead. Starbuck was an honest, upright man; but out of Starbuck's heart, at that instant when he saw the muskets, there strangely evolved an evil thought; but so blent with its neutral or good accompaniments that for the instant he hardly knew it for itself. He would have shot me once, he murmured, yes, there's the very musket that he pointed at me; --that one with the studded stock; let me touch it --lift it. Strange, that I, who have ..

handled so many deadly lances, strange, that I should shake so now. Loaded? I must see. Aye, aye; and powder in the pan; -- that's not good. Best spill it? --wait. I'll cure myself of this. I'll hold the musket boldly while I think. --I come to report a fair wind to him. But how fair? Fair for death and doom, -- that's fair for Moby Dick. It's a fair wind that's only fair for that accursed fish. --The very tube he pointed at me! --the very one; this one --I hold it here; he would have killed me with the very thing I handle now. --Aye and he would fain kill all his crew. Does he not say he will not strike his spars to any gale? Has he not dashed his heavenly quadrant? and in these same perilous seas, gropes he not his way by mere dead reckoning of the error-abounding log? and in this very Typhoon, did he not swear that he would have no lightning-rods? But shall this crazed old man be tamely suffered to drag a whole ship's company down to doom with him? --Yes, it would make him the wilful murderer of thirty men and more, if this ship come to any deadly harm; and come to deadly harm, my soul swears this ship will, if Ahab have his way. If, then, he were this instant--put aside, that crime would not be his. Ha! is he muttering in his sleep? Yes, just there, --in there, he's sleeping. Sleeping? aye, but still alive, and soon awake again. I can't withstand thee, then, old man. Not reasoning; not remonstrance; not entreaty wilt thou hearken to; all this thou scornest. Flat obedience to thy own flat commands, this is all thou breathest. Aye, and say'st the men have vow'd thy vow; say'st all of us are Ahabs. Great God forbid! -- But is there no other way? no lawful way? --Make him a prisoner to be taken home? What! hope to wrest this old man's living power from his own living hands? Only a fool would try it. Say he were pinioned even; knotted all over with ropes and hawsers; chained down to ring-bolts on this cabin floor; he would be more hideous than a caged tiger, then. I could not endure the sight; could not possibly fly his howlings; all comfort, sleep itself, inestimable reason would leave me on the long intolerable voyage. What, then, remains? The land is hundreds of leagues away, and locked Japan the nearest. I stand alone here upon an open sea, with two oceans and a whole continent between me and law. --Aye, aye, 'tis so. --Is heaven a murderer ..

when its lightning strikes a would-be murderer in his bed, tindering sheets and skin together? --And would I be a murderer, then, if --and slowly, stealthily, and half sideways looking, he placed the loaded musket's end against the door. On this level, Ahab's hammock swings within; his head this way. A touch, and Starbuck may survive to hug his wife and child again. --Oh Mary! Mary! --boy! boy! boy! --But if I wake thee not to death, old man, who can tell to what unsounded deeps Starbuck's body this day week may sink, with all the crew! Great God, where art thou? Shall I? shall I? --The wind has gone down and shifted, sir; the fore and main topsails are reefed and set; she heads her course. Stern all! Oh Moby Dick, I clutch thy heart at last! Such were the sounds that now came hurtling from out the old man's tormented sleep, as if Starbuck's voice had caused the long dumb dream to speak. The yet levelled musket shook like a drunkard's arm against the panel; Starbuck seemed wrestling with an angel; but turning from the door, he placed the death-tube in its rack, and left the place. He's too sound asleep, Mr Stubb; go thou down, and wake him, and tell him. I must see to the deck here. Thou know'st what to say. ..

.. < chapter cxxiv 25 THE NEEDLE > Next morning the not-yet-subsided sea rolled in long slow billows of mighty bulk, and striving in the Pequod's gurgling track, pushed her on like giants' palms outspread. The strong, unstaggering breeze abounded so, that sky and air seemed vast outbellying sails; the whole world boomed before the wind. Muffled in the full morning light, the invisible sun was only known by the spread intensity of his place; where his bayonet ..

rays moved on in stacks. Emblazonings, as of crowned Babylonian kings and queens, reigned over everything. The sea was as a crucible of molten gold, that bubblingly leaps with light and heat. Long maintaining an enchanted silence, Ahab stood apart; and every time the tetering ship loweringly pitched down her bowsprit, he turned to eye the bright sun's rays produced ahead; and when she profoundly settled by the stern, he turned behind, and saw the sun's rearward place, and how the same yellow rays were blending with his undeviating wake. Ha, ha, my ship! thou mightest well be taken now for the sea-chariot of the sun. Ho, ho! all ye nations before my prow, I bring the sun to ye! Yoke on the further billows; hallo! a tandem, I drive the sea! But suddenly reined back by some counter thought, he hurried towards the helm, huskily demanding how the ship was heading. East-sou-east, sir, said the frightened steersman. Thou liest! smiting him with his clenched fist. Heading East at this hour in the morning, and the sun astern? Upon this every soul was confounded; for the phenomenon just then observed by Ahab had unaccountably escaped every one else; but its very blinding palpableness must have been the cause. Thrusting his head half way into the binnacle, Ahab caught one glimpse of the compasses; his uplifted arm slowly fell; for a moment he almost seemed to stagger. Standing behind him Starbuck looked, and lo! the two compasses pointed East, and the Pequod was as infallibly going West. But ere the first wild alarm could get out abroad among the crew, the old man with a rigid laugh exclaimed, I have it! It has happened before. Mr. Starbuck, last night's thunder turned our compasses --that's all. Thou hast before now heard of such a thing, I take it. Aye; but never before has it happened to me, sir, said the pale mate, gloomily. Here, it must needs be said, that accidents like this have in more than one case occurred to ships in violent storms. The ..

magnetic energy, as developed in the mariner's needle, is, as all know, essentially one with the electricity beheld in heaven; hence it is not to be much marvelled at, that such things should be. In instances where the lightning has actually struck the vessel, so as to smite down some of the spars and rigging, the effect upon the needle has at times been still more fatal; all its loadstone virtue being annihilated, so that the before magnetic steel was of no more use than an old wife's knitting needle. But in either case, the needle never again, of itself, recovers the original virtue thus marred or lost; and if the binnacle compasses be affected, the same fate reaches all the others that may be in the ship; even were the lowermost one inserted into the kelson. Deliberately standing before the binnacle, and eyeing the transpointed compasses, the old man, with the sharp of his extended hand, now took the precise bearing of the sun, and satisfied that the needles were exactly inverted, shouted out his orders for the ship's course to be changed accordingly. The yards were hard up; and once more the Pequod thrust her undaunted bows into the opposing wind, for the supposed fair one had only been juggling her. Meanwhile, whatever were his own secret thoughts, Starbuck said nothing, but quietly he issued all requisite orders; while Stubb and Flask --who in some small degree seemed then to be sharing his feelings --likewise unmurmuringly acquiesced. As for the men, though some of them lowly rumbled, their fear of Ahab was greater than their fear of Fate. But as ever before, the pagan harpooneers remained almost wholly unimpressed; or if impressed, it was only with a certain magnetism shot into their congenial hearts from inflexible Ahab's. For a space the old man walked the deck in rolling reveries. But chancing to slip with his ivory heel, he saw the crushed copper sight-tubes of the quadrant he had the day before dashed to the deck. Thou poor, proud heaven-gazer and sun's pilot! yesterday I wrecked thee, and to-day the compasses would feign have wrecked me. So, so. But Ahab is lord over the level load-stone ..

yet. Mr. Starbuck--a lance without a pole; a top-maul, and the smallest of the sail-maker's needles. Quick! Accessory, perhaps, to the impulse dictating the thing he was now about to do, were certain prudential motives, whose object might have been to revive the spirits of his crew by a stroke of his subtile skill, in a matter so wondrous as that of the inverted compasses. Besides, the old man well knew that to steer by transpointed needles, though clumsily practicable, was not a thing to be passed over by superstitious sailors, without some shudderings and evil portents. Men, said he, steadily turning upon the crew, as the mate handed him the things he had demanded, my men, the thunder turned old Ahab's needles; but out of this bit of steel Ahab can make one of his own, that will point as true as any. Abashed glances of servile wonder were exchanged by the sailors, as this was said; and with fascinated eyes they awaited whatever magic might follow. But Starbuck looked away. With a blow from the top-maul Ahab knocked off the steel head of the lance, and then handing to the mate the long iron rod remaining, bade him hold it upright, without its touching the deck. Then, with the maul, after repeatedly smiting the upper end of this iron rod, he placed the blunted needle endwise on the top of it, and less strongly hammered that, several times, the mate still holding the rod as before. Then going through some small strange motions with it --whether indispensable to the magnetizing of the steel, or merely intended to augment the awe of the crew, is uncertain --he called for linen thread; and moving to the binnacle, slipped out the two reversed needles there, and horizontally suspended the sail-needle by its middle, over one of the compass-cards. At first, the steel went round and round, quivering and vibrating at either end; but at last it settled to its place, when Ahab, who had been intently watching for this result, stepped frankly back from the binnacle, and pointing his stretched arm towards it, exclaimed, --Look ye, for yourselves, if Ahab be not the lord of the level loadstone! The sun is East, and that compass swears it! One after another they peered in, for nothing but their own ..

eyes could persuade such ignorance as theirs, and one after another they slunk away. In his fiery eyes of scorn and triumph, you then saw Ahab in all his fatal pride. ..

.. < chapter cxxv 6 THE LOG AND LINE > While now the fated Pequod had been so long afloat this voyage, the log and line had but very seldom been in use. Owing to a confident reliance upon other means of determining the vessel's place, some merchantmen, and many whalemen, especially when cruising, wholly neglect to heave the log; though at the same time, and frequently more for form's sake than anything else, regularly putting down upon the customary slate the course steered by the ship, as well as the presumed average rate of progression every hour. It had been thus with the Pequod. The wooden reel and angular log attached hung, long untouched, just beneath the railing of the after bulwarks. Rains and spray had damped it; the sun and wind had warped it; all the elements had combined to rot a thing that hung so idly. But heedless of all this, his mood seized Ahab, as he happened to glance upon the reel, not many hours after the magnet scene, and he remembered how his quadrant was no more, and recalled his frantic oath about the level log and line. The ship was sailing plungingly; astern the billows rolled in riots. Forward, there! Heave the log! Two seamen came. The golden-hued Tahitian and the grizzly Manxman. Take the reel, one of ye, I'll heave. They went towards the extreme stern, on the ship's lee side, where the deck, with the oblique energy of the wind, was now almost dipping into the creamy, sidelong-rushing sea. The Manxman took the reel, and holding it high up, by the projecting handle-ends of the spindle, round which the spool ..

of line revolved, so stood with the angular log hanging downwards, till Ahab advanced to him. Ahab stood before him, and was lightly unwinding some thirty or forty turns to form a preliminary hand-coil to toss overboard, when the old Manxman, who was intently eyeing both him and the line, made bold to speak. Sir, I mistrust it; this line looks far gone, long heat and wet have spoiled it. 'Twill hold, old gentleman. Long heat and wet, have they spoiled thee? Thou seem'st to hold. Or, truer perhaps, life holds thee; not thou it. I hold the spool, sir. But just as my captain says. With these grey hairs of mine 'tis not worth while disputing, 'specially with a superior, who'll ne'er confess. What's that? There now's a patched professor in Queen Nature's granite-founded College; but methinks he's too subservient. Where wert thou born? In the little rocky Isle of Man, sir. Excellent! Thou'st hit the world by that. I know not, sir, but I was born there. In the Isle of Man, hey? Well, the other way, it's good. Here's a man from Man; a man born in once independent Man, and now unmanned of Man; which is sucked in --by what? Up with the reel! The dead, blind wall butts all inquiring heads at last. Up with it! So. The log was heaved. The loose coils rapidly straightened out in a long dragging line astern, and then, instantly, the reel began to whirl. In turn, jerkingly raised and lowered by the rolling billows, the towing resistance of the log caused the old reelman to stagger strangely. Hold hard! Snap! the overstrained line sagged down in one long festoon; the tugging log was gone. I crush the quadrant, the thunder turns the needles, and now the mad sea parts the log-line. But Ahab can mend all. Haul in here, Tahitian; reel up, Manxman. And look ye, let the carpenter make another log, and mend thou the line. See to it. ..

There he goes now; to him nothing's happened; but to me, the skewer seems loosening out of the middle of the world. Haul in, haul in, Tahitian! These lines run whole, and whirling out: come in broken, and dragging slow. Ha, Pip? come to help; eh, Pip? Pip? whom call ye Pip? Pip jumped from the whale-boat. pip's missing. let's see now if ye haven't fished him up here, fisherman. It drags hard; I guess he's holding on. Jerk him, Tahiti! Jerk him off; we haul in no cowards here. Ho! there's his arm just breaking water. A hatchet! a hatchet! cut it off -- we haul in no cowards here. Captain Ahab! sir, sir! here's Pip, trying to get on board again. Peace, thou crazy loon, cried the Manxman, seizing him by the arm. Away from the quarter-deck! The greater idiot ever scolds the lesser, muttered Ahab, advancing. Hands off from that holiness! Where sayest thou Pip was, boy? Astern there, sir, astern! Lo, lo! And who art thou, boy? I see not my reflection in the vacant pupils of thy eyes. Oh God! that man should be a thing for immortal souls to sieve through! Who art thou, boy? Bell-boy, sir; ship's-crier; ding, dong, ding! Pip! Pip! Pip! One hundred pounds of clay reward for Pip; five feet high-- looks cowardly --quickest known by that! Ding, dong, ding! Who's seen Pip the coward? There can be no hearts above the snow-line. Oh, ye frozen heavens! look down here. Ye did beget this luckless child, and have abandoned him, ye creative libertines. Here, boy; Ahab's cabin shall be Pip's home henceforth, while Ahab lives. Thou touchest my inmost centre, boy; thou art tied to me by cords woven of my heart-strings. Come, let's down. What's this? here's velvet shark-skin, intently gazing at Ahab's hand, and feeling it. Ah, now, had poor Pip but felt so kind a thing as this, perhaps he had ne'er been lost! This seems to me, sir, as a man-rope; something that weak souls may hold by. Oh, sir, let old Perth now come and rivet these two hands together; the black one with the white, for I will not let this go. ..

Oh, boy, nor will I thee, unless I should thereby drag thee to worse horrors than are here. come, then, to my cabin. Lo! ye believers in gods all goodness, and in man all ill, lo you! see the omniscient gods oblivious of suffering man; and man, though idiotic, and knowing not what he does, yet full of the sweet things of love and gratitude. Come! I feel prouder leading thee by thy black hand, than though I grasped an Emperor's! There go two daft ones now, muttered the old Manxman. One daft with strength, the other daft with weakness. But here's the end of the rotten line --all dripping, too. Mend it, eh? I think we had best have a new line altogether. I'll see Mr. Stubb about it. ..

.. < chapter cxxvi 14 THE LIFE-BUOY > Steering now south-eastward by Ahab's levelled steel, and her progress solely determined by Ahab's level log and line; the Pequod held on her path towards the Equator. Making so long a passage through such unfrequented waters, descrying no ships, and ere long, sideways impelled by unvarying trade winds, over waves monotonously mild; all these seemed the strange calm things preluding some riotous and desperate scene. At last, when the ship drew near to the outskirts, as it were, of the Equatorial fishing-ground, and in the deep darkness that goes before the dawn, was sailing by a cluster of rocky islets; the watch --then headed by Flask --was startled by a cry so plaintively wild and unearthly --like half-articulated wailings of the ghosts of all Herod's murdered Innocents --that one and all, they started from their reveries, and for the space of some moments stood, or sat, or leaned all transfixedly listening, like the carved Roman slave, while that wild cry remained within hearing. The Christian or civilized part of the crew said it was mermaids, and shuddered; but the pagan harpooneers remained ..

unappalled. Yet the grey Manxman --the oldest mariner of all -- declared that the wild thrilling sounds that were heard, were the voices of newly drowned men in the sea. below in his hammock, ahab did not hear of this till grey dawn, when he came to the deck; it was then recounted to him by Flask, not unaccompanied with hinted dark meanings. He hollowly laughed, and thus explained the wonder. Those rocky islands the ship had passed were the resort of great numbers of seals, and some young seals that had lost their dams, or some dams that had lost their cubs, must have risen nigh the ship and kept company with her, crying and sobbing with their human sort of wail. But this only the more affected some of them, because most mariners cherish a very superstitious feeling about seals, arising not only from their peculiar tones when in distress, but also from the human look of their round heads and semi-intelligent faces, seen peeringly uprising from the water alongside. In the sea, under certain circumstances, seals have more than once been mistaken for men. But the bodings of the crew were destined to receive a most plausible confirmation in the fate of one of their number that morning. At sun-rise this man went from his hammock to his mast-head at the fore; and whether it was that he was not yet half waked from his sleep (for sailors sometimes go aloft in a transition state), whether it was thus with the man, there is now no telling; but, be that as it may, he had not been long at his perch, when a cry was heard --a cry and a rushing --and looking up, they saw a falling phantom in the air; and looking down, a little tossed heap of white bubbles in the blue of the sea. The life-buoy --a long slender cask --was dropped from the stern, where it always hung obedient to a cunning spring; but no hand rose to seize it, and the sun having long beat upon this cask it had shrunken, so that it slowly filled, and the parched wood also filled at its every pore; and the studded iron-bound cask followed the sailor to the bottom, as if to yield him his pillow, though in sooth but a hard one. And thus the first man of the pequod that mounted the mast to look out for the White Whale, on the White Whale's own ..

peculiar ground; that man was swallowed up in the deep. But few, perhaps, thought of that at the time. Indeed, in some sort, they were not grieved at this event, at least as a portent; for they regarded it, not as a foreshadowing of evil in the future, but as the fulfilment of an evil already presaged. They declared that now they knew the reason of those wild shrieks they had heard the night before. But again the old Manxman said nay. The lost life-buoy was now to be replaced; Starbuck was directed to see to it; but as no cask of sufficient lightness could be found, and as in the feverish eagerness of what seemed the approaching crisis of the voyage, all hands were impatient of any toil but what was directly connected with its final end, whatever that might prove to be; therefore, they were going to leave the ship's stern unprovided with a buoy, when by certain strange signs and inuendoes Queequeg hinted a hint concerning his coffin. A life-buoy of a coffin! cried Starbuck, starting. Rather queer, that, I should say, said Stubb. It will make a good enough one, said Flask, the carpenter here can arrange it easily. Bring it up; there's nothing else for it, said Starbuck, after a melancholy pause. Rig it, carpenter; do not look at me so -- the coffin, I mean. Dost thou hear me? Rig it. And shall I nail down the lid, sir? moving his hand as with a hammer. aye. And shall I caulk the seams, sir? moving his hand as with a caulking-iron. Aye. And shall I then pay over the same with pitch, sir? moving his hand as with a pitch-pot. Away! What possesses thee to this? Make a life-buoy of the coffin, and no more. --Mr. Stubb, Mr. Flask, come forward with me. He goes off in a huff. The whole he can endure; at the parts he baulks. Now I don't like this. i make a leg for captain ahab, and he wears it like a gentleman; but I make a bandbox for Queequeg, and he wont put his head into it. Are ..

all my pains to go for nothing with that coffin? And now I'm ordered to make a life-buoy of it. It's like turning an old coat; going to bring the flesh on the other side now. I don't like this cobbling sort of business --I don't like it at all; it's undignified; it's not my place. Let tinkers' brats do tinkerings; we are their betters. I like to take in hand none but clean, virgin, fair-and-square mathematical jobs, something that regularly begins at the beginning, and is at the middle when midway, and comes to an end at the conclusion; not a cobbler's job, that's at an end in the middle, and at the beginning at the end. It's the old woman's tricks to be giving cobbling jobs. Lord! what an affection all old women have for tinkers. I know an old woman of sixty-five who ran away with a bald-headed young tinker once. And that's the reason I never would work for lonely widow old women ashore, when I kept my job-shop in the Vineyard; they might have taken it into their lonely old heads to run off with me. But heigh-ho! there are no caps at sea but snow-caps. Let me see. Nail down the lid; caulk the seams; pay over the same with pitch; batten them down tight, and hang it with the snap-spring over the ship's stern. Were ever such things done before with a coffin? Some superstitious old carpenters, now, would be tied up in the rigging, ere they would do the job. But I'm made of knotty Aroostook hemlock; I don't budge. Cruppered with a coffin! Sailing about with a grave-yard tray! But never mind. We workers in woods make bridal-bedsteads and card-tables, as well as coffins and hearses. We work by the month, or by the job, or by the profit; not for us to ask the why and wherefore of our work, unless it be too confounded cobbling, and then we stash it if we can. hem! i'll do the job, now, tenderly. I'll have me --let's see --how many in the ship's company, all told? But I've forgotten. Any way, I'll have me thirty separate, Turk's-headed life-lines, each three feet long hanging all round to the coffin. Then, if the hull go down, there'll be thirty lively fellows all fighting for one coffin, a sight not seen very often beneath the sun! Come hammer, calking-iron, pitch-pot, and marling-spike! Let's to it. ..

.. < chapter cxxvii 2 THE DECK > The coffin laid upon two line-tubs, between the vice-bench and the open hatchway; the Carpenter calking its seams; the string of twisted oakum slowly unwinding from a large roll of it placed in the bosom of his frock. --Ahab comes slowly from the cabin-gangway, and hears Pip following him. Back, lad; I will be with ye again presently. He goes! Not this hand complies with my humor more genially than that boy. -- Middle aisle of a church! What's here? Life buoy, sir. Mr. Starbuck's orders. Oh, look, sir! Beware the hatchway! Thank ye, man. Thy coffin lies handy to the vault. Sir? The hatchway? oh! So it does, sir, so it does. Art not thou the leg-maker? Look, did not this stump come from thy shop? I believe it did, sir; does the ferrule stand, sir? Well enough. But art thou not also the undertaker? Aye, sir; I patched up this thing here as a coffin for Queequeg; but they've set me now to turning it into something else. Then tell me; art thou not an arrant, all-grasping, inter-meddling, monopolizing, heathenish old scamp, to be one day making legs, and the next day coffins to clap them in, and yet again life-buoys out of those same coffins? Thou art as unprincipled as the gods, and as much of a jack-of-all-trades. But I do not mean anything, sir. I do as I do. The gods again. hark ye, dost thou not ever sing working about a coffin? The Titans, they say, hummed snatches when chipping out the craters for volcanoes; and the grave-digger in the play sings, spade in hand. Dost thou never? Sing, sir? Do I sing? Oh, I'm indifferent enough, sir, for that; but the reason why the grave-digger made music must ..

have been because there was none in his spade, sir. But the calking mallet is full of it. Hark to it. Aye, and that's because the lid there's a sounding-board; and what in all things makes the sounding-board is this --there's naught beneath. And yet, a coffin with a body in it rings pretty much the same, Carpenter. Hast thou ever helped carry a bier, and heard the coffin knock against the churchyard gate, going in? Faith, sir, I've-- Faith? What's that? Why, faith, sir, it's only a sort of exclamation-like --that's all, sir. Um, um; go on. I was about to say, sir, that-- Art thou a silk-worm? Dost thou spin thy own shroud out of thyself? Look at thy bosom! Despatch! and get these traps out of sight. He goes aft. That was sudden, now; but squalls come sudden in hot latitudes. I've heard that the Isle of Albemarle, one of the Gallipagos, is cut by the Equator right in the middle. Seems to me some sort of Equator cuts yon old man, too, right in his middle. He's always under the Line--fiery hot, I tell ye! He's looking this way --come, oakum; quick. Here we go again. This wooden mallet is the cork, and I'm the professor of musical glasses --tap, tap! ( Ahab to himself.) There's a sight! There's sound! The greyheaded woodpecker tapping the hollow tree! Blind and dumb might well be envied now. See! that thing rests on two line-tubs, full of tow-lines. A most malicious wag, that fellow. Rat-tat! So man's seconds tick! Oh! how immaterial are all materials! What things real are there, but imponderable thoughts? Here now's the very dreaded symbol of grim death, by a mere hap, made the expressive sign of the help and hope of most endangered life. A life-buoy of a coffin! Does it go further? Can it be that in some spiritual sense the coffin is, after all, but an immortality-preserver! I'll think of that. But no. So far gone ..

am I in the dark side of earth, that its other side, the theoretic bright one, seems but uncertain twilight to me. Will ye never have done, Carpenter, with that accursed sound? I go below; let me not see that thing here when I return again. Now, then, Pip, we'll talk this over; I do suck most wondrous philosophies from thee! Some unknown conduits from the unknown worlds must empty into thee! ..

.. < chapter cxxviii 9 THE PEQUOD MEETS THE RACHEL > Next day, a large ship, the Rachel, was descried, bearing directly down upon the Pequod, all her spars thickly clustering with men. At the time the Pequod was making good speed through the water; but as the broad-winged windward stranger shot nigh to her, the boastful sails all fell together as blank bladders that are burst, and all life fled from the smitten hull. Bad news; she brings bad news, muttered the old Manxman. But ere her commander, who, with trumpet to mouth, stood up in his boat; ere he could hopefully hail, Ahab's voice was heard. Hast seen the White Whale? Aye, yesterday. Have ye seen a whale-boat adrift? Throttling his joy, Ahab negatively answered this unexpected question; and would then have fain boarded the stranger, when the stranger captain himself, having stopped his vessel's way, was seen descending her side. A few keen pulls, and his boat-hook soon clinched the Pequod's main-chains, and he sprang to the deck. Immediately he was recognized by ahab for a nantucketer he knew. But no formal salutation was exchanged. Where was he? --not killed! --not killed! cried Ahab, closely advancing. How was it? It seemed that somewhat late on the afternoon of the day previous, while three of the stranger's boats were engaged with ..

a shoal of whales, which had led them some four or five miles from the ship; and while they were yet in swift chase to windward, the white hump and head of Moby Dick had suddenly loomed up out of the blue water, not very far to leeward; whereupon, the fourth rigged boat --a reserved one --had been instantly lowered in chase. After a keen sail before the wind, this fourth boat --the swiftest keeled of all --seemed to have succeeded in fastening --at least, as well as the man at the mast-head could tell anything about it. In the distance he saw the diminished dotted boat; and then a swift gleam of bubbling white water; and after that nothing more; whence it was concluded that the stricken whale must have indefinitely run away with his pursuers, as often happens. There was some apprehension, but no positive alarm, as yet. The recall signals were placed in the rigging; darkness came on; and forced to pick up her three far to windward boats --ere going in quest of the fourth one in the precisely opposite direction --the ship had not only been necessitated to leave that boat to its fate till near midnight, but, for the time, to increase her distance from it. But the rest of her crew being at last safe aboard, she crowded all sail --stunsail on stunsail --after the missing boat; kindling a fire in her try-pots for a beacon; and every other man aloft on the look-out. But though when she had thus sailed a sufficient distance to gain the presumed place of the absent ones when last seen; though she then paused to lower her spare boats to pull all around her; and not finding anything, had again dashed on; again paused, and lowered her boats; and though she had thus continued doing till day light; yet not the least glimpse of the missing keel had been seen. The story told, the stranger Captain immediately went on to reveal his object in boarding the Pequod. He desired that ship to unite with his own in the search; by sailing over the sea some four or five miles apart, on parallel lines, and so sweeping a double horizon, as it were. I will wager something now, whispered Stubb to Flask, that some one in that missing boat wore off that Captain's best coat; mayhap, his watch --he's so cursed anxious to get it back. Who ever heard of two pious whale-ships cruising after ..

one missing whale-boat in the height of the whaling season? See, Flask, only see how pale he looks --pale in the very buttons of his eyes --look --it wasn't the coat --it must have been the-- My boy, my own boy is among them. For God's sake --I beg, I conjure --here exclaimed the stranger Captain to Ahab, who thus far had but icily received his petition. For eight-and-forty hours let me charter your ship --I will gladly pay for it, and roundly pay for it --if there be no other way --for eight-and-forty hours only --only that --you must, oh, you must, and you shall do this thing. His son! cried Stubb, oh, it's his son he's lost! I take back the coat and watch --what says Ahab? We must save that boy. He's drowned with the rest on 'em, last night, said the old Manx sailor standing behind them; I heard; all of ye heard their spirits. Now, as it shortly turned out, what made this incident of the Rachel's the more melancholy, was the circumstance, that not only was one of the Captain's sons among the number of the missing boat's crew; but among the number of the other boat's crews, at the same time, but on the other hand, separated from the ship during the dark vicissitudes of the chase, there had been still another son; as that for a time, the wretched father was plunged to the bottom of the cruellest perplexity; which was only solved for him by his chief mate's instinctively adopting the ordinary procedure of a whale-ship in such emergencies, that is, when placed between jeopardized but divided boats, always to pick up the majority first. But the captain, for some unknown constitutional reason, had refrained from mentioning all this, and not till forced to it by Ahab's iciness did he allude to his one yet missing boy; a little lad, but twelve years old, whose father with the earnest but unmisgiving hardihood of a Nantucketer's paternal love, had thus early sought to initiate him in the perils and wonders of a vocation almost immemorially the destiny of all his race. Nor does it unfrequently occur, that Nantucket captains will send a son of such tender age away from them, for a protracted three or four years' voyage in some other ship than their own; so that their first knowledge of a whaleman's career shall be unenervated by any chance display ..

of a father's natural but untimely partiality, or undue apprehensiveness and concern. Meantime, now the stranger was still beseeching his poor boon of Ahab; and Ahab still stood like an anvil, receiving every shock, but without the least quivering of his own. I will not go, said the stranger, till you say aye to me. Do to me as you would have me do to you in the like case. For you too have a boy, Captain Ahab --though but a child, and nestling safely at home now --a child of your old age too -- Yes, yes, you relent; I see it --run, run, men, now, and stand by to square in the yards. Avast, cried Ahab -- touch not a rope-yarn; then in a voice that prolongingly moulded every word -- Captain Gardiner, I will not do it. Even now I lose time. Good bye, good bye. God bless ye, man, and may I forgive myself, but I must go. Mr. Starbuck, look at the binnacle watch, and in three minutes from this present instant warn off all strangers: then brace forward again, and let the ship sail as before. Hurriedly turning, with averted face, he descended into his cabin, leaving the strange captain transfixed at this unconditional and utter rejection of his so earnest suit. But starting from his enchantment, Gardiner silently hurried to the side; more fell than stepped into his boat, and returned to his ship. Soon the two ships diverged their wakes; and long as the strange vessel was in view, she was seen to yaw hither and thither at every dark spot, however small, on the sea. This way and that her yards were swung round; starboard and larboard, she continued to tack; now she beat against a head sea; and again it pushed her before it; while all the while, her masts and yards were thickly clustered with men, as three tall cherry trees, when the boys are cherrying among the boughs. But by her still halting course and winding, woful way, you plainly saw that this ship that so wept with spray, still remained without comfort. She was Rachel, weeping for her children, because they were not. ..

.. < chapter cxxix 2 THE CABIN > (Ahab moving to go on deck; Pip catches him by the hand to follow.) Lad, lad, I tell thee thou must not follow Ahab now. The hour is coming when Ahab would not scare thee from him, yet would not have thee by him. There is that in thee, poor lad, which I feel too curing to my malady. Like cures like; and for this hunt, my malady becomes my most desired health. Do thou abide below here, where they shall serve thee, as if thou wert the captain. Aye, lad, thou shalt sit here in my own screwed chair; another screw to it, thou must be. No, no, no! ye have not a whole body, sir; do ye but use poor me for your one lost leg; only tread upon me, sir; I ask no more, so I remain a part of ye. Oh! spite of million villains, this makes me a bigot in the fadeless fidelity of man! --and a black! and crazy! --but methinks like-cures-like applies to him too; he grows so sane again. They tell me, sir, that Stubb did once desert poor little Pip, whose drowned bones now show white, for all the blackness of his living skin. But I will never desert ye, sir, as Stubb did him. Sir, I must go with ye. If thou speakest thus to me much more, Ahab's purpose keels up in him. I tell thee no; it cannot be. Oh good master, master, master! Weep so, and I will murder thee! have a care, for Ahab too is mad. Listen, and thou wilt often hear my ivory foot upon the deck, and still know that I am there. And now I quit thee. Thy hand! --Met! True art thou, lad, as the circumference to its centre. So: God for ever bless thee; and if it come to that, -- God for ever save thee, let what will befall. ..

Ahab goes; Pip steps one step forward.) Here he this instant stood; I stand in his air, --but I'm alone. Now were even poor Pip here I could endure it, but he's missing. Pip! Pip! Ding, dong, ding! Who's seen Pip? He must be up here; let's try the door. What? neither lock, nor bolt, nor bar; and yet there's no opening it. It must be the spell; he told me to stay here: Aye, and told me this screwed chair was mine. Here, then, I'll seat me, against the transom, in the ship's full middle, all her keel and her three masts before me. Here, our old sailors say, in their black seventy-fours great admirals sometimes sit at table, and lord it over rows of captains and lieutenants. Ha! what's this? epaulets! epaulets! the epaulets all come crowding! Pass round the decanters; glad to see ye; fill up, monsieurs! What an odd feeling, now, when a black boy's host to white men with gold lace upon their coats! --Monsieurs, have ye seen one Pip? --a little negro lad, five feet high, hang-dog look, and cowardly! Jumped from a whale-boat once; --seen him? No! Well then, fill up again, captains, and let's drink shame upon all cowards! I name no names. Shame upon them! Put one foot upon the table. Shame upon all cowards. --Hist! above there, I hear ivory --Oh, master, master! I am indeed down-hearted when you walk over me. But here I'll stay, though this stern strikes rocks; and they bulge through; and oysters come to join me. ..

.. < chapter cxxx 26 THE HAT > And now that at the proper time and place, after so long and wide a preliminary cruise, Ahab, --all other whaling waters swept --seemed to have chased his foe into an ocean-fold, to slay him the more securely there; now, that he found himself hard by the very latitude and longitude where his tormenting wound ..

had been inflicted; now that a vessel had been spoken which on the very day preceding had actually encountered Moby Dick; --and now that all his successive meetings with various ships contrastingly concurred to show the demoniac indifference with which the white whale tore his hunters, whether sinning or sinned against; now it was that there lurked a something in the old man's eyes, which it was hardly sufferable for feeble souls to see. As the unsetting polar star, which through the livelong, arctic, six months' night sustains its piercing, steady, central gaze; so Ahab's purpose now fixedly gleamed down upon the constant midnight of the gloomy crew. It domineered above them so, that all their bodings, doubts, misgivings, fears, were fain to hide beneath their souls, and not sprout forth a single spear or leaf. In this foreshadowing interval too, all humor, forced or natural, vanished. Stubb no more strove to raise a smile; Starbuck no more strove to check one. Alike, joy and sorrow, hope and fear, seemed ground to finest dust, and powdered, for the time, in the clamped mortar of ahab's iron soul. like machines, they dumbly moved about the deck, ever conscious that the old man's despot eye was on them. But did you deeply scan him in his more secret confidential hours; when he thought no glance but one was on him; then you would have seen that even as Ahab's eyes so awed the crew's, the inscrutable Parsee's glance awed his; or somehow, at least, in some wild way, at times affected it. Such an added, gliding strangeness began to invest the thin Fedallah now; such ceaseless shudderings shook him; that the men looked dubious at him; half uncertain, as it seemed, whether indeed he were a mortal substance, or else a tremulous shadow cast upon the deck by some unseen being's body. And that shadow was always hovering there. For not by night, even, had Fedallah ever certainly been known to slumber, or go below. He would stand still for hours: but never sat or leaned; his wan but wondrous eyes did plainly say --We two watchmen never rest. Nor, at any time, by night or day could the mariners now step up the deck, unless Ahab was before them; either standing in his pivot-hole, or exactly pacing the planks between two ..

undeviating limits, --the main-mast and the mizen; or else they saw him standing in the cabin-scuttle, --his living foot advanced upon the deck, as if to step; his hat slouched heavily over his eyes; so that however motionless he stood, however the days and nights were added on, that he had not swung in his hammock; yet hidden beneath that slouching hat, they could never tell unerringly whether, for all this, his eyes were really closed at times; or whether he was still intently scanning them; no matter, though he stood so in the scuttle for a whole hour on the stretch, and the unheeded night-damp gathered in beads of dew upon that stone-carved coat and hat. The clothes that the night had wet, the next day's sunshine dried upon him; and so, day after day, and night after night; he went no more beneath the planks; whatever he wanted from the cabin that thing he sent for. He ate in the same open air; that is, his two only meals, -- breakfast and dinner: supper he never touched; nor reaped his beard; which darkly grew all gnarled, as unearthed roots of trees blown over, which still grow idly on at naked base, though perished in the upper verdure. But though his whole life was now become one watch on deck; and though the Parsee's mystic watch was without intermission as his own; yet these two never seemed to speak --one man to the other --unless at long intervals some passing unmomentous matter made it necessary. Though such a potent spell seemed secretly to join the twain; openly, and to the awe-struck crew, they seemed pole-like asunder. If by day they chanced to speak one word; by night, dumb men were both, so far as concerned the slightest verbal interchange. At times, for longest hours, without a single hail, they stood far parted in the starlight; Ahab in his scuttle, the Parsee by the mainmast; but still fixedly gazing upon each other; as if in the Parsee Ahab saw his forethrown shadow, in Ahab the Parsee his abandoned substance. And yet, somehow, did Ahab --in his own proper self, as daily, hourly, and every instant, commandingly revealed to his subordinates, --Ahab seemed an independent lord; the Parsee but his slave. Still again both seemed yoked together, and an unseen ..

tyrant driving them; the lean shade siding the solid rib. For be this Parsee what he may, all rib and keel was solid Ahab. At the first faintest glimmering of the dawn, his iron voice was heard from aft -- Man the mast-heads! --and all through the day, till after sunset and after twilight, the same voice every hour, at the striking of the helmsman's bell, was heard -- What d'ye see? --sharp! sharp! But when three or four days had slided by, after meeting the children-seeking Rachel; and no spout had yet been seen; the monomaniac old man seemed distrustful of his crew's fidelity; at least, of nearly all except the Pagan harpooneers; he seemed to doubt, even, whether Stubb and Flask might not willingly overlook the sight he sought. But if these suspicions were really his, he sagaciously refrained from verbally expressing them, however his actions might seem to hint them. I will have the first sight of the whale myself, --he said. Aye! Ahab must have the doubloon! and with his own hands he rigged a nest of basketed bowlines; and sending a hand aloft, with a single sheaved block, to secure to the main-mast head, he received the two ends of the downward-reeved rope; and attaching one to his basket prepared a pin for the other end, in order to fasten it at the rail. This done, with that end yet in his hand and standing beside the pin, he looked round upon his crew, sweeping from one to the other; pausing his glance long upon Daggoo, Queequeg, Tashtego; but shunning Fedallah; and then settling his firm relying eye upon the chief mate, said, -- Take the rope, sir --I give it into thy hands, Starbuck. Then arranging his person in the basket, he gave the word for them to hoist him to his perch, Starbuck being the one who secured the rope at last; and afterwards stood near it. And thus, with one hand clinging round the royal mast, Ahab gazed abroad upon the sea for miles and miles, --ahead, astern, this side, and that, --within the wide expanded circle commanded at so great a height. When in working with his hands at some lofty almost isolated place in the rigging, which chances to afford no foothold, the sailor at sea is hoisted up to that spot, and sustained there by ..

the rope; under these circumstances, its fastened end on deck is always given in strict charge to some one man who has the special watch of it. Because in such a wilderness of running rigging, whose various different relations aloft cannot always be infallibly discerned by what is seen of them at the deck; and when the deck-ends of these ropes are being every few minutes cast down from the fastenings, it would be but a natural fatality, if, unprovided with a constant watchman, the hoisted sailor should by some carelessness of the crew be cast adrift and fall all swooping to the sea. So Ahab's proceedings in this matter were not unusual; the only strange thing about them seemed to be, that Starbuck, almost the one only man who had ever ventured to oppose him with anything in the slightest degree approaching to decision --one of those too, whose faithfulness on the look-out he had seemed to doubt somewhat; --it was strange, that this was the very man he should select for his watchman; freely giving his whole life into such an otherwise distrusted person's hands. Now, the first time Ahab was perched aloft; ere he had been there ten minutes; one of those red-billed savage sea-hawks which so often fly incommodiously close round the manned mast-heads of whalemen in these latitudes; one of these birds came wheeling and screaming round his head in a maze of untrackably swift circlings. Then it darted a thousand feet straight up into the air; then spiralized downwards, and went eddying again round his head. But with his gaze fixed upon the dim and distant horizon, Ahab seemed not to mark this wild bird; nor, indeed, would any one else have marked it much, it being no uncommon circumstance; only now almost the least heedful eye seemed to see some sort of cunning meaning in almost every sight. Your hat, your hat, sir! suddenly cried the Sicilian seaman, who being posted at the mizen-mast-head, stood directly behind Ahab, though somewhat lower than his level, and with a deep gulf of air dividing them. But already the sable wing was before the old man's eyes; the long hooked bill at his head: with a scream, the black hawk darted away with his prize. ..

an eagle flew thrice round Tarquin's head, removing his cap to replace it, and thereupon Tanaquil, his wife, declared that Tarquin would be king of Rome. But only by the replacing of the cap was that omen accounted good. Ahab's hat was never restored; the wild hawk flew on and on with it; far in advance of the prow: and at last disappeared; while from the point of that disappearance, a minute black spot was dimly discerned, falling from that vast height into the sea. ..

.. < chapter cxxxi 10 THE PEQUOD MEETS THE DELIGHT > The intense Pequod sailed on; the rolling waves and days went by; the life-buoy-coffin still lightly swung; and another ship, most miserably misnamed the Delight, was descried. As she drew nigh, all eyes were fixed upon her broad beams, called shears, which, in some whaling-ships, cross the quarter-deck at the height of eight or nine feet; serving to carry the spare, unrigged, or disabled boats. Upon the stranger's shears were beheld the shattered, white ribs, and some few splintered planks, of what had once been a whale-boat; but you now saw through this wreck, as plainly as you see through the peeled, half-unhinged, and bleaching skeleton of a horse. Hast seen the White Whale? Look! replied the hollow-cheeked captain from his taffrail; and with his trumpet he pointed to the wreck. Hast killed him? The harpoon is not yet forged that will ever do that, answered the other, sadly glancing upon a rounded hammock on the deck, whose gathered sides some noiseless sailors were busy in sewing together. Not forged! and snatching Perth's levelled iron from the crotch, Ahab held it out, exclaiming -- Look ye, Nantucketer; ..

here in this hand I hold his death! Tempered in blood, and tempered by lightning are these barbs; and I swear to temper them triply in that hot place behind the fin, where the white whale most feels his accursed life! Then God keep thee, old man --see'st thou that --pointing to the hammock -- I bury but one of five stout men, who were alive only yesterday; but were dead ere night. Only that one I bury; the rest were buried before they died; you sail upon their tomb. Then turning to his crew -- Are ye ready there? place the plank then on the rail, and lift the body; so, then -- Oh! God --advancing towards the hammock with uplifted hands -- may the resurrection and the life-- Brace forward! Up helm! cried Ahab like lightning to his men. But the suddenly started Pequod was not quick enough to escape the sound of the splash that the corpse soon made as it struck the sea; not so quick, indeed, but that some of the flying bubbles might have sprinkled her hull with their ghostly baptism. As Ahab now glided from the dejected Delight, the strange life-buoy hanging at the Pequod's stern came into conspicuous relief. Ha! yonder! look yonder, men! cried a foreboding voice in her wake. In vain, oh, ye strangers, ye fly our sad burial; ye but turn us your taffrail to show us your coffin! ..

.. < chapter cxxxii 26 THE SYMPHONY > It was a clear steel-blue day. The firmaments of air and sea were hardly separable in that all-pervading azure; only, the pensive air was transparently pure and soft, with a woman's look, and the robust and man-like sea heaved with long, strong, lingering swells, as Samson's chest in his sleep. ..

Hither, and thither, on high, glided the snow-white wings of small, unspeckled birds; these were the gentle thoughts of the feminine air; but to and fro in the deeps, far down in the bottomless blue, rushed mighty leviathans, sword-fish, and sharks; and these were the strong, troubled, murderous thinkings of the masculine sea. But though thus contrasting within, the contrast was only in shades and shadows without; those two seemed one; it was only the sex, as it were, that distinguished them. Aloft, like a royal czar and king, the sun seemed giving this gentle air to this bold and rolling sea; even as bride to groom. And at the girdling line of the horizon, a soft and tremulous motion --most seen here at the equator --denoted the fond, throbbing trust, the loving alarms, with which the poor bride gave her bosom away. Tied up and twisted; gnarled and knotted with wrinkles; haggardly firm and unyielding; his eyes glowing like coals, that still glow in the ashes of ruin; untottering Ahab stood forth in the clearness of the morn; lifting his splintered helmet of a brow to the fair girl's forehead of heaven. Oh, immortal infancy, and innocency of the azure! Invisible winged creatures that frolic all round us! Sweet childhood of air and sky! how oblivious were ye of old Ahab's close-coiled woe! But so have I seen little Miriam and Martha, laughing-eyed elves, heedlessly gambol around their old sire; sporting with the circle of singed locks which grew on the marge of that burnt-out crater of his brain. Slowly crossing the deck from the scuttle, Ahab leaned over the side, and watched how his shadow in the water sank and sank to his gaze, the more and the more that he strove to pierce the profundity. But the lovely aromas in that enchanted air did at last seem to dispel, for a moment, the cankerous thing in his soul. That glad, happy air, that winsome sky, did at last stroke and caress him; the step-mother world, so long cruel -- forbidding --now threw affectionate arms round his stubborn neck, and did seem to joyously sob over him, as if over one, that however wilful and erring, she could yet find it in her ..

heart to save and to bless. From beneath his slouched hat Ahab dropped a tear into the sea; nor did all the pacific contain such wealth as that one wee drop. Starbuck saw the old man; saw him, how he heavily leaned over the side; and he seemed to hear in his own true heart the measureless sobbing that stole out of the centre of the serenity around. Careful not to touch him, or be noticed by him, he yet drew near to him, and stood there. Ahab turned. Starbuck! Sir. Oh, Starbuck! it is a mild, mild wind, and a mild looking sky. On such a day --very much such a sweetness as this --I struck my first whale --a boy-harpooneer of eighteen! Forty-- forty--forty years ago! --ago! Forty years of continual whaling! forty years of privation, and peril, and storm-time! forty years on the pitiless sea! for forty years has Ahab forsaken the peaceful land, for forty years to make war on the horrors of the deep! Aye and yes, Starbuck, out of those forty years I have not spent three ashore. When I think of this life I have led; the desolation of solitude it has been; the masoned, walled-town of a Captain's exclusiveness, which admits but small entrance to any sympathy from the green country without --oh, weariness! heaviness! Guinea-coast slavery of solitary command! --when I think of all this; only half-suspected, not so keenly known to me before --and how for forty years I have fed upon dry salted fare -- fit emblem of the dry nourishment of my soul --when the poorest landsman has had fresh fruit to his daily hand, and broken the world's fresh bread to my mouldy crusts --away, whole oceans away, from that young girl-wife I wedded past fifty, and sailed for Cape Horn the next day, leaving but one dent in my marriage pillow --wife? wife? --rather a widow with her husband alive! Aye, I widowed that poor girl when I married her, Starbuck; and then, the madness, the frenzy, the boiling blood and the smoking brow, with which, for a thousand lowerings old Ahab has furiously, foamingly chased his prey --more a demon than a man! --aye, aye! what a forty years' fool --fool --old fool, has old Ahab been! Why this strife of the chase? why weary, ..

and palsy the arm at the oar, and the iron, and the lance? how the richer or better is Ahab now? Behold. Oh, Starbuck! is it not hard, that with this weary load I bear, one poor leg should have been snatched from under me? Here, brush this old hair aside; it blinds me, that I seem to weep. Locks so grey did never grow but from out some ashes! But do I look very old, so very, very old, Starbuck? I feel deadly faint, bowed, and humped, as though I were Adam, staggering beneath the piled centuries since Paradise. God! God! God! --crack my heart!-- stave my brain! --mockery! mockery! bitter, biting mockery of grey hairs, have I lived enough joy to wear ye; and seem and feel thus intolerably old? Close! stand close to me, Starbuck; let me look into a human eye; it is better than to gaze into sea or sky; better than to gaze upon God. By the green land; by the bright hearth-stone! this is the magic glass, man; I see my wife and my child in thine eye. No, no; stay on board, on board! --lower not when I do; when branded Ahab gives chase to Moby Dick. That hazard shall not be thine. No, no! not with the far away home I see in that eye! Oh, my Captain! my Captain! noble soul! grand old heart, after all! why should any one give chase to that hated fish! Away with me! let us fly these deadly waters! let us home! Wife and child, too, are Starbuck's --wife and child of his brotherly, sisterly, play-fellow youth; even as thine, sir, are the wife and child of thy loving, longing, paternal old age! Away! let us away! --this instant let me alter the course! How cheerily, how hilariously, O my Captain, would we bowl on our way to see old Nantucket again! I think, sir, they have some such mild blue days, even as this, in nantucket. they have, they have. I have seen them --some summer days in the morning. About this time --yes, it is his noon nap now -- the boy vivaciously wakes; sits up in bed; and his mother tells him of me, of cannibal old me; how I am abroad upon the deep, but will yet come back to dance him again. Tis my Mary, my Mary herself! She promised that my boy, every morning, should be carried to the hill to catch the first glimpse of his father's sail! Yes, yes! no more! it is done! we head for Nantucket! Come, my Captain, study out the course, ..

and let us away! See, see! the boy's face from the window! the boy's hand on the hill! But Ahab's glance was averted; like a blighted fruit tree he shook, and cast his last, cindered apple to the soil. What is it, what nameless, inscrutable, unearthly thing is it; what cozzening, hidden lord and master, and cruel, remorseless emperor commands me; that against all natural lovings and longings, I so keep pushing, and crowding, and jamming myself on all the time; recklessly making me ready to do what in my own proper, natural heart, I durst not so much as dare? Is Ahab, Ahab? Is it I, God, or who, that lifts this arm? But if the great sun move not of himself; but is as an errand-boy in heaven; nor one single star can revolve, but by some invisible power; how then can this one small heart beat; this one small brain think thoughts; unless God does that beating, does that thinking, does that living, and not I. By heaven, man, we are turned round and round in this world, like yonder windlass, and Fate is the handspike. And all the time, lo! that smiling sky, and this unsounded sea! Look! see yon Albicore! who put it into him to chase and fang that flying-fish? Where do murderers go, man! Who's to doom, when the judge himself is dragged to the bar? But it is a mild, mild wind, and a mild looking sky; and the air smells now, as if it blew from a far-away meadow; they have been making hay somewhere under the slopes of the Andes, Starbuck, and the mowers are sleeping among the new-mown hay. Sleeping? Aye, toil we how we may, we all sleep at last on the field. Sleep? Aye, and rust amid greenness; as last year's scythes flung down, and left in the half-cut swaths --Starbuck! But blanched to a corpse's hue with despair, the Mate had stolen away. Ahab crossed the deck to gaze over on the other side; but started at two reflected, fixed eyes in the water there. Fedallah was motionlessly leaning over the same rail. ..

.. < chapter cxxxiii 2 THE CHASE--FIRST DAY > That night, in the mid-watch, when the old man --as his wont at intervals --stepped forth from the scuttle in which he leaned, and went to his pivot-hole, he suddenly thrust out his face fiercely, snuffing up the sea air as a sagacious ship's dog will, in drawing nigh to some barbarous isle. He declared that a whale must be near. Soon that peculiar odor, sometimes to a great distance given forth by the living sperm whale, was palpable to all the watch; nor was any mariner surprised when, after inspecting the compass, and then the dog-vane, and then ascertaining the precise bearing of the odor as nearly as possible, Ahab rapidly ordered the ship's course to be slightly altered, and the sail to be shortened. The acute policy dictating these movements was sufficiently vindicated at daybreak, by the sight of a long sleek on the sea directly and lengthwise ahead, smooth as oil, and resembling in the pleated watery wrinkles bordering it, the polished metallic-like marks of some swift tide-rip, at the mouth of a deep, rapid stream. Man the mast-heads! Call all hands! Thundering with the butts of three clubbed handspikes on the forecastle deck, Daggoo roused the sleepers with such judgment claps that they seemed to exhale from the scuttle, so instantaneously did they appear with their clothes in their hands. What d'ye see? cried Ahab, flattening his face to the sky. Nothing, nothing, sir! was the sound hailing down in reply. T'gallant sails! --stunsails! alow and aloft, and on both sides! All sail being set, he now cast loose the life-line, reserved for swaying him to the main royal-mast head; and in a few moments they were hoisting him thither, when, while but two thirds of the way aloft, and while peering ahead through the horizontal vacancy between the main-top-sail and top-gallant-sail, ..

he raised a gull-like cry in the air, There she blows! --there she blows! A hump like a snow-hill! It is Moby Dick! Fired by the cry which seemed simultaneously taken up by the three look-outs, the men on deck rushed to the rigging to behold the famous whale they had so long been pursuing. Ahab had now gained his final perch, some feet above the other look-outs, Tashtego standing just beneath him on the cap of the top-gallant mast, so that the Indian's head was almost on a level with Ahab's heel. From this height the whale was now seen some mile or so ahead, at every roll of the sea revealing his high sparkling hump, and regularly jetting his silent spout into the air. To the credulous mariners it seemed the same silent spout they had so long ago beheld in the moonlit Atlantic and Indian Oceans. And did none of ye see it before? cried Ahab, hailing the perched men all around him. I saw him almost that same instant, sir, that Captain Ahab did, and I cried out, said Tashtego. Not the same instant; not the same --no, the doubloon is mine, Fate reserved the doubloon for me. I only; none of ye could have raised the White Whale first. There she blows! there she blows! --there she blows! There again! --there again! he cried, in long-drawn, lingering, methodic tones, attuned to the gradual prolongings of the whale's visible jets. He's going to sound! In stunsails! Down top-gallant-sails! Stand by three boats. Mr. Starbuck, remember, stay on board, and keep the ship. Helm there! Luff, luff a point! So; steady, man, steady! There go flukes! No, no; only black water! All ready the boats there? Stand by, stand by! Lower me, Mr. Starbuck; lower, lower, --quick, quicker! and he slid through the air to the deck. He is heading straight to leeward, sir, cried Stubb, right away from us; cannot have seen the ship yet. Be dumb, man! Stand by the braces! Hard down the helm! --brace up! Shiver her! --shiver her! So; well that! Boats, boats! Soon all the boats but Starbuck's were dropped; all the boat-sails set --all the paddles plying; with rippling swiftness, shooting to leeward; and Ahab heading the onset. A pale, death-glimmer ..

lit up Fedallah's sunken eyes; a hideous motion gnawed his mouth. Like noiseless nautilus shells, their light prows sped through the sea; but only slowly they neared the foe. As they neared him, the ocean grew still more smooth; seemed drawing a carpet over its waves; seemed a noon-meadow, so serenely it spread. At length the breathless hunter came so nigh his seemingly unsuspecting prey, that his entire dazzling hump was distinctly visible, sliding along the sea as if an isolated thing, and continually set in a revolving ring of finest, fleecy, greenish foam. He saw the vast, involved wrinkles of the slightly projecting head beyond. Before it, far out on the soft Turkish-rugged waters, went the glistening white shadow from his broad, milky forehead, a musical rippling playfully accompanying the shade; and behind, the blue waters interchangeably flowed over into the moving valley of his steady wake; and on either hand bright bubbles arose and danced by his side. But these were broken again by the light toes of hundreds of gay fowl softly feathering the sea, alternate with their fitful flight; and like to some flag-staff rising from the painted hull of an argosy, the tall but shattered pole of a recent lance projected from the white whale's back; and at intervals one of the cloud of soft-toed fowls hovering, and to and fro skimming like a canopy over the fish, silently perched and rocked on this pole, the long tail feathers streaming like pennons. A gentle joyousness --a mighty mildness of repose in swiftness, invested the gliding whale. Not the white bull Jupiter swimming away with ravished Europa clinging to his graceful horns; his lovely, leering eyes sideways intent upon the maid; with smooth bewitching fleetness, rippling straight for the nuptial bower in Crete; not Jove, not that great majesty Supreme! did surpass the glorified White Whale as he so divinely swam. On each soft side --coincident with the parted swell, that but once leaving him, then flowed so wide away --on each bright side, the whale shed off enticings. No wonder there had been some among the hunters who namelessly transported and allured by all this serenity, had ventured to assail it; but had fatally ..

found that quietude but the vesture of tornadoes. Yet calm, enticing calm, oh, whale! thou glidest on, to all who for the first time eye thee, no matter how many in that same way thou may'st have bejuggled and destroyed before. And thus, through the serene tranquillities of the tropical sea, among waves whose hand-clappings were suspended by exceeding rapture, Moby Dick moved on, still withholding from sight the full terrors of his submerged trunk, entirely hiding the wrenched hideousness of his jaw. But soon the fore part of him slowly rose from the water; for an instant his whole marbleized body formed a high arch, like Virginia's Natural Bridge, and warningly waving his bannered flukes in the air, the grand god revealed himself, sounded, and went out of sight. Hoveringly halting, and dipping on the wing, the white sea-fowls longingly lingered over the agitated pool that he left. With oars apeak, and paddles down, the sheets of their sails adrift, the three boats now stilly floated, awaiting Moby Dick's reappearance. An hour, said Ahab, standing rooted in his boat's stern; and he gazed beyond the whale's place, towards the dim blue spaces and wide wooing vacancies to leeward. It was only an instant; for again his eyes seemed whirling round in his head as he swept the watery circle. The breeze now freshened; the sea began to swell. The birds! --the birds! cried Tashtego. In long Indian file, as when herons take wing, the white birds were now all flying towards Ahab's boat; and when within a few yards began fluttering over the water there, wheeling round and round, with joyous, expectant cries. Their vision was keener than man's; Ahab could discover no sign in the sea. But suddenly as he peered down and down into its depths, he profoundly saw a white living spot no bigger than a white weasel, with wonderful celerity uprising, and magnifying as it rose, till it turned, and then there were plainly revealed two long crooked rows of white, glistening teeth, floating up from the undiscoverable bottom. It was Moby Dick's open mouth and scrolled jaw; his vast, shadowed bulk still half blending with the blue of the sea. The glittering mouth yawned beneath ..

the boat like an open-doored marble tomb; and giving one side-long sweep with his steering oar, Ahab whirled the craft aside from this tremendous apparition. Then, calling upon Fedallah to change places with him, went forward to the bows, and seizing Perth's harpoon, commanded his crew to grasp their oars and stand by to stern. Now, by reason of this timely spinning round the boat upon its axis, its bow, by anticipation, was made to face the whale's head while yet under water. But as if perceiving this strategem, moby dick, with that malicious intelligence ascribed to him, sidelingly transplanted himself, as it were, in an instant, shooting his pleated head lengthwise beneath the boat. Through and through; through every plank and each rib, it thrilled for an instant, the whale obliquely lying on his back, in the manner of a biting shark, slowly and feelingly taking its bows full within his mouth, so that the long, narrow, scrolled lower jaw curled high up into the open air, and one of the teeth caught in a row-lock. The bluish pearl-white of the inside of the jaw was within six inches of Ahab's head, and reached higher than that. In this attitude the White Whale now shook the slight cedar as a mildly cruel cat her mouse. With unastonished eyes Fedallah gazed, and crossed his arms; but the tiger-yellow crew were tumbling over each other's heads to gain the uttermost stern. And now, while both elastic gunwales were springing in and out, as the whale dallied with the doomed craft in this devilish way; and from his body being submerged beneath the boat, he could not be darted at from the bows, for the bows were almost inside of him, as it were; and while the other boats involuntarily paused, as before a quick crisis impossible to withstand, then it was that monomaniac Ahab, furious with this tantalizing vicinity of his foe, which placed him all alive and helpless in the very jaws he hated; frenzied with all this, he seized the long bone with his naked hands, and wildly strove to wrench it from its gripe. As now he thus vainly strove, the jaw slipped from him; the frail gunwales bent in, collapsed, and snapped, as both jaws, like an enormous shears, sliding further aft, bit the craft completely in twain, and locked themselves fast again in ..

the sea, midway between the two floating wrecks. These floated aside, the broken ends drooping, the crew at the stern-wreck clinging to the gunwales, and striving to hold fast to the oars to lash them across. At that preluding moment, ere the boat was yet snapped, Ahab, the first to perceive the whale's intent, by the crafty upraising of his head, a movement that loosed his hold for the time; at that moment his hand had made one final effort to push the boat out of the bite. But only slipping further into the whale's mouth, and tilting over sideways as it slipped, the boat had shaken off his hold on the jaw; spilled him out of it, as he leaned to the push; and so he fell flat-faced upon the sea. Ripplingly withdrawing from his prey, Moby Dick now lay at a little distance, vertically thrusting his oblong white head up and down in the billows; and at the same time slowly revolving his whole spindled body; so that when his vast wrinkled forehead rose --some twenty or more feet out of the water --the now rising swells, with all their confluent waves, dazzlingly broke against it; vindictively tossing their shivered spray still higher into the air. So, in a gale, the but half-baffled Channel billows only recoil from the base of the Eddystone, triumphantly to overleap its summit with their scud. But soon resuming his horizontal attitude, Moby Dick swam swiftly round and round the wrecked crew; sideways churning the water in his vengeful wake, as if lashing himself up to still another and more deadly assault. The sight of the splintered boat seemed to madden him, as the blood of grapes and mulberries cast before Antiochus's elephants in the book of Maccabees. Meanwhile Ahab half smothered in the foam of the whale's insolent tail, and too much of a cripple to swim, --though he could still keep afloat, even in the heart of such a whirlpool as that; helpless Ahab's head was seen, like a tossed bubble which the least chance shock might burst. From the boat's fragmentary ..

stern, Fedallah incuriously and mildly eyed him; the clinging crew, at the other drifting end, could not succor him; more than enough was it for them to look to themselves. For so revolvingly appalling was the White Whale's aspect, and so planetarily swift the ever-contracting circles he made, that he seemed horizontally swooping upon them. And though the other boats, unharmed, still hovered hard by; still they dared not pull into the eddy to strike, lest that should be the signal for the instant destruction of the jeopardized castaways, Ahab and all; nor in that case could they themselves hope to escape. With straining eyes, then, they remained on the outer edge of the direful zone, whose centre had now become the old man's head. Meantime, from the beginning all this had been descried from the ship's mast heads; and squaring her yards, she had borne down upon the scene; and was now so nigh, that Ahab in the water hailed her; -- Sail on the --but that moment a breaking sea dashed on him from Moby Dick, and whelmed him for the time. But struggling out of it again, and chancing to rise on a towering crest, he shouted, -- Sail on the whale! --Drive him off! The Pequod's prows were pointed; and breaking up the charmed circle, she effectually parted the white whale from his victim. As he sullenly swam off, the boats flew to the rescue. Dragged into Stubb's boat with blood-shot, blinded eyes, the white brine caking in his wrinkles; the long tension of Ahab's bodily strength did crack, and helplessly he yielded to his body's doom: for a time, lying all crushed in the bottom of Stubb's boat, like one trodden under foot of herds of elephants. Far inland, nameless wails came from him, as desolate sounds from out ravines. But this intensity of his physical prostration did but so much the more abbreviate it. In an instant's compass, great hearts sometimes condense to one deep pang, the sum total of those shallow pains kindly diffused through feebler men's whole lives. And so, such hearts, though summary in each one suffering; still, if the gods decree it, in their life-time aggregate a whole age of woe, wholly made up of instantaneous intensities; for even in their pointless centres, those noble natures contain the entire circumferences of inferior souls. ..

The harpoon, said Ahab, half way rising, and draggingly leaning on one bended arm -- is it safe? Aye, sir, for it was not darted; this is it, said Stubb, showing it. Lay it before me; --any missing men? One, two, three, four, five; --there were five oars, sir, and here are five men. That's good. --Help me, man; I wish to stand. So, so, I see him! there! there! going to leeward still; what a leaping spout! Hands off from me! The eternal sap runs up in Ahab's bones again! Set the sail; out oars; the helm! It is often the case that when a boat is stove, its crew, being picked up by another boat, help to work that second boat; and the chase is thus continued with what is called double-banked oars. It was thus now. But the added power of the boat did not equal the added power of the whale, for he seemed to have treble-banked his every fin; swimming with a velocity which plainly showed, that if now, under these circumstances, pushed on, the chase would prove an indefinitely prolonged, if not a hopeless one; nor could any crew endure for so long a period, such an unintermitted, intense straining at the oar; a thing barely tolerable only in some one brief vicissitude. The ship itself, then, as it sometimes happens, offered the most promising intermediate means of overtaking the chase. Accordingly, the boats now made for her, and were soon swayed up to their cranes --the two parts of the wrecked boat having been previously secured by her --and then hoisting everything to her side, and stacking her canvas high up, and sideways outstretching it with stun-sails, like the double-jointed wings of an albatross; the Pequod bore down in the leeward wake of Moby Dick. At the well known, methodic intervals, the whale's glittering spout was regularly announced from the manned mast-heads; and when he would be reported as just gone down, Ahab would take the time, and then pacing the deck, binnacle-watch in hand, so soon as the last second of the allotted hour expired, his voice was heard. -- Whose is the doubloon now? D'ye see him? and if the reply was, No, sir! straightway he commanded them to lift him to his perch. In this way the day wore on; Ahab, ..

now aloft and motionless; anon, unrestingly pacing the planks. As he was thus walking, uttering no sound, except to hail the men aloft, or to bid them hoist a sail still higher, or to spread one to a still greater breadth --thus to and fro pacing, beneath his slouched hat, at every turn he passed his own wrecked boat, which had been dropped upon the quarter-deck, and lay there reversed; broken bow to shattered stern. At last he paused before it; and as in an already over-clouded sky fresh troops of clouds will sometimes sail across, so over the old man's face there now stole some such added gloom as this. Stubb saw him pause; and perhaps intending, not vainly, though, to evince his own unabated fortitude, and thus keep up a valiant place in his Captain's mind, he advanced, and eyeing the wreck exclaimed -- The thistle the ass refused; it pricked his mouth too keenly, sir; ha! ha! What soulless thing is this that laughs before a wreck? Man, man! did I not know thee brave as fearless fire (and as mechanical) I could swear thou wert a poltroon. Groan nor laugh should be heard before a wreck. Aye, sir, said Starbuck drawing near, 'tis a solemn sight; an omen, and an ill one. Omen? omen? --the dictionary! If the gods think to speak outright to man, they will honorably speak outright; not shake their heads, and give an old wives' darkling hint. --Begone! Ye two are the opposite poles of one thing; Starbuck is Stubb reversed, and Stubb is Starbuck; and ye two are all mankind; and Ahab stands alone among the millions of the peopled earth, nor gods nor men his neighbors! Cold, cold --I shiver! --How now? Aloft there! D'ye see him? Sing out for every spout, though he spout ten times a second! The day was nearly done; only the hem of his golden robe was rustling. Soon, it was almost dark, but the look-out men still remained unset. Can't see the spout now, sir; --too dark --cried a voice from the air. How heading when last seen? As before, sir, --straight to leeward. Good! he will travel slower now 'tis night. Down royals and ..

top-gallant stun-sails, Mr. Starbuck. We must not run over him before morning; he's making a passage now, and may heave-to a while. Helm there! keep her full before the wind! --Aloft! come down! --Mr. Stubb, send a fresh hand to the fore-mast head, and see it manned till morning. --Then advancing towards the doubloon in the main-mast -- Men, this gold is mine, for I earned it; but I shall let it abide here till the White Whale is dead; and then, whosoever of ye first raises him, upon the day he shall be killed, this gold is that man's; and if on that day I shall again raise him, then, ten times its sum shall be divided among all of ye! Away now! --the deck is thine, sir. And so saying, he placed himself half way within the scuttle, and slouching his hat, stood there till dawn, except when at intervals rousing himself to see how the night wore on. ..

This motion is peculiar to the sperm whale. It receives its designation (pitchpoling) from its being likened to that preliminary up-and-down poise of the whale-lance, in the exercise called pitchpoling, previously described. By this motion the whale must best and most comprehensively view whatever objects may be encircling him. ..

.. < chapter cxxxiv 16 THE CHASE--SECOND DAY > At day-break, the three mast-heads were punctually manned afresh. D'ye see him? cried Ahab, after allowing a little space for the light to spread. see nothing, sir. Turn up all hands and make sail! he travels faster than I thought for; --the top-gallant sails! --aye, they should have been kept on her all night. But no matter --'tis but resting for the rush. Here be it said, that this pertinacious pursuit of one particular whale, continued through day into night, and through night into day, is a thing by no means unprecedented in the South sea fishery. For such is the wonderful skill, prescience of experience, and invincible confidence acquired by some great natural geniuses among the Nantucket commanders; that from the simple observation of a whale when last descried, they will, ..

under certain given circumstances, pretty accurately foretell both the direction in which he will continue to swim for a time, while out of sight, as well as his probable rate of progression during that period. And, in these cases, somewhat as a pilot, when about losing sight of a coast, whose general trending he well knows, and which he desires shortly to return to again, but at some further point; like as this pilot stands by his compass, and takes the precise bearing of the cape at present visible, in order the more certainly to hit aright the remote, unseen headland, eventually to be visited: so does the fisherman, at his compass, with the whale; for after being chased, and diligently marked, through several hours of daylight, then, when night obscures the fish, the creature's future wake through the darkness is almost as established to the sagacious mind of the hunter, as the pilot's coast is to him. So that to this hunter's wondrous skill, the proverbial evanescence of a thing writ in water, a wake, is to all desired purposes well nigh as reliable as the steadfast land. And as the mighty iron Leviathan of the modern railway is so familiarly known in its every pace, that, with watches in their hands, men time his rate as doctors that of a baby's pulse; and lightly say of it, the up train or the down train will reach such or such a spot, at such or such an hour; even so, almost, there are occasions when these Nantucketers time that other Leviathan of the deep, according to the observed humor of his speed; and say to themselves, so many hours hence this whale will have gone two hundred miles, will have about reached this or that degree of latitude or longitude. But to render this acuteness at all successful in the end, the wind and the sea must be the whaleman's allies; for of what present avail to the becalmed or windbound mariner is the skill that assures him he is exactly ninety-three leagues and a quarter from his port? Inferable from these statements, are many collateral subtile matters touching the chase of whales. The ship tore on; leaving such a furrow in the sea as when a cannon-ball, missent, becomes a plough-share and turns up the level field. By salt and hemp! cried Stubb, but this swift motion of the deck creeps up one's legs and tingles at the heart. This ..

ship and I are two brave fellows! --Ha! ha! Some one take me up, and launch me, spine-wise, on the sea, --for by live-oaks! my spine's a keel. Ha, ha! we go the gait that leaves no dust behind! There she blows --she blows! --she blows! --right ahead! was now the mast-head cry. Aye, aye! cried Stubb. I knew it --ye can't escape --blow on and split your spout, O whale! the mad fiend himself is after ye! blow your trump --blister your lungs! --Ahab will dam off your blood, as a miller shuts his water-gate upon the stream! And Stubb did but speak out for well nigh all that crew. The frenzies of the chase had by this time worked them bubblingly up, like old wine worked anew. Whatever pale fears and forebodings some of them might have felt before; these were not only now kept out of sight through the growing awe of Ahab, but they were broken up, and on all sides routed, as timid prairie hares that scatter before the bounding bison. The hand of Fate had snatched all their souls; and by the stirring perils of the previous day; the rack of the past night's suspense; the fixed, unfearing, blind, reckless way in which their wild craft went plunging towards its flying mark; by all these things, their hearts were bowled along. The wind that made great bellies of their sails, and rushed the vessel on by arms invisible as irresistible; this seemed the symbol of that unseen agency which so enslaved them to the race. They were one man, not thirty. For as the one ship that held them all; though it was put together of all contrasting things --oak, and maple, and pine wood; iron, and pitch, and hemp --yet all these ran into each other in the one concrete hull, which shot on its way, both balanced and directed by the long central keel; even so, all the individualities of the crew, this man's valor, that man's fear; guilt and guiltiness, all varieties were welded into oneness, and were all directed to that fatal goal which Ahab their one lord and keel did point to. The rigging lived. The mast-heads, like the tops of tall palms, were outspreadingly tufted with arms and legs. Clinging to a spar with one hand, some reached forth the other with impatient wavings; others, shading their eyes from the vivid sunlight, sat ..

far out on the rocking yards; all the spars in full bearing of mortals, ready and ripe for their fate. Ah! how they still strove through that infinite blueness to seek out the thing that might destroy them! Why sing ye not out for him, if ye see him? cried Ahab, when, after the lapse of some minutes since the first cry, no more had been heard. Sway me up, men; ye have been deceived; not moby dick casts one odd jet that way, and then disappears. It was even so; in their headlong eagerness, the men had mistaken some other thing for the whale-spout, as the event itself soon proved; for hardly had Ahab reached his perch; hardly was the rope belayed to its pin on deck, when he struck the key-note to an orchestra, that made the air vibrate as with the combined discharges of rifles. The triumphant halloo of thirty buckskin lungs was heard, as --much nearer to the ship than the place of the imaginary jet, less than a mile ahead --Moby Dick bodily burst into view! For not by any calm and indolent spoutings; not by the peaceable gush of that mystic fountain in his head, did the White Whale now reveal his vicinity; but by the far more wondrous phenomenon of breaching. Rising with his utmost velocity from the furthest depths, the Sperm Whale thus booms his entire bulk into the pure element of air, and piling up a mountain of dazzling foam, shows his place to the distance of seven miles and more. In those moments, the torn, enraged waves he shakes off, seem his mane; in some cases, this breaching is his act of defiance. There she breaches! there she breaches! was the cry, as in his immeasureable bravadoes the White Whale tossed himself salmon-like to Heaven. So suddenly seen in the blue plain of the sea, and relieved against the still bluer margin of the sky, the spray that he raised, for the moment, intolerably glittered and glared like a glacier; and stood there gradually fading and fading away from its first sparkling intensity, to the dim mistiness of an advancing shower in a vale. Aye, breach your last to the sun, Moby Dick! cried Ahab, thy hour and thy harpoon are at hand! --Down! down all of ye, but one man at the fore. The boats! --stand by! ..

Unmindful of the tedious rope-ladders of the shrouds, the men, like shooting stars, slid to the deck, by the isolated back-stays and halyards; while Ahab, less dartingly, but still rapidly was dropped from his perch. Lower away, he cried, so soon as he had reached his boat --a spare one, rigged the afternoon previous. Mr. Starbuck, the ship is thine --keep away from the boats, but keep near them. Lower, all! As if to strike a quick terror into them, by this time being the first assailant himself, Moby Dick had turned, and was now coming for the three crews. Ahab's boat was central; and cheering his men, he told them he would take the whale head-and-head, --that is, pull straight up to his forehead, --a not uncommon thing; for when within a certain limit, such a course excludes the coming onset from the whale's sidelong vision. But ere that close limit was gained, and while yet all three boats were plain as the ship's three masts to his eye; the White Whale churning himself into furious speed, almost in an instant as it were, rushing among the boats with open jaws, and a lashing tail, offered appalling battle on every side; and heedless of the irons darted at him from every boat, seemed only intent on annihilating each separate plank of which those boats were made. But skilfully manoeuvred, incessantly wheeling like trained chargers in the field; the boats for a while eluded him; though, at times, but by a plank's breadth; while all the time, Ahab's unearthly slogan tore every other cry but his to shreds. But at last in his untraceable evolutions, the White Whale so crossed and recrossed, and in a thousand ways entangled the slack of the three lines now fast to him, that they foreshortened, and, of themselves, warped the devoted boats towards the planted irons in him; though now for a moment the whale drew aside a little, as if to rally for a more tremendous charge. Seizing that opportunity, Ahab first paid out more line: and then was rapidly hauling and jerking in upon it again --hoping that way to disencumber it of some snarls --when lo! --a sight more savage than the embattled teeth of sharks! Caught and twisted --corkscrewed in the mazes of the line, loose harpoons and lances, with all their bristling barbs and ..

points, came flashing and dripping up to the chocks in the bows of Ahab's boat. Only one thing could be done. Seizing the boat-knife, he critically reached within --through --and then, without --the rays of steel; dragged in the line beyond, passed it, inboard, to the bowsman, and then, twice sundering the rope near the chocks --dropped the intercepted fagot of steel into the sea; and was all fast again. That instant, the White Whale made a sudden rush among the remaining tangles of the other lines; by so doing, irresistibly dragged the more involved boats of Stubb and Flask towards his flukes; dashed them together like two rolling husks on a surf-beaten beach, and then, diving down into the sea, disappeared in a boiling maelstrom, in which, for a space, the odorous cedar chips of the wrecks danced round and round, like the grated nutmeg in a swiftly stirred bowl of punch. While the two crews were yet circling in the waters, reaching out after the revolving line-tubs, oars, and other floating furniture, while aslope little Flask bobbed up and down like an empty vial, twitching his legs upwards to escape the dreaded jaws of sharks; and Stubb was lustily singing out for some one to ladle him up; and while the old man's line --now parting -- admitted of his pulling into the creamy pool to rescue whom he could; --in that wild simultaneousness of a thousand concreted perils, --Ahab's yet unstricken boat seemed drawn up towards Heaven by invisible wires, --as, arrow-like, shooting perpendicularly from the sea, the White Whale dashed his broad forehead against its bottom, and sent it, turning over and over, into the air; till it fell again --gunwale downwards --and Ahab and his men struggled out from under it, like seals from a seaside cave. The first uprising momentum of the whale --modifying its direction as he struck the surface --involuntarily launched him along it, to a little distance from the centre of the destruction he had made; and with his back to it, he now lay for a moment slowly feeling with his flukes from side to side; and whenever a stray oar, bit of plank, the least chip or crumb of the boats touched his skin, his tail swiftly drew back, and came sideways smiting the sea. But soon, as if satisfied that his work for that time was done, he pushed his pleated forehead through the ..

ocean, and trailing after him the intertangled lines, continued his leeward way at a traveller's methodic pace. As before, the attentive ship having descried the whole fight, again came bearing down to the rescue, and dropping a boat, picked up the floating mariners, tubs, oars and whatever else could be caught at, and safely landed them on her decks. Some sprained shoulders, wrists, and ankles; livid contusions; wrenched harpoons and lances; inextricable intricacies of rope; shattered oars and planks; all these were there; but no fatal or even serious ill seemed to have befallen any one. As with Fedallah the day before, so Ahab was now found grimly clinging to his boat's broken half, which afforded a comparatively easy float; nor did it so exhaust him as the previous day's mishap. But when he was helped to the deck, all eyes were fastened upon him; as instead of standing by himself he still half-hung upon the shoulder of Starbuck, who had thus far been the foremost to assist him. His ivory leg had been snapped off, leaving but one short sharp splinter. Aye, aye, Starbuck, 'tis sweet to lean sometimes, be the leaner who he will; and would old Ahab had leaned oftener than he has. The ferrule has not stood, sir, said the carpenter, now coming up; I put good work into that leg. But no bones broken, sir, I hope, said Stubb with true concern. Aye! and all splintered to pieces, Stubb! --d'ye see it. -- But even with a broken bone, old Ahab is untouched; and I account no living bone of mine one jot more me, than this dead one that's lost. Nor white whale, nor man, nor fiend, can so much as graze old Ahab in his own proper and inaccessible being. Can any lead touch yonder floor, any mast scrape yonder roof? -- Aloft there! which way? Dead to leeward, sir. Up helm, then; pile on the sail again, ship keepers! down the rest of the spare boats and rig them --Mr. Starbuck away, and muster the boat's crews. Let me first help thee towards the bulwarks, sir. Oh, oh, oh! how this splinter gores me now! Accursed fate! ..

that the unconquerable captain in the soul should have such a craven mate! Sir? My body, man, not thee. Give me something for a cane -- there, that shivered lance will do. Muster the men. Surely I have not seen him yet. By heaven it cannot be! --missing? -- quick! call them all. The old man's hinted thought was true. Upon mustering the company, the Parsee was not there. The Parsee! cried Stubb -- he must have been caught in-- The black vomit wrench thee! --run all of ye above, alow, cabin, forecastle --find him --not gone --not gone! But quickly they returned to him with the tidings that the Parsee was nowhere to be found. Aye, sir, said Stubb -- caught among the tangles of your line --I thought I saw him dragging under. My line! my line? Gone? --gone? What means that little word? --What death-knell rings in it, that old Ahab shakes as if he were the belfry. The harpoon, too! --toss over the litter there, --d'ye see it? --the forged iron, men, the white whale's -- no, no, no, --blistered fool; this hand did dart it! --'tis in the fish! --Aloft there! keep him nailed --quick! --all hands to the rigging of the boats --collect the oars --harpooneers! the irons, the irons! -- hoist the royals higher --a pull on all the sheets! --helm there! steady, steady for your life! I'll ten times girdle the unmeasured globe; yea and dive straight through it, but I'll slay him yet! Great God! but for one single instant show thyself, cried Starbuck; never, never wilt thou capture him, old man --In Jesus' name no more of this, that's worse than devil's madness. Two days chased; twice stove to splinters; thy very leg once more snatched from under thee; thy evil shadow gone --all good angels mobbing thee with warnings: --what more wouldst thou have? --Shall we keep chasing this murderous fish till he swamps the last man? Shall we be dragged by him to the bottom of the sea? Shall we be towed by him to the infernal world? Oh, oh, -- Impiety and blasphemy to hunt him more! Starbuck, of late I've felt strangely moved to thee; ever since that hour we both saw --thou know'st what, in one another's ..

eyes. But in this matter of the whale, be the front of thy face to me as the palm of this hand --a lipless, unfeatured blank. Ahab is for ever Ahab, man. This whole act's immutably decreed. 'Twas rehearsed by thee and me a billion years before this ocean rolled. Fool! I am the Fates' lieutenant; I act under orders. Look thou, underling! that thou obeyest mine. --Stand round me, men. Ye see an old man cut down to the stump; leaning on a shivered lance; propped up on a lonely foot. 'Tis Ahab --his body's part; but Ahab's soul's a centipede, that moves upon a hundred legs. I feel strained, half stranded, as ropes that tow dismasted frigates in a gale; and I may look so. But ere I break, ye'll hear me crack; and till ye hear that, know that Ahab's hawser tows his purpose yet. Believe ye, men, in the things called omens? Then laugh aloud, and cry encore! For ere they drown, drowning things will twice rise to the surface; then rise again, to sink for evermore. So with Moby Dick --two days he's floated --to-morrow will be the third. Aye, men, he'll rise once more, --but only to spout his last! D'ye feel brave men, brave? As fearless fire, cried Stubb. And as mechanical, muttered Ahab. Then as the men went forward, he muttered on: -- The things called omens! And yesterday I talked the same to Starbuck there, concerning my broken boat. Oh! how valiantly I seek to drive out of others' hearts what's clinched so fast in mine! --The Parsee --the Parsee! -- gone, gone? and he was to go before: --but still was to be seen again ere I could perish --How's that? --There's a riddle now might baffle all the lawyers backed by the ghosts of the whole line of judges: --like a hawk's beak it pecks my brain. I'll, I'll solve it, though! When dusk descended, the whale was still in sight to leeward. So once more the sail was shortened, and everything passed nearly as on the previous night; only, the sound of hammers, and the hum of the grindstone was heard till nearly daylight, as the men toiled by lanterns in the complete and careful rigging of the spare boats and sharpening their fresh weapons for the morrow. Meantime, of the broken keel of Ahab's wrecked craft the carpenter made him another leg; while still as on the ..

night before, slouched Ahab stood fixed within his scuttle; his hid, heliotrope glance anticipatingly gone backward on its dial; sat due eastward for the earliest sun. ..

THE CHASE--THIRD DAY The morning of the third day dawned fair and fresh, and once more the solitary night-man at the fore-mast-head was relieved by crowds of the daylight look-outs, who dotted every mast and almost every spar. D'ye see him? cried Ahab; but the whale was not yet in sight. In his infallible wake, though; but follow that wake, that's all. Helm there; steady, as thou goest, and hast been going. What a lovely day again; were it a new-made world, and made for a summer-house to the angels, and this morning the first of its throwing open to them, a fairer day could not dawn upon that world. Here's food for thought, had Ahab time to think; but Ahab never thinks; he only feels, feels, feels; that's tingling enough for mortal man! to think's audacity. God only has that right and privilege. Thinking is, or ought to be, a coolness and a calmness; and our poor hearts throb, and our poor brains beat too much for that. And yet, I've sometimes thought my brain was very calm --frozen calm, this old skull cracks so, like a glass in which the contents turned to ice, and shiver it. And still this hair is growing now; this moment growing, and heat must breed it; but no, it's like that sort of common grass that will grow anywhere, between the earthy clefts of Greenland ice or in Vesuvius lava. How the wild winds blow it; they whip it about me as the torn shreds of split sails lash the tossed ship they cling to. A vile wind that has no doubt blown ere this through prison corridors and cells, and wards of hospitals, and ventilated them, and now comes blowing hither as innocent as ..

fleeces. Out upon it! --it's tainted. Were I the wind, I'd blow no more on such a wicked, miserable world. I'd crawl somewhere to a cave, and slink there. And yet, 'tis a noble and heroic thing, the wind! who ever conquered it? In every fight it has the last and bitterest blow. Run tilting at it, and you but run through it. Ha! a coward wind that strikes stark naked men, but will not stand to receive a single blow. Even Ahab is a braver thing --a nobler thing that that. Would now the wind but had a body; but all the things that most exasperate and outrage mortal man, all these things are bodiless, but only bodiless as objects, not as agents. There's a most special, a most cunning, oh, a most malicious difference! And yet, I say again, and swear it now, that there's something all glorious and gracious in the wind. These warm Trade Winds, at least, that in the clear heavens blow straight on, in strong and steadfast, vigorous mildness; and veer not from their mark, however the baser currents of the sea may turn and tack, and mightiest Mississippies of the land swift and swerve about, uncertain where to go at last. And by the eternal Poles! these same Trades that so directly blow my good ship on; these Trades, or something like them --something so unchangeable, and full as strong, blow my keeled soul along! To it! Aloft there! What d'ye see? Nothing, sir. Nothing! and noon at hand! The doubloon goes a-begging! See the sun! Aye, aye, it must be so. I've oversailed him. How, got the start? Aye, he's chasing me now; not I, him --that's bad; I might have known it, too. Fool! the lines --the harpoons he's towing. Aye, aye, I have run him by last night. About! about! Come down, all of ye, but the regular look outs! Man the braces! Steering as she had done, the wind had been somewhat on the Pequod's quarter, so that now being pointed in the reverse direction, the braced ship sailed hard upon the breeze as she rechurned the cream in her own white wake. Against the wind he now steers for the open jaw, murmured Starbuck to himself, as he coiled the new-hauled main-brace upon the rail. God keep us, but already my bones feel ..

damp within me, and from the inside wet my flesh. I misdoubt me that I disobey my God in obeying him! Stand by to sway me up! cried Ahab, advancing to the hempen basket. We should meet him soon. Aye, aye, sir, and straightway Starbuck did Ahab's bidding, and once more Ahab swung on high. a whole hour now passed; gold-beaten out to ages. time itself now held long breaths with keen suspense. But at last, some three points off the weather bow, Ahab descried the spout again, and instantly from the three mast-heads three shrieks went up as if the tongues of fire had voiced it. Forehead to forehead I meet thee, this third time, Moby Dick! On deck there! --brace sharper up; crowd her into the wind's eye. He's too far off to lower yet, Mr. Starbuck. The sails shake! Stand over that helmsman with a top-maul! So, so; he travels fast, and I must down. But let me have one more good round look aloft here at the sea; there's time for that. An old, old sight, and yet somehow so young; aye, and not changed a wink since I first saw it, a boy, from the sand-hills of Nantucket! The same! --the same! --the same to Noah as to me. There's a soft shower to leeward. Such lovely leewardings! They must lead somewhere --to something else than common land, more palmy than the palms. Leeward! the white whale goes that way; look to windward, then; the better if the bitterer quarter. But good bye, good bye, old mast-head! What's this? -- green? aye, tiny mosses in these warped cracks. No such green weather stains on Ahab's head! There's the difference now between man's old age and matter's. But aye, old mast, we both grow old together; sound in our hulls, though, are we not, my ship? Aye, minus a leg, that's all. By heaven this dead wood has the better of my live flesh every way. I can't compare with it; and I've known some ships made of dead trees outlast the lives of men made of the most vital stuff of vital fathers. What's that he said? he should still go before me, my pilot; and yet to be seen again? But where? Will I have eyes at the bottom of the sea, supposing I descend those endless stairs? and all night I've been sailing from him, wherever he did sink to. Aye, ..

aye, like many more thou told'st direful truth as touching thyself, O Parsee; but, Ahab, there thy shot fell short. Good by, mast-head --keep a good eye upon the whale, the while I'm gone. We'll talk to-morrow, nay, to-night, when the white whale lies down there, tied by head and tail. He gave the word; and still gazing round him, was steadily lowered through the cloven blue air to the deck. In due time the boats were lowered, but as standing in his shallop's stern, Ahab just hovered upon the point of the descent, he waved to the mate, --who held one of the tackle-ropes on deck --and bade him pause. Starbuck! Sir? For the third time my soul's ship starts upon this voyage, Starbuck. Aye, sir, thou wilt have it so. Some ships sail from their ports, and ever afterwards are missing, Starbuck! Truth, sir: saddest truth. Some men die at ebb tide; some at low water; some at the full of the flood; --and I feel now like a billow that's all one crested comb, Starbuck. I am old; --shake hands with me, man. Their hands met; their eyes fastened; Starbuck's tears the glue. Oh, my captain, my captain! --noble heart --go not --go not! -- see, it's a brave man that weeps; how great the agony of the persuasion then! Lower away! --cried Ahab, tossing the mate's arm from him. Stand by the crew! In an instant the boat was pulling round close under the stern. The sharks! the sharks! cried a voice from the low cabin-window there; O master, my master, come back! But Ahab heard nothing; for his own voice was high-lifted then; and the boat leaped on. Yet the voice spake true; for scarce had he pushed from the ship, when numbers of sharks, seemingly rising from out the dark waters beneath the hull, maliciously snapped at the blades of the oars, every time they dipped in the water; and in this ..

way accompanied the boat with their bites. It is a thing not uncommonly happening to the whale-boats in those swarming seas; the sharks at times apparently following them in the same prescient way that vultures hover over the banners of marching regiments in the east. But these were the first sharks that had been observed by the Pequod since the White Whale had been first descried; and whether it was that Ahab's crew were all such tiger-yellow barbarians, and therefore their flesh more musky to the senses of the sharks --a matter sometimes well known to affect them, --however it was, they seemed to follow that one boat without molesting the others. Heart of wrought steel! murmured Starbuck gazing over the side, and following with his eyes the receding boat -- canst thou yet ring boldly to that sight? --lowering thy keel among ravening sharks, and followed by them, open-mouthed to the chase; and this the critical third day? --For when three days flow together in one continuous intense pursuit; be sure the first is the morning, the second the noon, and the third the evening and the end of that thing --be that end what it may. Oh! my God! what is this that shoots through me, and leaves me so deadly calm, yet expectant, --fixed at the top of a shudder! Future things swim before me, as in empty outlines and skeletons; all the past is somehow grown dim. Mary, girl! thou fadest in pale glories behind me; boy! I seem to see but thy eyes grown wondrous blue. Strangest problems of life seem clearing; but clouds sweep between --Is my journey's end coming? My legs feel faint; like his who has footed it all day. Feel thy heart, --beats it yet? --Stir thyself, Starbuck! --stave it off-- move, move! speak aloud! --Mast-head there! See ye my boy's hand on the hill? --Crazed; --aloft there! --keep thy keenest eye upon the boats: --mark well the whale! --Ho! again! --drive off that hawk! see! he pecks --he tears the vane --pointing to the red flag flying at the main-truck -- Ha! he soars away with it! -- Where's the old man now? sees't thou that sight, oh Ahab! -- shudder, shudder! The boats had not gone very far, when by a signal from the mast-heads --a downward pointed arm, Ahab knew that the whale had sounded; but intending to be near him at the next rising, he ..

held on his way a little sideways from the vessel; the becharmed crew maintaining the profoundest silence, as the head-beat waves hammered and hammered against the opposing bow. Drive, drive in your nails, oh ye waves! to their uttermost heads, drive them in! ye but strike a thing without a lid; and no coffin and no hearse can be mine: --and hemp only can kill me! Ha! ha! Suddenly the waters around them slowly swelled in broad circles; then quickly upheaved, as if sideways sliding from a submerged berg of ice, swiftly rising to the surface. A low rumbling sound was heard; a subterraneous hum; and then all held their breaths; as bedraggled with trailing ropes, and harpoons, and lances, a vast form shot lengthwise, but obliquely from the sea. Shrouded in a thin drooping veil of mist, it hovered for a moment in the rainbowed air; and then fell swamping back into the deep. Crushed thirty feet upwards, the waters flashed for an instant like heaps of fountains, then brokenly sank in a shower of flakes, leaving the circling surface creamed like new milk round the marble trunk of the whale. Give way! cried Ahab to the oarsmen, and the boats darted forward to the attack; but maddened by yesterday's fresh irons that corroded in him, Moby Dick seemed combinedly possessed by all the angels that fell from heaven. The wide tiers of welded tendons overspreading his broad white forehead, beneath the transparent skin, looked knitted together; as head on, he came churning his tail among the boats; and once more flailed them apart; spilling out the irons and lances from the two mates' boats, and dashing in one side of the upper part of their bows, but leaving Ahab's almost without a scar. While Daggoo and Queequeg were stopping the strained planks; and as the whale swimming out from them, turned, and showed one entire flank as he shot by them again; at that moment a quick cry went up. Lashed round and round to the fish's back; pinioned in the turns upon turns in which, during the past night, the whale had reeled the involutions of the lines around him, the half torn body of the Parsee was seen; his sable raiment frayed to shreds; his distended eyes turned full upon old Ahab. ..

The harpoon dropped from his hand. Befooled, befooled! --drawing in a long lean breath -- Aye, Parsee! I see thee again. --Aye, and thou goest before; and this, this then is the hearse that thou didst promise. But I hold thee to the last letter of thy word. Where is the second hearse? Away, mates, to the ship! those boats are useless now; repair them if ye can in time, and return to me; if not, Ahab is enough to die --Down, men! the first thing that but offers to jump from this boat I stand in, that thing I harpoon. Ye are not other men, but my arms and my legs; and so obey me. --Where's the whale? gone down again? But he looked too nigh the boat; for as if bent upon escaping with the corpse he bore, and as if the particular place of the last encounter had been but a stage in his leeward voyage, Moby Dick was now again steadily swimming forward; and had almost passed the ship, --which thus far had been sailing in the contrary direction to him, though for the present her headway had been stopped. He seemed swimming with his utmost velocity, and now only intent upon pursuing his own straight path in the sea. Oh! Ahab, cried Starbuck, not too late is it, even now, the third day, to desist. See! Moby Dick seeks thee not. It is thou, thou, that madly seekest him! Setting sail to the rising wind, the lonely boat was swiftly impelled to leeward, by both oars and canvas. And at last when Ahab was sliding by the vessel, so near as plainly to distinguish Starbuck's face as he leaned over the rail, he hailed him to turn the vessel about, and follow him, not too swiftly, at a judicious interval. Glancing upwards, he saw Tashtego, Queequeg, and Daggoo, eagerly mounting to the three mast-heads; while the oarsmen were rocking in the two staved boats which had but just been hoisted to the side, and were busily at work in repairing them. One after the other, through the portholes, as he sped, he also caught flying glimpses of Stubb and Flask, busying themselves on deck among bundles of new irons and lances. As he saw all this; as he heard the hammers in the broken boats; far other hammers seemed driving a nail into his heart. But he rallied. And now marking that the vane or ..

flag was gone from the main-mast-head, he shouted to Tashtego, who had just gained that perch, to descend again for another flag, and a hammer and nails, and so nail it to the mast. Whether fagged by the three days' running chase, and the resistance to his swimming in the knotted hamper he bore; or whether it was some latent deceitfulness and malice in him: whichever was true, the White Whale's way now began to abate, as it seemed, from the boat so rapidly nearing him once more; though indeed the whale's last start had not been so long a one as before. And still as Ahab glided over the waves the unpitying sharks accompanied him; and so pertinaciously stuck to the boat; and so continually bit at the plying oars, that the blades became jagged and crunched, and left small splinters in the sea, at almost every dip. Heed them not! those teeth but give new rowlocks to your oars. Pull on! 'tis the better rest, the shark's jaw than the yielding water. But at every bite, sir, the thin blades grow smaller and smaller! They will last long enough! pull on! --But who can tell --he muttered -- whether these sharks swim to feast on the whale or on ahab? --But pull on! Aye, all alive, now --we near him. The helm! take the helm; let me pass, --and so saying, two of the oarsmen helped him forward to the bows of the still flying boat. At length as the craft was cast to one side, and ran ranging along with the White Whale's flank, he seemed strangely oblivious of its advance --as the whale sometimes will --and Ahab was fairly within the smoky mountain mist, which, thrown off from the whale's spout, curled round his great, Monadnock hump; he was even thus close to him; when, with body arched back, and both arms lengthwise high-lifted to the poise, he darted his fierce iron, and his far fiercer curse into the hated whale. As both steel and curse sank to the socket, as if sucked into a morass, Moby Dick sideways writhed; spasmodically rolled his nigh flank against the bow, and, without staving a hole in it, so suddenly canted the boat over, that had it not been for the elevated part of the gunwale to which he then clung, Ahab would once more have been tossed into the sea. ..

As it was, three of the oarsmen --who foreknew not the precise instant of the dart, and were therefore unprepared for its effects -- these were flung out; but so fell, that, in an instant two of them clutched the gunwale again, and rising to its level on a combing wave, hurled themselves bodily inboard again; the third man helplessly dropping astern, but still afloat and swimming. Almost simultaneously, with a mighty volition of ungraduated, instantaneous swiftness, the White Whale darted through the weltering sea. But when Ahab cried out to the steersman to take new turns with the line, and hold it so; and commanded the crew to turn round on their seats, and tow the boat up to the mark; the moment the treacherous line felt that double strain and tug, it snapped in the empty air! What breaks in me? Some sinew cracks! --'tis whole again; oars! oars! Burst in upon him! Hearing the tremendous rush of the sea-crashing boat, the whale wheeled round to present his blank forehead at bay; but in that evolution, catching sight of the nearing black hull of the ship; seemingly seeing in it the source of all his persecutions; bethinking it --it may be --a larger and nobler foe; of a sudden, he bore down upon its advancing prow, smiting his jaws amid fiery showers of foam. Ahab staggered; his hand smote his forehead. I grow blind; hands! stretch out before me that I may yet grope my way. Is't night? The whale! The ship! cried the cringing oarsmen. Oars! oars Slope downwards to thy depths, O sea, that ere it be for ever too late, Ahab may slide this last, last time upon his mark; I see: the ship! the ship! Dash on, my men! Will ye not save my ship? But as the oarsmen violently forced their boat through the sledge-hammering seas, the before whale-smitten bow-ends of two planks burst through, and in an instant almost, the temporarily disabled boat lay nearly level with the waves; its half-wading, splashing crew, trying hard to stop the gap and bale out the pouring water. Meantime, for that one beholding instant, Tashtego's mast-head hammer remained suspended in his hand; and the red ..

flag, half-wrapping him as with a plaid, then streamed itself straight out from him, as his own forward-flowing heart; while Starbuck and Stubb, standing upon the bowsprit beneath, caught sight of the down-coming monster just as soon as he. The whale, the whale! Up helm, up helm! Oh, all ye sweet powers of air, now hug me close! Let not Starbuck die, if die he must, in a woman's fainting fit. Up helm, I say --ye fools, the jaw! the jaw! Is this the end of all my bursting prayers? all my life-long fidelities? Oh, Ahab, Ahab, lo, thy work. Steady! helmsman, steady. Nay, nay! Up helm again! He turns to meet us! Oh, his unappeasable brow drives on towards one, whose duty tells him he cannot depart. My God, stand by me now! Stand not by me, but stand under me, whoever you are that will now help Stubb; for Stubb, too, sticks here. I grin at thee, thou grinning whale! Who ever helped Stubb, or kept Stubb awake, but Stubb's own unwinking eye? And now poor Stubb goes to bed upon a mattrass that is all too soft; would it were stuffed with brushwood! I grin at thee, thou grinning whale! Look ye, sun, moon, and stars! I call ye assassins of as good a fellow as ever spouted up his ghost. For all that, I would yet ring glasses with ye, would ye but hand the cup! Oh, oh! oh, oh! thou grinning whale, but there'll be plenty of gulping soon! Why fly ye not, O Ahab! For me, off shoes and jacket to it; let Stubb die in his drawers! A most mouldy and over salted death, though; --cherries! cherries! cherries! Oh, Flask, for one red cherry ere we die! Cherries? I only wish that we were where they grow. Oh, Stubb, I hope my poor mother's drawn my part-pay ere this; if not, few coppers will now come to her, for the voyage is up. From the ship's bows, nearly all the seamen now hung inactive; hammers, bits of plank, lances, and harpoons, mechanically retained in their hands, just as they had darted from their various employments; all their enchanted eyes intent upon the whale, which from side to side strangely vibrating his predestinating head, sent a broad band of overspreading semicircular foam before him as he rushed. Retribution, swift vengeance, eternal malice were in his whole aspect, and spite of all that mortal man could do, the solid white buttress of his forehead ..

smote the ship's starboard bow, till men and timbers reeled. Some fell flat upon their faces. Like dislodged trucks, the heads of the harpooneers aloft shook on their bull-like necks. Through the breach, they heard the waters pour, as mountain torrents down a flume. The ship! The hearse! --the second hearse! cried ahab from the boat; its wood could only be American! Diving beneath the settling ship, the whale ran quivering along its keel; but turning under water, swiftly shot to the surface again, far off the other bow, but within a few yards of Ahab's boat, where, for a time, he lay quiescent. I turn my body from the sun. What ho, Tashtego! Let me hear thy hammer. Oh! ye three unsurrendered spires of mine; thou uncracked keel; and only god-bullied hull; thou firm deck, and haughty helm, and Pole-pointed prow, --death-glorious ship! must ye then perish, and without me? Am I cut off from the last fond pride of meanest shipwrecked captains? Oh, lonely death on lonely life! Oh, now I feel my topmost greatness lies in my topmost grief. Ho, ho! from all your furthest bounds, pour ye now in, ye bold billows of my whole foregone life, and top this one piled comber of my death! Towards thee I roll, thou all-destroying but unconquering whale; to the last I grapple with thee; from hell's heart I stab at thee; for hate's sake I spit my last breath at thee. Sink all coffins and all hearses to one common pool! and since neither can be mine, let me then tow to pieces, while still chasing thee, though tied to thee, thou damned whale! Thus, I give up the spear! The harpoon was darted; the stricken whale flew forward; with igniting velocity the line ran through the groove; --ran foul. Ahab stooped to clear it; he did clear it; but the flying turn caught him round the neck, and voicelessly as Turkish mutes bowstring their victim, he was shot out of the boat, ere the crew knew he was gone. Next instant, the heavy eye-splice in the rope's final end flew out of the stark-empty tub, knocked down an oarsman, and smiting the sea, disappeared in its depths. For an instant, the tranced boat's crew stood still; then turned. The ship? Great God, where is the ship? Soon they through dim, bewildering mediums saw her sidelong fading phantom, ..

as in the gaseous Fata Morgana; only the uppermost masts out of water; while fixed by infatuation, or fidelity, or fate, to their once lofty perches, the pagan harpooneers still maintained their sinking lookouts on the sea. And now, concentric circles seized the lone boat itself, and all its crew, and each floating oar, and every lance-pole, and spinning, animate and inanimate, all round and round in one vortex, carried the smallest chip of the Pequod out of sight. But as the last whelmings intermixingly poured themselves over the sunken head of the Indian at the mainmast, leaving a few inches of the erect spar yet visible, together with long streaming yards of the flag, which calmly undulated, with ironical coincidings, over the destroying billows they almost touched; --at that instant, a red arm and a hammer hovered backwardly uplifted in the open air, in the act of nailing the flag faster and yet faster to the subsiding spar. A sky-hawk that tauntingly had followed the main-truck downwards from its natural home among the stars, pecking at the flag, and incommoding Tashtego there; this bird now chanced to intercept its broad fluttering wing between the hammer and the wood; and simultaneously feeling that etherial thrill, the submerged savage beneath, in his death-gasp, kept his hammer frozen there; and so the bird of heaven, with archangelic shrieks, and his imperial beak thrust upwards, and his whole captive form folded in the flag of Ahab, went down with his ship, which, like Satan, would not sink to hell till she had dragged a living part of heaven along with her, and helmeted herself with it. Now small fowls flew screaming over the yet yawning gulf; a sullen white surf beat against its steep sides; then all collapsed, and the great shroud of the sea rolled on as it rolled five thousand years ago. .. < epilogue / This text of Melville's Moby-Dick is based on the Hendricks House / edition. It was prepared by Professor Eugene F. Irey AT THE +UNIVERSIT Y / OF +COLORADO, +BOULDER, +COLORADO 80309, +U.+S.+A. / +ANY SUBSEQUENT COP IES OF THIS DATA MUST INCLUDE THIS NOTICE / AND ANY PUBLICATIONS RESULTING FRO M ANALYSIS OF THIS DATA MUST INCLUDE / REFERENCE TO +PROFESSOR +IREY'S WORK. 2 +AND +I ONLY AM ESCAPED ALONE TO TELL THEE. +JOB. +THE DRAMA'S DONE. +WHY THEN HERE DOES ANY ONE STEP FORTH? --+BECAUSE ONE DID SURVIVE THE WRECK. + IT SO CHANCED, THAT AFTER THE +PARSEE'S DISAPPEARANCE, +I WAS HE WHOM THE +FA TES ORDAINED TO TAKE THE PLACE OF +AHAB'S BOWSMAN, WHEN THAT BOWSMAN ASSUMED TH E VACANT POST; THE SAME, WHO, WHEN ON THE LAST DAY THE THREE MEN WERE TOSSED F ROM OUT THE ROCKING BOAT, WAS DROPPED ASTERN. +SO, FLOATING ON THE MARGIN OF THE ENSUING SCENE, AND IN FULL SIGHT OF IT, WHEN THE HALF-SPENT SUCTION OF T HE SUNK SHIP REACHED ME, +I WAS THEN, BUT SLOWLY, DRAWN TOWARDS THE CLOSING VO RTEX. +WHEN +I REACHED IT, IT HAD SUBSIDED TO A CREAMY POOL. +ROUND AND ROUND , THEN, AND EVER CONTRACTING TOWARDS THE BUTTON-LIKE BLACK BUBBLE AT THE AXIS OF THAT SLOWLY WHEELING CIRCLE, LIKE ANOTHER +IXION +I DID REVOLVE. +TILL, G AINING THAT VITAL CENTRE, THE BLACK BUBBLE UPWARD BURST; AND NOW, LIBERATED BY REASON OF ITS CUNNING SPRING, AND OWING TO ITS GREAT BUOYANCY, RISING WITH GREAT FORCE, THE COFFIN LIFE-BUOY SHOT LENGTHWISE FROM THE SEA, FELL OVER, AND FLOATED BY MY SIDE. +BUOYED UP BY THAT COFFIN, FOR ALMOST ONE WHOLE DAY AND NIGHT, +I FLOATED ON A SOFT AND DIRGE-LIKE MAIN. +THE UNHARMING SHARKS, THEY GLIDED BY AS IF WITH PADLOCKS ON THEIR MOUTHS; THE SAVAGE SEA-HAWKS SAILE D WITH SHEATHED BEAKS. +ON THE SECOND DAY, A SAIL DREW NEAR, NEARER, AND PIC KED ME UP AT LAST. +IT WAS THE DEVIOUS-CRUISING +RACHEL, THAT IN HER RETRACIN uimaj-2.4.0/uimaj-core/src/test/resources/data/IBM_LifeSciences.xml0000644000175000017500000000776511665471102025031 0ustar drazzibdrazzib IBM announces $100 Million investment in Life Sciences 16 August 2000 "Life sciences is one of the emerging markets at the heart of IBM's growth strategy," said John M. Thompson, IBM senior vice president & group executive, Software. "This investment is the first of a number of steps we will be taking to advance IBM's life sciences initiatives." In his role as newly appointed IBM Corporation vice chairman, effective September 1, Mr. Thompson will be responsible for integrating and accelerating IBM's efforts to exploit life sciences and other emerging growth areas. IBM estimates the market for IT solutions for life sciences will skyrocket from $3.5 billion today to more than $9 billion by 2003. Driving demand is the explosive growth in genomic, proteomic and pharmaceutical research. For example, the Human Genome Database is approximately three terabytes of data, or the equivalent of 150 million pages of information. The volume of life sciences data is doubling every six months. "All of this genetic data is worthless without the information technology that can help scientists manage and analyze it to unlock the pathways that will lead to new cures for many of today's diseases," said Dr. Caroline Kovac, vice president of IBM's new Life Sciences unit. "IBM can help speed this process by enabling more efficient interpretation of data and sharing of knowledge. The potential for change based on innovation in life sciences is bigger than the change caused by the digital circuit." Among the life sciences initiatives already underway at IBM are: - DiscoveryLink* -- For the first time, researchers using this combination of innovative middleware and integration services can join together information from many sources to solve complex medical research problems. DiscoveryLink creates a "virtual database" that permits data to be accessed and extracted from multiple data sources used in research and development projects. This IT solution can dramatically improve product cycle time and lower development costs for pharmaceutical, biotechnology and agri-science companies. - Blue Gene* - IBM is building a supercomputer 100 times faster than any available today designed to advance understanding of the mechanisms behind protein folding through large-scale biomolecular simulation. In December, IBM committed $100 million to this five-year research project to advance the state-of-the-art in supercomputing for biological applications. - Bio-Dictionary* -- IBM has compiled a protein dictionary containing some 30 million protein "words" designed to accelerate the understanding of protein shapes and functions.Bio-Dictionaries for selected genomes, as well as bioinformatics algorithms for pattern discovery and other relevant applications, are available to scientists and researchers for noncommercial use through a website dedicated to life sciences content at http://www.research.ibm.com/compsci/compbio/.

* Indicates trademark or registered trademark of IBM Corporation.
uimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/0000755000175000017500000000000011665471106025015 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/dataPathDir/0000755000175000017500000000000011665471106027202 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/dataPathDir/TypePrioritiesImportedFromDataPath.xmluimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/dataPathDir/TypePrioritiesImportedF0000644000175000017500000000255011665471106033734 0ustar drazzibdrazzib TypePrioritiesImportedFromDataPath This is a test of the import mechanism. 0.1 The Apache Software Foundation TestType1 TestType2 TestType3 uimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/Circular2.xml0000644000175000017500000000246511665471106027374 0ustar drazzibdrazzib Circular2 For testing circular imports. 0.1 The Apache Software Foundation B C uimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/SimpleTypePriorities.xml0000644000175000017500000000230311665471106031702 0ustar drazzibdrazzib TestType1 TestType2 TestType1 TestType3 uimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/Circular1.xml0000644000175000017500000000246511665471106027373 0ustar drazzibdrazzib Circular1 For testing circular imports. 0.1 The Apache Software Foundation A B ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/TypePrioritiesImportedByLocation.xmluimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/TypePrioritiesImportedByLocation.xm0000644000175000017500000000253111665471106034047 0ustar drazzibdrazzib TypePrioritiesImportedByLocation This is a test of the import mechanism. 0.1 The Apache Software Foundation DocumentStructure NamedEntity uimaj-2.4.0/uimaj-core/src/test/resources/TypePrioritiesImplTest/TestTypePriorities.xml0000644000175000017500000000270411665471106031375 0ustar drazzibdrazzib TestTypePriorities This is a test. 0.1 The Apache Software Foundation Paragraph Sentence NamedEntity uimaj-2.4.0/uimaj-core/src/test/resources/org/0000755000175000017500000000000011665471072021131 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/0000755000175000017500000000000011665471072022352 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/0000755000175000017500000000000011665471072023305 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/analysis_engine/0000755000175000017500000000000011665471072026455 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/analysis_engine/impl/0000755000175000017500000000000011665471072027416 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/analysis_engine/impl/documentAnnotationRedefinitionTS.xmluimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/analysis_engine/impl/documentAnnotationRed0000644000175000017500000000365211665471072033653 0ustar drazzibdrazzib documentAnnotationRedefinitionTS 1.0 org.apache.uima.test.MyAnnotation uima.tcas.Annotation uima.tcas.DocumentAnnotation org.apache.uima.test.MyAnnotation my.new.Annotation uima.cas.TOP uima.tcas.Annotation my.new.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/analysis_engine/impl/testDataFile3.dat0000644000175000017500000000001611665471072032541 0ustar drazzibdrazzibthis is a testuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/cas_data/0000755000175000017500000000000011665471072025044 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/cas_data/impl/0000755000175000017500000000000011665471072026005 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/cas_data/impl/xcastest.xml0000644000175000017500000000236411665471072030372 0ustar drazzibdrazzib 000064393EC7A277F3D76D39002B49CC This is a test http://www.nolimitmedia.com/index.php?act=group&gro=1&gron=Flash&PHPSESSID=5dcc31fb425c4a204b70d9eab92531a5 uimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/0000755000175000017500000000000011665471072025134 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/0000755000175000017500000000000011665471072026714 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/impl/0000755000175000017500000000000011665471072027655 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/impl/ConfigParamEmptyGroup.xmluimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/impl/ConfigParamEmptyGro0000644000175000017500000000240611665471072033457 0ustar drazzibdrazzib FeatureIndex The name of the index to use. String false true ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/impl/TypeSystemImportedByName.xmluimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/metadata/impl/TypeSystemImportedB0000644000175000017500000000372011665471072033536 0ustar drazzibdrazzib TypeSystemImportedByLocation This is for testing the import mechanism. 0.1 The Apache Software Foundation TestType1 This is a test. uima.tcas.Annotation Foo uima.cas.String NamedEntity A named entity. uima.tcas.Annotation TestType2 uima.cas.TOP Foo uima.cas.Integer uimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/impl/0000755000175000017500000000000011665471072026075 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/resource/impl/ResourceInClasspath.txt0000644000175000017500000000000011665471072032545 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/util/0000755000175000017500000000000011665471072024262 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/util/impl/0000755000175000017500000000000011665471074025225 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/org/apache/uima/util/impl/logger_test_messages.properties0000644000175000017500000000200711665471074033547 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** UIMA_logger_test = Exception test messageuimaj-2.4.0/uimaj-core/src/test/resources/UimaContextTest/0000755000175000017500000000000011665471100023432 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/UimaContextTest/CasConsumerForUimaContextTest.xml0000644000175000017500000001701611665471100032073 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.resource.TestCasConsumer CAS Consumer for Testing UimaContext For testing the UimaContext. 1.0 The Apache Software Foundation StringParam String StringArrayParam String true IntegerParam Integer IntegerArrayParam Integer true FloatParam Float FloatArrayParam Float true StringParam myString StringArrayParam one two IntegerParam 42 IntegerArrayParam 1 2 3 FloatParam 3.14 TestFileResource TestFileLanguageResource TestResourceObject org.apache.uima.resource.impl.TestResourceInterface TestLanguageResourceObject org.apache.uima.resource.impl.TestResourceInterface OtherFileResource AdditionalResource org.apache.uima.resource.impl.TestResourceInterface true MyFileResource file:testDataFile.dat MyFileLanguageResource file:FileLanguageResource_implTest_data_ .dat MyResourceObject file:testDataFile.dat org.apache.uima.resource.impl.TestResourceInterface_impl MyLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl MyOtherFileResource Test.dat TestFileResource MyFileResource TestFileLanguageResource MyFileLanguageResource TestResourceObject MyResourceObject TestLanguageResourceObject MyLanguageResourceObject OtherFileResource MyOtherFileResource uimaj-2.4.0/uimaj-core/src/test/resources/featurePathTests/0000755000175000017500000000000011665471076023641 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/featurePathTests/FeaturePathTestTypeSystem.xml0000644000175000017500000001346411665471076031512 0ustar drazzibdrazzib FeaturePathTestTypeSystem 1.0 uima.tt.TestAnnotation uima.tcas.Annotation stringFeature uima.cas.String uima.tt.TestAnnotSub uima.tt.TestAnnotation testFeature uima.cas.String uima.tcas.DocumentAnnotation uima.tcas.Annotation stringFeature uima.cas.String shortFeature uima.cas.Short floatFeature uima.cas.Float doubleFeature uima.cas.Double longFeature uima.cas.Long intFeature uima.cas.Integer booleanFeature uima.cas.Boolean byteFeature uima.cas.Byte refFeature uima.tcas.Annotation refFeature2 uima.tcas.DocumentAnnotation stringArray uima.cas.StringArray shortArray uima.cas.ShortArray floatArray uima.cas.FloatArray doubleArray uima.cas.DoubleArray longArray uima.cas.LongArray intArray uima.cas.IntegerArray booleanArray uima.cas.BooleanArray byteArray uima.cas.ByteArray fsArray uima.cas.FSArray uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/0000755000175000017500000000000011665471072022367 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/NamesAndPersonTitles_TAE.xml0000644000175000017500000000361511665471072027651 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Name Recognizer and Person Title Annotator Detects Names and Person Titles NameRecognizer PersonTitleAnnotator example.Name example.PersonTitle en uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/SimpleTestAggregate.xml0000644000175000017500000000453711665471072027022 0ustar drazzibdrazzib org.apache.uima.java false Test Aggregate TAE Detects Nothing TestMultiplier NoOp en true true false uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/NoOpAnnotator.xml0000644000175000017500000000563111665471072025657 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.ae.noop.NoOpAnnotator NoOpAnnotator Annotator That Does Nothin 1.0 The Apache Software Foundation ErrorFrequency Frequency of Generated Errors Integer false true ProcessDelay Process Delay Integer false false ErrorFrequency 0 true true false uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/SimpleNameRecognizer_RegEx_TAE.xml0000644000175000017500000000715211665471072030763 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.RegExAnnotator Simple Name Recognizer using Regular Expressions Detects Names using a simple regular expression. Patterns Regular expression patterns to match. The language is that supported by Java 1.4. String true false TypeNames Names of CAS Types to create for the patterns found. The indexes of this array correspond to the indexes of the Patterns or PatternFiles arrays. If a match is found for Patterns[i], it will result in an annotation of type TypeNames[i]. String true false ContainingAnnotationTypes Names of CAS Input Types within which annotations should be created. String true false AnnotateEntireContainingAnnotation When the ContainingAnnoationTypes parameter is specified, a value of true for this parameter will cause the entire containing annotation to be used as the span of the new annotation, rather than just the span of the regular expression match. This can be used to "classify" previously created annotations according to whether or not they contain text matching a regular expression. Boolean false false Patterns \p{Upper}\w*(\.?\s\p{Upper}\w*)+ TypeNames example.Name example.Name A proper name. uima.tcas.Annotation example.Name uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/arrayTypeSerialization.xml0000644000175000017500000000460611665471072027635 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.cas.test.ArrayIndexTest arrayTypeSerialization 1.0 Test.ArrayType uima.cas.TOP arrayFeature uima.cas.FSArray Test.ArrayType true true false uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/SimpleCasGenerator.xml0000644000175000017500000002024411665471072026642 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.ae.multiplier.SimpleCasGenerator Simple Text Segmenter Generates specified number of CASes. 1.0 The Apache Software Foundation NumberToGenerate Approximate number of CASes to create. Integer false true StringOne document text String false true StringTwo document text String false true InputFile document text String false true NumberToGenerate 1 StringOne Upcoming UIMA Seminars April 7, 2004 Distillery Lunch Seminar UIMA and its Metadata 12:00PM-1:00PM in HAW GN-K35. Dave Ferrucci will give a UIMA overview and discuss the types of component metadata that UIMA components provide. Jon Lenchner will give a demo of the Text Analysis Engine configurator tool. April 16, 2004 KM & I Department Tea Title: An Eclipse-based TAE Configurator Tool 3:00PM-4:30PM in HAW GN-K35 . Jon Lenchner will demo an Eclipse plugin for configuring TAE descriptors, which will be available soon for you to use. No more editing XML descriptors by hand! May 11, 2004 UIMA Tutorial 9:00AM-5:00PM in HAW GN-K35. This is a full-day, hands-on tutorial on UIMA, covering the development of Text Analysis Engines and Collection Processing Engines, as well as how to include these components in your own applications. StringTwo UIMA Summer School August 26, 2003 UIMA 101 - The New UIMA Introduction (Hands-on Tutorial) 9:00AM-5:00PM in HAW GN-K35 August 28, 2003 FROST Tutorial 9:00AM-5:00PM in HAW GN-K35 September 15, 2003 UIMA 201: UIMA Advanced Topics (Hands-on Tutorial) 9:00AM-5:00PM in HAW 1S-F53 September 17, 2003 The UIMA System Integration Test and Hardening Service The "SITH" 3:00PM-4:30PM in HAW GN-K35 UIMA Summer School Tutorial and Presentation Details UIMA 101: The new UIMA tutorial Tuesday August 26 9:00AM - 4:30PM in GN-K35 UIMA 101 is a hands-on programming tutorial. UIMA 101 is intended for people who want a first introductory course to UIMA or for people who would like a refresher. The tutorial covers the same concepts in the first UIMA tutorial given in 3Q 2002 except for some key updates: 1) It uses a new interface to the CAS that makes it more natural to access and update CAS feature structures using ordinary Java objects (i.e., the JCAS) and 2) It uses updated TAE interfaces that give the application developer more control over managing multiple CASs. Please NOTE expert users of UIMA can skip this one and should consider attending the Advanced Topics tutorial. Prerequisites for the UIMA 101 Tutorial 1) Java Programming 2) Some experience with Eclipse IDE helpful FROST Tutorial August 28 9:00AM - 5:00PM in GN-K35 Visitors from the FROST team will be here to talk to us about FROST. UIMA 201: The UIMA Advanced Topics Tutorial September 15: 9:00AM - 5:30PM in Hawthorne 1S-F53 UIMA 201 will introduce some new UIMA concepts and walk the student through hands-on examples. The advanced topics tutorial is designed for people who have some experience with UIMA and want to use new capabilities of UIMA 1.0 to address one or more of the following Advanced Topics: 1) Collection Processing and Collection Processing Engines (CPEs) 2) Multi-Threading and CAS Pooling 3) Using the UIMA adapter framework to integrate network TAEs with Java TAEs 4) A Semantic Search Application that brings it all together Prerequisites for UIMA 201 1) UIMA 101 Tutorial OR Extensive UIMA Experience The UIMA Integration Test bed Service (The "SITH") September 17 3:00PM - 4:30PM in HAW GN-K35 We have developed the first version of the UIMA Integration Test bed service. This service is being developed to help test, evaluate, certify and publish UIMA compliant components. In this talk we will explain the service and what it is intended to provide the UIMA community. We will address the following topics: 1. SITH Services 2. How to submit components and what to expect in return 3. Overview of the test bed implementation using Collection Processing UIMA and Juru. 4. Next Steps for the SITH InputFile src/test/resources/data/IBM_LifeSciences.xml foo.Bar uima.tcas.Annotation NamedEntity uima.tcas.Annotation DocumentStructure uima.tcas.Annotation NamedEntity DocumentStructure false true true uimaj-2.4.0/uimaj-core/src/test/resources/ExampleTae/PersonTitleAnnotator_WithinNamesOnly.xml0000644000175000017500000001425611665471072032427 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cas.PersonTitleAnnotator Person Title Annotator - Within Names only A configuration of the PersonTitleAnnotator that looks for Person Titles only within existing Name annotations. See also PersonTitleAnnotator.xml. 1.0 The Apache Software Foundation CivilianTitles List of Civilian Titles to be annotated. String true true MilitaryTitles List of Military Titles to be annotated. String true true GovernmentTitles List of Government Titles to be annotated. String true true ContainingAnnotationType Annotation type within which to search for Person Titles. If no value is specified, the entire document will be searched. String false false CivilianTitles Mr. Ms. Mrs. Dr. MilitaryTitles Gen. Col. Maj. Capt. Lt. Gen. Lt Col. Lt. GovernmentTitles Vice President President Vice Pres. Pres. Governor Lt. Governor Gov. Lt. Gov. Senator Sen. ContainingAnnotationType example.Name example.PersonTitle A Personal Title. uima.tcas.Annotation Kind The kind of title - Civilian, Military, or Government. example.PersonTitleKind example.PersonTitleKind A kind of person title - Civilian, Military, or Government. uima.cas.String Civilian Title of a person not in military or government service. Military Title of a person in the military. Government Title of a government official. example.Name A proper name. uima.tcas.Annotation example.Name example.PersonTitle example.PersonTitle:Kind en uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/0000755000175000017500000000000011665471074022773 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/DataResource_implTest_tempDataFile.dat0000644000175000017500000000004511665471074032345 0ustar drazzibdrazzibThis is a test. This is only a test.uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/FileLanguageResource_implTest_data_en.dat0000644000175000017500000000001111665471074033044 0ustar drazzibdrazzibEnglish uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/ResourceManager_implTest_tempDataFile.dat0000644000175000017500000000004511665471074033046 0ustar drazzibdrazzibThis is a test. This is only a test.uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/spaces in dir name/0000755000175000017500000000000011665471074026300 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/spaces in dir name/Test.dat0000644000175000017500000000001711665471074027707 0ustar drazzibdrazzibThis is a test.uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/FileLanguageResource_implTest_data_de.dat0000644000175000017500000000001111665471074033032 0ustar drazzibdrazzibDeutsch uimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/subdir/0000755000175000017500000000000011665471074024263 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/subdir/test/0000755000175000017500000000000011665471074025242 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ResourceTest/subdir/test/relativePathTest.dat0000644000175000017500000000003611665471074031223 0ustar drazzibdrazzibthis file is in a subdirectoryuimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/0000755000175000017500000000000011665471070022520 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TransAnnotatorAggregateWithoutSofaNameMapping.xmluimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TransAnnotatorAggregateWithoutSofaNameMapping.0000644000175000017500000000424411665471070033623 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - 2 Translation Annotators Does translation from English to German twice 1.0 The Apache Software Foundation Translator1 Translator2 SourceDocument OutputTranslator1 OutputTranslator2 en uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TransAnnotatorAndTestAnnotatorAggregate.xml0000644000175000017500000000547411665471070033211 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - Translation followed by Person Title Annotator Does translation from English to German then runs the TestAnnotator 1.0 The Apache Software Foundation Translator TestAnnotator SourceDocument Translation en Translator EnglishDocument SourceDocument Translator GermanDocument Translation TestAnnotator _InitialView Translation uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/SofaFlowController.xml0000644000175000017500000000314311665471070027027 0ustar drazzibdrazzib org.apache.uima.java org.apache.uima.flow.impl.FixedFlowController Fixed Flow Controller Simple FlowController that uses the FixedFlow element of the aggregate descriptor to determine a linear flow. 1.0 The Apache Software Foundation OriginalDocument uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TCasTransAnnotatorAggregate.xml0000644000175000017500000000640211665471070030603 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - 2 Translation Annotators Does translation from English to German twice 1.0 The Apache Software Foundation Translator1 Translator2 SourceDocument OutputTranslator1 OutputTranslator2 en Translator1 GermanDocument OutputTranslator1 Translator1 SourceDocument Translator2 EnglishDocument SourceDocument Translator2 GermanDocument OutputTranslator2 MyFlowController OriginalDocument SourceDocument uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TransAnnotatorAggregate.xml0000644000175000017500000000637611665471070030042 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE - 2 Translation Annotators Does translation from English to German twice 1.0 The Apache Software Foundation Translator1 Translator2 SourceDocument OutputTranslator1 OutputTranslator2 en Translator1 GermanDocument OutputTranslator1 Translator1 EnglishDocument SourceDocument Translator2 EnglishDocument SourceDocument Translator2 GermanDocument OutputTranslator2 MyFlowController OriginalDocument SourceDocument uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TcasTransAnnotator.xml0000644000175000017500000000405611665471070027037 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cpm.sofa.TcasTransAnnotator English to German translator Takes a TCAS as input and creates output GermanDocument SofA in de CAS 1.0 The Apache Software Foundation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/CpeSofaTest/TransAnnotator.xml0000644000175000017500000000430711665471070026223 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.examples.cpm.sofa.TransAnnotator English to German translator Takes a Text SofA as input and creates output SofA in de CAS 1.0 The Apache Software Foundation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation EnglishDocument GermanDocument uimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerImplTest/0000755000175000017500000000000011665471102025100 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerImplTest/ResourceTestAnnotator.xml0000644000175000017500000001066411665471102032146 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Resource Test Primitive TAE For testing the resource manager. 1.0 The Apache Software Foundation TestFileResource TestFileLanguageResource TestResourceObject org.apache.uima.resource.impl.TestResourceInterface TestLanguageResourceObject org.apache.uima.resource.impl.TestResourceInterface AdditionalResource org.apache.uima.resource.impl.TestResourceInterface true MyFileResource file:testDataFile.dat MyFileLanguageResource file:FileLanguageResource_implTest_data_ .dat MyResourceObject file:testDataFile.dat org.apache.uima.resource.impl.TestResourceInterface_impl MyLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl TestFileResource MyFileResource TestFileLanguageResource MyFileLanguageResource TestResourceObject MyResourceObject TestLanguageResourceObject MyLanguageResourceObject uimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerImplTest/ResourceTestAnnotator2.xml0000644000175000017500000001071511665471102032225 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Resource Test Primitive TAE For testing the resource manager. 1.0 The Apache Software Foundation TestFileResource TestFileLanguageResource TestResourceObject org.apache.uima.resource.impl.TestResourceInterface TestLanguageResourceObject org.apache.uima.resource.impl.TestResourceInterface AdditionalResource org.apache.uima.resource.impl.TestResourceInterface true MyFileResource file:testDataFile.dat MyFileLanguageResource This is a test file:FileLanguageResource_implTest_data_ .dat MyResourceObject file:testDataFile.dat org.apache.uima.resource.impl.TestResourceInterface_impl MyLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl TestFileResource MyFileResource TestFileLanguageResource MyFileLanguageResource TestResourceObject MyResourceObject TestLanguageResourceObject MyLanguageResourceObject uimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerImplTest/ResourceTestAggregate.xml0000644000175000017500000000541611665471102032066 0ustar drazzibdrazzib org.apache.uima.java false Resource Test Aggregate TAE For testing the resource manager. 1.0 The Apache Software Foundation Annotator1 Annotator2 MyFileResource file:testDataFile2.dat OverriddenLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl Annotator1/TestLanguageResourceObject OverriddenLanguageResourceObject uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/0000755000175000017500000000000011665471076023140 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerFixedExpected.txt0000644000175000017500000000044211665471076030275 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsZhCN.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsZhCN.tx0000644000175000017500000000035211665471076033612 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotationuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerFixedAggregate.xml0000644000175000017500000000664411665471076030415 0ustar drazzibdrazzib org.apache.uima.java false Sequencer Test aggregate TAE SequencerTest runs same primitive annotator two times. 1.0 The Apache Software Foundation Corporation annotator2 annotator1 uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation x-unspecified uima.tt.Lemma uima.tt.CompPartAnnotation cs da de en es fi fr it ja ko nb nl nn pl pt ru sv zh-CN zh-TW uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/Annotator2.xml0000644000175000017500000000522611665471076025716 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Test Annotator 2 uima.tt.Lemma uima.tt.CompPartAnnotation de en ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageAggregateResultSpec.xmluimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageAggregateResultSp0000644000175000017500000000473111665471076034001 0ustar drazzibdrazzib org.apache.uima.java false Sequencer Test aggregate TAE SequencerTest runs same primitive annotator two times. 1.0 The Apache Software Foundation Corporation annotator1 annotator2 uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation uima.tt.Lemma x-unspecified ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedJaResultSpec.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedJaResultS0000644000175000017500000000033411665471076033742 0ustar drazzibdrazzib ResultSpec for annotator Test Annotator 1: uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Test Annotator 3: uima.tcas.DocumentAnnotation:categoriesuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/FrostImitation.xml0000644000175000017500000000664511665471076026650 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Frost imitation uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation uima.tt.CompPartAnnotation uima.tt.Lemma cs da de en es fi fr it ja ko nb nl nn pl pt ru sv zh-CN zh-TW ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedResultSpecSetByFlowController.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedResultSpe0000644000175000017500000000027511665471076034020 0ustar drazzibdrazzib ResultSpec for annotator Whitespace tokenizer: uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Token Lemma annotator: uima.tt.Lemma././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsZhCNResultSpec.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsZhCNRes0000644000175000017500000000035211665471076033632 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotationuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/FrostImitationTypeSystem.xml0000644000175000017500000000477511665471076030721 0ustar drazzibdrazzib FrostImitationTypeSystem 1.0 uima.tt.TokenAnnotation uima.tt.TokenLikeAnnotation uima.tt.SentenceAnnotation uima.tcas.Annotation uima.tt.ParagraphAnnotation uima.tcas.Annotation uima.tt.Lemma uima.cas.TOP uima.tt.CompPartAnnotation uima.tcas.Annotation uima.tcas.DocumentAnnotation uima.tcas.Annotation categories uima.cas.StringArray uima.tt.TokenLikeAnnotation uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEn.txt0000644000175000017500000000044311665471076033247 0ustar drazzibdrazzib ResultSpec for annotator Test Annotator 1: uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Test Annotator 2: uima.tt.CompPartAnnotation uima.tt.Lemma ResultSpec for annotator Test Annotator 3: uima.tcas.DocumentAnnotation:categories././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedXunSpec.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedXunSpec.t0000644000175000017500000000031611665471076033715 0ustar drazzibdrazzib ResultSpec for annotator Test Annotator 1: uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Test Annotator 3: uima.tcas.DocumentAnnotation:categoriesuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/Annotator3.xml0000644000175000017500000000513711665471076025720 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Test Annotator 3 uima.tcas.DocumentAnnotation:categories x-unspecified uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageAggregateES.xml0000644000175000017500000000676311665471076033335 0ustar drazzibdrazzib org.apache.uima.java false Sequencer Test aggregate TAE SequencerTest runs same primitive annotator two times. 1.0 The Apache Software Foundation Corporation annotator2 annotator1 uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation uima.tt.DummyAnnotation x-unspecified uima.tt.Lemma uima.tt.CompPartAnnotation cs da de en es fi fr it ja ko nb nl nn pl pt ru sv zh-CN zh-TW ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsEnResultSpec.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsEnResul0000644000175000017500000000035211665471076033733 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotationuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsAr.txt0000644000175000017500000000022711665471076033537 0ustar drazzibdrazzib ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotation uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsEnUS.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsEnUS.tx0000644000175000017500000000035211665471076033622 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotationuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/TokenLemmaAnnotator.xml0000644000175000017500000000504611665471076027611 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Token Lemma annotator uima.tt.TokenAnnotation uima.tt.Lemma x-unspecified uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/WhitespaceTokenizer.xml0000644000175000017500000000566111665471076027661 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Whitespace tokenizer uima.tt.DummyAnnotation uima.tcas.Annotation uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation uima.tt.DummyAnnotation x-unspecified true true false ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEnResultSpec.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEnResultS0000644000175000017500000000044311665471076033753 0ustar drazzibdrazzib ResultSpec for annotator Test Annotator 1: uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Test Annotator 2: uima.tt.CompPartAnnotation uima.tt.Lemma ResultSpec for annotator Test Annotator 3: uima.tcas.DocumentAnnotation:categoriesuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/Annotator1.xml0000644000175000017500000000567611665471076025726 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.sequencer.SequencerTestAnnotator SequencerTestAnnotator The simplest possible annotator. 1.0 The Apache Software Foundation Corporation AnnotatorName name of the annotator String false false AnnotatorName Test Annotator 1 uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation x-unspecified uima.tt.Lemma ja uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsEn.txt0000644000175000017500000000035211665471076033536 0ustar drazzibdrazzib ResultSpec for annotator Frost imitation: uima.tt.CompPartAnnotation uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotation././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txtuimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown0000644000175000017500000000022711665471076034016 0ustar drazzibdrazzib ResultSpec for annotator Whitespace tokenizer: uima.tt.DummyAnnotation uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageAggregate.xml0000644000175000017500000000603011665471076033070 0ustar drazzibdrazzib org.apache.uima.java false Sequencer Test aggregate TAE SequencerTest runs same primitive annotator two times. 1.0 The Apache Software Foundation Corporation annotator1 annotator2 annotator3 uima.tt.TokenAnnotation uima.tt.SentenceAnnotation uima.tt.ParagraphAnnotation uima.tcas.DocumentAnnotation:categories x-unspecified uima.tt.Lemma uima.tt.CompPartAnnotation en de ja uimaj-2.4.0/uimaj-core/src/test/resources/SequencerTest/SequencerCapabilityLanguageExpectedJa.txt0000644000175000017500000000033411665471076033236 0ustar drazzibdrazzib ResultSpec for annotator Test Annotator 1: uima.tt.Lemma uima.tt.ParagraphAnnotation uima.tt.SentenceAnnotation uima.tt.TokenAnnotation ResultSpec for annotator Test Annotator 3: uima.tcas.DocumentAnnotation:categoriesuimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/0000755000175000017500000000000011665471100025370 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/FsIndexCollectionImportedByLocation.xmluimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/FsIndexCollectionImportedByLocat0000644000175000017500000000313411665471100033652 0ustar drazzibdrazzib FsIndexCollectionImportedByLocation This is for testing the import mechanism. 0.1 The Apache Software Foundation uima.tcas.Annotation sorted end standard begin reverse uimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/dataPathDir/0000755000175000017500000000000011665471076027571 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/dataPathDir/FsIndexCollectionImportedFromDataPath.xmluimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/dataPathDir/FsIndexCollectionImp0000644000175000017500000000275111665471076033543 0ustar drazzibdrazzib FsIndexCollectionImportedFromDataPath This is for testing the import mechanism. 0.1 The Apache Software Foundation TestType1 sorted Foo standard uimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/Circular2.xml0000644000175000017500000000263211665471100027743 0ustar drazzibdrazzib Circular2 For testing circular imports. 0.1 The Apache Software Foundation org.apache.nimd.Entity bag uimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/Circular1.xml0000644000175000017500000000263611665471100027746 0ustar drazzibdrazzib Circular1 For testing circular imports. 0.1 The Apache Software Foundation org.apache.nimd.Referent bag uimaj-2.4.0/uimaj-core/src/test/resources/FsIndexCollectionImplTest/TestFsIndexCollection.xml0000644000175000017500000000354211665471100032332 0ustar drazzibdrazzib TestFsIndexCollection This is a test. 0.1 The Apache Software Foundation NamedEntity bag DocumentStructure set begin standard end reverse uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/0000755000175000017500000000000011665471106026354 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/TestTypeSystem.xml0000644000175000017500000000641011665471106032065 0ustar drazzibdrazzib TestTypeSystem This is a test. 0.1 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure sentences Direct references to sentences in this paragraph uima.cas.FSArray Sentence false testMultiRefAllowedFeature A test feature that allows multiple references. uima.cas.FSArray true Sentence A sentence. DocumentStructure uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/dataPathDir/0000755000175000017500000000000011665471106030541 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/dataPathDir/TypeSystemImportedFromDataPath.xmluimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/dataPathDir/TypeSystemImport0000644000175000017500000000347411665471106034015 0ustar drazzibdrazzib TypeSystemImportedFromDataPath This is for testing the import mechanism. 0.1 The Apache Software Foundation TestType4 This is a test. uima.tcas.DocumentAnnotation Bar uima.cas.String TestType3 uima.cas.TOP Foo uima.cas.Integer uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/Circular2.xml0000644000175000017500000000261711665471106030732 0ustar drazzibdrazzib Circular2 For testing circular imports. 0.1 The Apache Software Foundation Bar uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/InvalidTypeSystem1.xml0000644000175000017500000000656311665471106032626 0ustar drazzibdrazzib Invalid Type System 1 Tests error checking for type system descriptors. 0.1 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity one Test value one. two Test value two. Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure sentences Direct references to sentences in this paragraph uima.cas.FSArray Sentence false testMultiRefAllowedFeature A test feature that allows multiple references. uima.cas.FSArray true Sentence A sentence. DocumentStructure uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/TaeImportingTypeSystem.xml0000644000175000017500000000433711665471106033556 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator TAE that imports a type system For testing only. 1.0 The Apache Software Foundation Paragraph Sentence DocumentStructure begin standard DocumentStructure NamedEntity en ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/TypeSystemImportedByLocation.xmluimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/TypeSystemImportedByLocation0000644000175000017500000000345611665471106034125 0ustar drazzibdrazzib TypeSystemImportedByName This is for testing the import mechanism. 0.1 The Apache Software Foundation TestType1 This is a test. uima.tcas.Annotation Foo uima.cas.String TestType3 uima.cas.TOP Foo uima.cas.Integer uimaj-2.4.0/uimaj-core/src/test/resources/TypeSystemDescriptionImplTest/Circular1.xml0000644000175000017500000000262011665471106030723 0ustar drazzibdrazzib Circular1 For testing circular imports. 0.1 The Apache Software Foundation Foo uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/0000755000175000017500000000000011665471072022364 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/v1cas.xml0000644000175000017500000142773011665471070024137 0ustar drazzibdrazzib IBM Announces Recipients Of Internet Research Grants Resources Will Help Universities Explore Internet2 Applications Waltham, Mass., January 15, 1998 -- As part of its $3.5 million commitment to support the development of Internet2, IBM has announced the names of seven higher education institutions that will receive resources through the company's sponsored research program. These resources will facilitate development of Internet2 applications and participation in the Internet2 project. The grant recipients are Clemson University in South Carolina, Duke University in North Carolina, Indiana University, Northwestern University in Illinois, the University of Chicago, the University of Michigan, and the University of South Carolina. Donated resources will be in the form of hardware, software, switches and other pieces of network infrastructure critical to Internet2 applications, connections, and operation. In addition, grant recipients have access to the technological expertise of IBM personnel. Many of the grant recipients will use the donations to create networked consortiums with other higher educational institutions in their areas. Grant resources will be used to enhance specific advanced technology applications -- ranging from telemedicine to the maintenance of a digital Movietone newsreel archive. Irving Wladawsky-Berger, general manager of IBM's Internet Division, emphasized the company's commitment to the new Internet. He said, The Internet has succeeded beyond our wildest imagination. More and more people are getting connected around the world, as the Internet is being embraced across the research community, educational institutions, businesses of all sizes, and society at large. The Internet2 efforts will take us all to the next levels, with significant improvements in bandwidth and quality of service. Most important, the Internet2 efforts will make possible all kinds of new, exciting applications. IBM is very proud to continue its associations and contributions to the Internet. Sean C. Rush, general manager of IBM Global Education, agrees. He said, Internet2 is being developed with the needs of higher education inmind. Internet2 capabilities include high speed, dependability, and networking power. For example, data base analysis that took hours or days will take minutes. Researchers worldwide will be able to share large amounts of data without interruptions or slow downs. And finally, Internet2 will serve as an important repository for a wealth of materials, and researchers will now have high quality, high speed access to books, art work, films, and music. Don Haile, vice president of IBM's Networking Hardware Development, has worked closely with several Internet2 universities over the past year. The recent revolutions in networking technology, including the advent of ATM, switched LANs and route-switching, are allowing today's university faculty to consider network-based applications that they previously only dreamed about, said Don. Professors can transmit voice and video in real time over a network, enriching research collaborations and distance learning classroom experiences. By providing high speed communication links, Internet2 is supporting research that will benefit students and local communities, across the country. Internet2 Since its recent inception, Internet2 has grown from 34 to over 100 research universities. With Internet2, network applications are better served by new network points-of-presence (PoPs) capable of transmitting gigabits (billions of bits) of information per second. Internet2 participants broaden their research and development expenditures to help create these GigaPoPs. Member universities, working with private member companies and non-profit organizations are developing tools for scientific research and higher education in the 21st century. The Internet2 homepage is located at http://www.internet2.edu/ IBM Global Education Industry The Global Education Industry is a unit of IBM, the largest information technology company. The Global Education Industry provides targeted products, consulting, and services to K-12 education and institutions of higher education throughout North America, Latin America, Europe and Asia. IBM's Higher Education homepage is located at http://www.hied.ibm.com IBM Internet Division IBM is a leader in the development of the Internet and is dedicated to helping customers and developers exploit the potential of network computing, drawing on the resources of over 24 information technology products and services, including computer systems, software, networking systems, storage devices and microelectronics. Developers and customers can find out more about IBM's many initiatives relating to Internet technologies, products and services on the Web at http://www.internet.ibm.com IBM Networking Hardware Division IBM's Networking Hardware Division (NHD) develops and manufactures industry-leading networking technologies and products, providing global end-to-end solutions for Token-Ring, Ethernet, Gigabit Ethernet, ATM, IP and SNA networks. IBM NHD also provides consulting, education, service and support worldwide to help customers achieve their business objectives. For additional information on IBM's networking solutions, visit our Web site at www.networking.ibm.com or call 800-IBM-3333 or outside the U.S. 770-644-5997. # # # The following term is a trademark of the IBM Corporation in the United States or other countries or both: IBM org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.College 100002 100003 100004 uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/testTypeSystem_withMultiRefs.xml0000644000175000017500000005331011665471070031022 0ustar drazzibdrazzib org.apache.uima.testTypeSystem.EntityAnnotation uima.tcas.Annotation links uima.cas.FSList org.apache.uima.testTypeSystem.Link true componentId uima.cas.String mentionType uima.cas.String org.apache.uima.testTypeSystem.RelationAnnotation uima.tcas.Annotation links uima.cas.FSList org.apache.uima.testTypeSystem.Link true componentId uima.cas.String predicate uima.tcas.Annotation relationArgs org.apache.uima.testTypeSystem.RelationArgs org.apache.uima.testTypeSystem.RelationArgs uima.cas.TOP org.apache.uima.testTypeSystem.BinaryRelationArgs org.apache.uima.testTypeSystem.RelationArgs domainValue uima.tcas.Annotation rangeValue uima.tcas.Annotation org.apache.uima.testTypeSystem.GenericRelationArgs org.apache.uima.testTypeSystem.RelationArgs args uima.cas.FSList true org.apache.uima.testTypeSystem.Referent uima.cas.TOP links uima.cas.FSList org.apache.uima.testTypeSystem.Link true componentId uima.cas.String classes uima.cas.StringArray true canonicalForm uima.cas.String variantForms uima.cas.StringList true id uima.cas.String org.apache.uima.testTypeSystem.Entity org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Relation org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Link uima.cas.TOP componentId uima.cas.String from uima.cas.TOP to uima.cas.TOP org.apache.uima.testTypeSystem.HasOccurrence org.apache.uima.testTypeSystem.Link org.apache.uima.testTypeSystem.Argument org.apache.uima.testTypeSystem.Link role uima.cas.String org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.EntityAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.RegionInternational org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.EducationalOrganization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.EducationalOrganization org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TopEntity tid uima.cas.String value uima.cas.String functionInDocument uima.cas.String temporalFunction uima.cas.String anchorTimeId uima.cas.String org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Time org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Year org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.RelationAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.LexicalAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Thing org.apache.uima.testTypeSystem.LexicalAnnotation org.apache.uima.testTypeSystem.CharacteristicAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Occupation org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.NondefiningRole org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.Method org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.Symptom org.apache.uima.testTypeSystem.CharacteristicAnnotation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation org.apache.uima.testTypeSystem.AnnotationArrayTest uima.tcas.Annotation arrayOfAnnotations uima.cas.FSArray uima.tcas.Annotation true uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/cas.xml0000644000175000017500000144017011665471070023661 0ustar drazzibdrazzib org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.College 100002 100003 100004 uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/v1MultiSofaCas.xml0000644000175000017500000000554711665471070025720 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/v1xmiCas.xml0000644000175000017500000067712211665471070024616 0ustar drazzibdrazzib IBM Announces Recipients Of Internet Research Grants Resources Will Help Universities Explore Internet2 Applications Waltham, Mass., January 15, 1998 -- As part of its $3.5 million commitment to support the development of Internet2, IBM has announced the names of seven higher education institutions that will receive resources through the company's sponsored research program. These resources will facilitate development of Internet2 applications and participation in the Internet2 project. The grant recipients are Clemson University in South Carolina, Duke University in North Carolina, Indiana University, Northwestern University in Illinois, the University of Chicago, the University of Michigan, and the University of South Carolina. Donated resources will be in the form of hardware, software, switches and other pieces of network infrastructure critical to Internet2 applications, connections, and operation. In addition, grant recipients have access to the technological expertise of IBM personnel. Many of the grant recipients will use the donations to create networked consortiums with other higher educational institutions in their areas. Grant resources will be used to enhance specific advanced technology applications -- ranging from telemedicine to the maintenance of a digital Movietone newsreel archive. Irving Wladawsky-Berger, general manager of IBM's Internet Division, emphasized the company's commitment to the new Internet. He said, The Internet has succeeded beyond our wildest imagination. More and more people are getting connected around the world, as the Internet is being embraced across the research community, educational institutions, businesses of all sizes, and society at large. The Internet2 efforts will take us all to the next levels, with significant improvements in bandwidth and quality of service. Most important, the Internet2 efforts will make possible all kinds of new, exciting applications. IBM is very proud to continue its associations and contributions to the Internet. Sean C. Rush, general manager of IBM Global Education, agrees. He said, Internet2 is being developed with the needs of higher education inmind. Internet2 capabilities include high speed, dependability, and networking power. For example, data base analysis that took hours or days will take minutes. Researchers worldwide will be able to share large amounts of data without interruptions or slow downs. And finally, Internet2 will serve as an important repository for a wealth of materials, and researchers will now have high quality, high speed access to books, art work, films, and music. Don Haile, vice president of IBM's Networking Hardware Development, has worked closely with several Internet2 universities over the past year. The recent revolutions in networking technology, including the advent of ATM, switched LANs and route-switching, are allowing today's university faculty to consider network-based applications that they previously only dreamed about, said Don. Professors can transmit voice and video in real time over a network, enriching research collaborations and distance learning classroom experiences. By providing high speed communication links, Internet2 is supporting research that will benefit students and local communities, across the country. Internet2 Since its recent inception, Internet2 has grown from 34 to over 100 research universities. With Internet2, network applications are better served by new network points-of-presence (PoPs) capable of transmitting gigabits (billions of bits) of information per second. Internet2 participants broaden their research and development expenditures to help create these GigaPoPs. Member universities, working with private member companies and non-profit organizations are developing tools for scientific research and higher education in the 21st century. The Internet2 homepage is located at http://www.internet2.edu/ IBM Global Education Industry The Global Education Industry is a unit of IBM, the largest information technology company. The Global Education Industry provides targeted products, consulting, and services to K-12 education and institutions of higher education throughout North America, Latin America, Europe and Asia. IBM's Higher Education homepage is located at http://www.hied.ibm.com IBM Internet Division IBM is a leader in the development of the Internet and is dedicated to helping customers and developers exploit the potential of network computing, drawing on the resources of over 24 information technology products and services, including computer systems, software, networking systems, storage devices and microelectronics. Developers and customers can find out more about IBM's many initiatives relating to Internet technologies, products and services on the Web at http://www.internet.ibm.com IBM Networking Hardware Division IBM's Networking Hardware Division (NHD) develops and manufactures industry-leading networking technologies and products, providing global end-to-end solutions for Token-Ring, Ethernet, Gigabit Ethernet, ATM, IP and SNA networks. IBM NHD also provides consulting, education, service and support worldwide to help customers achieve their business objectives. For additional information on IBM's networking solutions, visit our Web site at www.networking.ibm.com or call 800-IBM-3333 or outside the U.S. 770-644-5997. # # # The following term is a trademark of the IBM Corporation in the United States or other countries or both: IBM org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.HoldsDuring uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/testTypeSystem.xml0000644000175000017500000005200211665471070026131 0ustar drazzibdrazzib org.apache.uima.testTypeSystem.EntityAnnotation uima.tcas.Annotation links uima.cas.FSList componentId uima.cas.String mentionType uima.cas.String org.apache.uima.testTypeSystem.RelationAnnotation uima.tcas.Annotation links uima.cas.FSList componentId uima.cas.String predicate uima.tcas.Annotation relationArgs org.apache.uima.testTypeSystem.RelationArgs org.apache.uima.testTypeSystem.RelationArgs uima.cas.TOP org.apache.uima.testTypeSystem.BinaryRelationArgs org.apache.uima.testTypeSystem.RelationArgs domainValue uima.tcas.Annotation rangeValue uima.tcas.Annotation org.apache.uima.testTypeSystem.GenericRelationArgs org.apache.uima.testTypeSystem.RelationArgs args uima.cas.FSList org.apache.uima.testTypeSystem.Referent uima.cas.TOP links uima.cas.FSList componentId uima.cas.String classes uima.cas.StringArray canonicalForm uima.cas.String variantForms uima.cas.StringList id uima.cas.String org.apache.uima.testTypeSystem.Entity org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Relation org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Link uima.cas.TOP componentId uima.cas.String from uima.cas.TOP to uima.cas.TOP org.apache.uima.testTypeSystem.HasOccurrence org.apache.uima.testTypeSystem.Link org.apache.uima.testTypeSystem.Argument org.apache.uima.testTypeSystem.Link role uima.cas.String org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.EntityAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.RegionInternational org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.EducationalOrganization org.apache.uima.testTypeSystem.Organization org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.EducationalOrganization org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TopEntity tid uima.cas.String value uima.cas.String functionInDocument uima.cas.String temporalFunction uima.cas.String anchorTimeId uima.cas.String org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Time org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Year org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.RelationAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.LexicalAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Thing org.apache.uima.testTypeSystem.LexicalAnnotation org.apache.uima.testTypeSystem.CharacteristicAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Occupation org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.NondefiningRole org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.Method org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.Symptom org.apache.uima.testTypeSystem.CharacteristicAnnotation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation org.apache.uima.testTypeSystem.AnnotationArrayTest uima.tcas.Annotation arrayOfAnnotations uima.cas.FSArray uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/multiSofaCas.xml0000644000175000017500000000630111665471070025476 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/simpleCas.xmi0000644000175000017500000002116111665471070025022 0ustar drazzibdrazzib 2685 2694 ACE 0.0 NAME org.apache.uima.testTypeSystem.College org.apache.uima.testTypeSystem.Organization USC U of SC uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/xmiMsCasV1.xml0000644000175000017500000000555311665471070025047 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/partialTestTypeSystem.xml0000644000175000017500000005107211665471070027454 0ustar drazzibdrazzib org.apache.uima.testTypeSystem.EntityAnnotation uima.tcas.Annotation links uima.cas.FSList componentId uima.cas.String org.apache.uima.testTypeSystem.RelationAnnotation uima.tcas.Annotation links uima.cas.FSList componentId uima.cas.String predicate uima.tcas.Annotation org.apache.uima.testTypeSystem.RelationArgs uima.cas.TOP org.apache.uima.testTypeSystem.BinaryRelationArgs org.apache.uima.testTypeSystem.RelationArgs domainValue uima.tcas.Annotation rangeValue uima.tcas.Annotation org.apache.uima.testTypeSystem.GenericRelationArgs org.apache.uima.testTypeSystem.RelationArgs args uima.cas.FSList org.apache.uima.testTypeSystem.Referent uima.cas.TOP links uima.cas.FSList componentId uima.cas.String canonicalForm uima.cas.String id uima.cas.String org.apache.uima.testTypeSystem.Entity org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Relation org.apache.uima.testTypeSystem.Referent org.apache.uima.testTypeSystem.Link uima.cas.TOP componentId uima.cas.String from uima.cas.TOP to uima.cas.TOP org.apache.uima.testTypeSystem.HasOccurrence org.apache.uima.testTypeSystem.Link org.apache.uima.testTypeSystem.Argument org.apache.uima.testTypeSystem.Link role uima.cas.String org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.EntityAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Person org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.RegionInternational org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.Facility org.apache.uima.testTypeSystem.Location org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.GeographicEntity org.apache.uima.testTypeSystem.Continent org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Nation org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.UsState org.apache.uima.testTypeSystem.NationalAdministrativeDivision org.apache.uima.testTypeSystem.City org.apache.uima.testTypeSystem.GPE org.apache.uima.testTypeSystem.Weapon org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TopEntity tid uima.cas.String value uima.cas.String functionInDocument uima.cas.String temporalFunction uima.cas.String anchorTimeId uima.cas.String org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.HistoricalDuration org.apache.uima.testTypeSystem.Duration org.apache.uima.testTypeSystem.Time org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Timex org.apache.uima.testTypeSystem.TimeOfYear org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Year org.apache.uima.testTypeSystem.Date org.apache.uima.testTypeSystem.Clothing org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Number org.apache.uima.testTypeSystem.SmallWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.LargeWholeNumber org.apache.uima.testTypeSystem.WholeNumber org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Money org.apache.uima.testTypeSystem.Measurement org.apache.uima.testTypeSystem.BodyPart org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.PhoneNumber org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.Tool org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.MiscellaneousEntity org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.URL org.apache.uima.testTypeSystem.TopEntity org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.RelationAnnotation confidence uima.cas.Float org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.Physical org.apache.uima.testTypeSystem.SubPlace org.apache.uima.testTypeSystem.PartOf org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.ManagerOf org.apache.uima.testTypeSystem.Staff org.apache.uima.testTypeSystem.Subsidiary org.apache.uima.testTypeSystem.OrganizationalRelationship org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.Owner org.apache.uima.testTypeSystem.AgentArtifact org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.BasedIn org.apache.uima.testTypeSystem.GpeAffiliation org.apache.uima.testTypeSystem.HoldsDuring org.apache.uima.testTypeSystem.TopRelation org.apache.uima.testTypeSystem.LexicalAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Thing org.apache.uima.testTypeSystem.LexicalAnnotation org.apache.uima.testTypeSystem.CharacteristicAnnotation uima.tcas.Annotation componentId uima.cas.String confidence uima.cas.Float org.apache.uima.testTypeSystem.Occupation org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.NondefiningRole org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.CharacteristicAnnotation org.apache.uima.testTypeSystem.Method org.apache.uima.testTypeSystem.EventCharacteristic org.apache.uima.testTypeSystem.Symptom org.apache.uima.testTypeSystem.CharacteristicAnnotation sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/testIndexes.xml0000644000175000017500000000257011665471072025411 0ustar drazzibdrazzib org.apache.uima.testTypeSystem.Entity bag org.apache.uima.testTypeSystem.Relation bag uimaj-2.4.0/uimaj-core/src/test/resources/ExampleCas/newprimitives.xcas0000644000175000017500000000671411665471070026157 0ustar drazzibdrazzib 1.7976931348623157E308 4.9E-324 1.5555 99.000000005 4.444444444444445 9223372036854775807 9223372036854775806 9223372036854775805 9223372036854775804 9223372036854775803 32767 32766 32765 32764 32763 8 16 64 -128 -1 true false true false true false true false true false true false true false true false true false true false zzzzzz yyyyyy xxxxxx wwwwww vvvvvv 3.4028235E38 3.4028234E35 42.0 1.401E-42 1.4E-45 2147483647 2147483646 42 -2147483647 -2147483648 uimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/0000755000175000017500000000000011665471076027642 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/ResourceManagerConfigurationWithImports.xmluimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/ResourceManagerConfig0000644000175000017500000000261311665471076033777 0ustar drazzibdrazzib SSindexGenerator JURU_XML_IndexGenerator ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TaeImportingResourceManagerConfigurationOldStyle.xmluimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TaeImportingResourceM0000644000175000017500000000721011665471076034014 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator TAE Importing Resource Manager Configuration For testing only. 1.0 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure Sentence A sentence. DocumentStructure Paragraph Sentence DocumentStructure begin standard DocumentStructure NamedEntity en ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TaeImportingResourceManagerConfiguration.xmluimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TaeImportingResourceM0000644000175000017500000000724011665471076034017 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator TAE Importing Resource Manager Configuration For testing only. 1.0 The Apache Software Foundation NamedEntity Anything that has a name. uima.tcas.Annotation CanonicalName Canonical name for this entity. uima.cas.String Person A person. NamedEntity Place A place. NamedEntity SubType Kind of place. uima.cas.String DocumentStructure Identifies document structure, such as sentence or paragraph. uima.tcas.Annotation Paragraph A paragraph. DocumentStructure Sentence A sentence. DocumentStructure Paragraph Sentence DocumentStructure begin standard DocumentStructure NamedEntity en ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TestResourceManagerConfiguration.xmluimaj-2.4.0/uimaj-core/src/test/resources/ResourceManagerConfigurationImplTest/TestResourceManagerCo0000644000175000017500000000573611665471076034004 0ustar drazzibdrazzib Test Resource Manager Configuration This is a test. This is only a test. The Apache Software Foundation 0.1 MyFileResource file:testDataFile.dat MyFileLanguageResource file:FileLanguageResource_implTest_data_ .dat MyResourceObject file:testDataFile.dat org.apache.uima.resource.impl.TestResourceInterface_impl MyLanguageResourceObject file:FileLanguageResource_implTest_data_ .dat org.apache.uima.resource.impl.TestResourceInterface_impl _CollectionReader/TestFileResource MyFileResource _CasInitializer/TestFileLanguageResource MyFileLanguageResource TestTae/TestResourceObject MyResourceObject TestTae/TestLanguageResourceObject MyLanguageResourceObject uimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/0000755000175000017500000000000011665471076023302 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/TS.xml0000644000175000017500000000305211665471076024352 0ustar drazzibdrazzib Test Type System 3 This is for testing the import mechanism. 0.1 The Apache Software Foundation TestType4 This is yet another test. uima.tcas.Annotation Bar uima.cas.String uimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/subdir/0000755000175000017500000000000011665471076024572 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/subdir/subdir2/0000755000175000017500000000000011665471076026144 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/subdir/subdir2/AggregateTaeForNestedImportTest.xmluimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/subdir/subdir2/AggregateTaeForNestedImportT0000644000175000017500000000341711665471076033545 0ustar drazzibdrazzib org.apache.uima.java false Aggregate TAE for Nested Import Test For testing nested imports. 1.0 The Apache Software Foundation Annotator1 uimaj-2.4.0/uimaj-core/src/test/resources/ImportImplTest/subdir/PrimitiveTaeForNestedImportTest.xml0000644000175000017500000000324711665471076033571 0ustar drazzibdrazzib org.apache.uima.java true org.apache.uima.analysis_engine.impl.TestAnnotator Primitive TAE For Nested Import Test For testing only. 1.0 The Apache Software Foundation en uimaj-2.4.0/uimaj-core/src/test/resources/ClassLoaderTest/0000755000175000017500000000000011665471076023402 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/resources/ClassLoaderTest/classLoadingTest.jar0000644000175000017500000000122311665471076027341 0ustar drazzibdrazzibPKP5META-INF/MANIFEST.MFMLK-. K-*ϳR03PKPK}59org/apache/uima/internal/util/ClassloadingTestClass.class=O@ _7iCІ8$R )ҫ\?F&ۏzϯ !\e.ZPҰUZL5W.xL>m9OWa1]ֵ$=wtNB0`v.zQ|ש,gj7?NKoӷKU."OE]fN5T5Y܃_[Qž'78|EⰃv>#Gя1veV PK>5CPKP5META-INF/MANIFEST.MFPK}5>5C9aorg/apache/uima/internal/util/ClassloadingTestClass.classPKuimaj-2.4.0/uimaj-core/src/test/java/0000755000175000017500000000000011665471070017247 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/aa/0000755000175000017500000000000011665471052017630 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/aa/Root.java0000644000175000017500000003430311665471052021421 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.FSArray; import org.apache.uima.jcas.cas.FloatArray; import org.apache.uima.jcas.cas.IntegerArray; import org.apache.uima.jcas.cas.StringArray; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 XML source: * C:/a/Eclipse/3.1/j4/jedii_jcas_tests/testTypes.xml * * @generated */ public class Root extends TOP { /** * @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(Root.class); /** * @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() { return typeIndexID; } /** * Never called. Disable default constructor * * @generated */ protected Root() { } /** * Internal - constructor used by generator * * @generated */ public Root(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public Root(JCas jcas) { super(jcas); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *--------------* // * Feature: arrayInt /** * getter for arrayInt - gets * * @generated */ public IntegerArray getArrayInt() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayInt == null) this.jcasType.jcas.throwFeatMissing("arrayInt", "aa.Root"); return (IntegerArray) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt))); } /** * setter for arrayInt - sets * * @generated */ public void setArrayInt(IntegerArray v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayInt == null) this.jcasType.jcas.throwFeatMissing("arrayInt", "aa.Root"); jcasType.ll_cas.ll_setRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt, jcasType.ll_cas.ll_getFSRef(v)); } /** * indexed getter for arrayInt - gets an indexed value - * * @generated */ public int getArrayInt(int i) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayInt == null) this.jcasType.jcas.throwFeatMissing("arrayInt", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt), i); return jcasType.ll_cas.ll_getIntArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt), i); } /** * indexed setter for arrayInt - sets an indexed value - * * @generated */ public void setArrayInt(int i, int v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayInt == null) this.jcasType.jcas.throwFeatMissing("arrayInt", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt), i); jcasType.ll_cas.ll_setIntArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayInt), i, v); } // *--------------* // * Feature: arrayRef /** * getter for arrayRef - gets * * @generated */ public FSArray getArrayRef() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayRef == null) this.jcasType.jcas.throwFeatMissing("arrayRef", "aa.Root"); return (FSArray) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef))); } /** * setter for arrayRef - sets * * @generated */ public void setArrayRef(FSArray v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayRef == null) this.jcasType.jcas.throwFeatMissing("arrayRef", "aa.Root"); jcasType.ll_cas.ll_setRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef, jcasType.ll_cas.ll_getFSRef(v)); } /** * indexed getter for arrayRef - gets an indexed value - * * @generated */ public TOP getArrayRef(int i) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayRef == null) this.jcasType.jcas.throwFeatMissing("arrayRef", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef), i); return (TOP) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefArrayValue( jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef), i))); } /** * indexed setter for arrayRef - sets an indexed value - * * @generated */ public void setArrayRef(int i, TOP v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayRef == null) this.jcasType.jcas.throwFeatMissing("arrayRef", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef), i); jcasType.ll_cas.ll_setRefArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayRef), i, jcasType.ll_cas.ll_getFSRef(v)); } // *--------------* // * Feature: arrayFloat /** * getter for arrayFloat - gets * * @generated */ public FloatArray getArrayFloat() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayFloat == null) this.jcasType.jcas.throwFeatMissing("arrayFloat", "aa.Root"); return (FloatArray) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat))); } /** * setter for arrayFloat - sets * * @generated */ public void setArrayFloat(FloatArray v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayFloat == null) this.jcasType.jcas.throwFeatMissing("arrayFloat", "aa.Root"); jcasType.ll_cas.ll_setRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat, jcasType.ll_cas.ll_getFSRef(v)); } /** * indexed getter for arrayFloat - gets an indexed value - * * @generated */ public float getArrayFloat(int i) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayFloat == null) this.jcasType.jcas.throwFeatMissing("arrayFloat", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat), i); return jcasType.ll_cas.ll_getFloatArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat), i); } /** * indexed setter for arrayFloat - sets an indexed value - * * @generated */ public void setArrayFloat(int i, float v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayFloat == null) this.jcasType.jcas.throwFeatMissing("arrayFloat", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat), i); jcasType.ll_cas.ll_setFloatArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayFloat), i, v); } // *--------------* // * Feature: arrayString /** * getter for arrayString - gets * * @generated */ public StringArray getArrayString() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayString == null) this.jcasType.jcas.throwFeatMissing("arrayString", "aa.Root"); return (StringArray) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString))); } /** * setter for arrayString - sets * * @generated */ public void setArrayString(StringArray v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayString == null) this.jcasType.jcas.throwFeatMissing("arrayString", "aa.Root"); jcasType.ll_cas.ll_setRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString, jcasType.ll_cas.ll_getFSRef(v)); } /** * indexed getter for arrayString - gets an indexed value - * * @generated */ public String getArrayString(int i) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayString == null) this.jcasType.jcas.throwFeatMissing("arrayString", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString), i); return jcasType.ll_cas.ll_getStringArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString), i); } /** * indexed setter for arrayString - sets an indexed value - * * @generated */ public void setArrayString(int i, String v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_arrayString == null) this.jcasType.jcas.throwFeatMissing("arrayString", "aa.Root"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString), i); jcasType.ll_cas.ll_setStringArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_arrayString), i, v); } // *--------------* // * Feature: plainInt /** * getter for plainInt - gets * * @generated */ public int getPlainInt() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainInt == null) this.jcasType.jcas.throwFeatMissing("plainInt", "aa.Root"); return jcasType.ll_cas.ll_getIntValue(addr, ((Root_Type) jcasType).casFeatCode_plainInt); } /** * setter for plainInt - sets * * @generated */ public void setPlainInt(int v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainInt == null) this.jcasType.jcas.throwFeatMissing("plainInt", "aa.Root"); jcasType.ll_cas.ll_setIntValue(addr, ((Root_Type) jcasType).casFeatCode_plainInt, v); } // *--------------* // * Feature: plainFloat /** * getter for plainFloat - gets * * @generated */ public float getPlainFloat() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainFloat == null) this.jcasType.jcas.throwFeatMissing("plainFloat", "aa.Root"); return jcasType.ll_cas.ll_getFloatValue(addr, ((Root_Type) jcasType).casFeatCode_plainFloat); } /** * setter for plainFloat - sets * * @generated */ public void setPlainFloat(float v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainFloat == null) this.jcasType.jcas.throwFeatMissing("plainFloat", "aa.Root"); jcasType.ll_cas.ll_setFloatValue(addr, ((Root_Type) jcasType).casFeatCode_plainFloat, v); } // *--------------* // * Feature: plainString /** * getter for plainString - gets * * @generated */ public String getPlainString() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainString == null) this.jcasType.jcas.throwFeatMissing("plainString", "aa.Root"); return jcasType.ll_cas.ll_getStringValue(addr, ((Root_Type) jcasType).casFeatCode_plainString); } /** * setter for plainString - sets * * @generated */ public void setPlainString(String v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainString == null) this.jcasType.jcas.throwFeatMissing("plainString", "aa.Root"); jcasType.ll_cas.ll_setStringValue(addr, ((Root_Type) jcasType).casFeatCode_plainString, v); } // *--------------* // * Feature: plainRef /** * getter for plainRef - gets * * @generated */ public Root getPlainRef() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainRef == null) this.jcasType.jcas.throwFeatMissing("plainRef", "aa.Root"); return (Root) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Root_Type) jcasType).casFeatCode_plainRef))); } /** * setter for plainRef - sets * * @generated */ public void setPlainRef(Root v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_plainRef == null) this.jcasType.jcas.throwFeatMissing("plainRef", "aa.Root"); jcasType.ll_cas.ll_setRefValue(addr, ((Root_Type) jcasType).casFeatCode_plainRef, jcasType.ll_cas.ll_getFSRef(v)); } // *--------------* // * Feature: concreteString /** * getter for concreteString - gets * * @generated */ public String getConcreteString() { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_concreteString == null) this.jcasType.jcas.throwFeatMissing("concreteString", "aa.Root"); return jcasType.ll_cas.ll_getStringValue(addr, ((Root_Type) jcasType).casFeatCode_concreteString); } /** * setter for concreteString - sets * * @generated */ public void setConcreteString(String v) { if (Root_Type.featOkTst && ((Root_Type) jcasType).casFeat_concreteString == null) this.jcasType.jcas.throwFeatMissing("concreteString", "aa.Root"); jcasType.ll_cas.ll_setStringValue(addr, ((Root_Type) jcasType).casFeatCode_concreteString, v); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/AbstractType.java0000644000175000017500000000557011665471052023107 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 XML source: * C:/a/Eclipse/3.1/j4/jedii_jcas_tests/testTypes.xml * * @generated */ public class AbstractType extends TOP { /** * @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(AbstractType.class); /** * @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() { return typeIndexID; } /** * Never called. Disable default constructor * * @generated */ protected AbstractType() { } /** * Internal - constructor used by generator * * @generated */ public AbstractType(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public AbstractType(JCas jcas) { super(jcas); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *--------------* // * Feature: abstractInt /** * getter for abstractInt - gets * * @generated */ public int getAbstractInt() { if (AbstractType_Type.featOkTst && ((AbstractType_Type) jcasType).casFeat_abstractInt == null) this.jcasType.jcas.throwFeatMissing("abstractInt", "aa.AbstractType"); return jcasType.ll_cas.ll_getIntValue(addr, ((AbstractType_Type) jcasType).casFeatCode_abstractInt); } /** * setter for abstractInt - sets * * @generated */ public void setAbstractInt(int v) { if (AbstractType_Type.featOkTst && ((AbstractType_Type) jcasType).casFeat_abstractInt == null) this.jcasType.jcas.throwFeatMissing("abstractInt", "aa.AbstractType"); jcasType.ll_cas.ll_setIntValue(addr, ((AbstractType_Type) jcasType).casFeatCode_abstractInt, v); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/MissingInCas.java0000644000175000017500000000403111665471052023020 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 XML source: * C:/a/Eclipse/3.1/j4/jedii_jcas_tests/testTypes.xml * * @generated */ public class MissingInCas extends TOP { /** * @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(MissingInCas.class); /** * @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() { return typeIndexID; } /** * Never called. Disable default constructor * * @generated */ protected MissingInCas() { } /** * Internal - constructor used by generator * * @generated */ public MissingInCas(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public MissingInCas(JCas jcas) { super(jcas); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-core/src/test/java/aa/MissingFeatureInCas_Type.java0000644000175000017500000001267711665471052025354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 * * @generated */ public class MissingFeatureInCas_Type extends TOP_Type { /** @generated */ protected FSGenerator getFSGenerator() { return fsGenerator; } /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (MissingFeatureInCas_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = MissingFeatureInCas_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new MissingFeatureInCas(addr, MissingFeatureInCas_Type.this); MissingFeatureInCas_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new MissingFeatureInCas(addr, MissingFeatureInCas_Type.this); } }; /** @generated */ public final static int typeIndexID = MissingFeatureInCas.typeIndexID; /** * @generated * @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("aa.MissingFeatureInCas"); /** @generated */ final Feature casFeat_haveThisOne; /** @generated */ final int casFeatCode_haveThisOne; /** @generated */ public int getHaveThisOne(int addr) { if (featOkTst && casFeat_haveThisOne == null) this.jcas.throwFeatMissing("haveThisOne", "aa.MissingFeatureInCas"); return ll_cas.ll_getIntValue(addr, casFeatCode_haveThisOne); } /** @generated */ public void setHaveThisOne(int addr, int v) { if (featOkTst && casFeat_haveThisOne == null) this.jcas.throwFeatMissing("haveThisOne", "aa.MissingFeatureInCas"); ll_cas.ll_setIntValue(addr, casFeatCode_haveThisOne, v); } /** @generated */ final Feature casFeat_missingThisOne; /** @generated */ final int casFeatCode_missingThisOne; /** @generated */ public float getMissingThisOne(int addr) { if (featOkTst && casFeat_missingThisOne == null) this.jcas.throwFeatMissing("missingThisOne", "aa.MissingFeatureInCas"); return ll_cas.ll_getFloatValue(addr, casFeatCode_missingThisOne); } /** @generated */ public void setMissingThisOne(int addr, float v) { if (featOkTst && casFeat_missingThisOne == null) this.jcas.throwFeatMissing("missingThisOne", "aa.MissingFeatureInCas"); ll_cas.ll_setFloatValue(addr, casFeatCode_missingThisOne, v); } /** @generated */ final Feature casFeat_changedFType; /** @generated */ final int casFeatCode_changedFType; /** @generated */ public String getChangedFType(int addr) { if (featOkTst && casFeat_changedFType == null) this.jcas.throwFeatMissing("changedFType", "aa.MissingFeatureInCas"); return ll_cas.ll_getStringValue(addr, casFeatCode_changedFType); } /** @generated */ public void setChangedFType(int addr, String v) { if (featOkTst && casFeat_changedFType == null) this.jcas.throwFeatMissing("changedFType", "aa.MissingFeatureInCas"); ll_cas.ll_setStringValue(addr, casFeatCode_changedFType, v); } /** * initialize variables to correspond with Cas Type and Features * * @generated */ public MissingFeatureInCas_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_haveThisOne = jcas.getRequiredFeatureDE(casType, "haveThisOne", "uima.cas.Integer", featOkTst); casFeatCode_haveThisOne = (null == casFeat_haveThisOne) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_haveThisOne).getCode(); casFeat_missingThisOne = jcas.getRequiredFeatureDE(casType, "missingThisOne", "uima.cas.Float", featOkTst); casFeatCode_missingThisOne = (null == casFeat_missingThisOne) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_missingThisOne).getCode(); casFeat_changedFType = jcas.getRequiredFeatureDE(casType, "changedFType", "uima.cas.String", featOkTst); casFeatCode_changedFType = (null == casFeat_changedFType) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_changedFType).getCode(); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/MissingInCas_Type.java0000644000175000017500000000477311665471052024036 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 * * @generated */ public class MissingInCas_Type extends TOP_Type { /** @generated */ protected FSGenerator getFSGenerator() { return fsGenerator; } /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (MissingInCas_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = MissingInCas_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new MissingInCas(addr, MissingInCas_Type.this); MissingInCas_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new MissingInCas(addr, MissingInCas_Type.this); } }; /** @generated */ public final static int typeIndexID = MissingInCas.typeIndexID; /** * @generated * @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("aa.MissingInCas"); /** * initialize variables to correspond with Cas Type and Features * * @generated */ public MissingInCas_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/ConcreteType_Type.java0000644000175000017500000000676311665471052024114 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 * * @generated */ public class ConcreteType_Type extends AbstractType_Type { /** @generated */ protected FSGenerator getFSGenerator() { return fsGenerator; } /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (ConcreteType_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = ConcreteType_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new ConcreteType(addr, ConcreteType_Type.this); ConcreteType_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new ConcreteType(addr, ConcreteType_Type.this); } }; /** @generated */ public final static int typeIndexID = ConcreteType.typeIndexID; /** * @generated * @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("aa.ConcreteType"); /** @generated */ final Feature casFeat_concreteString; /** @generated */ final int casFeatCode_concreteString; /** @generated */ public String getConcreteString(int addr) { if (featOkTst && casFeat_concreteString == null) this.jcas.throwFeatMissing("concreteString", "aa.ConcreteType"); return ll_cas.ll_getStringValue(addr, casFeatCode_concreteString); } /** @generated */ public void setConcreteString(int addr, String v) { if (featOkTst && casFeat_concreteString == null) this.jcas.throwFeatMissing("concreteString", "aa.ConcreteType"); ll_cas.ll_setStringValue(addr, casFeatCode_concreteString, v); } /** * initialize variables to correspond with Cas Type and Features * * @generated */ public ConcreteType_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_concreteString = jcas.getRequiredFeatureDE(casType, "concreteString", "uima.cas.String", featOkTst); casFeatCode_concreteString = (null == casFeat_concreteString) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_concreteString).getCode(); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/MissingFeatureInCas.java0000644000175000017500000001167211665471052024345 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 XML source: * C:/a/Eclipse/3.1/j4/jedii_jcas_tests/testTypes.xml * * @generated */ public class MissingFeatureInCas extends TOP { /** * @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(MissingFeatureInCas.class); /** * @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() { return typeIndexID; } /** * Never called. Disable default constructor * * @generated */ protected MissingFeatureInCas() { } /** * Internal - constructor used by generator * * @generated */ public MissingFeatureInCas(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public MissingFeatureInCas(JCas jcas) { super(jcas); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *--------------* // * Feature: haveThisOne /** * getter for haveThisOne - gets * * @generated */ public int getHaveThisOne() { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_haveThisOne == null) this.jcasType.jcas.throwFeatMissing("haveThisOne", "aa.MissingFeatureInCas"); return jcasType.ll_cas.ll_getIntValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_haveThisOne); } /** * setter for haveThisOne - sets * * @generated */ public void setHaveThisOne(int v) { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_haveThisOne == null) this.jcasType.jcas.throwFeatMissing("haveThisOne", "aa.MissingFeatureInCas"); jcasType.ll_cas.ll_setIntValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_haveThisOne, v); } // *--------------* // * Feature: missingThisOne /** * getter for missingThisOne - gets * * @generated */ public float getMissingThisOne() { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_missingThisOne == null) this.jcasType.jcas.throwFeatMissing("missingThisOne", "aa.MissingFeatureInCas"); return jcasType.ll_cas.ll_getFloatValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_missingThisOne); } /** * setter for missingThisOne - sets * * @generated */ public void setMissingThisOne(float v) { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_missingThisOne == null) this.jcasType.jcas.throwFeatMissing("missingThisOne", "aa.MissingFeatureInCas"); jcasType.ll_cas.ll_setFloatValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_missingThisOne, v); } // *--------------* // * Feature: changedFType /** * getter for changedFType - gets * * @generated */ public String getChangedFType() { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_changedFType == null) this.jcasType.jcas.throwFeatMissing("changedFType", "aa.MissingFeatureInCas"); return jcasType.ll_cas.ll_getStringValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_changedFType); } /** * setter for changedFType - sets * * @generated */ public void setChangedFType(String v) { if (MissingFeatureInCas_Type.featOkTst && ((MissingFeatureInCas_Type) jcasType).casFeat_changedFType == null) this.jcasType.jcas.throwFeatMissing("changedFType", "aa.MissingFeatureInCas"); jcasType.ll_cas.ll_setStringValue(addr, ((MissingFeatureInCas_Type) jcasType).casFeatCode_changedFType, v); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/AbstractType_Type.java0000644000175000017500000000673511665471052024114 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 * * @generated */ public class AbstractType_Type extends TOP_Type { /** @generated */ protected FSGenerator getFSGenerator() { return fsGenerator; } /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (AbstractType_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = AbstractType_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new AbstractType(addr, AbstractType_Type.this); AbstractType_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new AbstractType(addr, AbstractType_Type.this); } }; /** @generated */ public final static int typeIndexID = AbstractType.typeIndexID; /** * @generated * @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("aa.AbstractType"); /** @generated */ final Feature casFeat_abstractInt; /** @generated */ final int casFeatCode_abstractInt; /** @generated */ public int getAbstractInt(int addr) { if (featOkTst && casFeat_abstractInt == null) this.jcas.throwFeatMissing("abstractInt", "aa.AbstractType"); return ll_cas.ll_getIntValue(addr, casFeatCode_abstractInt); } /** @generated */ public void setAbstractInt(int addr, int v) { if (featOkTst && casFeat_abstractInt == null) this.jcas.throwFeatMissing("abstractInt", "aa.AbstractType"); ll_cas.ll_setIntValue(addr, casFeatCode_abstractInt, v); } /** * initialize variables to correspond with Cas Type and Features * * @generated */ public AbstractType_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_abstractInt = jcas.getRequiredFeatureDE(casType, "abstractInt", "uima.cas.Integer", featOkTst); casFeatCode_abstractInt = (null == casFeat_abstractInt) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_abstractInt).getCode(); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/ConcreteType.java0000644000175000017500000000565711665471052023114 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 XML source: * C:/a/Eclipse/3.1/j4/jedii_jcas_tests/testTypes.xml * * @generated */ public class ConcreteType extends AbstractType { /** * @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(ConcreteType.class); /** * @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() { return typeIndexID; } /** * Never called. Disable default constructor * * @generated */ protected ConcreteType() { } /** * Internal - constructor used by generator * * @generated */ public ConcreteType(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public ConcreteType(JCas jcas) { super(jcas); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *--------------* // * Feature: concreteString /** * getter for concreteString - gets * * @generated */ public String getConcreteString() { if (ConcreteType_Type.featOkTst && ((ConcreteType_Type) jcasType).casFeat_concreteString == null) this.jcasType.jcas.throwFeatMissing("concreteString", "aa.ConcreteType"); return jcasType.ll_cas.ll_getStringValue(addr, ((ConcreteType_Type) jcasType).casFeatCode_concreteString); } /** * setter for concreteString - sets * * @generated */ public void setConcreteString(String v) { if (ConcreteType_Type.featOkTst && ((ConcreteType_Type) jcasType).casFeat_concreteString == null) this.jcasType.jcas.throwFeatMissing("concreteString", "aa.ConcreteType"); jcasType.ll_cas.ll_setStringValue(addr, ((ConcreteType_Type) jcasType).casFeatCode_concreteString, v); } } uimaj-2.4.0/uimaj-core/src/test/java/aa/Root_Type.java0000644000175000017500000003422311665471052022423 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package aa; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /** * Updated by JCasGen Tue Feb 21 14:56:04 EST 2006 * * @generated */ public class Root_Type extends TOP_Type { /** @generated */ protected FSGenerator getFSGenerator() { return fsGenerator; } /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (Root_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = Root_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Root(addr, Root_Type.this); Root_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Root(addr, Root_Type.this); } }; /** @generated */ public final static int typeIndexID = Root.typeIndexID; /** * @generated * @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("aa.Root"); /** @generated */ final Feature casFeat_arrayInt; /** @generated */ final int casFeatCode_arrayInt; /** @generated */ public int getArrayInt(int addr) { if (featOkTst && casFeat_arrayInt == null) this.jcas.throwFeatMissing("arrayInt", "aa.Root"); return ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt); } /** @generated */ public void setArrayInt(int addr, int v) { if (featOkTst && casFeat_arrayInt == null) this.jcas.throwFeatMissing("arrayInt", "aa.Root"); ll_cas.ll_setRefValue(addr, casFeatCode_arrayInt, v); } /** @generated */ public int getArrayInt(int addr, int i) { if (featOkTst && casFeat_arrayInt == null) this.jcas.throwFeatMissing("arrayInt", "aa.Root"); if (lowLevelTypeChecks) return ll_cas.ll_getIntArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i); return ll_cas.ll_getIntArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i); } /** @generated */ public void setArrayInt(int addr, int i, int v) { if (featOkTst && casFeat_arrayInt == null) this.jcas.throwFeatMissing("arrayInt", "aa.Root"); if (lowLevelTypeChecks) ll_cas.ll_setIntArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i, v, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i); ll_cas.ll_setIntArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayInt), i, v); } /** @generated */ final Feature casFeat_arrayRef; /** @generated */ final int casFeatCode_arrayRef; /** @generated */ public int getArrayRef(int addr) { if (featOkTst && casFeat_arrayRef == null) this.jcas.throwFeatMissing("arrayRef", "aa.Root"); return ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef); } /** @generated */ public void setArrayRef(int addr, int v) { if (featOkTst && casFeat_arrayRef == null) this.jcas.throwFeatMissing("arrayRef", "aa.Root"); ll_cas.ll_setRefValue(addr, casFeatCode_arrayRef, v); } /** @generated */ public int getArrayRef(int addr, int i) { if (featOkTst && casFeat_arrayRef == null) this.jcas.throwFeatMissing("arrayRef", "aa.Root"); if (lowLevelTypeChecks) return ll_cas.ll_getRefArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i); return ll_cas.ll_getRefArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i); } /** @generated */ public void setArrayRef(int addr, int i, int v) { if (featOkTst && casFeat_arrayRef == null) this.jcas.throwFeatMissing("arrayRef", "aa.Root"); if (lowLevelTypeChecks) ll_cas.ll_setRefArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i, v, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i); ll_cas.ll_setRefArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayRef), i, v); } /** @generated */ final Feature casFeat_arrayFloat; /** @generated */ final int casFeatCode_arrayFloat; /** @generated */ public int getArrayFloat(int addr) { if (featOkTst && casFeat_arrayFloat == null) this.jcas.throwFeatMissing("arrayFloat", "aa.Root"); return ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat); } /** @generated */ public void setArrayFloat(int addr, int v) { if (featOkTst && casFeat_arrayFloat == null) this.jcas.throwFeatMissing("arrayFloat", "aa.Root"); ll_cas.ll_setRefValue(addr, casFeatCode_arrayFloat, v); } /** @generated */ public float getArrayFloat(int addr, int i) { if (featOkTst && casFeat_arrayFloat == null) this.jcas.throwFeatMissing("arrayFloat", "aa.Root"); if (lowLevelTypeChecks) return ll_cas.ll_getFloatArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i); return ll_cas.ll_getFloatArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i); } /** @generated */ public void setArrayFloat(int addr, int i, float v) { if (featOkTst && casFeat_arrayFloat == null) this.jcas.throwFeatMissing("arrayFloat", "aa.Root"); if (lowLevelTypeChecks) ll_cas.ll_setFloatArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i, v, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i); ll_cas.ll_setFloatArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayFloat), i, v); } /** @generated */ final Feature casFeat_arrayString; /** @generated */ final int casFeatCode_arrayString; /** @generated */ public int getArrayString(int addr) { if (featOkTst && casFeat_arrayString == null) this.jcas.throwFeatMissing("arrayString", "aa.Root"); return ll_cas.ll_getRefValue(addr, casFeatCode_arrayString); } /** @generated */ public void setArrayString(int addr, int v) { if (featOkTst && casFeat_arrayString == null) this.jcas.throwFeatMissing("arrayString", "aa.Root"); ll_cas.ll_setRefValue(addr, casFeatCode_arrayString, v); } /** @generated */ public String getArrayString(int addr, int i) { if (featOkTst && casFeat_arrayString == null) this.jcas.throwFeatMissing("arrayString", "aa.Root"); if (lowLevelTypeChecks) return ll_cas.ll_getStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i); return ll_cas.ll_getStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i); } /** @generated */ public void setArrayString(int addr, int i, String v) { if (featOkTst && casFeat_arrayString == null) this.jcas.throwFeatMissing("arrayString", "aa.Root"); if (lowLevelTypeChecks) ll_cas.ll_setStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i, v, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i); ll_cas.ll_setStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_arrayString), i, v); } /** @generated */ final Feature casFeat_plainInt; /** @generated */ final int casFeatCode_plainInt; /** @generated */ public int getPlainInt(int addr) { if (featOkTst && casFeat_plainInt == null) this.jcas.throwFeatMissing("plainInt", "aa.Root"); return ll_cas.ll_getIntValue(addr, casFeatCode_plainInt); } /** @generated */ public void setPlainInt(int addr, int v) { if (featOkTst && casFeat_plainInt == null) this.jcas.throwFeatMissing("plainInt", "aa.Root"); ll_cas.ll_setIntValue(addr, casFeatCode_plainInt, v); } /** @generated */ final Feature casFeat_plainFloat; /** @generated */ final int casFeatCode_plainFloat; /** @generated */ public float getPlainFloat(int addr) { if (featOkTst && casFeat_plainFloat == null) this.jcas.throwFeatMissing("plainFloat", "aa.Root"); return ll_cas.ll_getFloatValue(addr, casFeatCode_plainFloat); } /** @generated */ public void setPlainFloat(int addr, float v) { if (featOkTst && casFeat_plainFloat == null) this.jcas.throwFeatMissing("plainFloat", "aa.Root"); ll_cas.ll_setFloatValue(addr, casFeatCode_plainFloat, v); } /** @generated */ final Feature casFeat_plainString; /** @generated */ final int casFeatCode_plainString; /** @generated */ public String getPlainString(int addr) { if (featOkTst && casFeat_plainString == null) this.jcas.throwFeatMissing("plainString", "aa.Root"); return ll_cas.ll_getStringValue(addr, casFeatCode_plainString); } /** @generated */ public void setPlainString(int addr, String v) { if (featOkTst && casFeat_plainString == null) this.jcas.throwFeatMissing("plainString", "aa.Root"); ll_cas.ll_setStringValue(addr, casFeatCode_plainString, v); } /** @generated */ final Feature casFeat_plainRef; /** @generated */ final int casFeatCode_plainRef; /** @generated */ public int getPlainRef(int addr) { if (featOkTst && casFeat_plainRef == null) this.jcas.throwFeatMissing("plainRef", "aa.Root"); return ll_cas.ll_getRefValue(addr, casFeatCode_plainRef); } /** @generated */ public void setPlainRef(int addr, int v) { if (featOkTst && casFeat_plainRef == null) this.jcas.throwFeatMissing("plainRef", "aa.Root"); ll_cas.ll_setRefValue(addr, casFeatCode_plainRef, v); } /** @generated */ final Feature casFeat_concreteString; /** @generated */ final int casFeatCode_concreteString; /** @generated */ public String getConcreteString(int addr) { if (featOkTst && casFeat_concreteString == null) this.jcas.throwFeatMissing("concreteString", "aa.Root"); return ll_cas.ll_getStringValue(addr, casFeatCode_concreteString); } /** @generated */ public void setConcreteString(int addr, String v) { if (featOkTst && casFeat_concreteString == null) this.jcas.throwFeatMissing("concreteString", "aa.Root"); ll_cas.ll_setStringValue(addr, casFeatCode_concreteString, v); } /** * initialize variables to correspond with Cas Type and Features * * @generated */ public Root_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_arrayInt = jcas.getRequiredFeatureDE(casType, "arrayInt", "uima.cas.IntegerArray", featOkTst); casFeatCode_arrayInt = (null == casFeat_arrayInt) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_arrayInt).getCode(); casFeat_arrayRef = jcas .getRequiredFeatureDE(casType, "arrayRef", "uima.cas.FSArray", featOkTst); casFeatCode_arrayRef = (null == casFeat_arrayRef) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_arrayRef).getCode(); casFeat_arrayFloat = jcas.getRequiredFeatureDE(casType, "arrayFloat", "uima.cas.FloatArray", featOkTst); casFeatCode_arrayFloat = (null == casFeat_arrayFloat) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_arrayFloat).getCode(); casFeat_arrayString = jcas.getRequiredFeatureDE(casType, "arrayString", "uima.cas.StringArray", featOkTst); casFeatCode_arrayString = (null == casFeat_arrayString) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_arrayString).getCode(); casFeat_plainInt = jcas .getRequiredFeatureDE(casType, "plainInt", "uima.cas.Integer", featOkTst); casFeatCode_plainInt = (null == casFeat_plainInt) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_plainInt).getCode(); casFeat_plainFloat = jcas.getRequiredFeatureDE(casType, "plainFloat", "uima.cas.Float", featOkTst); casFeatCode_plainFloat = (null == casFeat_plainFloat) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_plainFloat).getCode(); casFeat_plainString = jcas.getRequiredFeatureDE(casType, "plainString", "uima.cas.String", featOkTst); casFeatCode_plainString = (null == casFeat_plainString) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_plainString).getCode(); casFeat_plainRef = jcas.getRequiredFeatureDE(casType, "plainRef", "aa.Root", featOkTst); casFeatCode_plainRef = (null == casFeat_plainRef) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_plainRef).getCode(); casFeat_concreteString = jcas.getRequiredFeatureDE(casType, "concreteString", "uima.cas.String", featOkTst); casFeatCode_concreteString = (null == casFeat_concreteString) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_concreteString).getCode(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/0000755000175000017500000000000011665471052020036 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/0000755000175000017500000000000011665471052021257 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/lang/0000755000175000017500000000000011665471052022200 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/lang/LanguagePair.java0000644000175000017500000000776011665471052025414 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.lang; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /* comment 7 of 14 */ public class LanguagePair extends TOP { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(LanguagePair.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected LanguagePair() { } /** Internal - Constructor used by generator */ public LanguagePair(int addr, TOP_Type type) { super(addr, type); } public LanguagePair(JCas jcas) { super(jcas); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *------------------* // * Feature: lang1 /** getter for lang1 * */ public String getLang1() { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_lang1 == null) this.jcasType.jcas.throwFeatMissing("lang1", "org.apache.lang.LanguagePair"); return jcasType.ll_cas .ll_getStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_lang1); } /** setter for lang1 * */ public void setLang1(String v) { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_lang1 == null) this.jcasType.jcas.throwFeatMissing("lang1", "org.apache.lang.LanguagePair"); jcasType.ll_cas.ll_setStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_lang1, v); } // *------------------* // * Feature: lang2 /** getter for lang2 * */ public String getLang2() { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_lang2 == null) this.jcasType.jcas.throwFeatMissing("lang2", "org.apache.lang.LanguagePair"); return jcasType.ll_cas .ll_getStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_lang2); } /** setter for lang2 * */ public void setLang2(String v) { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_lang2 == null) this.jcasType.jcas.throwFeatMissing("lang2", "org.apache.lang.LanguagePair"); jcasType.ll_cas.ll_setStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_lang2, v); } // *------------------* // * Feature: description /** getter for description * */ public String getDescription() { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_description == null) this.jcasType.jcas.throwFeatMissing("description", "org.apache.lang.LanguagePair"); return jcasType.ll_cas.ll_getStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_description); } /** setter for description * */ public void setDescription(String v) { if (LanguagePair_Type.featOkTst && ((LanguagePair_Type) jcasType).casFeat_description == null) this.jcasType.jcas.throwFeatMissing("description", "org.apache.lang.LanguagePair"); jcasType.ll_cas.ll_setStringValue(addr, ((LanguagePair_Type) jcasType).casFeatCode_description, v); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/lang/LanguagePair_Type.java0000644000175000017500000001221311665471052026402 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.lang; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /* comment 7 of 14 */ public class LanguagePair_Type extends TOP_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new LanguagePair(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new LanguagePair(addr, instanceOf_Type); } }; public final static int typeIndexID = LanguagePair.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("org.apache.lang.LanguagePair"); final Feature casFeat_lang1; final int casFeatCode_lang1; public String getLang1(int addr) { if (featOkTst && casFeat_lang1 == null) this.jcas.throwFeatMissing("lang1", "org.apache.lang.LanguagePair"); return ll_cas.ll_getStringValue(addr, casFeatCode_lang1); } public void setLang1(int addr, String v) { if (featOkTst && casFeat_lang1 == null) this.jcas.throwFeatMissing("lang1", "org.apache.lang.LanguagePair"); ll_cas.ll_setStringValue(addr, casFeatCode_lang1, v); } final Feature casFeat_lang2; final int casFeatCode_lang2; public String getLang2(int addr) { if (featOkTst && casFeat_lang2 == null) this.jcas.throwFeatMissing("lang2", "org.apache.lang.LanguagePair"); return ll_cas.ll_getStringValue(addr, casFeatCode_lang2); } public void setLang2(int addr, String v) { if (featOkTst && casFeat_lang2 == null) this.jcas.throwFeatMissing("lang2", "org.apache.lang.LanguagePair"); ll_cas.ll_setStringValue(addr, casFeatCode_lang2, v); } final Feature casFeat_description; final int casFeatCode_description; public String getDescription(int addr) { if (featOkTst && casFeat_description == null) this.jcas.throwFeatMissing("description", "org.apache.lang.LanguagePair"); return ll_cas.ll_getStringValue(addr, casFeatCode_description); } public void setDescription(int addr, String v) { if (featOkTst && casFeat_description == null) this.jcas.throwFeatMissing("description", "org.apache.lang.LanguagePair"); ll_cas.ll_setStringValue(addr, casFeatCode_description, v); } // * initialize variables to correspond with Cas Type and Features public LanguagePair_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_lang1 = jcas .getRequiredFeatureDE(casType, "lang1", "org.apache.lang.Group1", featOkTst); casFeatCode_lang1 = (null == casFeat_lang1) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_lang1).getCode(); casFeat_lang2 = jcas .getRequiredFeatureDE(casType, "lang2", "org.apache.lang.Group2", featOkTst); casFeatCode_lang2 = (null == casFeat_lang2) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_lang2).getCode(); casFeat_description = jcas.getRequiredFeatureDE(casType, "description", "uima.cas.String", featOkTst); casFeatCode_description = (null == casFeat_description) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_description).getCode(); } protected LanguagePair_Type() { // block default new operator casFeat_lang1 = null; casFeatCode_lang1 = JCas.INVALID_FEATURE_CODE; casFeat_lang2 = null; casFeatCode_lang2 = JCas.INVALID_FEATURE_CODE; casFeat_description = null; casFeatCode_description = JCas.INVALID_FEATURE_CODE; throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/0000755000175000017500000000000011665471066022217 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/0000755000175000017500000000000011665471064025365 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/0000755000175000017500000000000011665471066026330 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotatorContext_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotatorContext_implTest.0000644000175000017500000007772111665471066033542 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.annotator.AnnotatorContext; import org.apache.uima.analysis_engine.annotator.AnnotatorContextException; import org.apache.uima.resource.DataResource; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.impl.TestResourceInterface; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class AnnotatorContext_implTest extends TestCase { protected final String TEST_DATAPATH = JUnitExtension.getFile("AnnotatorContextTest").getPath() + System.getProperty("path.separator") + JUnitExtension.getFile("ResourceTest"); protected final String TEST_EXTENSION_CLASSPATH = JUnitExtension.getFile( "ResourceTest/spaces in dir name").getPath(); private AnnotatorContext mAC1; private AnnotatorContext mAC2; private AnnotatorContext mAC3; private AnnotatorContext mAC4; private AnnotatorContext mAC5; /** * Constructor for AnnotatorContext_implTest. * * @param arg0 */ public AnnotatorContext_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); // create primitive analysis engine with configuration groups XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithConfigurationGroups.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); PrimitiveAnalysisEngine_impl tae = new PrimitiveAnalysisEngine_impl(); // set data path just to test that we can get it later Map map = new HashMap(); ResourceManager rm = UIMAFramework.newDefaultResourceManager(); rm.setDataPath(TEST_DATAPATH); rm.setExtensionClassPath(TEST_EXTENSION_CLASSPATH, true); map.put(AnalysisEngine.PARAM_RESOURCE_MANAGER, rm); tae.initialize(desc, map); // this should include an annotator context mAC1 = new AnnotatorContext_impl(tae.getUimaContextAdmin()); // create aggregate analysis engine with configuration parameter overrides XMLInputSource in2 = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AggregateTaeWithConfigParamOverrides.xml")); AnalysisEngineDescription aggDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in2); AggregateAnalysisEngine_impl aggTae = new AggregateAnalysisEngine_impl(); aggTae.initialize(aggDesc, map); // get the primitive TAE PrimitiveAnalysisEngine_impl primTae = (PrimitiveAnalysisEngine_impl) aggTae._getASB() .getComponentAnalysisEngines().values().toArray()[0]; // this should include an annotator context mAC2 = new AnnotatorContext_impl(primTae.getUimaContextAdmin()); // create primitive analysis engine for resource testing XMLInputSource in3 = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/ResourceTestAnnotator.xml")); AnalysisEngineDescription resTestDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in3); PrimitiveAnalysisEngine_impl resTestTae = new PrimitiveAnalysisEngine_impl(); resTestTae.initialize(resTestDesc, map); // this should include an annotator context mAC3 = new AnnotatorContext_impl(resTestTae.getUimaContextAdmin()); // create primitive TAE with configuration groups and default fallback XMLInputSource in4 = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithDefaultFallbackConfiguration.xml")); AnalysisEngineDescription desc4 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in4); PrimitiveAnalysisEngine_impl tae4 = new PrimitiveAnalysisEngine_impl(); // set data path just to test that we can get it later tae4.initialize(desc4, null); // this should include an annotator context mAC4 = new AnnotatorContext_impl(tae4.getUimaContextAdmin()); // create primitive TAE with configuration parameters (no groups) XMLInputSource in5 = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithConfigurationParameters.xml")); AnalysisEngineDescription desc5 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in5); PrimitiveAnalysisEngine_impl tae5 = new PrimitiveAnalysisEngine_impl(); // set data path just to test that we can get it later tae5.initialize(desc5, null); // this should include an annotator context mAC5 = new AnnotatorContext_impl(tae5.getUimaContextAdmin()); } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Object getConfigParameterValue(String) */ public void testGetConfigParameterValueString() throws Exception { try { // this method should get parameter values from the default "en" group String str = (String) mAC1.getConfigParameterValue("StringParam"); Assert.assertEquals("en", str); String[] strArr = (String[]) mAC1.getConfigParameterValue("StringArrayParam"); Assert.assertEquals(2, strArr.length); Assert.assertEquals("e", strArr[0]); Assert.assertEquals("n", strArr[1]); Integer intVal = (Integer) mAC1.getConfigParameterValue("IntegerParam"); Assert.assertEquals(42, intVal.intValue()); Integer[] intArr = (Integer[]) mAC1.getConfigParameterValue("IntegerArrayParam"); Assert.assertEquals(3, intArr.length); Assert.assertEquals(1, intArr[0].intValue()); Assert.assertEquals(2, intArr[1].intValue()); Assert.assertEquals(3, intArr[2].intValue()); Float floatVal = (Float) mAC1.getConfigParameterValue("FloatParam"); Assert.assertEquals(null, floatVal); // test override String str2 = (String) mAC2.getConfigParameterValue("StringParam"); Assert.assertEquals("override", str2); // other values should not be affected Integer intVal2 = (Integer) mAC1.getConfigParameterValue("IntegerParam"); Assert.assertEquals(42, intVal2.intValue()); // test default fallback String str3 = (String) mAC4.getConfigParameterValue("StringParam"); Assert.assertEquals("test", str3); String[] strArr2 = (String[]) mAC4.getConfigParameterValue("StringArrayParam"); Assert.assertEquals(4, strArr2.length); Assert.assertEquals("t", strArr2[0]); Assert.assertEquals("e", strArr2[1]); Assert.assertEquals("s", strArr2[2]); Assert.assertEquals("t", strArr2[3]); } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Object getConfigParameterValue(String, String) */ public void testGetConfigParameterValueStringString() throws Exception { try { // en-US group String str = (String) mAC1.getConfigParameterValue("en-US", "StringParam"); Assert.assertEquals("en", str); // language fallback String[] strArr = (String[]) mAC1.getConfigParameterValue("en-US", "StringArrayParam"); Assert.assertEquals(5, strArr.length); Assert.assertEquals("e", strArr[0]); Assert.assertEquals("n", strArr[1]); Assert.assertEquals("-", strArr[2]); Assert.assertEquals("U", strArr[3]); Assert.assertEquals("S", strArr[4]); Integer intVal = (Integer) mAC1.getConfigParameterValue("en-US", "IntegerParam"); Assert.assertEquals(1776, intVal.intValue()); Integer[] intArr = (Integer[]) mAC1.getConfigParameterValue("en-US", "IntegerArrayParam"); Assert.assertEquals(3, intArr.length); // language fallback Assert.assertEquals(1, intArr[0].intValue()); Assert.assertEquals(2, intArr[1].intValue()); Assert.assertEquals(3, intArr[2].intValue()); Float floatVal = (Float) mAC1.getConfigParameterValue("en-US", "FloatParam"); Assert.assertEquals(null, floatVal); // de group String str2 = (String) mAC1.getConfigParameterValue("de", "StringParam"); Assert.assertEquals("de", str2); String[] strArr2 = (String[]) mAC1.getConfigParameterValue("de", "StringArrayParam"); Assert.assertEquals(2, strArr2.length); Assert.assertEquals("d", strArr2[0]); Assert.assertEquals("e", strArr2[1]); Integer intVal2 = (Integer) mAC1.getConfigParameterValue("de", "IntegerParam"); Assert.assertEquals(42, intVal2.intValue()); // default fallback Integer[] intArr2 = (Integer[]) mAC1.getConfigParameterValue("de", "IntegerArrayParam"); Assert.assertEquals(3, intArr2.length); Assert.assertEquals(4, intArr2[0].intValue()); Assert.assertEquals(5, intArr2[1].intValue()); Assert.assertEquals(6, intArr2[2].intValue()); Float floatVal2 = (Float) mAC1.getConfigParameterValue("de", "FloatParam"); Assert.assertEquals(null, floatVal2); // zh group String str3 = (String) mAC1.getConfigParameterValue("zh", "StringParam"); Assert.assertEquals("zh", str3); String[] strArr3 = (String[]) mAC1.getConfigParameterValue("zh", "StringArrayParam"); Assert.assertEquals(2, strArr3.length); Assert.assertEquals("z", strArr3[0]); Assert.assertEquals("h", strArr3[1]); Integer intVal3 = (Integer) mAC1.getConfigParameterValue("zh", "IntegerParam"); Assert.assertEquals(42, intVal3.intValue()); // default fallback Integer[] intArr3 = (Integer[]) mAC1.getConfigParameterValue("zh", "IntegerArrayParam"); Assert.assertEquals(3, intArr3.length); // default fallback Assert.assertEquals(1, intArr3[0].intValue()); Assert.assertEquals(2, intArr3[1].intValue()); Assert.assertEquals(3, intArr3[2].intValue()); Float floatVal3 = (Float) mAC1.getConfigParameterValue("zh", "FloatParam"); Assert.assertEquals(3.14, floatVal3.floatValue(), 0.0001); // test override String str4 = (String) mAC2.getConfigParameterValue("en", "StringParam"); Assert.assertEquals("override", str4); // fallback too String str5 = (String) mAC2.getConfigParameterValue("en-GB", "StringParam"); Assert.assertEquals("override", str5); // other groups should not be affected String str6 = (String) mAC2.getConfigParameterValue("de", "StringParam"); Assert.assertEquals("de", str6); // test empty string array String[] strArr4 = (String[]) mAC2.getConfigParameterValue("x-unspecified", "StringArrayParam"); Assert.assertTrue(Arrays.equals(strArr4, new String[0])); // test nonexistent group String str7 = (String) mAC1.getConfigParameterValue("es", "StringParam"); Assert.assertEquals("en", str7); // language_fallback for completely nonexistent language String str8 = (String) mAC4.getConfigParameterValue("es", "StringParam"); Assert.assertEquals("test", str8); // default_fallback for nonexistent group } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetConfigurationGroupNames() { String[] names = mAC1.getConfigurationGroupNames(); Assert.assertEquals(5, names.length); List l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("en")); Assert.assertTrue(l.contains("en-US")); Assert.assertTrue(l.contains("de")); Assert.assertTrue(l.contains("zh")); Assert.assertTrue(l.contains("x-unspecified")); // try on something that has no groups names = mAC5.getConfigurationGroupNames(); Assert.assertEquals(0, names.length); } public void testGetConfigParameterNames() { String[] names = mAC5.getConfigParameterNames(); Assert.assertEquals(6, names.length); Assert.assertEquals("StringParam", names[0]); Assert.assertEquals("StringArrayParam", names[1]); Assert.assertEquals("IntegerParam", names[2]); Assert.assertEquals("IntegerArrayParam", names[3]); Assert.assertEquals("FloatParam", names[4]); Assert.assertEquals("FloatArrayParam", names[5]); // try on something that has groups names = mAC1.getConfigParameterNames(); Assert.assertEquals(0, names.length); } public void testGetConfigParameterNamesString() { String[] names = mAC1.getConfigParameterNames("en"); Assert.assertEquals(4, names.length); List l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("StringParam")); Assert.assertTrue(l.contains("StringArrayParam")); Assert.assertTrue(l.contains("IntegerParam")); Assert.assertTrue(l.contains("IntegerArrayParam")); // try on nonexistent group names = mAC1.getConfigParameterNames("foo"); Assert.assertEquals(0, names.length); // try on something that has no groups names = mAC4.getConfigParameterNames("en"); Assert.assertEquals(0, names.length); } public void testGetResourceObjectString() throws Exception { try { // custom object Object r = mAC3.getResourceObject("TestResourceObject"); Assert.assertNotNull(r); Assert.assertTrue(r instanceof TestResourceInterface); // standard data resource Object r2 = mAC3.getResourceObject("TestFileResource"); Assert.assertNotNull(r2); Assert.assertTrue(r2 instanceof DataResource); // parameterized resources (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceObject("TestFileLanguageResource"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceObject("TestLanguageResourceObject"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) Object r3 = mAC3.getResourceObject("Unknown"); Assert.assertNull(r3); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURLString() throws Exception { try { // standard data resource (should succeed) URL url = mAC3.getResourceURL("TestFileResource"); Assert.assertNotNull(url); // custom resource object (should return null) URL url2 = mAC3.getResourceURL("TestResourceObject"); Assert.assertNull(url2); // parameterized resources (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceURL("TestFileLanguageResource"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURL("TestLanguageResourceObject"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URL url3 = mAC3.getResourceURL("Unknown"); Assert.assertNull(url3); // passthrough to class loader URL url5 = mAC3.getResourceURL("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(url5); // passthrough to data path URL url6 = mAC1.getResourceURL("testDataFile.dat"); Assert.assertNotNull(url6); // for directory URL url7 = mAC3.getResourceURL("subdir"); Assert.assertNotNull(url7); // spaces as part of extension classpath (spaces should be URL-encoded) URL url8 = mAC3.getResourceURL("OtherFileResource"); assertNotNull(url8); assertTrue(url8.getPath().indexOf("%20") > -1); assertTrue(url8.getPath().indexOf(" ") == -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURIString() throws Exception { try { // standard data resource (should succeed) URI uri = mAC3.getResourceURI("TestFileResource"); Assert.assertNotNull(uri); // custom resource object (should return null) URI uri2 = mAC3.getResourceURI("TestResourceObject"); Assert.assertNull(uri2); // parameterized resources (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceURI("TestFileLanguageResource"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURI("TestLanguageResourceObject"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URI uri3 = mAC3.getResourceURI("Unknown"); Assert.assertNull(uri3); // passthrough to class loader URI uri5 = mAC3.getResourceURI("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(uri5); // passthrough to data path URI uri6 = mAC1.getResourceURI("testDataFile.dat"); Assert.assertNotNull(uri6); // for directory URI uri7 = mAC3.getResourceURI("subdir"); Assert.assertNotNull(uri7); // spaces as part of extension classpath (spaces should be decoded) URI uri8 = mAC3.getResourceURI("OtherFileResource"); assertNotNull(uri8); assertTrue(uri8.getPath().indexOf("%20") == -1); assertTrue(uri8.getPath().indexOf(" ") > -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceFilePathString() throws Exception { try { // standard data resource (should succeed) String path = mAC3.getResourceFilePath("TestFileResource"); Assert.assertNotNull(path); // custom resource object (should return null) String path2 = mAC3.getResourceFilePath("TestResourceObject"); Assert.assertNull(path2); // parameterized resources (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceFilePath("TestFileLanguageResource"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceFilePath("TestLanguageResourceObject"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) String path3 = mAC3.getResourceFilePath("Unknown"); Assert.assertNull(path3); // passthrough to class loader String path5 = mAC3 .getResourceFilePath("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(path5); // passthrough to data path String path6 = mAC1.getResourceFilePath("testDataFile.dat"); Assert.assertNotNull(path6); // for directory String path7 = mAC3.getResourceFilePath("subdir"); Assert.assertNotNull(path7); // spaces as part of extension classpath (spaces should be decoded) String path8 = mAC3.getResourceFilePath("OtherFileResource"); assertNotNull(path8); assertTrue(path8.indexOf("%20") == -1); assertTrue(path8.indexOf(" ") > -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceAsStreamString() throws Exception { try { // standard data resource (should succeed) InputStream strm = mAC3.getResourceAsStream("TestFileResource"); Assert.assertNotNull(strm); // custom resource object (should return null) InputStream strm2 = mAC3.getResourceAsStream("TestResourceObject"); Assert.assertNull(strm2); // parameterized resources (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceAsStream("TestFileLanguageResource"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceAsStream("TestLanguageResourceObject"); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) InputStream strm3 = mAC3.getResourceAsStream("Unknown"); Assert.assertNull(strm3); // passthrough to class loader InputStream strm4 = mAC3 .getResourceAsStream("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(strm4); // for directory InputStream strm5 = mAC3.getResourceAsStream("subdir"); Assert.assertNotNull(strm5); // passthrough to data path InputStream strm6 = mAC1.getResourceAsStream("testDataFile.dat"); Assert.assertNotNull(strm6); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceObjectStringStringArray() throws Exception { try { // standard data resource Object r = mAC3.getResourceObject("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(r); Assert.assertTrue(r instanceof DataResource); Object r2 = mAC3.getResourceObject("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(r2); Assert.assertTrue(r2 instanceof DataResource); Assert.assertFalse(r2.equals(r)); // custom object Object r3 = mAC3.getResourceObject("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNotNull(r3); Assert.assertTrue(r3 instanceof TestResourceInterface); Object r4 = mAC3.getResourceObject("TestLanguageResourceObject", new String[] { "de" }); Assert.assertNotNull(r4); Assert.assertTrue(r4 instanceof TestResourceInterface); Assert.assertFalse(r4.equals(r3)); // parameter values for which no resource exists (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceObject("TestFileLanguageResource", new String[] { "zh" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceObject("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mAC3.getResourceObject("TestFileResource", new String[] { "en" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceObject("TestResourceObject", new String[] { "de" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) Object r5 = mAC3.getResourceObject("Unknown", new String[] { "en" }); Assert.assertNull(r5); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceAsStreamStringStringArray() throws Exception { try { // standard data resource InputStream strm = mAC3 .getResourceAsStream("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(strm); InputStream strm2 = mAC3.getResourceAsStream("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(strm2); Assert.assertFalse(strm2.equals(strm)); // custom object (should return null) InputStream strm3 = mAC3.getResourceAsStream("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(strm3); // parameter values for which no resource exists (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceAsStream("TestFileLanguageResource", new String[] { "zh" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceAsStream("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mAC3.getResourceAsStream("TestFileResource", new String[] { "en" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceAsStream("TestResourceObject", new String[] { "de" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) InputStream strm4 = mAC3.getResourceAsStream("Unknown", new String[] { "en" }); Assert.assertNull(strm4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURLStringStringArray() throws Exception { try { // standard data resource URL url = mAC3.getResourceURL("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(url); URL url2 = mAC3.getResourceURL("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(url2); Assert.assertFalse(url2.toString().equals(url.toString())); // custom object (should return null) URL url3 = mAC3.getResourceURL("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(url3); // parameter values for which no resource exists (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceURL("TestFileLanguageResource", new String[] { "zh" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURL("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mAC3.getResourceURL("TestFileResource", new String[] { "en" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURL("TestResourceObject", new String[] { "de" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URL url4 = mAC3.getResourceURL("Unknown", new String[] { "en" }); Assert.assertNull(url4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURIStringStringArray() throws Exception { try { // standard data resource URI uri = mAC3.getResourceURI("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(uri); URI uri2 = mAC3.getResourceURI("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(uri2); Assert.assertFalse(uri2.equals(uri)); // custom object (should return null) URI uri3 = mAC3.getResourceURI("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(uri3); // parameter values for which no resource exists (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceURI("TestFileLanguageResource", new String[] { "zh" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURI("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mAC3.getResourceURI("TestFileResource", new String[] { "en" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceURI("TestResourceObject", new String[] { "de" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URI uri4 = mAC3.getResourceURI("Unknown", new String[] { "en" }); Assert.assertNull(uri4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceFilePathStringStringArray() throws Exception { try { // standard data resource String path = mAC3.getResourceFilePath("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(path); String path2 = mAC3.getResourceFilePath("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(path2); Assert.assertFalse(path2.equals(path)); // custom object (should return null) String path3 = mAC3.getResourceFilePath("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(path3); // parameter values for which no resource exists (should fail) AnnotatorContextException ex = null; try { mAC3.getResourceFilePath("TestFileLanguageResource", new String[] { "zh" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceFilePath("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mAC3.getResourceFilePath("TestFileResource", new String[] { "en" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mAC3.getResourceFilePath("TestResourceObject", new String[] { "de" }); } catch (AnnotatorContextException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) String path4 = mAC3.getResourceFilePath("Unknown", new String[] { "en" }); Assert.assertNull(path4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetDataPath() throws Exception { try { Assert.assertEquals(TEST_DATAPATH, mAC1.getDataPath()); Assert.assertEquals(System.getProperty("user.dir"), mAC4.getDataPath()); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ParallelFlowController.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ParallelFlowController.jav0000644000175000017500000000607611665471066033473 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.Set; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; import org.apache.uima.flow.CasFlowController_ImplBase; import org.apache.uima.flow.CasFlow_ImplBase; import org.apache.uima.flow.FinalStep; import org.apache.uima.flow.Flow; import org.apache.uima.flow.FlowControllerContext; import org.apache.uima.flow.ParallelStep; import org.apache.uima.flow.Step; import org.apache.uima.resource.ResourceInitializationException; /** * FlowController for testing ParallelStep. */ public class ParallelFlowController extends CasFlowController_ImplBase { public void initialize(FlowControllerContext aContext) throws ResourceInitializationException { super.initialize(aContext); } /* * (non-Javadoc) * * @see org.apache.uima.flow.CasFlowController_ImplBase#computeFlow(org.apache.uima.cas.CAS) */ public Flow computeFlow(CAS aCAS) throws AnalysisEngineProcessException { ParallelFlowObject ffo = new ParallelFlowObject(); ffo.setCas(aCAS); return ffo; } class ParallelFlowObject extends CasFlow_ImplBase { private boolean done = false; /** * Create a new fixed flow starting at step startStep of the fixed sequence. * */ public ParallelFlowObject() { //do nothing } /* * (non-Javadoc) * * @see org.apache.uima.flow.Flow#next() */ public Step next() throws AnalysisEngineProcessException { if (!done) { done = true; Set keys = getContext().getAnalysisEngineMetaDataMap().keySet(); return new ParallelStep(keys); } else { return new FinalStep(); } } /* (non-Javadoc) * @see org.apache.uima.flow.CasFlow_ImplBase#newCasProduced(org.apache.uima.cas.CAS, java.lang.String) */ protected Flow newCasProduced(CAS newCas, String producedBy) throws AnalysisEngineProcessException { //for this test, new segments don't continue in the flow return new EmptyFlow(); } } class EmptyFlow extends CasFlow_ImplBase { public Step next() { return new FinalStep(); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineResegmenter.java0000644000175000017500000001146511665471064033002 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.Iterator; import org.apache.uima.analysis_component.JCasMultiplier_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.AbstractCas; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.examples.SourceDocumentInformation; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation; /** * */ public class NewlineResegmenter extends JCasMultiplier_ImplBase { JCas mCurrentInputCas; String mDoc; int mCurIndex = 0; StringBuffer mBuf = new StringBuffer(); JCas[] mJCases = new JCas[2]; int mActiveJCas = 0; boolean mHasNext; /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS) */ public void process(JCas aJCas) throws AnalysisEngineProcessException { mCurrentInputCas = aJCas; mDoc = aJCas.getDocumentText(); readToNextNewline(); } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext() */ public boolean hasNext() throws AnalysisEngineProcessException { return mHasNext; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#next() */ public AbstractCas next() throws AnalysisEngineProcessException { // we should already have a JCas ready to return JCas toReturn = mJCases[mActiveJCas]; mJCases[mActiveJCas] = null; assert toReturn != null; // now go read the next segment into our other JCas mActiveJCas ^= 1; if (mCurIndex < mDoc.length()) { readToNextNewline(); } else { // end of the input document mCurIndex = 0; mHasNext = false; } return toReturn; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.JCasSegmenter_ImplBase#getCasInstancesRequired() */ public int getCasInstancesRequired() { return 2; } private void readToNextNewline() { // does this doc contain a newline? int nlIndex = mDoc.indexOf('\n', mCurIndex); if (nlIndex == -1) // no newline { // append entire rest of doc to active buffer int begin = mBuf.length(); // record start offset of new text mBuf.append(mDoc.substring(mCurIndex)); if (mJCases[mActiveJCas] == null) { mJCases[mActiveJCas] = getEmptyJCas(); } // add SourceDocumentInformation to active JCas SourceDocumentInformation sdi = new SourceDocumentInformation(mJCases[mActiveJCas]); sdi.setBegin(begin); sdi.setEnd(mBuf.length()); sdi.setUri(getCasSourceUri(mCurrentInputCas)); sdi.addToIndexes(); mHasNext = false; // we need to see another input CAS before we can create output mCurIndex = 0; } else // yes, newline { // append doc up to newline int begin = mBuf.length(); // record start offset of new text mBuf.append(mDoc.substring(mCurIndex, nlIndex)); if (mJCases[mActiveJCas] == null) { mJCases[mActiveJCas] = getEmptyJCas(); } // add SourceDocumentInformation to active JCas SourceDocumentInformation sdi = new SourceDocumentInformation(mJCases[mActiveJCas]); sdi.setBegin(begin); sdi.setEnd(mBuf.length()); sdi.setUri(getCasSourceUri(mCurrentInputCas)); sdi.addToIndexes(); // set doc text mJCases[mActiveJCas].setDocumentText(mBuf.toString()); mBuf.setLength(0); mCurIndex = nlIndex + 1; mHasNext = true; // ready to output! } } private String getCasSourceUri(JCas jcas) { Iterator iter = jcas.getJFSIndexRepository().getAnnotationIndex(SourceDocumentInformation.type) .iterator(); if (iter.hasNext()) { SourceDocumentInformation sdi = (SourceDocumentInformation) iter.next(); return sdi.getUri(); } else { return "unknown"; } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecification_implTe0000644000175000017500000005644311665471064033556 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.util.Arrays; import java.util.List; import java.util.Vector; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ResultSpecification_implTest extends TestCase { private TypeOrFeature[] mTypesAndFeatures; private Capability[] capabilities; private Capability cap4; private List languages; private TypeOrFeature t1, t2, f1; /** * Constructor for ResultSpecification_implTest. * * @param arg0 */ public ResultSpecification_implTest(String arg0) { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { // create array of types and features for use in testing t1 = new TypeOrFeature_impl(); t1.setType(true); t1.setName("FakeType"); t1.setAllAnnotatorFeatures(false); f1 = new TypeOrFeature_impl(); f1.setType(false); f1.setName("FakeType:FakeFeature"); t2 = new TypeOrFeature_impl(); t2.setType(true); t2.setName("AnotherType"); t2.setAllAnnotatorFeatures(true); mTypesAndFeatures = new TypeOrFeature[] { t1, f1, t2 }; // create capability[] for language tests // capability 1 - using t1 Capability cap1 = new Capability_impl(); String[] languages1 = { "en", "de", "en-US", "en-GB" }; TypeOrFeature[] tofs1 = { t1 }; cap1.setLanguagesSupported(languages1); cap1.setOutputs(tofs1); // capability 2 - using f1 Capability cap2 = new Capability_impl(); String[] languages2 = { "ja", "en" }; TypeOrFeature[] tofs2 = { f1 }; cap2.setLanguagesSupported(languages2); cap2.setOutputs(tofs2); // capability 3 - using t2 Capability cap3 = new Capability_impl(); String[] languages3 = { "x-unspecified" }; TypeOrFeature[] tofs3 = { t2 }; cap3.setLanguagesSupported(languages3); cap3.setOutputs(tofs3); // capability 4 - using f1 cap4 = new Capability_impl(); String[] languages4 = {}; // length 0 string TypeOrFeature[] tofs4 = { f1 }; cap4.setLanguagesSupported(languages4); cap4.setOutputs(tofs4); // make capability array with the above specified values capabilities = new Capability[] { cap1, cap2, cap3 }; // make languages array languages = new Vector(3); languages.add(0, languages1); languages.add(1, languages2); languages.add(2, languages3); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddCapabilities() throws Exception { try { // create ResultSpecification with capabilities ResultSpecification_impl resultSpecLanguage = new ResultSpecification_impl(); // add capabilities to the result spec resultSpecLanguage.addCapabilities(capabilities); // check TypeOrFeature[] result = resultSpecLanguage.getResultTypesAndFeatures(); // sort array before check Arrays.sort(result); Arrays.sort(mTypesAndFeatures); Assert.assertEquals(mTypesAndFeatures.length, result.length); for (int i = 0; i < result.length; i++) { Assert.assertEquals(mTypesAndFeatures[i], result[i]); } // test defaulting - if no language, should be x-unspecified resultSpecLanguage = new ResultSpecification_impl(); resultSpecLanguage.addCapabilities(new Capability[] {cap4}); assertTrue(resultSpecLanguage.containsFeature("FakeType:FakeFeature")); assertTrue(resultSpecLanguage.containsFeature("FakeType:FakeFeature", "en")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddCapabilitiesWithoutLanguage() throws Exception { try { TypeOrFeature t4 = new TypeOrFeature_impl(); t4.setType(true); t4.setName("AnotherFakeType"); t4.setAllAnnotatorFeatures(false); // capability 4 - using t4 but now language Capability cap4 = new Capability_impl(); TypeOrFeature[] tofs4 = { t4 }; cap4.setOutputs(tofs4); // create ResultSpecification with capabilities ResultSpecification_impl resultSpec = new ResultSpecification_impl(); // add capabilities to the result spec resultSpec.addCapabilities(new Capability[] { cap4 }); assertTrue(resultSpec.containsType("AnotherFakeType")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSetResultTypesAndFeatures() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures); // check TypeOrFeature[] result = rs.getResultTypesAndFeatures(); // sort array before check Arrays.sort(result); Arrays.sort(mTypesAndFeatures); Assert.assertEquals(mTypesAndFeatures.length, result.length); for (int i = 0; i < result.length; i++) { Assert.assertEquals(mTypesAndFeatures[i], result[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSetResultTypesAndFeaturesWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures, languages.get(0)); // check for language en TypeOrFeature[] resultEn = rs.getResultTypesAndFeatures("en"); // sort array before check Arrays.sort(resultEn); Arrays.sort(mTypesAndFeatures); Assert.assertEquals(mTypesAndFeatures.length, resultEn.length); for (int i = 0; i < resultEn.length; i++) { Assert.assertEquals(mTypesAndFeatures[i], resultEn[i]); } // check for language ja TypeOrFeature[] resultJa = rs.getResultTypesAndFeatures("ja"); Assert.assertEquals(0, resultJa.length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultTypeOrFeature() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); for (int i = 0; i < mTypesAndFeatures.length; i++) { rs.addResultTypeOrFeature(mTypesAndFeatures[i]); } // check TypeOrFeature[] result = rs.getResultTypesAndFeatures(); Arrays.sort(result); Arrays.sort(mTypesAndFeatures); Assert.assertEquals(mTypesAndFeatures.length, result.length); for (int i = 0; i < result.length; i++) { Assert.assertEquals(mTypesAndFeatures[i], result[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultTypeOrFeatureWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); for (int i = 0; i < mTypesAndFeatures.length; i++) { rs.addResultTypeOrFeature(mTypesAndFeatures[i], languages.get(i)); } // check for language en TypeOrFeature[] expectedEnResult = new TypeOrFeature[] { t1, t2, f1 }; Arrays.sort(expectedEnResult); TypeOrFeature[] resultEn = rs.getResultTypesAndFeatures("en"); Arrays.sort(resultEn); Assert.assertEquals(expectedEnResult.length, resultEn.length); for (int i = 0; i < resultEn.length; i++) { Assert.assertEquals(expectedEnResult[i], resultEn[i]); } // check for language de TypeOrFeature[] expectedDeResult = new TypeOrFeature[] { t1, t2 }; Arrays.sort(expectedDeResult); TypeOrFeature[] resultDe = rs.getResultTypesAndFeatures("de"); Arrays.sort(resultDe); Assert.assertEquals(expectedDeResult.length, resultDe.length); for (int i = 0; i < resultDe.length; i++) { Assert.assertEquals(expectedDeResult[i], resultDe[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultType() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addResultType("FakeType", false); rs.addResultType("AnotherType", true); // check TypeOrFeature[] result = rs.getResultTypesAndFeatures(); Assert.assertEquals(2, result.length); int ftIndex = result[0].getName().equals("FakeType") ? 0 : 1; int atIndex = ftIndex == 0 ? 1 : 0; Assert.assertEquals("FakeType", result[ftIndex].getName()); Assert.assertEquals(true, result[ftIndex].isType()); Assert.assertEquals(false, result[ftIndex].isAllAnnotatorFeatures()); Assert.assertEquals("AnotherType", result[atIndex].getName()); Assert.assertEquals(true, result[atIndex].isType()); Assert.assertEquals(true, result[atIndex].isAllAnnotatorFeatures()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultTypeWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addResultType("FakeType", false, languages.get(0)); rs.addResultType("AnotherType", true, languages.get(2)); rs.addResultType("NewDefinedType", true, new String[] { "ja" }); // check for language en TypeOrFeature[] resultEn = rs.getResultTypesAndFeatures("en"); Arrays.sort(resultEn); Assert.assertEquals(2, resultEn.length); int ftIndex = resultEn[0].getName().equals("FakeType") ? 0 : 1; int atIndex = ftIndex == 0 ? 1 : 0; Assert.assertEquals("AnotherType", resultEn[atIndex].getName()); Assert.assertEquals(true, resultEn[atIndex].isType()); Assert.assertEquals(true, resultEn[atIndex].isAllAnnotatorFeatures()); Assert.assertEquals("FakeType", resultEn[ftIndex].getName()); Assert.assertEquals(true, resultEn[ftIndex].isType()); Assert.assertEquals(false, resultEn[ftIndex].isAllAnnotatorFeatures()); // check for language ja TypeOrFeature[] resultJa = rs.getResultTypesAndFeatures("ja"); Arrays.sort(resultJa); Assert.assertEquals(2, resultJa.length); atIndex = resultJa[0].getName().equals("AnotherType") ? 0 : 1; int ndtIndex = atIndex == 0 ? 1 : 0; Assert.assertEquals("AnotherType", resultJa[atIndex].getName()); Assert.assertEquals(true, resultJa[atIndex].isType()); Assert.assertEquals(true, resultJa[atIndex].isAllAnnotatorFeatures()); Assert.assertEquals("NewDefinedType", resultJa[ndtIndex].getName()); Assert.assertEquals(true, resultJa[ndtIndex].isType()); Assert.assertEquals(true, resultJa[ndtIndex].isAllAnnotatorFeatures()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultFeature() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addResultFeature("FakeType:FakeFeature"); rs.addResultFeature("AnotherType:AnotherFeature"); // check TypeOrFeature[] result = rs.getResultTypesAndFeatures(); Arrays.sort(result); Assert.assertEquals(2, result.length); int atafIndex = result[0].getName().equals("AnotherType:AnotherFeature") ? 0 : 1; int ftffIndex = atafIndex == 0 ? 1 : 0; Assert.assertEquals("AnotherType:AnotherFeature", result[atafIndex].getName()); Assert.assertEquals(false, result[atafIndex].isType()); Assert.assertEquals("FakeType:FakeFeature", result[ftffIndex].getName()); Assert.assertEquals(false, result[ftffIndex].isType()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAddResultFeatureWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addResultFeature("FakeType:FakeFeature", new String[] { "ja" }); rs.addResultFeature("AnotherType:AnotherFeature", new String[] { "en" }); // check for language en TypeOrFeature[] resultEn = rs.getResultTypesAndFeatures("en"); Assert.assertEquals(1, resultEn.length); Assert.assertEquals("AnotherType:AnotherFeature", resultEn[0].getName()); Assert.assertEquals(false, resultEn[0].isType()); // check for language ja TypeOrFeature[] resultJa = rs.getResultTypesAndFeatures("ja"); Assert.assertEquals(1, resultJa.length); Assert.assertEquals("FakeType:FakeFeature", resultJa[0].getName()); Assert.assertEquals(false, resultJa[0].isType()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testContainsType() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures); Assert.assertTrue(rs.containsType("FakeType")); Assert.assertFalse(rs.containsType("NotThere")); Assert.assertTrue(rs.containsType("AnotherType")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("AnotherType:AnotherFeature")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testContainsTypeWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addCapabilities(capabilities); Assert.assertTrue(rs.containsType("FakeType", "en")); Assert.assertFalse(rs.containsType("FakeType", "ja")); Assert.assertFalse(rs.containsType("NotThere", "en")); Assert.assertTrue(rs.containsType("AnotherType", "en-US")); Assert.assertTrue(rs.containsType("AnotherType", "x-unspecified")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature", "de")); Assert.assertFalse(rs.containsType("AnotherType:AnotherFeature", "de")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testContainsFeature() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures); Assert.assertTrue(rs.containsFeature("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature2")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl")); Assert.assertFalse(rs.containsType("NotThere:FakeFeature")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testContainsFeatureWithLanguage() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addCapabilities(capabilities); Assert.assertTrue(rs.containsFeature("FakeType:FakeFeature", "ja")); Assert.assertTrue(rs.containsFeature("FakeType:FakeFeature", "en")); Assert.assertFalse(rs.containsFeature("FakeType:FakeFeature", "de")); Assert.assertFalse(rs.containsFeature("FakeType:FakeFeature2", "ja")); Assert.assertFalse(rs.containsFeature("FakeType:FakeFeature2", "x-unspecified")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature", "en")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature", "de")); Assert.assertFalse(rs.containsFeature("AnotherType1:YetAnotherFeature", "de")); Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl", "ja")); Assert.assertFalse(rs.containsFeature("NotThere:FakeFeature", "ja")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testRemoveTypeOrFeature() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addCapabilities(capabilities); // remove t1 rs.removeTypeOrFeature(t1); // check TypeOrFeature[] expectedResult = new TypeOrFeature[] { f1, t2 }; TypeOrFeature[] result = rs.getResultTypesAndFeatures(); Arrays.sort(result); Arrays.sort(expectedResult); Assert.assertEquals(expectedResult.length, result.length); for (int i = 0; i < result.length; i++) { Assert.assertEquals(expectedResult[i], result[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCompile() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures); // create Type System CASMgr casMgr = CASFactory.createCAS(); TypeSystemMgr tsMgr = casMgr.getTypeSystemMgr(); Type fakeType = tsMgr.addType("FakeType", tsMgr.getTopType()); Type anotherType = tsMgr.addType("AnotherType", tsMgr.getTopType()); tsMgr.addFeature("FakeFeature", fakeType, tsMgr.getTopType()); tsMgr.addFeature("FakeFeature2", fakeType, tsMgr.getTopType()); tsMgr.addFeature("AnotherFeature", anotherType, tsMgr.getTopType()); tsMgr.addFeature("YetAnotherFeature", anotherType, tsMgr.getTopType()); // compile rs.compile(tsMgr); // check Assert.assertTrue(rs.containsType("FakeType")); Assert.assertFalse(rs.containsType("NotThere")); Assert.assertTrue(rs.containsType("AnotherType")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature2")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl")); // unknown features are there, if the type says allFeats Assert.assertFalse(rs.containsType("NotThere:FakeFeature")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCompileWithCapabilities() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.addCapabilities(capabilities); // create Type System CASMgr casMgr = CASFactory.createCAS(); TypeSystemMgr tsMgr = casMgr.getTypeSystemMgr(); Type fakeType = tsMgr.addType("FakeType", tsMgr.getTopType()); Type anotherType = tsMgr.addType("AnotherType", tsMgr.getTopType()); tsMgr.addFeature("FakeFeature", fakeType, tsMgr.getTopType()); tsMgr.addFeature("FakeFeature2", fakeType, tsMgr.getTopType()); tsMgr.addFeature("AnotherFeature", anotherType, tsMgr.getTopType()); tsMgr.addFeature("YetAnotherFeature", anotherType, tsMgr.getTopType()); tsMgr.addType("SubType", fakeType); // compile rs.compile(tsMgr); // check Assert.assertFalse(rs.containsType("FakeType")); Assert.assertTrue(rs.containsType("FakeType", "en")); Assert.assertTrue(rs.containsType("FakeType", "en-us")); Assert.assertTrue(rs.containsType("FakeType", "EN_US")); Assert.assertFalse(rs.containsType("NotThere")); Assert.assertTrue(rs.containsType("AnotherType")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("AnotherType:AnotherFeature")); Assert.assertFalse(rs.containsFeature("FakeType:FakeFeature")); Assert.assertFalse(rs.containsType("FakeType:FakeFeature2")); Assert.assertTrue(rs.containsFeature("AnotherType:AnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:YetAnotherFeature")); Assert.assertTrue(rs.containsFeature("AnotherType:asdfghjkl")); // unknown features are there if type says allfeats Assert.assertFalse(rs.containsType("NotThere:FakeFeature")); Assert.assertFalse(rs.containsFeature("NotThere:FakeFeature")); Assert.assertFalse(rs.containsType("SubType")); Assert.assertTrue(rs.containsType("SubType", "en")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXmlization() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); Arrays.sort(mTypesAndFeatures); rs.setResultTypesAndFeatures(mTypesAndFeatures); // write object to XML StringWriter writer = new StringWriter(); rs.toXML(writer); String rsXml = writer.getBuffer().toString(); // System.out.println(rsXml); // parse object back from XML InputStream is = new ByteArrayInputStream(rsXml.getBytes(encoding)); ResultSpecification newRS = UIMAFramework.getXMLParser().parseResultSpecification( new XMLInputSource(is, null)); TypeOrFeature[] tofs = newRS.getResultTypesAndFeatures(); Arrays.sort(tofs); newRS.setResultTypesAndFeatures(tofs); Assert.assertEquals(rs, newRS); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testClone() throws Exception { try { ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setResultTypesAndFeatures(mTypesAndFeatures); ResultSpecification_impl rsNew = (ResultSpecification_impl) rs.clone(); TypeOrFeature[] rsToFs = rs.getResultTypesAndFeatures(); TypeOrFeature[] rsNewToFs = rsNew.getResultTypesAndFeatures(); Arrays.sort(rsToFs); Arrays.sort(rsNewToFs); Assert.assertEquals(rsToFs.length, rsNewToFs.length); for (int i = 0; i < rsToFs.length; i++) { Assert.assertEquals(rsToFs[i], rsNewToFs[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/TestAnnotator.java0000644000175000017500000000630611665471064032003 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException; import org.apache.uima.analysis_engine.annotator.AnnotatorContext; import org.apache.uima.analysis_engine.annotator.AnnotatorContextException; import org.apache.uima.analysis_engine.annotator.AnnotatorInitializationException; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.Annotator_ImplBase; import org.apache.uima.analysis_engine.annotator.TextAnnotator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; /** * Annotator class used for testing * */ public class TestAnnotator extends Annotator_ImplBase implements TextAnnotator { // Process method saves information to these static fields, // which are queried by the unit test. public static String lastDocument; public static String stringParamValue; public static ResultSpecification lastResultSpec; public static boolean typeSystemInitCalled; public static synchronized String getLastDocument() { return lastDocument; } public static synchronized ResultSpecification getLastResultSpec() { return lastResultSpec; } /** * @see org.apache.uima.analysis_engine.annotator.Annotator#initialize(AnnotatorContext) */ public void initialize(AnnotatorContext aContext) throws AnnotatorConfigurationException, AnnotatorInitializationException { super.initialize(aContext); typeSystemInitCalled = false; lastResultSpec = null; lastDocument = null; try { stringParamValue = (String) getContext().getConfigParameterValue("StringParam"); } catch (AnnotatorContextException e) { throw new AnnotatorInitializationException(e); } } public void typeSystemInit(TypeSystem aTypeSystem) { typeSystemInitCalled = true; } /** * @see org.apache.uima.analysis_engine.annotator.TextAnnotator#process(CAS,ResultSpecification) */ public void process(CAS aCAS, ResultSpecification aResultSpec) throws AnnotatorProcessException { // set static fields to contain document text, result spec, // and value of StringParam configuration parameter. lastDocument = aCAS.getDocumentText(); lastResultSpec = aResultSpec; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/0000755000175000017500000000000011665471064030320 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerTestAnnotator.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerTestAnn0000644000175000017500000001167611665471064033505 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl.sequencer; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Arrays; import java.util.Comparator; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException; import org.apache.uima.analysis_engine.annotator.AnnotatorContext; import org.apache.uima.analysis_engine.annotator.AnnotatorContextException; import org.apache.uima.analysis_engine.annotator.AnnotatorInitializationException; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.Annotator_ImplBase; import org.apache.uima.analysis_engine.annotator.TextAnnotator; import org.apache.uima.cas.CAS; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Dummy annotator which does not processing. Annotator only writes his name and * his result specification to a text file * */ public class SequencerTestAnnotator extends Annotator_ImplBase implements TextAnnotator { // annotator name private String name; private File testBaseDir; public SequencerTestAnnotator() { super(); this.testBaseDir = JUnitExtension.getFile("SequencerTest"); } /** * method to read configuration parameter for the annotator */ private static String secureGetConfigParameterValue( AnnotatorContext context, String param, String defaultValue) throws AnnotatorContextException { String name = (String) context.getConfigParameterValue(param); if (name != null) { return name; } return defaultValue; } /** * @see org.apache.uima.analysis_engine.annotator.BaseAnnotator#initialize(org.apache.uima.analysis_engine.annotator.AnnotatorContext) */ public void initialize(AnnotatorContext context) throws AnnotatorInitializationException, AnnotatorConfigurationException { try { // read annotator name from configuration parameter 'AnnotatorName' this.name = secureGetConfigParameterValue(context, "AnnotatorName", "defaultName"); } catch (AnnotatorContextException e) { throw new AnnotatorConfigurationException(e); } } /** * @see org.apache.uima.analysis_engine.annotator.TextAnnotator#process(org.apache.uima.cas.text.CAS, * org.apache.uima.analysis_engine.ResultSpecification) */ public void process(CAS tcas, ResultSpecification resultSpec) throws AnnotatorProcessException { if (true) { try { // use standard output file File fp = new File(this.testBaseDir, "SequencerTest.txt"); if (!fp.exists()) { fp.createNewFile(); } if (fp.canWrite()) { // write result specification to the output file OutputStreamWriter writer = new OutputStreamWriter( new FileOutputStream(fp, true), "UTF-8"); writer.write("\nResultSpec for annotator " + this.name + ":\n"); TypeOrFeature[] tofs = resultSpec.getResultTypesAndFeatures(); // sort by name to ensure consistent output for testing purposes Arrays.sort(tofs, new Comparator() { public int compare(TypeOrFeature o1, TypeOrFeature o2) { return o1.getName().compareTo(o2.getName()); } }); for (int i = 0; i < tofs.length; i++) { writer.write(tofs[i].getName() + "\n"); } writer.flush(); writer.close(); } else { throw new IOException("Cannot write to " + fp.getAbsolutePath()); } } catch (IOException e) { // If an error occurs, throw new annotator exception throw new AnnotatorProcessException(e); } } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerFixedTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerFixedTe0000644000175000017500000003527111665471064033456 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl.sequencer; import java.io.File; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.FileCompare; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /* */ /** * TestCase for the Sequencer with a fixedFlow */ public class SequencerFixedTest extends TestCase { private File testBaseDir; /** * Constructor for SequencerTest * * @param arg0 */ public SequencerFixedTest(String arg0) { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // get test base path this.testBaseDir = JUnitExtension.getFile("SequencerTest"); } public void testSequencerFixedEn() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("en"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedEN() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("EN"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedEnUS() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("en-US"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedEnus() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("en-us"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedUnkown() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("unkown"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedFooBar() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("foo-BAR"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerFixedXunSpec() throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file outputReferenceFile.deleteOnExit(); // delete file after closing VM // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("SequencerTest/SequencerFixedAggregate.xml")); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage("x-unspecified"); // Process the sample document. ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); // check fileoutput Assert.assertTrue(FileCompare.compare(outputReferenceFile, JUnitExtension .getFile("SequencerTest/SequencerFixedExpected.txt"))); outputReferenceFile.delete(); } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerCapabilityLanguageTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/sequencer/SequencerCapabil0000644000175000017500000002336211665471064033457 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl.sequencer; import java.io.File; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.FileCompare; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * Testclass for Sequencers with a capabilityLanguageFlow * */ public class SequencerCapabilityLanguageTest extends TestCase { private File testBaseDir = null; /** * Constructor for SequencerTest * * @param arg0 */ public SequencerCapabilityLanguageTest(String arg0) { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { this.testBaseDir = JUnitExtension.getFile("SequencerTest"); } public void runTest(String desc, String language, String refFile, boolean doResultSpec) throws Exception { AnalysisEngine ae = null; try { // create TempFile for test File outputReferenceFile = new File(this.testBaseDir, "SequencerTest.txt"); outputReferenceFile.delete(); // delete file if exist outputReferenceFile.createNewFile(); // create new file // Create an XML input source from the specifier file. XMLInputSource in = new XMLInputSource(JUnitExtension.getFile(desc)); // Parse the specifier. ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); // Create the Text Analysis Engine. ae = UIMAFramework.produceAnalysisEngine(specifier, null, null); // Create a new CAS. CAS cas = ae.newCAS(); // Our sample text. String text = "Hello world!"; // System.out.println("Processing text: \"" + text + "\""); // Set the document text on the CAS. cas.setDocumentText(text); cas.setDocumentLanguage(language); // Process the sample document. if (doResultSpec) { ResultSpecification resultSpec = UIMAFramework.getResourceSpecifierFactory() .createResultSpecification(); resultSpec.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ae.process(cas, resultSpec); } else { ae.process(cas); } // check fileoutput boolean compare = FileCompare.compare(outputReferenceFile, JUnitExtension.getFile(refFile)); Assert.assertTrue(compare); if (compare) { outputReferenceFile.delete(); } } catch (Exception ex) { JUnitExtension.handleException(ex); } finally { // Destroy the CAS, releasing resources. if (ae != null) { ae.destroy(); } } } public void testSequencerCapabilityLanguageEsEn() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "en", "SequencerTest/SequencerCapabilityLanguageExpectedEsEn.txt", false); } public void testSequencerCapabilityLanguageEsEnResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "en", "SequencerTest/SequencerCapabilityLanguageExpectedEsEnResultSpec.txt", true); } public void testSequencerCapabilityLanguageEsEnUS() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "en-US", "SequencerTest/SequencerCapabilityLanguageExpectedEsEnUS.txt", false); } public void testSequencerCapabilityLanguageEsEnUSResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "en-US", "SequencerTest/SequencerCapabilityLanguageExpectedEsEnResultSpec.txt", true); } public void testSequencerCapabilityLanguageEsAr() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "ar", "SequencerTest/SequencerCapabilityLanguageExpectedEsAr.txt", false); } public void testSequencerCapabilityLanguageEsArResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "ar", "SequencerTest/SequencerCapabilityLanguageExpectedEsAr.txt", true); } public void testSequencerCapabilityLanguageEsUnkown() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "unknown", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", false); } public void testSequencerCapabilityLanguageEsUnkownResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "unknown", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", true); } public void testSequencerCapabilityLanguageEsZhCN() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "zh-CN", "SequencerTest/SequencerCapabilityLanguageExpectedEsZhCN.txt", false); } public void testSequencerCapabilityLanguageEsZhCNResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "zh-CN", "SequencerTest/SequencerCapabilityLanguageExpectedEsZhCNResultSpec.txt", true); } public void testSequencerCapabilityLanguageEsXunSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "x-unspecified", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", false); } public void testSequencerCapabilityLanguageEsXunSpecResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "x-unspecified", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", true); } public void testSequencerCapabilityLanguageEn() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "en", "SequencerTest/SequencerCapabilityLanguageExpectedEn.txt", false); } public void testSequencerCapabilityLanguageEnResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "en", "SequencerTest/SequencerCapabilityLanguageExpectedEnResultSpec.txt", true); } public void testSequencerCapabilityLanguageEnResultSpecCapital() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "EN", "SequencerTest/SequencerCapabilityLanguageExpectedEnResultSpec.txt", true); } public void testSequencerCapabilityLanguageJa() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "ja", "SequencerTest/SequencerCapabilityLanguageExpectedJa.txt", false); } public void testSequencerCapabilityLanguageJaResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "ja", "SequencerTest/SequencerCapabilityLanguageExpectedJaResultSpec.txt", true); } public void testSequencerCapabilityLanguageXunSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "x-unspecified", "SequencerTest/SequencerCapabilityLanguageExpectedXunSpec.txt", false); } public void testSequencerCapabilityLanguageXunSpecResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregate.xml", "x-unspecified", "SequencerTest/SequencerCapabilityLanguageExpectedXunSpec.txt", true); } public void testSequencerCapabilityLanguageEsFooBar() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "foo-BAR", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", false); } public void testSequencerCapabilityLanguageEsFooBarResultSpec() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "foo-BAR", "SequencerTest/SequencerCapabilityLanguageExpectedEsUnknown.txt", true); } public void testSequencerCapabilityLanguageEsZhCNSmall() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "zh-cn", "SequencerTest/SequencerCapabilityLanguageExpectedEsZhCN.txt", false); } public void testSequencerCapabilityLanguageEsZhCNResultSpecSmall() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateES.xml", "zh-cn", "SequencerTest/SequencerCapabilityLanguageExpectedEsZhCNResultSpec.txt", true); } public void testSequencerCapabilityLanguageResultSpecSetByFlowController() throws Exception { runTest("SequencerTest/SequencerCapabilityLanguageAggregateResultSpec.xml", "en", "SequencerTest/SequencerCapabilityLanguageExpectedResultSpecSetByFlowController.txt", false); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/metadata/0000755000175000017500000000000011665471064030106 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/metadata/SofaMapping_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/metadata/SofaMapping_implT0000644000175000017500000000545011665471064033406 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl.metadata; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.metadata.impl.SofaMapping_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class SofaMapping_implTest extends TestCase { SofaMapping_impl sm1; SofaMapping_impl sm2; /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); sm1 = new SofaMapping_impl(); sm1.setAggregateSofaName("aggSofa"); sm1.setComponentKey("myAnnotator"); sm1.setComponentSofaName("compSofa"); sm2 = new SofaMapping_impl(); sm2.setAggregateSofaName("aggSofa"); sm2.setComponentKey("myAnnotator2"); } public void testXmlization() throws Exception { try { // write to XML StringWriter writer = new StringWriter(); sm1.toXML(writer); String sm1Xml = writer.getBuffer().toString(); writer = new StringWriter(); sm2.toXML(writer); String sm2Xml = writer.getBuffer().toString(); // parse from XML InputStream is = new ByteArrayInputStream(sm1Xml.getBytes(encoding)); SofaMapping_impl newSm1 = (SofaMapping_impl) UIMAFramework.getXMLParser().parse( new XMLInputSource(is, null)); is = new ByteArrayInputStream(sm2Xml.getBytes(encoding)); SofaMapping_impl newSm2 = (SofaMapping_impl) UIMAFramework.getXMLParser().parse( new XMLInputSource(is, null)); Assert.assertEquals(sm1, newSm1); Assert.assertEquals(sm2, newSm2); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngineDescription_0000644000175000017500000006445011665471066033540 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.analysis_engine.metadata.impl.FlowControllerDeclaration_impl; import org.apache.uima.cas.CAS; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.flow.impl.FlowControllerDescription_impl; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.OperationalProperties; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.Import_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Test the AnalysisEngineDescription_impl class. * */ public class AnalysisEngineDescription_implTest extends TestCase { // Text encoding to use for the various byte/character conversions happening in this test case. // Public because also used by other test cases. public static final String encoding = "utf-8"; private AnalysisEngineDescription primitiveDesc; private AnalysisEngineDescription aggregateDesc; /** * Constructor for AnalysisEngineDescription_implTest. * * @param arg0 */ public AnalysisEngineDescription_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Fake", "Fake Type", "Annotation"); FeatureDescription feature1 = type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Fake"); priorityList.addType("EnumType"); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("testIndex"); index.setTypeName("Fake"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("TestFeature"); key1.setComparator(1); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Start"); key2.setComparator(0); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setTypePriority(true); index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("testIndex2"); index2.setTypeName("Fake"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl(); key1a.setFeatureName("TestFeature"); key1a.setComparator(1); index2.setKeys(new FsIndexKeyDescription[] { key1a }); // create primitive AE description primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primitiveDesc.setPrimitive(true); primitiveDesc.setAnnotatorImplementationName("org.apache.uima.examples.TestAnnotator"); AnalysisEngineMetaData md = primitiveDesc.getAnalysisEngineMetaData(); md.setName("Test TAE"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); md.setTypeSystem(typeSystem); md.setTypePriorities(typePriorities); md.setFsIndexes(new FsIndexDescription[] { index, index2 }); Capability cap1 = new Capability_impl(); cap1.setDescription("First fake capability"); cap1.addOutputType("Fake", false); cap1.addOutputFeature("TestFeature"); Capability cap2 = new Capability_impl(); cap2.setDescription("Second fake capability"); cap2.addInputType("Fake", true); cap2.addOutputType("Fake", true); // SimplePrecondition precond1 = new SimplePrecondition_impl(); // precond1.setFeatureDescription(feature1); // precond1.setComparisonValue(new String[]{"en,de"}); // precond1.setPredicate(SimplePrecondition.LANGUAGE_SUBSUMED); // cap1.setPreconditions(new Precondition[]{precond1}); cap1.setLanguagesSupported(new String[] { "en", "de" }); cap1.setMimeTypesSupported(new String[] { "text/plain" }); md.setCapabilities(new Capability[] { cap1, cap2 }); ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl(); cfgParam1.setName("param1"); cfgParam1.setDescription("Test Parameter 1"); cfgParam1.setType("String"); ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl(); cfgParam2.setName("param2"); cfgParam2.setDescription("Test Parameter 2"); cfgParam2.setType("Integer"); ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl(); cfgGrp1.setNames(new String[] { "cfgGrp1" }); cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 }); ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl(); cfgParam3.setName("param3"); cfgParam3.setDescription("Test Parameter 3"); cfgParam3.setType("Float"); ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl(); cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" }); cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 }); md.getConfigurationParameterDeclarations().setConfigurationGroups( new ConfigurationGroup[] { cfgGrp1, cfgGrp2 }); NameValuePair nvp1 = new NameValuePair_impl("param1", "test"); NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42")); NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045")); NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927")); ConfigurationParameterSettings settings = md.getConfigurationParameterSettings(); settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 }); settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a }); settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b }); // create aggregate AE description aggregateDesc = new AnalysisEngineDescription_impl(); aggregateDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggregateDesc.setPrimitive(false); Map delegateTaeMap = aggregateDesc.getDelegateAnalysisEngineSpecifiersWithImports(); delegateTaeMap.put("Test", primitiveDesc); AnalysisEngineDescription_impl primDesc2 = new AnalysisEngineDescription_impl(); primDesc2.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primDesc2.setAnnotatorImplementationName("fakeClass"); primDesc2.getAnalysisEngineMetaData().setName("fakeAnnotator"); primDesc2.getAnalysisEngineMetaData().setCapabilities( new Capability[] { new Capability_impl() }); delegateTaeMap.put("Empty", primDesc2); URISpecifier uriSpec = new URISpecifier_impl(); uriSpec.setUri("http://incubator.apache.org/uima"); uriSpec.setProtocol(Constants.PROTOCOL_SOAP); FlowControllerDeclaration fcDecl = new FlowControllerDeclaration_impl(); fcDecl.setKey("TestFlowController"); FlowControllerDescription fcDesc = new FlowControllerDescription_impl(); fcDesc.getMetaData().setName("MyTestFlowController"); fcDecl.setSpecifier(fcDesc); aggregateDesc.setFlowControllerDeclaration(fcDecl); ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDependency(); dep.setKey("ResourceKey"); dep.setDescription("Test"); aggregateDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep }); ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory() .createResourceManagerConfiguration(); ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDescription(); extRes.setResourceSpecifier(uriSpec); extRes.setName("Resource1"); extRes.setDescription("Test"); resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes }); ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceBinding(); binding.setKey("ResourceKey"); binding.setResourceName("Resource1"); aggregateDesc.setResourceManagerConfiguration(resMgrCfg); // AsbCreationSpecifier asbSpec = new AsbCreationSpecifier_impl(); // asbSpec.getAsbMetaData().setAsynchronousModeSupported(true); // asbSpec.getAsbMetaData().setSupportedProtocols(new String[]{Constants.PROTOCOL_SOAP}); // aggregateDesc.setAsbSpecifier(asbSpec); // AnalysisSequencerCrea1tionSpecifier seqSpec = new // AnalysisSequencerCreationSpecifier_impl(); // seqSpec.getAnalysisSequencerMetaData().setSupportedPreconditionTypes( // new String[]{SimplePrecondition.PRECONDITION_TYPE}); // aggregateDesc.setSequencerSpecifier(seqSpec); md = aggregateDesc.getAnalysisEngineMetaData(); md.setName("Test Aggregate TAE"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); // md.setTypeSystem(typeSystem); // md.setFsIndexes(new FsIndexDescription[]{index}); md.setCapabilities(primitiveDesc.getAnalysisEngineMetaData().getCapabilities()); FixedFlow fixedFlow = new FixedFlow_impl(); fixedFlow.setFixedFlow(new String[] { "Test", "Empty" }); md.setFlowConstraints(fixedFlow); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); primitiveDesc.toXML(writer); String primitiveDescXml = writer.getBuffer().toString(); // System.out.println(primitiveDescXml); writer = new StringWriter(); aggregateDesc.toXML(writer); String aggregateDescXml = writer.getBuffer().toString(); // System.out.println(aggregateDescXml); // parse objects from XML InputStream is = new ByteArrayInputStream(primitiveDescXml.getBytes(encoding)); AnalysisEngineDescription newPrimitiveDesc = (AnalysisEngineDescription) UIMAFramework .getXMLParser().parse(new XMLInputSource(is, null)); is = new ByteArrayInputStream(aggregateDescXml.getBytes(encoding)); AnalysisEngineDescription newAggregateDesc = (AnalysisEngineDescription) UIMAFramework .getXMLParser().parse(new XMLInputSource(is, null)); Assert.assertEquals(primitiveDesc, newPrimitiveDesc); Assert.assertEquals(aggregateDesc, newAggregateDesc); // test a complex descriptor XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); OperationalProperties opProps = desc.getAnalysisEngineMetaData().getOperationalProperties(); assertNotNull(opProps); assertEquals(true, opProps.getModifiesCas()); assertEquals(true, opProps.isMultipleDeploymentAllowed()); writer = new StringWriter(); desc.toXML(writer); String descXml = writer.getBuffer().toString(); is = new ByteArrayInputStream(descXml.getBytes(encoding)); AnalysisEngineDescription newDesc = (AnalysisEngineDescription) UIMAFramework.getXMLParser() .parse(new XMLInputSource(is, null)); Assert.assertEquals(desc, newDesc); // test a descriptor that includes a CasConsumer in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); writer = new StringWriter(); desc.toXML(writer); descXml = writer.getBuffer().toString(); is = new ByteArrayInputStream(descXml.getBytes(encoding)); newDesc = (AnalysisEngineDescription) UIMAFramework.getXMLParser().parse( new XMLInputSource(is, null)); Assert.assertEquals(desc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSerialization() throws Exception { try { // serialize objects to byte array byte[] primitiveDescBytes = SerializationUtils.serialize(primitiveDesc); byte[] aggregateDescBytes = SerializationUtils.serialize(aggregateDesc); // deserialize AnalysisEngineDescription newPrimitiveDesc = (AnalysisEngineDescription) SerializationUtils .deserialize(primitiveDescBytes); AnalysisEngineDescription newAggregateDesc = (AnalysisEngineDescription) SerializationUtils .deserialize(aggregateDescBytes); Assert.assertEquals(primitiveDesc, newPrimitiveDesc); Assert.assertEquals(aggregateDesc, newAggregateDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDelegateImports() throws Exception { // create aggregate TAE description and add delegate AE import AnalysisEngineDescription testAgg = new AnalysisEngineDescription_impl(); Map delegateMap = testAgg.getDelegateAnalysisEngineSpecifiersWithImports(); Import_impl delegateImport = new Import_impl(); delegateImport.setLocation(JUnitExtension.getFile( "TextAnalysisEngineImplTest/TestPrimitiveTae1.xml").toURL().toString()); delegateMap.put("key", delegateImport); // test that import is resolved Map mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers(); assertEquals(1, mapWithImportsResolved.size()); ResourceSpecifier obj = mapWithImportsResolved.values().iterator().next(); assertTrue(obj instanceof AnalysisEngineDescription); // test that remove works delegateMap.remove("key"); mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers(); assertEquals(0, mapWithImportsResolved.size()); // test the re-add works delegateMap.put("key", delegateImport); mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers(); assertEquals(1, mapWithImportsResolved.size()); obj = mapWithImportsResolved.values().iterator().next(); assertTrue(obj instanceof AnalysisEngineDescription); // serialize to XML, preserving imports testAgg.toXML(new StringWriter(), true); // verify that imports are still resolved mapWithImportsResolved = testAgg.getDelegateAnalysisEngineSpecifiers(); assertEquals(1, mapWithImportsResolved.size()); obj = mapWithImportsResolved.values().iterator().next(); assertTrue(obj instanceof AnalysisEngineDescription); } public void testDoFullValidation() throws Exception { // try some descriptors that are invalid due to config. param problems for (int i = 1; i <= 13; i++) { _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/InvalidConfigParams" + i + ".xml")); } // try a descriptor that's invalid due to an unsatisfied resource dependency _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.xml")); // try some invalid operational properties _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/InvalidAggregateSegmenter.xml")); // invalid fs indexes _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/InvalidFsIndexes.xml")); // circular import _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateThatImportsItself.xml")); // try some that should work XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); in = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); // try aggregate containing remote service - should work even if can't connect in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithUnknownRemoteComponent.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); // try aggregate with sofas in = new XMLInputSource(JUnitExtension.getFile("CpeSofaTest/TransAnnotatorAggregate.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); // try another aggregate with sofas in = new XMLInputSource(JUnitExtension .getFile("CpeSofaTest/TransAnnotatorAndTestAnnotatorAggregate.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); // try primitive with duplicate configuration group definitions in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigurationGroups.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); // try aggregate with duplicate configuration group definitions in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOverrides.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); //test aggregate with import by name and configuration parameter overrides in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); File dataPathDir = JUnitExtension.getFile("TextAnalysisEngineImplTest/dataPathDir"); resMgr.setDataPath(dataPathDir.getCanonicalPath()); desc.doFullValidation(resMgr); //test UIMA C++ descriptor (should succeed even though annotator library doesn't exist) in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestUimaCppAe.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestAggregateContainingCppAnnotator.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); } public void testValidate() throws Exception { //test aggregate with import by name and configuration parameter overrides XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AeWithConfigParamOverridesAndImportByName.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); File dataPathDir = JUnitExtension.getFile("TextAnalysisEngineImplTest/dataPathDir"); resMgr.setDataPath(dataPathDir.getCanonicalPath()); desc.validate(resMgr); //test invalid aggregate with undefined key in flow in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/InvalidAggregate_UndefinedKeyInFlow.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); try { desc.validate(); fail(); } catch(ResourceInitializationException e) { e.printStackTrace(); assertEquals(ResourceInitializationException.UNDEFINED_KEY_IN_FLOW, e.getMessageKey()); assertNotNull(e.getMessage()); assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); } } public void testGetAllComponentSpecifiers() throws Exception { try { Map allSpecs = aggregateDesc.getAllComponentSpecifiers(null); FlowControllerDescription fcDesc = (FlowControllerDescription) allSpecs .get("TestFlowController"); assertNotNull(fcDesc); assertEquals("MyTestFlowController", fcDesc.getMetaData().getName()); AnalysisEngineDescription aeDesc = (AnalysisEngineDescription) allSpecs.get("Test"); assertNotNull(aeDesc); assertEquals("Test TAE", aeDesc.getMetaData().getName()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDocumentAnnotationRedefine() { final String tsDescriptor = "org/apache/uima/analysis_engine/impl/documentAnnotationRedefinitionTS.xml"; File file = JUnitExtension.getFile(tsDescriptor); XMLParser parser = UIMAFramework.getXMLParser(); boolean resourceInitExc = false; try { TypeSystemDescription tsd = (TypeSystemDescription) parser.parse(new XMLInputSource(file)); CasCreationUtils.createCas(tsd, null, new FsIndexDescription[0]); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { resourceInitExc = true; } assertTrue(resourceInitExc); } protected void _testInvalidDescriptor(File aFile) throws IOException { assertTrue(aFile.exists()); XMLInputSource in = new XMLInputSource(aFile); Exception ex = null; try { AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); desc.doFullValidation(); } catch (InvalidXMLException e) { // e.printStackTrace(); ex = e; } catch (ResourceInitializationException e) { // e.printStackTrace(); ex = e; } Assert.assertNotNull(ex); Assert.assertNotNull(ex.getMessage()); Assert.assertFalse(ex.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/FlowControllerForErrorTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/FlowControllerForErrorTest0000644000175000017500000001220611665471066033550 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.ArrayList; import java.util.List; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.FlowConstraints; import org.apache.uima.cas.CAS; import org.apache.uima.flow.CasFlowController_ImplBase; import org.apache.uima.flow.CasFlow_ImplBase; import org.apache.uima.flow.FinalStep; import org.apache.uima.flow.Flow; import org.apache.uima.flow.FlowControllerContext; import org.apache.uima.flow.SimpleStep; import org.apache.uima.flow.Step; import org.apache.uima.resource.ResourceInitializationException; /** * FlowController for testing proper notification to the Flow Controller * when an error occurs. */ public class FlowControllerForErrorTest extends CasFlowController_ImplBase { public static final String PARAM_CONTINUE_ON_FAILURE = "ContinueOnFailure"; private String[] mSequence; private boolean mContinueOnFailure; public static List abortedDocuments = new ArrayList(); public static List failedAEs = new ArrayList(); public void initialize(FlowControllerContext aContext) throws ResourceInitializationException { super.initialize(aContext); FlowConstraints flowConstraints = aContext.getAggregateMetadata().getFlowConstraints(); mSequence = ((FixedFlow) flowConstraints).getFixedFlow(); Boolean paramVal = (Boolean)aContext.getConfigParameterValue(PARAM_CONTINUE_ON_FAILURE); mContinueOnFailure = paramVal != null && paramVal.booleanValue(); } /* * (non-Javadoc) * * @see org.apache.uima.flow.CasFlowController_ImplBase#computeFlow(org.apache.uima.cas.CAS) */ public Flow computeFlow(CAS aCAS) throws AnalysisEngineProcessException { FixedFlowObject ffo = new FixedFlowObject(aCAS, 0, false); ffo.setCas(aCAS); return ffo; } class FixedFlowObject extends CasFlow_ImplBase { private int currentStep; private boolean wasSegmented = false; private boolean internallyCreatedCas; /** * Create a new fixed flow starting at step startStep of the fixed sequence. * * @param startStep * index of mSequence to start at */ public FixedFlowObject(CAS cas, int startStep, boolean internallyCreatedCas) { setCas(cas); currentStep = startStep; this.internallyCreatedCas = internallyCreatedCas; } /* * (non-Javadoc) * * @see org.apache.uima.flow.Flow#next() */ public Step next() throws AnalysisEngineProcessException { if (currentStep >= mSequence.length) { return new FinalStep(); // this CAS has finished the sequence } // If CAS was segmented, do not continue with flow. The individual segments // are processed further but the original CAS is not. if (wasSegmented) { return new FinalStep(internallyCreatedCas); } // otherwise, we just send the CAS to the next AE in sequence. return new SimpleStep(mSequence[currentStep++]); } /* * (non-Javadoc) * * @see org.apache.uima.flow.CasFlow_ImplBase#newCasProduced(CAS, String) */ public Flow newCasProduced(CAS newCas, String producedBy) throws AnalysisEngineProcessException { // record that the input CAS has been segmented (affects its subsequent flow) wasSegmented = true; // start the new segment CAS from the next node after the Segmenter that produced it int i = 0; while (!mSequence[i].equals(producedBy)) i++; return new FixedFlowObject(newCas, i + 1, true); } /* (non-Javadoc) * @see org.apache.uima.flow.CasFlow_ImplBase#continueOnFailure(java.lang.String, java.lang.Exception) */ public boolean continueOnFailure(String failedAeKey, Exception failure) { failedAEs.add(failedAeKey); return mContinueOnFailure; } /* (non-Javadoc) * @see org.apache.uima.flow.CasFlow_ImplBase#aborted() */ public void aborted() { abortedDocuments.add(getCas().getDocumentText()); } } /** * */ public static void reset() { abortedDocuments.clear(); failedAEs.clear(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ErrorAnnotator.java0000644000175000017500000000317311665471064032154 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.Annotator_ImplBase; import org.apache.uima.analysis_engine.annotator.TextAnnotator; import org.apache.uima.cas.CAS; /** * Annotator class used for testing errors * */ public class ErrorAnnotator extends Annotator_ImplBase implements TextAnnotator { /** * @see org.apache.uima.analysis_engine.annotator.TextAnnotator#process(CAS,ResultSpecification) */ public void process(CAS aCAS, ResultSpecification aResultSpec) throws AnnotatorProcessException { if ("ERROR".equals(aCAS.getDocumentText())) { throw new RuntimeException("Test Error"); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotatorMissingSuper.java0000644000175000017500000000410311665471064033505 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.UIMARuntimeException; import org.apache.uima.UimaContext; import org.apache.uima.analysis_component.CasAnnotator_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; public class AnnotatorMissingSuper extends CasAnnotator_ImplBase { @Override public void process(CAS aCAS) throws AnalysisEngineProcessException { boolean caught = false; try { getContext(); } catch (UIMARuntimeException e) { caught = true; } if (!caught) { throw new RuntimeException("failed to throw for missing context"); } caught = false; try { getResultSpecification(); } catch (UIMARuntimeException e) { caught = true; } if (!caught) { throw new RuntimeException("failed to throw for missing resultSpec"); } } @Override public void initialize(UimaContext aContext) throws ResourceInitializationException { } @Override public void setResultSpecification(ResultSpecification aResultSpec) { } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecWithTypeSystemTe0000644000175000017500000002244511665471066033547 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import junit.framework.TestCase; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.TypeSystemImpl; /** * Test various kinds of inheritance issues * involving result specifications and type system */ public class ResultSpecWithTypeSystemTest extends TestCase { private static class TofLs { TypeOrFeature tof; String[] langs; } // languages private static final String EN = "en"; private static final String X = "x-unspecified"; private static final String EN_US = "en-us"; private static final String PTBR = "pt-br"; private static final String I = "I"; // split designator, not a language // types private static final TypeSystemMgr ts = new TypeSystemImpl(); private static final Type t1 = ts.addType("T1", ts.getTopType()); private static final Type t2 = ts.addType("T2", t1); private static final Type t3 = ts.addType("T3", t2); private static final Type t4 = ts.addType("T4", t1); // doesn't inherit from t2 private static final Feature f1 = ts.addFeature("F1", t1, t1); private static final Feature f2 = ts.addFeature("F2", t2, t3); private static final Feature f3 = ts.addFeature("F3", t3, t3); private static final Feature f4 = ts.addFeature("F4", t4, t4); static {ts.commit();}; // TypeOrFeature instances private static TypeOrFeature makeTof(String name, boolean isType, boolean allFeats) { TypeOrFeature r = new TypeOrFeature_impl(); r.setName(name); r.setType(isType); r.setAllAnnotatorFeatures(allFeats); return r; } private static final TypeOrFeature tofT1allFeat = makeTof("T1", true, true); private static final TypeOrFeature tofT1 = makeTof("T1", true, false); private static final TypeOrFeature tofT2allFeat = makeTof("T2", true, true); private static final TypeOrFeature tofT2 = makeTof("T2", true, false); private static final TypeOrFeature tofT3allFeat = makeTof("T3", true, true); private static final TypeOrFeature tofT3 = makeTof("T3", true, false); private static final TypeOrFeature tofT4allFeat = makeTof("T4", true, true); private static final TypeOrFeature tofT4 = makeTof("T4", true, false); private static final TypeOrFeature tofF1 = makeTof("T1:F1", false, false); private static final TypeOrFeature tofF2 = makeTof("T2:F2", false, false); private static final TypeOrFeature tofF3 = makeTof("T3:F3", false, false); private static final TypeOrFeature tofF4 = makeTof("T4:F4", false, false); private static final TypeOrFeature tofT2F1 = makeTof("T2:F1", false, false); // feature spec'd at subtype, but exists in supertype private static final TypeOrFeature tofT4F1 = makeTof("T4:F1", false, false); static enum K { // test kind Contains, NotContain, } // no languages // check type inheritance public void testTypeInheritance() { check(tofT1allFeat, K.Contains, t1); check(tofT1, K.Contains, t1); check(tofT1, K.Contains, t2); check(tofT1, K.Contains, t3); check(tofT2, K.Contains, t3); check(tofT2, K.NotContain, t4); check(tofT1, K.Contains, t4); } // no languages // check feat inheritance public void testFeatInheritance() { check(tofT1allFeat, K.Contains, f1); check(tofT1, K.NotContain, f1); check(tofF1, K.Contains, f1); check(tofT2, K.NotContain, f1); check(tofT2allFeat, K.Contains, f2); check(tofT2, K.NotContain, f2); check(tofT1allFeat, K.NotContain, f2); // because allFeat on T1 doesn't include F2 which is only introduced on T2 check(tofT2F1, K.NotContain, f1); // feature spec'd for subtype check(tofT2F1, K.Contains, "T2:F1"); check(tofT2F1, K.Contains, "T3:F1"); // oops, features not inheriting check(tofT1allFeat, K.NotContain, f4); // because allFeat on T1 doesn't include F4 which is only introduced on T4 check(tofT2allFeat, K.NotContain, f4); check(tofT1, K.NotContain, f4); } // languages // check type inheritance public void testTypeInheritanceL() { check(tofT1allFeat, X, K.Contains, t1, X); check(tofT1allFeat, EN, K.NotContain, t1, X); check(tofT1allFeat, EN, K.Contains, t1, EN); check(tofT1allFeat, EN, K.Contains, t1, EN_US); check(tofT1allFeat, EN_US, K.NotContain, t1, EN); check(tofT1, EN, K.Contains, t2, EN); check(tofT1, EN, K.Contains, t2, EN_US); TofLs[] tofls = aT(tofT1allFeat, X, tofT2, X); check(tofls, K.NotContain, f2); // bad } public void testFeatInheritanceL() { check(tofT1allFeat, X, K.Contains, f1, X); check(tofT1allFeat, EN, K.NotContain, f1, X); check(tofT1allFeat, EN, K.Contains, f1, EN); check(tofT1allFeat, EN, K.Contains, f1, EN_US); TofLs[] tofls =aT(tofT1allFeat, X, tofT2, EN); check(tofls, K.NotContain, f2, X); check(tofls, K.NotContain, f2, EN); check(tofls, K.NotContain, f2, EN_US); tofls =aT(tofT1allFeat, X, tofF2, EN); check(tofls, K.NotContain, f2, X); check(tofls, K.Contains, f2, EN); check(tofls, K.Contains, f2, EN_US); tofls = aT(tofT1allFeat, EN, tofT2allFeat, X); check(tofls, K.Contains, f2, X); check(tofls, K.Contains, f2, EN); check(tofls, K.Contains, f2, EN_US); tofls = aT(tofT2allFeat, EN, tofF1, X); check(tofls, K.Contains, f1, X); check(tofls, K.Contains, f1, EN); check(tofls, K.Contains, f1, EN_US); tofls = aT(tofT1allFeat, EN_US, tofT2, EN); check(tofls, K.NotContain, f2, X); check(tofls, K.NotContain, f2, EN); //broken check(tofls, K.NotContain, f2, EN_US); tofls = aT(tofT1, X, tofT2, EN_US); check(tofls, K.NotContain, f2, X); check(tofls, K.NotContain, f2, EN); check(tofls, K.NotContain, f2, EN_US); tofls = aT(tofF1, X, tofT2, EN_US); check(tofls, K.NotContain, f2, X); check(tofls, K.NotContain, f2, EN); check(tofls, K.NotContain, f2, EN_US); tofls = aT(tofF1, EN, tofF2, EN_US); check(tofls, K.NotContain, "T2:F1", X); check(tofls, K.Contains, "T2:F1", EN); check(tofls, K.Contains, "T2:F1", EN_US); check(tofls, K.NotContain, f2, EN); //broken check(tofls, K.Contains, f2, EN_US); } void check(TypeOrFeature tof, K testKind, Object t) { check(aT(tof, X), testKind, t, X); } void check(TofLs[] tofls, K testKind, Object t) { check(tofls, testKind, t, X); } void check(TypeOrFeature tof, String l1, K testKind, Object t, String l) { check(aT(tof, l1), testKind, t, l); } void check(TofLs[] tofls, K testKind, Object candidate, String lang) { String candidateName = (candidate instanceof Type) ? ((Type)candidate).getName() : (candidate instanceof Feature) ? ((Feature)candidate).getName() : (String) candidate; check(tofls, testKind, candidateName, lang); } void check(TofLs[] tofLss, K testKind, String candidateName, String lang) { boolean isType = -1 == candidateName.indexOf(TypeSystem.FEATURE_SEPARATOR); ResultSpecification_impl rs = new ResultSpecification_impl(); rs.setTypeSystem(ts); for (TofLs tofLs : tofLss) { rs.addResultTypeOrFeature(tofLs.tof, tofLs.langs); } switch (testKind) { case Contains : assertTrue(isType ? rs.containsType(candidateName, lang) : rs.containsFeature(candidateName, lang)); break; case NotContain : assertFalse(isType ? rs.containsType(candidateName, lang) : rs.containsFeature(candidateName, lang)); break; } } /** * Compose sets of { tof, lang, tof2, lang2, ...} into one object * Also handle langs: {tof, aL{lang1, lang2), ...) * @param tofls * @return */ TofLs[] aT(Object... tofls) { TofLs[] r = new TofLs[tofls.length / 2]; int j = 0; for (int i = 0; i < tofls.length; i = i + 2) { r[j] = new TofLs(); r[j].tof = (TypeOrFeature)tofls[i]; Object ls = tofls[i+1]; r[j++].langs = (ls instanceof String) ? aL(ls) : (String[]) ls; } return r; } String[] aL(Object... langs) { String[] r = new String[langs.length]; System.arraycopy(langs, 0, r, 0, langs.length); return r; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/TabSegmenter.java0000644000175000017500000000415711665471064031560 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.StringTokenizer; import org.apache.uima.analysis_component.CasMultiplier_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.AbstractCas; import org.apache.uima.cas.CAS; /** * */ public class TabSegmenter extends CasMultiplier_ImplBase { StringTokenizer mStringTok; /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS) */ public void process(CAS aCAS) throws AnalysisEngineProcessException { String doc = aCAS.getCurrentView().getDocumentText(); mStringTok = new StringTokenizer(doc, "\t"); } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext() */ public boolean hasNext() throws AnalysisEngineProcessException { return mStringTok.hasMoreTokens(); } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#next() */ public AbstractCas next() throws AnalysisEngineProcessException { String nextSeg = mStringTok.nextToken(); CAS cas = (CAS) getContext().getEmptyCas(CAS.class); cas.getCurrentView().setDocumentText(nextSeg); return cas; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnalysisEngine_implTest.ja0000644000175000017500000020650711665471066033450 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAException; import org.apache.uima.UIMAFramework; import org.apache.uima.UIMA_IllegalStateException; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.analysis_engine.CasIterator; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.asb.impl.ASB_impl; import org.apache.uima.analysis_engine.asb.impl.FlowControllerContainer; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FeatureDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.impl.ProcessTrace_impl; /** * Tests the TextAnalysisEngine_impl class. * */ public class AnalysisEngine_implTest extends TestCase { /** * Constructor for TextAnalysisEngine_implTest. * * @param arg0 */ public AnalysisEngine_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } public void testInitialize() throws Exception { try { PrimitiveAnalysisEngine_impl ae1 = new PrimitiveAnalysisEngine_impl(); // try to initialize with the wrong kind of specifier - should return false boolean result = ae1.initialize(new URISpecifier_impl(), null); Assert.assertFalse(result); // try to initialize with an empty TaeDescription - should throw exception Exception ex = null; try { AnalysisEngineDescription taeDesc = new AnalysisEngineDescription_impl(); taeDesc.setPrimitive(true); ae1.initialize(taeDesc, null); } catch (ResourceInitializationException e) { ex = e; } Assert.assertNotNull(ex); // initialize simple primitive TextAnalysisEngine ae1 = new PrimitiveAnalysisEngine_impl(); AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); result = ae1.initialize(primitiveDesc, null); Assert.assertTrue(result); // initialize again - should fail ex = null; try { ae1.initialize(primitiveDesc, null); } catch (UIMA_IllegalStateException e) { ex = e; } Assert.assertNotNull(ex); // initialize simple aggregate TextAnalysisEngine (also pass TextAnalysisEngineProcessData as // parameter) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggDesc.setPrimitive(false); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); AggregateAnalysisEngine_impl ae2 = new AggregateAnalysisEngine_impl(); result = ae2.initialize(aggDesc, null); Assert.assertTrue(result); // try some descriptors that are invalid due to config. param problems for (int i = 1; i <= 13; i++) { _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/InvalidConfigParams" + i + ".xml")); } // try a descriptor with configuration parameter overrides - should work XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); AggregateAnalysisEngine_impl ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); PrimitiveAnalysisEngine_impl delegate1 = (PrimitiveAnalysisEngine_impl) ae._getASB() .getComponentAnalysisEngines().get("Annotator1"); PrimitiveAnalysisEngine_impl delegate2 = (PrimitiveAnalysisEngine_impl) ae._getASB() .getComponentAnalysisEngines().get("Annotator2"); FlowControllerContainer flowController = ((ASB_impl) ae._getASB()) .getFlowControllerContainer(); String strVal1 = (String) delegate1.getUimaContext().getConfigParameterValue("en", "StringParam"); Assert.assertEquals("override", strVal1); String strVal2 = (String) delegate2.getUimaContext().getConfigParameterValue("en", "StringParam"); Assert.assertEquals("en", strVal2); String strVal3 = (String) flowController.getUimaContext().getConfigParameterValue("en", "StringParam"); Assert.assertEquals("en", strVal3); Assert.assertEquals("en", strVal2); Integer intVal1 = (Integer) delegate1.getUimaContext().getConfigParameterValue("en", "IntegerParam"); Assert.assertEquals(100, intVal1.intValue()); Integer intVal2 = (Integer) delegate1.getUimaContext().getConfigParameterValue("en", "IntegerParam"); Assert.assertEquals(100, intVal2.intValue()); Integer intVal3 = (Integer) flowController.getUimaContext().getConfigParameterValue("en", "IntegerParam"); Assert.assertEquals(100, intVal3.intValue()); String[] strArrVal1 = (String[]) delegate1.getUimaContext().getConfigParameterValue("en", "StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal1)); String[] strArrVal2 = (String[]) delegate2.getUimaContext().getConfigParameterValue("en", "StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal2)); String[] strArrVal3 = (String[]) flowController.getUimaContext().getConfigParameterValue( "en", "StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal3)); // anotherdescriptor with configuration parameter overrides (this time no groups) in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithConfigParamOverrides2.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); delegate1 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "Annotator1"); delegate2 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "Annotator2"); flowController = ((ASB_impl) ae._getASB()).getFlowControllerContainer(); strVal1 = (String) delegate1.getUimaContext().getConfigParameterValue("StringParam"); Assert.assertEquals("override", strVal1); strVal2 = (String) delegate2.getUimaContext().getConfigParameterValue("StringParam"); Assert.assertEquals("myString", strVal2); strVal3 = (String) flowController.getUimaContext().getConfigParameterValue("StringParam"); Assert.assertEquals("myString", strVal3); intVal1 = (Integer) delegate1.getUimaContext().getConfigParameterValue("IntegerParam"); Assert.assertEquals(100, intVal1.intValue()); intVal2 = (Integer) delegate2.getUimaContext().getConfigParameterValue("IntegerParam"); Assert.assertEquals(100, intVal2.intValue()); intVal3 = (Integer) flowController.getUimaContext().getConfigParameterValue("IntegerParam"); Assert.assertEquals(100, intVal3.intValue()); strArrVal1 = (String[]) delegate1.getUimaContext() .getConfigParameterValue("StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal1)); strArrVal2 = (String[]) delegate2.getUimaContext() .getConfigParameterValue("StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal2)); strArrVal3 = (String[]) flowController.getUimaContext().getConfigParameterValue( "StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "override" }), Arrays.asList(strArrVal3)); // try a descriptor that's invalid due to an unsatisfied resource dependency _testInvalidDescriptor(JUnitExtension .getFile("TextAnalysisEngineImplTest/UnsatisfiedResourceDependency.xml")); ae.destroy(); // test an aggregate TAE containing a CAS Consumer in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); delegate1 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "Annotator"); delegate2 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "CasConsumer"); assertTrue(delegate1.getAnalysisEngineMetaData().getOperationalProperties().getModifiesCas()); assertFalse(delegate2.getAnalysisEngineMetaData().getOperationalProperties().getModifiesCas()); ae.destroy(); // try an aggregate with no components (tests that empty flow works) in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/EmptyAggregate.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); FixedFlow emptyFlow = (FixedFlow) desc.getAnalysisEngineMetaData().getFlowConstraints(); assertNotNull(emptyFlow.getFixedFlow()); assertTrue(emptyFlow.getFixedFlow().length == 0); ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); ae.destroy(); // aggregate with duplicate group overrides in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithDuplicateGroupOverrides.xml")); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); delegate1 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "Annotator1"); delegate2 = (PrimitiveAnalysisEngine_impl) ae._getASB().getComponentAnalysisEngines().get( "Annotator2"); String commonParamA = (String) delegate1.getUimaContext().getConfigParameterValue("a", "CommonParam"); Assert.assertEquals("AggregateParam1a", commonParamA); String ann1_groupBParamBC = (String) delegate1.getUimaContext().getConfigParameterValue("b", "BCParam"); Assert.assertEquals("AggregateParam2b", ann1_groupBParamBC); String ann2_groupBParamBC = (String) delegate2.getUimaContext().getConfigParameterValue("b", "BCParam"); Assert.assertEquals("AggregateParam3b", ann2_groupBParamBC); ae.destroy(); } catch (Exception e) { JUnitExtension.handleException(e); } } protected void _testInvalidDescriptor(File aFile) throws IOException { XMLInputSource in = new XMLInputSource(aFile); Exception ex = null; try { AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); UIMAFramework.produceAnalysisEngine(desc); } catch (InvalidXMLException e) { // e.printStackTrace(); ex = e; } catch (ResourceInitializationException e) { // e.printStackTrace(); ex = e; } Assert.assertNotNull(ex); Assert.assertNotNull(ex.getMessage()); Assert.assertFalse(ex.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); } public void testProcess() throws Exception { try { // test simple primitive TextAnalysisEngine (using TestAnnotator class) // This test should work with or without a type system description AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); // TypeSystemDescription tsd = new TypeSystemDescription_impl(); // tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); // tsd.addType("DocumentStructure", "", "uima.cas.TOP"); // primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); Capability cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); Capability[] caps = new Capability[] {cap}; primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); _testProcess(primitiveDesc); primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); TypeSystemDescription tsd = new TypeSystemDescription_impl(); tsd.addType("NamedEntity", "", "uima.tcas.Annotation"); tsd.addType("DocumentStructure", "", "uima.cas.TOP"); primitiveDesc.getAnalysisEngineMetaData().setTypeSystem(tsd); cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); caps = new Capability[] {cap}; primitiveDesc.getAnalysisEngineMetaData().setCapabilities(caps); _testProcess(primitiveDesc); // test simple aggregate TextAnalysisEngine (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); aggDesc.getMetaData().setName("Test Aggregate TAE"); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); aggDesc.getAnalysisEngineMetaData().setCapabilities(caps); _testProcess(aggDesc); // test aggregate TAE containing a CAS Consumer File outFile = JUnitExtension.getFile("CpmOutput.txt"); if(outFile != null && outFile.exists()) { //outFile.delete() //can't be relied upon. Instead set file to zero length. FileOutputStream fos = new FileOutputStream(outFile, false); fos.close(); assertEquals(0,outFile.length()); } AnalysisEngineDescription aggWithCcDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml"))); _testProcess(aggWithCcDesc, new String[] {"en"}); // test that CAS Consumer ran if (null == outFile) { outFile = JUnitExtension.getFile("CpmOutput.txt"); } assertTrue(outFile != null && outFile.exists()); assertTrue(outFile.length() > 0); outFile.delete(); //test aggregate that uses ParallelStep AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension.getFile("TextAnalysisEngineImplTest/AggregateForParallelStepTest.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(desc); CAS cas = ae.newCAS(); cas.setDocumentText("new test"); ae.process(cas); assertEquals("new test", TestAnnotator.lastDocument); assertEquals("new test", TestAnnotator2.lastDocument); cas.reset(); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Auxiliary method used by testProcess() * * @param aTaeDesc * description of TextAnalysisEngine to test */ protected void _testProcess(AnalysisEngineDescription aTaeDesc) throws UIMAException { AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aTaeDesc); CAS tcas = ae.newCAS(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); _testProcessInner(ae, tcas, resultSpec, resultSpec); } protected void _testProcess(AnalysisEngineDescription aTaeDesc, String[] languages) throws UIMAException { AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aTaeDesc); CAS tcas = ae.newCAS(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); // includes subtypes Person, Sentence, Place, Paragraph // sets for lang = x-unspecified ResultSpecification expectedLastResultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); // interesting case: // Because the annotator extends a UIMA Version 1.x impl class, we go thru an "adapter" interface // which normally replaces the result spec with one that is based on language x-unspecified // (guessing because version 1.x didn't properly support languages) // However there's an exception to this: if the result spec would have no types or features // for the language in the CAS, the original result spec is used, rather than a // new one based on x-unspecified. expectedLastResultSpec.addResultType("NamedEntity", true, languages); _testProcessInner(ae, tcas, resultSpec, expectedLastResultSpec); } /** * Auxiliary method used by testProcess() * * @param aTaeDesc * description of TextAnalysisEngine to test */ protected void _testProcessInner(AnalysisEngine ae, CAS tcas, ResultSpecification resultSpec, ResultSpecification expectedLastResultSpec) throws UIMAException { // create and initialize TextAnalysisEngine // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. // We use these to make sure the information propagates correctly to the annotator. // process(CAS) // Calls with the Result spec set to default to that of the outer annotator output capabilities tcas.setDocumentText("new test"); ae.process(tcas); assertEquals("new test", TestAnnotator.lastDocument); tcas.reset(); // process(CAS,ResultSpecification) tcas.setDocumentText("testing..."); ae.process(tcas, resultSpec); assertEquals("testing...", TestAnnotator.lastDocument); assertEquals(expectedLastResultSpec, TestAnnotator.lastResultSpec); tcas.reset(); ae.destroy(); } public void testReconfigure() throws Exception { try { // create simple primitive TextAnalysisEngine descriptor (using TestAnnotator class) AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc.getMetaData().setName("Test Primitive TAE"); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("StringParam"); p1.setDescription("parameter with String data type"); p1.setType(ConfigurationParameter.TYPE_STRING); primitiveDesc.getMetaData().getConfigurationParameterDeclarations() .setConfigurationParameters(new ConfigurationParameter[] { p1 }); primitiveDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test1") }); // instantiate TextAnalysisEngine PrimitiveAnalysisEngine_impl ae = new PrimitiveAnalysisEngine_impl(); ae.initialize(primitiveDesc, null); // check value of string param (TestAnnotator saves it in a static field) assertEquals("Test1", TestAnnotator.stringParamValue); // reconfigure ae.setConfigParameterValue("StringParam", "Test2"); ae.reconfigure(); // test again assertEquals("Test2", TestAnnotator.stringParamValue); // test aggregate TAE AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggDesc.setPrimitive(false); aggDesc.getMetaData().setName("Test Aggregate TAE"); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); ConfigurationParameter p2 = new ConfigurationParameter_impl(); p2.setName("StringParam"); p2.setDescription("parameter with String data type"); p2.setType(ConfigurationParameter.TYPE_STRING); aggDesc.getMetaData().getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[] { p2 }); aggDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test3") }); // instantiate TextAnalysisEngine AggregateAnalysisEngine_impl aggAe = new AggregateAnalysisEngine_impl(); aggAe.initialize(aggDesc, null); assertEquals("Test3", TestAnnotator.stringParamValue); // reconfigure aggAe.setConfigParameterValue("StringParam", "Test4"); aggAe.reconfigure(); // test again assertEquals("Test4", TestAnnotator.stringParamValue); // reconfigure WITHOUT setting that parameter aggAe.reconfigure(); // test again assertEquals("Test4", TestAnnotator.stringParamValue); // test aggregate TAE that does NOT override parameter primitiveDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test1") }); AnalysisEngineDescription aggDesc2 = new AnalysisEngineDescription_impl(); aggDesc2.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggDesc2.setPrimitive(false); aggDesc2.getMetaData().setName("Test Aggregate TAE"); aggDesc2.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow2 = new FixedFlow_impl(); flow2.setFixedFlow(new String[] { "Test" }); aggDesc2.getAnalysisEngineMetaData().setFlowConstraints(flow2); ConfigurationParameter p3 = new ConfigurationParameter_impl(); p3.setName("IntParam"); p3.setDescription("parameter with Integer data type"); p3.setType(ConfigurationParameter.TYPE_INTEGER); aggDesc2.getMetaData().getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[] { p3 }); aggDesc2.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("IntParam", Integer.valueOf(42)) }); // instantiate TextAnalysisEngine AggregateAnalysisEngine_impl aggAe2 = new AggregateAnalysisEngine_impl(); aggAe2.initialize(aggDesc2, null); // call process - this should generate an event with a resource name equal // to the value of StringParam assertEquals("Test1", TestAnnotator.stringParamValue); // reconfigure aggAe2.setConfigParameterValue("IntParam", Integer.valueOf(0)); aggAe2.reconfigure(); // test again - should not have changed assertEquals("Test1", TestAnnotator.stringParamValue); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateAnalysisProcessData() throws Exception { try { // create simple primitive TAE with type system and indexes AnalysisEngineDescription desc = new AnalysisEngineDescription_impl(); desc.setPrimitive(true); desc.getMetaData().setName("Test Primitive TAE"); desc.setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Type1", "Test Type One", CAS.TYPE_NAME_ANNOTATION); FeatureDescription feat1 = new FeatureDescription_impl(); feat1.setName("Feature1"); feat1.setRangeTypeName(CAS.TYPE_NAME_INTEGER); type1.setFeatures(new FeatureDescription[] { feat1 }); TypeDescription type2 = typeSystem.addType("Type2", "Test Type Two", CAS.TYPE_NAME_ANNOTATION); FeatureDescription feat2 = new FeatureDescription_impl(); feat2.setName("Feature2"); feat2.setRangeTypeName("EnumType"); type2.setFeatures(new FeatureDescription[] { feat2 }); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); desc.getAnalysisEngineMetaData().setTypeSystem(typeSystem); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Type1"); priorityList.addType("Type2"); desc.getAnalysisEngineMetaData().setTypePriorities(typePriorities); FsIndexDescription index1 = new FsIndexDescription_impl(); index1.setLabel("Index1"); index1.setTypeName("Type1"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("Feature1"); key1.setComparator(FSIndexComparator.STANDARD_COMPARE); index1.setKeys(new FsIndexKeyDescription[] { key1 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("Index2"); index2.setTypeName("Type2"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Feature2"); key2.setComparator(FSIndexComparator.REVERSE_STANDARD_COMPARE); index2.setKeys(new FsIndexKeyDescription[] { key2 }); FsIndexDescription index3 = new FsIndexDescription_impl(); index3.setLabel("Index3"); index3.setTypeName("uima.tcas.Annotation"); index3.setKind(FsIndexDescription.KIND_SORTED); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setFeatureName("begin"); key3.setComparator(FSIndexComparator.STANDARD_COMPARE); FsIndexKeyDescription key4 = new FsIndexKeyDescription_impl(); key4.setTypePriority(true); index3.setKeys(new FsIndexKeyDescription[] { key3, key4 }); desc.getAnalysisEngineMetaData().setFsIndexes( new FsIndexDescription[] { index1, index2, index3 }); // instantiate TextAnalysisEngine PrimitiveAnalysisEngine_impl ae = new PrimitiveAnalysisEngine_impl(); ae.initialize(desc, null); // this calls createAnalysisProcessData // check results in CAS // type system CAS cas = ae.newCAS(); TypeSystem ts = cas.getTypeSystem(); Type t1 = ts.getType("Type1"); Assert.assertEquals("Type1", t1.getName()); Feature f1 = t1.getFeatureByBaseName("Feature1"); Feature f1a = ts.getFeatureByFullName("Type1:Feature1"); Assert.assertEquals(f1, f1a); Assert.assertEquals("Feature1", f1.getShortName()); Assert.assertEquals(t1, f1.getDomain()); Type t2 = ts.getType("Type2"); Assert.assertEquals("Type2", t2.getName()); Feature f2 = t2.getFeatureByBaseName("Feature2"); Feature f2a = ts.getFeatureByFullName("Type2:Feature2"); Assert.assertEquals(f2, f2a); Assert.assertEquals("Feature2", f2.getShortName()); Assert.assertEquals(t2, f2.getDomain()); Type et = ts.getType("EnumType"); Assert.assertEquals("EnumType", et.getName()); Assert.assertEquals(et, f2.getRange()); // indexes FSIndexRepository irep = cas.getIndexRepository(); FSIndex ind = irep.getIndex("Index1"); Assert.assertNotNull(ind); Assert.assertEquals("Type1", ind.getType().getName()); Assert.assertEquals(FSIndex.SORTED_INDEX, ind.getIndexingStrategy()); FeatureStructure fs1 = cas.createFS(t1); fs1.setIntValue(f1, 0); FeatureStructure fs2 = cas.createFS(t1); fs2.setIntValue(f1, 1); Assert.assertTrue(ind.compare(fs1, fs2) < 0); FSIndex ind2 = irep.getIndex("Index2"); Assert.assertNotNull(ind2); Assert.assertEquals("Type2", ind2.getType().getName()); Assert.assertEquals(FSIndex.SET_INDEX, ind2.getIndexingStrategy()); FeatureStructure fs3 = cas.createFS(t2); fs3.setStringValue(f2, "One"); FeatureStructure fs4 = cas.createFS(t2); fs4.setStringValue(f2, "Two"); Assert.assertTrue(ind2.compare(fs3, fs4) > 0); FSIndex ind3 = irep.getIndex("Index3"); Assert.assertNotNull(ind3); Assert.assertEquals("uima.tcas.Annotation", ind3.getType().getName()); Assert.assertEquals(FSIndex.SORTED_INDEX, ind3.getIndexingStrategy()); AnnotationFS fs5 = cas.createAnnotation(t1, 0, 0); AnnotationFS fs6 = cas.createAnnotation(t2, 0, 0); AnnotationFS fs7 = cas.createAnnotation(t1, 0, 0); Assert.assertTrue(ind3.compare(fs5, fs6) < 0); Assert.assertTrue(ind3.compare(fs6, fs7) > 0); // only way to check if allowed values is correct is to try to set an // invalid value? CASRuntimeException ex = null; try { fs4.setStringValue(f2, "Three"); } catch (CASRuntimeException e) { ex = e; } Assert.assertNotNull(ex); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcessDelegateAnalysisEngineMetaData() throws Exception { try { // create aggregate analysis engine whose delegates each declare // type system, type priorities, and indexes XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); AggregateAnalysisEngine_impl ae = new AggregateAnalysisEngine_impl(); ae.initialize(desc, Collections.EMPTY_MAP); // initialize method automatically calls processDelegateAnalysisEngineMetaData() // test results of merge // TypeSystem TypeSystemDescription typeSys = ae.getAnalysisEngineMetaData().getTypeSystem(); Assert.assertEquals(8, typeSys.getTypes().length); TypeDescription type0 = typeSys.getType("NamedEntity"); Assert.assertNotNull(type0); Assert.assertEquals("uima.tcas.Annotation", type0.getSupertypeName()); Assert.assertEquals(1, type0.getFeatures().length); TypeDescription type1 = typeSys.getType("Person"); Assert.assertNotNull(type1); Assert.assertEquals("NamedEntity", type1.getSupertypeName()); Assert.assertEquals(1, type1.getFeatures().length); TypeDescription type2 = typeSys.getType("Place"); Assert.assertNotNull(type2); Assert.assertEquals("NamedEntity", type2.getSupertypeName()); Assert.assertEquals(3, type2.getFeatures().length); TypeDescription type3 = typeSys.getType("Org"); Assert.assertNotNull(type3); Assert.assertEquals("uima.tcas.Annotation", type3.getSupertypeName()); Assert.assertEquals(0, type3.getFeatures().length); TypeDescription type4 = typeSys.getType("DocumentStructure"); Assert.assertNotNull(type4); Assert.assertEquals("uima.tcas.Annotation", type4.getSupertypeName()); Assert.assertEquals(0, type4.getFeatures().length); TypeDescription type5 = typeSys.getType("Paragraph"); Assert.assertNotNull(type5); Assert.assertEquals("DocumentStructure", type5.getSupertypeName()); Assert.assertEquals(0, type5.getFeatures().length); TypeDescription type6 = typeSys.getType("Sentence"); Assert.assertNotNull(type6); Assert.assertEquals("DocumentStructure", type6.getSupertypeName()); Assert.assertEquals(0, type6.getFeatures().length); TypeDescription type7 = typeSys.getType("test.flowController.Test"); Assert.assertNotNull(type7); Assert.assertEquals("uima.tcas.Annotation", type7.getSupertypeName()); Assert.assertEquals(1, type7.getFeatures().length); // TypePriorities TypePriorities pri = ae.getAnalysisEngineMetaData().getTypePriorities(); Assert.assertNotNull(pri); TypePriorityList[] priLists = pri.getPriorityLists(); Assert.assertEquals(3, priLists.length); String[] list0 = priLists[0].getTypes(); String[] list1 = priLists[1].getTypes(); String[] list2 = priLists[2].getTypes(); // order of the three lists is not defined Assert.assertTrue((list0.length == 2 && list1.length == 2 && list2.length == 3) || (list0.length == 2 && list1.length == 3 && list2.length == 2) || (list0.length == 3 && list1.length == 2 && list2.length == 2)); // Indexes FsIndexDescription[] indexes = ae.getAnalysisEngineMetaData().getFsIndexes(); Assert.assertEquals(3, indexes.length); // order of indexes is not defined String label0 = indexes[0].getLabel(); String label1 = indexes[1].getLabel(); String label2 = indexes[2].getLabel(); Assert.assertTrue(label0.equals("DocStructIndex") || label1.equals("DocStructIndex") || label2.equals("DocStructIndex")); Assert.assertTrue(label0.equals("PlaceIndex") || label1.equals("PlaceIndex") || label2.equals("PlaceIndex")); Assert.assertTrue(label0.equals("FlowControllerTestIndex") || label1.equals("FlowControllerTestIndex") || label2.equals("FlowControllerTestIndex")); // test that we can create a CAS CAS cas = ae.newCAS(); TypeSystem ts = cas.getTypeSystem(); assertNotNull(ts.getType("NamedEntity")); assertNotNull(ts.getType("Person")); assertNotNull(ts.getType("Place")); assertNotNull(ts.getType("Org")); assertNotNull(ts.getType("DocumentStructure")); assertNotNull(ts.getType("Paragraph")); assertNotNull(ts.getType("Sentence")); assertNotNull(ts.getType("test.flowController.Test")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCollectionProcessComplete() throws Exception { try { // test simple primitive TextAnalysisEngine (using TestAnnotator class) AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); PrimitiveAnalysisEngine_impl ae = new PrimitiveAnalysisEngine_impl(); ae.initialize(primitiveDesc, null); ae.collectionProcessComplete(new ProcessTrace_impl()); // test simple aggregate TextAnalysisEngine (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); aggDesc.getMetaData().setName("Test Aggregate TAE"); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow = new FixedFlow_impl(); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); AggregateAnalysisEngine_impl aggAe = new AggregateAnalysisEngine_impl(); aggAe.initialize(aggDesc, null); aggAe.collectionProcessComplete(new ProcessTrace_impl()); //test that fixedFlow order is used File descFile = JUnitExtension.getFile("TextAnalysisEngineImplTest/AggregateForCollectionProcessCompleteTest.xml"); AnalysisEngineDescription cpcTestDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(new XMLInputSource(descFile)); AnalysisEngine cpcTestAe = UIMAFramework.produceAnalysisEngine(cpcTestDesc); cpcTestAe.collectionProcessComplete(); assertEquals("One", AnnotatorForCollectionProcessCompleteTest.lastValue); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testBatchProcessComplete() throws Exception { try { // test simple primitive TextAnalysisEngine (using TestAnnotator class) AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Primitive TAE"); PrimitiveAnalysisEngine_impl ae = new PrimitiveAnalysisEngine_impl(); ae.initialize(primitiveDesc, null); ae.batchProcessComplete(new ProcessTrace_impl()); // test simple aggregate TextAnalysisEngine (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); aggDesc.getMetaData().setName("Test Aggregate TAE"); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); AggregateAnalysisEngine_impl aggAe = new AggregateAnalysisEngine_impl(); aggAe.initialize(aggDesc, null); aggAe.batchProcessComplete(new ProcessTrace_impl()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testTypeSystemInit() throws Exception { try { AnalysisEngineDescription aggWithCcDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeWithCasConsumer.xml"))); AggregateAnalysisEngine_impl aggAe = new AggregateAnalysisEngine_impl(); aggAe.initialize(aggWithCcDesc, null); CAS tcas = aggAe.newCAS(); tcas.setDocumentText("This is a test"); aggAe.process(tcas); assertTrue(TestAnnotator.typeSystemInitCalled); assertTrue(AnnotationWriter.typeSystemInitCalled); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcessAndOutputNewCASes() throws Exception { try { // primitive AnalysisEngineDescription segmenterDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/NewlineSegmenter.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(segmenterDesc); CAS cas = ae.newCAS(); cas.setDocumentText("Line one\nLine two\nLine three"); CasIterator iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); CAS outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line three", outCas.getDocumentText()); outCas.release(); assertFalse(iter.hasNext()); // aggregate AnalysisEngineDescription aggSegDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithSegmenter.xml"))); ae = UIMAFramework.produceAnalysisEngine(aggSegDesc); cas = ae.newCAS(); cas.setDocumentText("Line one\nLine two\nLine three"); iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); assertEquals("Line one", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); assertEquals("Line two", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line three", outCas.getDocumentText()); assertEquals("Line three", TestAnnotator.lastDocument); outCas.release(); assertFalse(iter.hasNext()); // Annotator should NOT get the original CAS according to the default flow assertEquals("Line three", TestAnnotator.lastDocument); // nested aggregate AnalysisEngineDescription nestedAggSegDesc = UIMAFramework .getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource( JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateContainingAggregateSegmenter.xml"))); ae = UIMAFramework.produceAnalysisEngine(nestedAggSegDesc); cas = ae.newCAS(); cas.setDocumentText("Line one\nLine two\nLine three"); iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); assertEquals("Line one", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); assertEquals("Line two", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line three", outCas.getDocumentText()); assertEquals("Line three", TestAnnotator.lastDocument); outCas.release(); assertFalse(iter.hasNext()); // Annotator should NOT get the original CAS according to the default flow assertEquals("Line three", TestAnnotator.lastDocument); // two segmenters AnalysisEngineDescription twoSegDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWith2Segmenters.xml"))); ae = UIMAFramework.produceAnalysisEngine(twoSegDesc); cas = ae.newCAS(); cas.setDocumentText("One\tTwo\nThree\tFour"); iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("One", outCas.getDocumentText()); assertEquals("One", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Two", outCas.getDocumentText()); assertEquals("Two", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Three", outCas.getDocumentText()); assertEquals("Three", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Four", outCas.getDocumentText()); assertEquals("Four", TestAnnotator.lastDocument); outCas.release(); assertFalse(iter.hasNext()); // Annotator should NOT get the original CAS according to the default flow assertEquals("Four", TestAnnotator.lastDocument); // dropping segments aggSegDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateSegmenterForDropTest.xml"))); ae = UIMAFramework.produceAnalysisEngine(aggSegDesc); cas = ae.newCAS(); cas.setDocumentText("Line one\nDROP\nLine two\nDROP\nLine three"); // results should be the same as the first aggregate segmenter test. // segmetns whose text is DROP should not be output. iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); assertEquals("Line one", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); assertEquals("Line two", TestAnnotator.lastDocument); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line three", outCas.getDocumentText()); assertEquals("Line three", TestAnnotator.lastDocument); outCas.release(); assertFalse(iter.hasNext()); // Annotator should NOT get the original CAS according to the default flow assertEquals("Line three", TestAnnotator.lastDocument); //with ParallelStep AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension.getFile("TextAnalysisEngineImplTest/AggregateForParallelStepCasMultiplierTest.xml"))); ae = UIMAFramework.produceAnalysisEngine(desc); cas.reset(); cas.setDocumentText("One\tTwo\nThree\tFour"); iter = ae.processAndOutputNewCASes(cas); Set expectedOutputs = new HashSet(); expectedOutputs.add("One"); expectedOutputs.add("Two\nThree"); expectedOutputs.add("Four"); expectedOutputs.add("One\tTwo"); expectedOutputs.add("Three\tFour"); while (iter.hasNext()) { outCas = iter.next(); assertTrue(expectedOutputs.remove(outCas.getDocumentText())); outCas.release(); } assertTrue(expectedOutputs.isEmpty()); // test aggregate with 2 AEs sharing resource manager AnalysisEngineDescription aggregateSegDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithSegmenter.xml"))); ResourceManager rsrcMgr = UIMAFramework.newDefaultResourceManager(); Map params = new HashMap(); AnalysisEngine ae1 = UIMAFramework.produceAnalysisEngine(aggregateSegDesc, rsrcMgr, params); AnalysisEngine ae2 = UIMAFramework.produceAnalysisEngine(aggregateSegDesc, rsrcMgr, params); // start with testing first ae CAS cas1 = ae1.newCAS(); cas1.setDocumentText("Line one\nLine two\nLine three"); CasIterator iter1 = ae1.processAndOutputNewCASes(cas1); assertTrue(iter1.hasNext()); CAS outCas1 = iter1.next(); assertEquals("Line one", outCas1.getDocumentText()); // now test second ae CAS cas2 = ae2.newCAS(); cas2.setDocumentText("Line one\nLine two\nLine three"); CasIterator iter2 = ae2.processAndOutputNewCASes(cas2); assertTrue(iter2.hasNext()); CAS outCas2 = iter2.next(); assertEquals("Line one", outCas2.getDocumentText()); outCas2.release(); assertTrue(iter2.hasNext()); outCas2 = iter2.next(); assertEquals("Line two", outCas2.getDocumentText()); outCas2.release(); assertTrue(iter2.hasNext()); outCas2 = iter2.next(); assertEquals("Line three", outCas2.getDocumentText()); outCas2.release(); assertFalse(iter2.hasNext()); // continue testing first ae outCas1.release(); assertTrue(iter1.hasNext()); outCas1 = iter1.next(); assertEquals("Line two", outCas1.getDocumentText()); outCas1.release(); assertTrue(iter1.hasNext()); outCas1 = iter1.next(); assertEquals("Line three", outCas1.getDocumentText()); outCas1.release(); assertFalse(iter1.hasNext()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcessAndOutputNewCASesWithError() throws Exception { try { // aggregate AnalysisEngineDescription aggSegDesc = UIMAFramework .getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource( JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithSegmenterForErrorTest.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aggSegDesc); CAS cas = ae.newCAS(); for (int i = 0; i < 2; i++) // verify we can do this more than once { FlowControllerForErrorTest.reset(); cas.setDocumentText("Line one\nLine two\nERROR"); CasIterator iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); CAS outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); outCas.release(); try { assertTrue(iter.hasNext()); outCas = iter.next(); fail(); // the above should throw an exception } catch (AnalysisEngineProcessException e) { //do nothing } //check that FlowController was notified twice, once for the //segment's flow and once for the complete document's flow assertEquals(2, FlowControllerForErrorTest.abortedDocuments.size()); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("ERROR")); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("Line one\nLine two\nERROR")); cas.reset(); } // nested aggregate AnalysisEngineDescription nestedAggSegDesc = UIMAFramework .getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource( JUnitExtension .getFile("TextAnalysisEngineImplTest/NestedAggregateSegmenterForErrorTest.xml"))); ae = UIMAFramework.produceAnalysisEngine(nestedAggSegDesc); cas = ae.newCAS(); for (int i = 0; i < 2; i++) // verify we can do this more than once { FlowControllerForErrorTest.reset(); cas.setDocumentText("Line one\nLine two\nERROR"); CasIterator iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); CAS outCas = iter.next(); assertEquals("Line one", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Line two", outCas.getDocumentText()); outCas.release(); try { assertTrue(iter.hasNext()); outCas = iter.next(); fail(); // the above should throw an exception } catch (AnalysisEngineProcessException e) { //do nothing } //check that FlowController was notified three times, once for the //segment's flow and twice for the complete document's flow (once //in each aggregate) assertEquals(3, FlowControllerForErrorTest.abortedDocuments.size()); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("ERROR")); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("Line one\nLine two\nERROR")); FlowControllerForErrorTest.abortedDocuments.remove("Line one\nLine two\nERROR"); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("Line one\nLine two\nERROR")); cas.reset(); } // 2 segmenters AnalysisEngineDescription twoSegDesc = UIMAFramework .getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource( JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWith2SegmentersForErrorTest.xml"))); ae = UIMAFramework.produceAnalysisEngine(twoSegDesc); cas = ae.newCAS(); for (int i = 0; i < 2; i++) // verify we can do this more than once { FlowControllerForErrorTest.abortedDocuments.clear(); cas.setDocumentText("One\tTwo\nThree\tERROR"); CasIterator iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); CAS outCas = iter.next(); assertEquals("One", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Two", outCas.getDocumentText()); outCas.release(); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("Three", outCas.getDocumentText()); outCas.release(); try { assertTrue(iter.hasNext()); outCas = iter.next(); fail(); // the above should throw an exception } catch (AnalysisEngineProcessException e) { //do nothing } //check that FlowController was notified three times, once for each level of granularity assertEquals(3, FlowControllerForErrorTest.abortedDocuments.size()); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("ERROR")); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("Three\tERROR")); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("One\tTwo\nThree\tERROR")); cas.reset(); } // segmenter that requests too many CASes AnalysisEngineDescription segmenterDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/BadSegmenter.xml"))); ae = UIMAFramework.produceAnalysisEngine(segmenterDesc); cas = ae.newCAS(); cas.setDocumentText("Line one\nLine two\nLine three"); CasIterator iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); CAS outCas = iter.next(); // first call OK outCas.release(); assertTrue(iter.hasNext()); // next call should fail with AnalysisEngineProcessException try { iter.next(); fail(); // should not get here } catch (AnalysisEngineProcessException e) { // should get here } // bad segmenter in an aggregate AnalysisEngineDescription aggWithBadSegmenterDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateWithBadSegmenterForErrorTest.xml"))); ae = UIMAFramework.produceAnalysisEngine(aggWithBadSegmenterDesc); FlowControllerForErrorTest.reset(); cas = ae.newCAS(); cas.setDocumentText("Line one\nLine two\nLine three"); iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); // first call OK outCas.release(); assertTrue(FlowControllerForErrorTest.abortedDocuments.isEmpty()); assertTrue(FlowControllerForErrorTest.failedAEs.isEmpty()); // next call should fail with AnalysisEngineProcessException try { if (iter.hasNext()) { iter.next(); } fail(); // should not get here } catch (AnalysisEngineProcessException e) { // should get here } assertEquals(1, FlowControllerForErrorTest.abortedDocuments.size()); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("Line one\nLine two\nLine three")); assertEquals(1,FlowControllerForErrorTest.failedAEs.size()); assertTrue(FlowControllerForErrorTest.failedAEs.contains("Segmenter")); //configure AE to continue after error ae = UIMAFramework.produceAnalysisEngine(aggWithBadSegmenterDesc); ae.setConfigParameterValue("ContinueOnFailure", Boolean.TRUE); ae.reconfigure(); FlowControllerForErrorTest.reset(); cas.reset(); cas.setDocumentText("Line one\nLine two\nLine three"); iter = ae.processAndOutputNewCASes(cas); assertTrue(iter.hasNext()); outCas = iter.next(); // first call OK outCas.release(); assertTrue(FlowControllerForErrorTest.abortedDocuments.isEmpty()); assertTrue(FlowControllerForErrorTest.failedAEs.isEmpty()); //next call should not have aborted, but FC should have been notified of the failiure, // and no CAS should come back assertFalse(iter.hasNext()); assertEquals(0, FlowControllerForErrorTest.abortedDocuments.size()); assertEquals(1, FlowControllerForErrorTest.failedAEs.size()); assertTrue(FlowControllerForErrorTest.failedAEs.contains("Segmenter")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResegment() throws Exception { try { // primitive AnalysisEngineDescription segmenterDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/NewlineResegmenter.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(segmenterDesc); CAS inputCas1 = ae.newCAS(); Type sdiType = inputCas1.getTypeSystem().getType( "org.apache.uima.examples.SourceDocumentInformation"); Feature uriFeat = sdiType.getFeatureByBaseName("uri"); inputCas1.setDocumentText("This is"); FeatureStructure sdiFS = inputCas1.createFS(sdiType); sdiFS.setStringValue(uriFeat, "cas1"); inputCas1.getIndexRepository().addFS(sdiFS); CAS inputCas2 = ae.newCAS(); inputCas2.setDocumentText(" one.\nThis is"); FeatureStructure sdiFS2 = inputCas2.createFS(sdiType); sdiFS2.setStringValue(uriFeat, "cas2"); inputCas2.getIndexRepository().addFS(sdiFS2); CAS inputCas3 = ae.newCAS(); inputCas3.setDocumentText(" two.\n"); FeatureStructure sdiFS3 = inputCas3.createFS(sdiType); sdiFS3.setStringValue(uriFeat, "cas3"); inputCas3.getIndexRepository().addFS(sdiFS3); // input first CAS. Should be no segments yet. CasIterator iter = ae.processAndOutputNewCASes(inputCas1); assertFalse(iter.hasNext()); // input second CAS. We should get back one segment. iter = ae.processAndOutputNewCASes(inputCas2); assertTrue(iter.hasNext()); CAS outCas = iter.next(); assertEquals("This is one.", outCas.getDocumentText()); // -- check SourceDocumentInformation FSs Iterator sdiIter = outCas.getAnnotationIndex(sdiType).iterator(); assertTrue(sdiIter.hasNext()); AnnotationFS outSdiFs = (AnnotationFS) sdiIter.next(); assertEquals("This is", outSdiFs.getCoveredText()); assertEquals("cas1", outSdiFs.getStringValue(uriFeat)); assertTrue(sdiIter.hasNext()); outSdiFs = (AnnotationFS) sdiIter.next(); assertEquals(" one.", outSdiFs.getCoveredText()); assertEquals("cas2", outSdiFs.getStringValue(uriFeat)); assertFalse(sdiIter.hasNext()); // -- assertFalse(iter.hasNext()); // input third CAS. We should get back one more segment. iter = ae.processAndOutputNewCASes(inputCas3); assertTrue(iter.hasNext()); outCas = iter.next(); assertEquals("This is two.", outCas.getDocumentText()); // -- check SourceDocumentInformation FSs sdiIter = outCas.getAnnotationIndex(sdiType).iterator(); assertTrue(sdiIter.hasNext()); outSdiFs = (AnnotationFS) sdiIter.next(); assertEquals("This is", outSdiFs.getCoveredText()); assertEquals("cas2", outSdiFs.getStringValue(uriFeat)); assertTrue(sdiIter.hasNext()); outSdiFs = (AnnotationFS) sdiIter.next(); assertEquals(" two.", outSdiFs.getCoveredText()); assertEquals("cas3", outSdiFs.getStringValue(uriFeat)); assertFalse(sdiIter.hasNext()); // -- assertFalse(iter.hasNext()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcessWithError() throws Exception { try { //This test uses an aggregate AE fails if the document text is set to "ERROR". AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension.getFile("TextAnalysisEngineImplTest/AggregateForErrorTest.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aeDesc); FlowControllerForErrorTest.reset(); CAS cas = ae.newCAS(); //try document that should succeed cas.setDocumentText("This is OK"); ae.process(cas); //flow controller should not be notified assertTrue(FlowControllerForErrorTest.abortedDocuments.isEmpty()); assertTrue(FlowControllerForErrorTest.failedAEs.isEmpty()); //now one that fails cas.reset(); cas.setDocumentText("ERROR"); try { ae.process(cas); fail(); } catch(AnalysisEngineProcessException e) { //expected } assertEquals(1, FlowControllerForErrorTest.abortedDocuments.size()); assertTrue(FlowControllerForErrorTest.abortedDocuments.contains("ERROR")); assertEquals(1, FlowControllerForErrorTest.failedAEs.size()); assertTrue(FlowControllerForErrorTest.failedAEs.contains("ErrorAnnotator")); //AE should still be able to process a new document now FlowControllerForErrorTest.reset(); cas.reset(); cas.setDocumentText("This is OK"); ae.process(cas); assertTrue(FlowControllerForErrorTest.abortedDocuments.isEmpty()); assertTrue(FlowControllerForErrorTest.failedAEs.isEmpty()); //configure AE to continue after error ae.setConfigParameterValue("ContinueOnFailure", Boolean.TRUE); ae.reconfigure(); cas.reset(); cas.setDocumentText("ERROR"); ae.process(cas); //should not throw exception now //document should not have aborted, but FC should have been notified of the failiure assertEquals(0, FlowControllerForErrorTest.abortedDocuments.size()); assertEquals(1, FlowControllerForErrorTest.failedAEs.size()); assertTrue(FlowControllerForErrorTest.failedAEs.contains("ErrorAnnotator")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMissingSuper() throws Exception { try { // initialize simple primitive TextAnalysisEngine AnalysisEngine ae1 = new PrimitiveAnalysisEngine_impl(); AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primitiveDesc.setPrimitive(true); primitiveDesc.setAnnotatorImplementationName(AnnotatorMissingSuper.class.getCanonicalName()); ae1.initialize(primitiveDesc, null); ae1.process(ae1.newCAS()); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/NewlineSegmenter.java0000644000175000017500000000462611665471064032454 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.StringTokenizer; import org.apache.uima.analysis_component.CasMultiplier_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.AbstractCas; import org.apache.uima.cas.CAS; /** * */ public class NewlineSegmenter extends CasMultiplier_ImplBase { StringTokenizer mStringTok; private boolean casAvailable; /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS) */ public void process(CAS aCAS) throws AnalysisEngineProcessException { String doc = aCAS.getCurrentView().getDocumentText(); mStringTok = new StringTokenizer(doc, "\n"); casAvailable = false; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext() */ public boolean hasNext() throws AnalysisEngineProcessException { // Check if have already returned true without an intervening next() if (casAvailable) { throw new RuntimeException("CasMultiplier's hasNext() called twice"); } return (casAvailable = mStringTok.hasMoreTokens()); } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#next() */ public AbstractCas next() throws AnalysisEngineProcessException { String nextSeg = mStringTok.nextToken(); CAS cas = (CAS) getContext().getEmptyCas(CAS.class); cas.getCurrentView().setDocumentText(nextSeg); casAvailable = false; return cas; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/BadSegmenter.java0000644000175000017500000000433511665471064031536 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.analysis_component.CasMultiplier_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.AbstractCas; import org.apache.uima.cas.CAS; /** * Segmenter that requests three CASes in every next() method but only asks for four in its * getCasInstancesRequired() method. It will run out on the second call. For testing that we can * catch segmenters that request too many CASes. */ public class BadSegmenter extends CasMultiplier_ImplBase { /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.CasSegmenter_ImplBase#process(org.apache.uima.cas.CAS) */ public void process(CAS aCAS) throws AnalysisEngineProcessException { //do nothing } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext() */ public boolean hasNext() throws AnalysisEngineProcessException { return true; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#next() */ public AbstractCas next() throws AnalysisEngineProcessException { // request too many CASes getContext().getEmptyCas(CAS.class); getContext().getEmptyCas(CAS.class); return getContext().getEmptyCas(CAS.class); } public int getCasInstancesRequired() { return 4; } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotatorForCollectionProcessCompleteTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotatorForCollectionProc0000644000175000017500000000430411665471064033526 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.UimaContext; import org.apache.uima.analysis_component.CasAnnotator_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; /** * Testing that collectionProcessComplete is correctly propogated to annotators. */ public class AnnotatorForCollectionProcessCompleteTest extends CasAnnotator_ImplBase { public static volatile String lastValue; private String testValue; /* (non-Javadoc) * @see org.apache.uima.analysis_component.AnalysisComponent_ImplBase#initialize(org.apache.uima.UimaContext) */ public void initialize(UimaContext aContext) throws ResourceInitializationException { super.initialize(aContext); testValue = (String)aContext.getConfigParameterValue("TestValue"); } /* (non-Javadoc) * @see org.apache.uima.analysis_component.CasAnnotator_ImplBase#process(org.apache.uima.cas.CAS) */ public void process(CAS aCAS) throws AnalysisEngineProcessException { //does nothing } /* (non-Javadoc) * @see org.apache.uima.analysis_component.AnalysisComponent_ImplBase#collectionProcessComplete() */ public void collectionProcessComplete() throws AnalysisEngineProcessException { lastValue = testValue; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/ResultSpecTest.java0000644000175000017500000001712511665471066032132 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.uima.UIMAException; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ResultSpecTest extends TestCase { private CAS cas; private static final String EN = "en"; private static final String X = "x-unspecified"; private static final String EN_US = "en-us"; private static final String PTBR = "pt-br"; private static final String I = "I"; // split designator // types private static final TypeSystemMgr ts = new TypeSystemImpl(); private static final Type t1 = ts.addType("T1", ts.getTopType()); private static final Feature f1 = ts.addFeature("F1", t1, t1); private static final Feature f1a = ts.addFeature("F1a", t1, t1); static {ts.commit();}; /** * Tests for https://issues.apache.org/jira/browse/UIMA-1840 */ public void testIntersection() { checkl(X, I, X, I, X); checkl(X, I, EN, I, EN); checkl(EN, I, X, I, EN); checkl(X, I, EN_US, I, EN_US); checkl(EN_US, I, X, I, EN_US); checkl(EN, I, EN, I, EN); checkl(EN, I, EN_US, I, EN_US); checkl(EN_US, I, EN, I, EN_US); checkl(EN_US, I, EN_US, I, EN_US); checkl(X, EN, I, EN, X, I, X); checkl(X, EN, I, EN, I, EN); checkl(EN, EN_US, I, X, I, EN, EN_US); checkl(X, PTBR, I, EN, I, EN); checkl(PTBR, I, EN, I, null); } private void checkl(String... args) { List rs1List = new ArrayList(); List rs2List = new ArrayList(); List expList = new ArrayList(); List[] tgts = new List[]{rs1List, rs2List, expList}; int tgtI = 0; for (int i = 0; i < args.length; i++) { if (args[i] == I) { tgtI ++; } else { if (args[i] != null) { tgts[tgtI].add(args[i]); } } } String[] rs1langs = rs1List.toArray(new String[rs1List.size()]); String[] rs2langs = rs2List.toArray(new String[rs2List.size()]); String[] explangs = expList.toArray(new String[expList.size()]); ResultSpecification_impl rs1 = new ResultSpecification_impl(ts); ResultSpecification_impl rs2 = new ResultSpecification_impl(ts); ResultSpecification_impl rsE = new ResultSpecification_impl(ts); //expected addResultTypeOneAtATime(rs1, rs1langs); addResultTypeOneAtATime(rs2, rs2langs); addResultTypeOneAtATime(rsE, explangs); ResultSpecification_impl rsQ = rs1.intersect(rs2); assertEquals(rsQ, rsE); } // we do this to avoid language normalization from collapsing x-unspecified // plus other languages into just x-unspecified private void addResultTypeOneAtATime(ResultSpecification_impl rs, String[] languages) { if (languages.length == 0) { return; } if (languages.length == 1) { rs.addResultType("T1", true, languages); } else { for (int i = 0; i < languages.length; i++) { rs.addResultType("T1", true, new String[]{languages[i]}); } } } public void testComputeAnalysisComponentResultSpec() throws Exception { try { AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension.getFile("SequencerTest/Annotator1.xml"))); PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); ResultSpecification_impl resultSpec = new ResultSpecification_impl(); resultSpec.addResultType("uima.tt.TokenLikeAnnotation", true); resultSpec.setTypeSystem(cas.getTypeSystem()); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testComputeAnalysisComponentResultSpecInherit() throws Exception { try { AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension.getFile("SequencerTest/Annotator1.xml"))); PrimitiveAnalysisEngine_impl ae = (PrimitiveAnalysisEngine_impl) UIMAFramework .produceAnalysisEngine(aeDesc); CAS cas = ae.newCAS(); ResultSpecification_impl resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); resultSpec.addResultType("uima.tcas.Annotation", true); ResultSpecification_impl rs2 = new ResultSpecification_impl(cas.getTypeSystem()); rs2.addCapabilities(ae.getAnalysisEngineMetaData().getCapabilities()); ResultSpecification acResultSpec = resultSpec.intersect(rs2); assertTrue(acResultSpec.containsType("uima.tt.TokenAnnotation")); assertTrue(acResultSpec.containsType("uima.tt.SentenceAnnotation")); assertFalse(acResultSpec.containsType("uima.tt.Lemma")); } catch (Exception e) { JUnitExtension.handleException(e); } } private ResultSpecification createResultSpec(String language) { ResultSpecification resultSpec = new ResultSpecification_impl(cas.getTypeSystem()); resultSpec.addResultType("Type1", true, new String[] {language}); return resultSpec; } /** * Auxiliary method used by testProcess() * * @param aTaeDesc * description of TextAnalysisEngine to test */ protected void _testProcess(AnalysisEngineDescription aed, String language) throws UIMAException { // create and initialize AnalysisEngine AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aed); cas = ae.newCAS(); ResultSpecification resultSpec = createResultSpec(language); cas.setDocumentText("new test"); ae.process(cas, resultSpec); cas.reset(); ae.destroy(); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/MultiprocessingAnalysisEngine_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/MultiprocessingAnalysisEng0000644000175000017500000005044311665471064033604 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.util.HashMap; import java.util.Map; import java.util.Random; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAException; import org.apache.uima.UIMAFramework; import org.apache.uima.UIMA_IllegalStateException; import org.apache.uima.ae.multiplier.SimpleCasGenerator; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class MultiprocessingAnalysisEngine_implTest extends TestCase { private AnalysisEngineDescription mSimpleDesc; private AnalysisEngineDescription mAggDesc; public volatile TypeSystem mLastTypeSystem; /** * Constructor for MultiprocessingAnalysisEngine_implTest. * * @param arg0 */ public MultiprocessingAnalysisEngine_implTest(String arg0) { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); mSimpleDesc = new AnalysisEngineDescription_impl(); mSimpleDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); mSimpleDesc.setPrimitive(true); mSimpleDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); mSimpleDesc.getMetaData().setName("Simple Test"); TypeSystemDescription typeSys = new TypeSystemDescription_impl(); typeSys.addType("foo.Bar", "test", "uima.tcas.Annotation"); typeSys.addType("NamedEntity", "test", "uima.tcas.Annotation"); typeSys.addType("DocumentStructure", "test", "uima.tcas.Annotation"); mSimpleDesc.getAnalysisEngineMetaData().setTypeSystem(typeSys); Capability cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); Capability[] caps = new Capability[] {cap}; mSimpleDesc.getAnalysisEngineMetaData().setCapabilities(caps); mAggDesc = new AnalysisEngineDescription_impl(); mAggDesc.setPrimitive(false); mAggDesc.getMetaData().setName("Simple Test Aggregate"); mAggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", mSimpleDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); mAggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); mAggDesc.getAnalysisEngineMetaData().setCapabilities(caps); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testInitialize() throws Exception { try { // initialize MultiprocesingTextAnalysisEngine MultiprocessingAnalysisEngine_impl mtae = new MultiprocessingAnalysisEngine_impl(); boolean result = mtae.initialize(mSimpleDesc, null); Assert.assertTrue(result); // initialize again - should fail Exception ex = null; try { mtae.initialize(mSimpleDesc, null); } catch (UIMA_IllegalStateException e) { ex = e; } Assert.assertNotNull(ex); // initialize a new TAE with parameters Map map = new HashMap(); map.put(AnalysisEngine.PARAM_NUM_SIMULTANEOUS_REQUESTS, Integer.valueOf(5)); map.put(AnalysisEngine.PARAM_TIMEOUT_PERIOD, Integer.valueOf(60000)); MultiprocessingAnalysisEngine_impl mtae2 = new MultiprocessingAnalysisEngine_impl(); result = mtae2.initialize(mSimpleDesc, map); Assert.assertTrue(result); // check parameter values Assert.assertEquals(5, mtae2.getPool().getSize()); Assert.assertEquals(60000, mtae2.getTimeout()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetAnalysisEngineMetaData() throws Exception { try { MultiprocessingAnalysisEngine_impl mtae = new MultiprocessingAnalysisEngine_impl(); boolean result = mtae.initialize(mSimpleDesc, null); Assert.assertTrue(result); AnalysisEngineMetaData md = mtae.getAnalysisEngineMetaData(); Assert.assertNotNull(md); Assert.assertEquals("Simple Test", md.getName()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testNewCAS() throws Exception { try { MultiprocessingAnalysisEngine_impl mtae = new MultiprocessingAnalysisEngine_impl(); boolean result = mtae.initialize(mSimpleDesc, null); Assert.assertTrue(result); CAS cas1 = mtae.newCAS(); // should have the type foo.Bar assertNotNull(cas1.getTypeSystem().getType("foo.Bar")); // should be able to get as many as we want and they should all be different CAS cas2 = mtae.newCAS(); Assert.assertNotNull(cas2); Assert.assertTrue(cas1 != cas2); CAS cas3 = mtae.newCAS(); Assert.assertNotNull(cas3); Assert.assertTrue(cas1 != cas3); Assert.assertTrue(cas2 != cas3); CAS cas4 = mtae.newCAS(); Assert.assertNotNull(cas4); Assert.assertTrue(cas1 != cas4); Assert.assertTrue(cas2 != cas4); Assert.assertTrue(cas3 != cas4); // try aggregate MultiprocessingAnalysisEngine_impl mtae2 = new MultiprocessingAnalysisEngine_impl(); result = mtae2.initialize(mAggDesc, null); Assert.assertTrue(result); CAS cas5 = mtae2.newCAS(); // should have the type foo.Bar assertNotNull(cas5.getTypeSystem().getType("foo.Bar")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcess() throws Exception { try { // test simple primitive MultiprocessingTextAnalysisEngine // (using TestAnnotator class) _testProcess(mSimpleDesc, 0); // test simple aggregate MultiprocessingTextAnalysisEngine // (again using TestAnnotator class) _testProcess(mAggDesc, 0); // multiple threads! MultiprocessingAnalysisEngine_impl ae = new MultiprocessingAnalysisEngine_impl(); Map params = new HashMap(); params.put(AnalysisEngine.PARAM_NUM_SIMULTANEOUS_REQUESTS, Integer.valueOf(3)); ae.initialize(mAggDesc, params); final int NUM_THREADS = 4; ProcessThread[] threads = new ProcessThread[NUM_THREADS]; Random random = new Random(); for (int repetitions = 0; repetitions < 4; repetitions++) { for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new ProcessThread(ae); threads[i].start(); Thread.sleep(random.nextInt(2)); // delay between 0 and 2 milliseconds } // wait for threads to finish and check if they got exceptions for (int i = 0; i < NUM_THREADS; i++) { try { threads[i].join(10000); } catch (InterruptedException ie) { System.err.println("got unexpected Interrupted exception " + ie); } if (threads[i].isAlive()) { System.err.println("timeout waiting for thread to complete " + i); fail("timeout waiting for thread to complete " + i); } Throwable failure = threads[i].getFailure(); if (failure != null) { if (failure instanceof Exception) { throw (Exception) failure; } else { fail(failure.getMessage()); } } } } //Check TestAnnotator fields only at the very end of processing, //we can't test from the threads themselves since the state of //these fields is nondeterministic during the multithreaded processing. assertEquals("testing...", TestAnnotator.getLastDocument()); ResultSpecification lastResultSpec = TestAnnotator.getLastResultSpec(); ResultSpecification resultSpec = new ResultSpecification_impl(lastResultSpec.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); assertEquals(resultSpec, lastResultSpec); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testProcessManyCM() throws Exception { //get Resource Specifier from XML file XMLInputSource in = new XMLInputSource("src/test/resources/ExampleTae/SimpleCasGenerator.xml"); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); for (int i = 0; i < 10; i++) { processMany(specifier); } } public void testProcessManyAgg() throws Exception { //get Resource Specifier from XML file XMLInputSource in = new XMLInputSource("src/test/resources/ExampleTae/SimpleTestAggregate.xml"); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); for (int i = 0; i < 10; i++) { processMany(specifier); } } final int NUM_THREADS = 5; final int NUM_INSTANCES = 3; public void processMany(ResourceSpecifier specifier) throws Exception { try { // multiple threads! MultiprocessingAnalysisEngine_impl ae = new MultiprocessingAnalysisEngine_impl(); Map params = new HashMap(); params.put(AnalysisEngine.PARAM_NUM_SIMULTANEOUS_REQUESTS, NUM_INSTANCES); ae.initialize(specifier , params); ProcessThreadMany[] threads = new ProcessThreadMany[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new ProcessThreadMany(ae); threads[i].start(); } // wait for threads to finish and check if they got exceptions for (int i = 0; i < NUM_THREADS; i++) { try { threads[i].join(10000); } catch (InterruptedException ie) { System.err.println("got unexpected Interrupted exception " + ie); } if (threads[i].isAlive()) { System.err.println("timeout waiting for thread to complete " + i); fail("timeout waiting for thread to complete " + i); } Throwable failure = threads[i].getFailure(); if (failure != null) { if (failure instanceof Exception) { throw (Exception) failure; } else { fail(failure.getMessage()); } } } //Check TestAnnotator fields only at the very end of processing, //we can't test from the threads themselves since the state of //these fields is nondeterministic during the multithreaded processing. assertEquals("testing...", SimpleCasGenerator.getLastDocument()); ResultSpecification lastResultSpec = SimpleCasGenerator.getLastResultSpec(); ResultSpecification resultSpec = new ResultSpecification_impl(lastResultSpec.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); assertEquals(resultSpec, lastResultSpec); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testReconfigure() throws Exception { try { // create simple primitive TextAnalysisEngine descriptor (using TestAnnotator class) AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Reconfigure Test 1"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("StringParam"); p1.setDescription("parameter with String data type"); p1.setType(ConfigurationParameter.TYPE_STRING); primitiveDesc.getMetaData().getConfigurationParameterDeclarations() .setConfigurationParameters(new ConfigurationParameter[] { p1 }); primitiveDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test1") }); // instantiate MultiprocessingTextAnalysisEngine MultiprocessingAnalysisEngine_impl tae = new MultiprocessingAnalysisEngine_impl(); tae.initialize(primitiveDesc, null); // check value of string param (TestAnnotator saves it in a static field) assertEquals("Test1", TestAnnotator.stringParamValue); // reconfigure tae.setConfigParameterValue("StringParam", "Test2"); tae.reconfigure(); // test again assertEquals("Test2", TestAnnotator.stringParamValue); // test aggregate TAE AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggDesc.setPrimitive(false); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", primitiveDesc); aggDesc.getMetaData().setName("Reconfigure Test 2"); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); ConfigurationParameter p2 = new ConfigurationParameter_impl(); p2.setName("StringParam"); p2.setDescription("parameter with String data type"); p2.setType(ConfigurationParameter.TYPE_STRING); aggDesc.getMetaData().getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[] { p2 }); aggDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test3") }); // instantiate TextAnalysisEngine MultiprocessingAnalysisEngine_impl aggTae = new MultiprocessingAnalysisEngine_impl(); aggTae.initialize(aggDesc, null); assertEquals("Test3", TestAnnotator.stringParamValue); // reconfigure aggTae.setConfigParameterValue("StringParam", "Test4"); aggTae.reconfigure(); // test again assertEquals("Test4", TestAnnotator.stringParamValue); // reconfigure WITHOUT setting that parameter aggTae.reconfigure(); // test again assertEquals("Test4", TestAnnotator.stringParamValue); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Auxilliary method used by testProcess() * * @param aTaeDesc * description of TextAnalysisEngine to test * @param i * thread identifier for multithreaded testing */ protected void _testProcess(AnalysisEngineDescription aTaeDesc, int i) throws UIMAException { // create and initialize MultiprocessingTextAnalysisEngine MultiprocessingAnalysisEngine_impl tae = new MultiprocessingAnalysisEngine_impl(); tae.initialize(aTaeDesc, null); // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. // We use thse to make sure the information propogates correctly to the annotator. // process(CAS) CAS tcas = tae.newCAS(); tcas.setDocumentText("new test"); tae.process(tcas); assertEquals("new test", TestAnnotator.lastDocument); tcas.reset(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); tcas.setDocumentText("testing..."); tae.process(tcas, resultSpec); assertEquals("testing...", TestAnnotator.lastDocument); assertEquals(resultSpec, TestAnnotator.lastResultSpec); tcas.reset(); } class ProcessThread extends Thread { ProcessThread(AnalysisEngine aAE) { mAE = aAE; } public void run() { try { // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. // We use thse to make sure the information propogates correctly to the // annotator. (However, we can't check these until after the threads are // finished, as their state is nondeterministic during multithreaded // processing.) // process(CAS) CAS tcas = mAE.newCAS(); mLastTypeSystem = tcas.getTypeSystem(); tcas.setDocumentText("new test"); mAE.process(tcas); tcas.reset(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); tcas.setDocumentText("testing..."); mAE.process(tcas, resultSpec); tcas.reset(); } catch (Throwable t) { t.printStackTrace(); //can't cause unit test to fail by throwing exception from thread. //record the failure and the main thread will check for it later. mFailure = t; } } public synchronized Throwable getFailure() { return mFailure; } Throwable mFailure = null; AnalysisEngine mAE; } class ProcessThreadMany extends Thread { Throwable mFailure = null; AnalysisEngine mAE; ProcessThreadMany(AnalysisEngine aAE) { mAE = aAE; } public void run() { try { // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. // We use thse to make sure the information propogates correctly to the // annotator. (However, we can't check these until after the threads are // finished, as their state is nondeterministic during multithreaded // processing.) // process(CAS) for (int i = 0; i < 5; i++) { CAS tcas = mAE.newCAS(); mLastTypeSystem = tcas.getTypeSystem(); tcas.setDocumentText("new test"); mAE.process(tcas); tcas.reset(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); tcas.setDocumentText("testing..."); mAE.process(tcas, resultSpec); tcas.reset(); } } catch (Throwable t) { t.printStackTrace(); //can't cause unit test to fail by throwing exception from thread. //record the failure and the main thread will check for it later. mFailure = t; } } public synchronized Throwable getFailure() { return mFailure; } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/AnnotationWriter.java0000644000175000017500000001377711665471064032517 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.collection.CasConsumer; import org.apache.uima.collection.CasConsumer_ImplBase; import org.apache.uima.resource.ResourceConfigurationException; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceProcessException; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.ProcessTrace; /** * The AnnotationWriter class writes specified annotations to an output file. The encoding of the * output file is UTF-8 */ public class AnnotationWriter extends CasConsumer_ImplBase implements CasConsumer { // output file File outFile; // output file writer OutputStreamWriter fileWriter; // only used by test case static boolean typeSystemInitCalled = false; /** * Initializes this CAS Consumer with the parameters specified in the descriptor. * * @throws ResourceInitializationException * if there is error in initializing the resources */ public void initialize() throws ResourceInitializationException { File testBaseDir = JUnitExtension.getFile("TextAnalysisEngineImplTest").getParentFile(); this.outFile = new File(testBaseDir, "CpmOutput.txt"); try { this.fileWriter = new OutputStreamWriter(new FileOutputStream(this.outFile, false), "UTF-8"); } catch (Exception e) { throw new ResourceInitializationException(e); } typeSystemInitCalled = false; } /* * (non-Javadoc) * * @see org.apache.uima.collection.CasConsumer_ImplBase#typeSystemInit(org.apache.uima.cas.TypeSystem) */ public void typeSystemInit(TypeSystem arg0) throws ResourceInitializationException { typeSystemInitCalled = true; } /** * print the cas content to the output file * * @param aCAS * CasContainer which has been populated by the TAEs * * @throws ResourceProcessException * if there is an error in processing the Resource * * @see org.apache.uima.collection.base_cpm.CasObjectProcessor#processCas(CAS) */ public synchronized void processCas(CAS aCAS) throws ResourceProcessException { try { // iterate and print annotations FSIterator typeIterator = aCAS.getCurrentView().getAnnotationIndex().iterator(); for (typeIterator.moveToFirst(); typeIterator.isValid(); typeIterator.moveToNext()) { AnnotationFS annot = (AnnotationFS) typeIterator.get(); this.fileWriter.write(annot.getCoveredText()); this.fileWriter.write(System.getProperty("line.separator")); this.fileWriter.write(annot.toString()); } this.fileWriter.flush(); } catch (Exception ex) { ex.printStackTrace(); } } /** * Called when a batch of processing is completed. * * @param aTrace * ProcessTrace object that will log events in this method. * @throws ResourceProcessException * if there is an error in processing the Resource * @throws IOException * if there is an IO Error * * @see org.apache.uima.collection.CasConsumer#batchProcessComplete(ProcessTrace) */ public void batchProcessComplete(ProcessTrace aTrace) throws ResourceProcessException, IOException { // nothing to do in this case as AnnotationPrinter doesnot do // anything cumulatively } /** * Called when the entire collection is completed. * * @param aTrace * ProcessTrace object that will log events in this method. * @throws ResourceProcessException * if there is an error in processing the Resource * @throws IOException * if there is an IO Error * @see org.apache.uima.collection.CasConsumer#collectionProcessComplete(ProcessTrace) */ public void collectionProcessComplete(ProcessTrace aTrace) throws ResourceProcessException, IOException { if (this.fileWriter != null) { this.fileWriter.close(); } } /** * Reconfigures the parameters of this Consumer.
* This is used in conjunction with the setConfigurationParameterValue to set the configuration * parameter values to values other than the ones specified in the descriptor. * * @throws ResourceConfigurationException * if the configuration parameter settings are invalid * * @see org.apache.uima.resource.ConfigurableResource#reconfigure() */ public void reconfigure() throws ResourceConfigurationException { //do nothing } /** * Called if clean up is needed in case of exit under error conditions. * * @see org.apache.uima.resource.Resource#destroy() */ public void destroy() { if (this.fileWriter != null) { try { this.fileWriter.close(); } catch (IOException e) { // ignore IOException on destroy } } } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/SegmentDroppingFlowController.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/SegmentDroppingFlowControl0000644000175000017500000001016511665471064033552 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.FlowConstraints; import org.apache.uima.cas.CAS; import org.apache.uima.flow.CasFlowController_ImplBase; import org.apache.uima.flow.CasFlow_ImplBase; import org.apache.uima.flow.FinalStep; import org.apache.uima.flow.Flow; import org.apache.uima.flow.FlowControllerContext; import org.apache.uima.flow.SimpleStep; import org.apache.uima.flow.Step; import org.apache.uima.resource.ResourceInitializationException; /** * Test FlowController that drops any segment whose document text is "DROP". Otherwise uses linear * flow. */ public class SegmentDroppingFlowController extends CasFlowController_ImplBase { String[] mSequence; public void initialize(FlowControllerContext aContext) throws ResourceInitializationException { super.initialize(aContext); FlowConstraints flowConstraints = aContext.getAggregateMetadata().getFlowConstraints(); mSequence = ((FixedFlow) flowConstraints).getFixedFlow(); } /* * (non-Javadoc) * * @see org.apache.uima.flow.CasFlowController_ImplBase#computeFlow(org.apache.uima.cas.CAS) */ public Flow computeFlow(CAS aCAS) throws AnalysisEngineProcessException { FixedFlowObject ffo = new FixedFlowObject(aCAS, 0); ffo.setCas(aCAS); return ffo; } class FixedFlowObject extends CasFlow_ImplBase { private int currentStep; private boolean wasSegmented = false; /** * Create a new fixed flow starting at step startStep of the fixed sequence. * * @param cas * aCAS * * @param startStep * index of mSequence to start at */ public FixedFlowObject(CAS cas, int startStep) { setCas(cas); currentStep = startStep; } /* * (non-Javadoc) * * @see org.apache.uima.flow.Flow#next() */ public Step next() throws AnalysisEngineProcessException { // drop any segment whose document text is "DROP" if ("DROP".equals(getCas().getCurrentView().getDocumentText())) { return new FinalStep(true); } if (currentStep >= mSequence.length) { return new FinalStep(); // this CAS has finished the sequence } // If CAS was segmented, do not continue with flow. The individual segments // are processed further but the original CAS is not. if (wasSegmented) { return new FinalStep(); } // otherwise, we just send the CAS to the next AE in sequence. return new SimpleStep(mSequence[currentStep++]); } /* * (non-Javadoc) * * @see org.apache.uima.flow.CasFlow_ImplBase#newCasProduced(CAS, String) */ public Flow newCasProduced(CAS newCas, String producedBy) throws AnalysisEngineProcessException { // record that the input CAS has been segmented (affects its subsequent flow) wasSegmented = true; // start the new segment CAS from the next node after the Segmenter that produced it int i = 0; while (!mSequence[i].equals(producedBy)) i++; return new FixedFlowObject(newCas, i + 1); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/TestAnnotator2.java0000644000175000017500000000631511665471064032065 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException; import org.apache.uima.analysis_engine.annotator.AnnotatorContext; import org.apache.uima.analysis_engine.annotator.AnnotatorContextException; import org.apache.uima.analysis_engine.annotator.AnnotatorInitializationException; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.Annotator_ImplBase; import org.apache.uima.analysis_engine.annotator.TextAnnotator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; /** * Annotator class used for testing. * */ public class TestAnnotator2 extends Annotator_ImplBase implements TextAnnotator { // Process method saves information to these static fields, // which are queried by the unit test. public static String lastDocument; public static String stringParamValue; public static ResultSpecification lastResultSpec; public static boolean typeSystemInitCalled; public static synchronized String getLastDocument() { return lastDocument; } public static synchronized ResultSpecification getLastResultSpec() { return lastResultSpec; } /** * @see org.apache.uima.analysis_engine.annotator.Annotator#initialize(CAS, AnnotatorContext) */ public void initialize(AnnotatorContext aContext) throws AnnotatorConfigurationException, AnnotatorInitializationException { super.initialize(aContext); typeSystemInitCalled = false; lastResultSpec = null; lastDocument = null; try { stringParamValue = (String) getContext().getConfigParameterValue("StringParam"); } catch (AnnotatorContextException e) { throw new AnnotatorInitializationException(e); } } public void typeSystemInit(TypeSystem aTypeSystem) { typeSystemInitCalled = true; } /** * @see org.apache.uima.analysis_engine.annotator.TextAnnotator#process(CAS,ResultSpecification) */ public void process(CAS aCAS, ResultSpecification aResultSpec) throws AnnotatorProcessException { // set static fields to contain document text, result spec, // and value of StringParam configuration parameter. lastDocument = aCAS.getDocumentText(); lastResultSpec = aResultSpec; } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/TaeDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/analysis_engine/impl/TaeDescription_implTest.ja0000644000175000017500000003554111665471066033452 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.analysis_engine.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.cas.CAS; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * Test the TaeDescription_impl class. * */ public class TaeDescription_implTest extends TestCase { private AnalysisEngineDescription primitiveDesc; private AnalysisEngineDescription aggregateDesc; /** * Constructor for TaeDescription_implTest. * * @param arg0 */ public TaeDescription_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Fake", "A Fake Type", "Annotation"); FeatureDescription feature1 = type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Fake"); priorityList.addType("EnumType"); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("testIndex"); index.setTypeName("Fake"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("TestFeature"); key1.setComparator(1); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Start"); key2.setComparator(0); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setTypePriority(true); index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("testIndex2"); index2.setTypeName("Fake"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl(); key1a.setFeatureName("TestFeature"); key1a.setComparator(1); index2.setKeys(new FsIndexKeyDescription[] { key1a }); // create primitive TAE description primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primitiveDesc.setPrimitive(true); primitiveDesc.setAnnotatorImplementationName("org.apache.uima.examples.TestAnnotator"); AnalysisEngineMetaData md = primitiveDesc.getAnalysisEngineMetaData(); md.setName("Test TAE"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); md.setTypeSystem(typeSystem); md.setTypePriorities(typePriorities); md.setFsIndexes(new FsIndexDescription[] { index, index2 }); Capability cap1 = new Capability_impl(); cap1.addOutputType("Fake", false); cap1.addOutputFeature("TestFeature"); Capability cap2 = new Capability_impl(); cap2.addInputType("Fake", true); cap2.addOutputType("Fake", true); // SimplePrecondition precond1 = new SimplePrecondition_impl(); // precond1.setFeatureDescription(feature1); // precond1.setComparisonValue(new String[]{"en,de"}); // precond1.setPredicate(SimplePrecondition.LANGUAGE_SUBSUMED); // cap1.setPreconditions(new Precondition[]{precond1}); cap1.setLanguagesSupported(new String[] { "en", "de" }); md.setCapabilities(new Capability[] { cap1, cap2 }); ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl(); cfgParam1.setName("param1"); cfgParam1.setDescription("Test Parameter 1"); cfgParam1.setType("String"); ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl(); cfgParam2.setName("param2"); cfgParam2.setDescription("Test Parameter 2"); cfgParam2.setType("Integer"); ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl(); cfgGrp1.setNames(new String[] { "cfgGrp1" }); cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 }); ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl(); cfgParam3.setName("param3"); cfgParam3.setDescription("Test Parameter 3"); cfgParam3.setType("Float"); ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl(); cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" }); cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 }); md.getConfigurationParameterDeclarations().setConfigurationGroups( new ConfigurationGroup[] { cfgGrp1, cfgGrp2 }); md.getConfigurationParameterDeclarations().setDefaultGroupName("cfgGrp1"); NameValuePair nvp1 = new NameValuePair_impl("param1", "test"); NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42")); NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045")); NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927")); ConfigurationParameterSettings settings = md.getConfigurationParameterSettings(); settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 }); settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a }); settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b }); // create aggregate TAE description aggregateDesc = new AnalysisEngineDescription_impl(); aggregateDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); aggregateDesc.setPrimitive(false); Map delegateTaeMap = aggregateDesc.getDelegateAnalysisEngineSpecifiersWithImports(); delegateTaeMap.put("Test", primitiveDesc); AnalysisEngineDescription_impl primDesc2 = new AnalysisEngineDescription_impl(); primDesc2.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); primDesc2.setAnnotatorImplementationName("fakeClass"); primDesc2.getAnalysisEngineMetaData().setName("fakeAnnotator"); primDesc2.getAnalysisEngineMetaData().setCapabilities( new Capability[] { new Capability_impl() }); delegateTaeMap.put("Empty", primDesc2); URISpecifier uriSpec = new URISpecifier_impl(); uriSpec.setUri("http://www.incubator.apache.org/uima"); uriSpec.setProtocol(Constants.PROTOCOL_SOAP); ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDependency(); dep.setKey("ResourceKey"); dep.setDescription("Test"); aggregateDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep }); ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory() .createResourceManagerConfiguration(); ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDescription(); extRes.setResourceSpecifier(uriSpec); extRes.setName("Resource1"); extRes.setDescription("Test"); resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes }); ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceBinding(); binding.setKey("ResourceKey"); binding.setResourceName("Resource1"); aggregateDesc.setResourceManagerConfiguration(resMgrCfg); // AsbCreationSpecifier asbSpec = new AsbCreationSpecifier_impl(); // asbSpec.getAsbMetaData().setAsynchronousModeSupported(true); // asbSpec.getAsbMetaData().setSupportedProtocols(new String[]{Constants.PROTOCOL_SOAP}); // aggregateDesc.setAsbSpecifier(asbSpec); // AnalysisSequencerCrea1tionSpecifier seqSpec = new // AnalysisSequencerCreationSpecifier_impl(); // seqSpec.getAnalysisSequencerMetaData().setSupportedPreconditionTypes( // new String[]{SimplePrecondition.PRECONDITION_TYPE}); // aggregateDesc.setSequencerSpecifier(seqSpec); md = aggregateDesc.getAnalysisEngineMetaData(); md.setName("Test Aggregate TAE"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); // md.setTypeSystem(typeSystem); // md.setFsIndexes(new FsIndexDescription[]{index}); md.setCapabilities(primitiveDesc.getAnalysisEngineMetaData().getCapabilities()); FixedFlow fixedFlow = new FixedFlow_impl(); fixedFlow.setFixedFlow(new String[] { "Test", "Empty" }); md.setFlowConstraints(fixedFlow); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); primitiveDesc.toXML(writer); String primitiveDescXml = writer.getBuffer().toString(); // System.out.println(primitiveDescXml); writer = new StringWriter(); aggregateDesc.toXML(writer); String aggregateDescXml = writer.getBuffer().toString(); // System.out.println(aggregateDescXml); // parse objects back from XML InputStream is = new ByteArrayInputStream(primitiveDescXml.getBytes(encoding)); AnalysisEngineDescription newPrimitiveDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(is, null)); is = new ByteArrayInputStream(aggregateDescXml.getBytes(encoding)); AnalysisEngineDescription newAggregateDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(is, null)); Assert.assertEquals(primitiveDesc, newPrimitiveDesc); Assert.assertEquals(aggregateDesc, newAggregateDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSerialization() throws Exception { try { byte[] primitiveDescBytes = SerializationUtils.serialize(primitiveDesc); AnalysisEngineDescription_impl primitiveDesc2 = (AnalysisEngineDescription_impl) SerializationUtils .deserialize(primitiveDescBytes); Assert.assertEquals(primitiveDesc, primitiveDesc2); byte[] aggregateDescBytes = SerializationUtils.serialize(aggregateDesc); AnalysisEngineDescription_impl aggregateDesc2 = (AnalysisEngineDescription_impl) SerializationUtils .deserialize(aggregateDescBytes); Assert.assertEquals(aggregateDesc, aggregateDesc2); // make sure XMLization still works StringWriter writer = new StringWriter(); primitiveDesc.toXML(writer); String primitiveDescXml = writer.getBuffer().toString(); writer = new StringWriter(); primitiveDesc2.toXML(writer); String primitiveDesc2xml = writer.getBuffer().toString(); Assert.assertEquals(primitiveDesc, primitiveDesc2); writer = new StringWriter(); aggregateDesc.toXML(writer); String aggregateDescXml = writer.getBuffer().toString(); writer = new StringWriter(); aggregateDesc2.toXML(writer); String aggregateDesc2xml = writer.getBuffer().toString(); Assert.assertEquals(aggregateDesc, aggregateDesc2); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/0000755000175000017500000000000011665471060022757 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/0000755000175000017500000000000011665471060023736 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/SofaTest.java0000644000175000017500000006624011665471060026341 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.StringTokenizer; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.UimaContextAdmin; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.ByteArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.DoubleArrayFS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FloatArrayFS; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.LongArrayFS; import org.apache.uima.cas.ShortArrayFS; import org.apache.uima.cas.SofaFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.CASSerializer; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.impl.XCASSerializer; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.impl.SofaID_impl; import org.apache.uima.jcas.JCas; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLSerializer; import org.xml.sax.SAXException; public class SofaTest extends TestCase { private CASMgr casMgr; private CAS cas; private Type annotationType; private Type docAnnotationType; private Type crossType; private Feature otherFeat; // private Feature annotSofaFeat; public SofaTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); this.casMgr = CASFactory.createCAS(); CasCreationUtils.setupTypeSystem(this.casMgr, (TypeSystemDescription) null); // Create a writable type system. TypeSystemMgr tsa = this.casMgr.getTypeSystemMgr(); // Add new types and features. // Type topType = tsa.getTopType(); this.annotationType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); // annotSofaFeat = annotationType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_SOFA); this.docAnnotationType = tsa.getType(CAS.TYPE_NAME_DOCUMENT_ANNOTATION); assertTrue(this.annotationType != null); this.crossType = tsa.addType("sofa.test.CrossAnnotation", this.annotationType); this.otherFeat = tsa.addFeature("otherAnnotation", this.crossType, this.annotationType); // Commit the type system. ((CASImpl) this.casMgr).commitTypeSystem(); // Create the Base indexes. this.casMgr.initCASIndexes(); FSIndexRepositoryMgr irm = this.casMgr.getIndexRepositoryMgr(); // init.initIndexes(irm, casMgr.getTypeSystemMgr()); irm.commit(); this.cas = this.casMgr.getCAS().getView(CAS.NAME_DEFAULT_SOFA); assertTrue(this.cas.getSofa() == null); assertTrue(this.cas.getViewName().equals(CAS.NAME_DEFAULT_SOFA)); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Test driver. */ public void testMain() throws Exception { try { // Create a Sofa (using old APIs for now) SofaID_impl id = new SofaID_impl(); id.setSofaID("EnglishDocument"); SofaFS es = this.cas.createSofa(id, "text"); // Initial View is #1!!! assertTrue(2 == es.getSofaRef()); // Set the document text es.setLocalSofaData("this beer is good"); // Test Multiple Sofas across XCAS serialization XCASSerializer ser = new XCASSerializer(this.cas.getTypeSystem()); OutputStream outputXCAS = new FileOutputStream("Sofa.xcas"); XMLSerializer xmlSer = new XMLSerializer(outputXCAS); try { ser.serialize(cas, xmlSer.getContentHandler()); outputXCAS.close(); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } // Deserialize XCAS this.cas.reset(); InputStream inputXCAS = new FileInputStream("Sofa.xcas"); try { XCASDeserializer.deserialize(inputXCAS, cas, false); inputXCAS.close(); } catch (SAXException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } // Add a new Sofa // SofaID_impl gid = new SofaID_impl(); // gid.setSofaID("GermanDocument"); // SofaFS gs = ((CASImpl)cas).createSofa(gid,"text"); CAS gerTcas =this.cas.createView("GermanDocument"); assertTrue(gerTcas.getViewName().equals("GermanDocument")); SofaFS gs = gerTcas.getSofa(); assertTrue(gs != null); assertTrue(3 == gs.getSofaRef()); // Set the document text // gs.setLocalSofaData("das bier ist gut"); gerTcas.setDocumentText("das bier ist gut"); // Test multiple Sofas across binary serialization CASSerializer cs = Serialization.serializeNoMetaData(cas); cas = Serialization.createCAS(casMgr, cs); // Add a new Sofa // SofaID_impl fid = new SofaID_impl(); // fid.setSofaID("FrenchDocument"); // SofaFS fs = ((CASImpl)cas).createSofa(fid, "text"); CAS frT =this.cas.createView("FrenchDocument"); assertTrue(frT.getViewName().equals("FrenchDocument")); SofaFS fs = frT.getSofa(); assertTrue(fs != null); assertTrue(4 == fs.getSofaRef()); // Test multiple Sofas across blob serialization ByteArrayOutputStream fos = new ByteArrayOutputStream(); Serialization.serializeCAS(cas, fos); this.cas.reset(); ByteArrayInputStream fis = new ByteArrayInputStream(fos.toByteArray()); Serialization.deserializeCAS(cas, fis); // Open TCas views of some Sofas CAS engTcas =this.cas.getView(es); assertTrue(engTcas.getViewName().equals("EnglishDocument")); CAS frTcas =this.cas.getView("FrenchDocument"); // Set the document text off SofaFS after the CAS view exists frTcas.setSofaDataString("cette biere est bonne", "text"); // Create standard annotations against one and cross annotations // against the other int engEnd = 0; int gerEnd = 0; int frEnd = 0; String engText = engTcas.getDocumentText(); String gerText = gerTcas.getDocumentText(); String frText = frTcas.getDocumentText(); StringTokenizer est = new StringTokenizer(engText); StringTokenizer gst = new StringTokenizer(gerText); StringTokenizer fst = new StringTokenizer(frText); while (est.hasMoreTokens()) { assertTrue(gst.hasMoreTokens()); assertTrue(fst.hasMoreTokens()); String eTok = est.nextToken(); int engBegin = engText.indexOf(eTok, engEnd); engEnd = engBegin + eTok.length(); String gTok = gst.nextToken(); int gerBegin = gerText.indexOf(gTok, gerEnd); gerEnd = gerBegin + gTok.length(); String fTok = fst.nextToken(); int frBegin = frText.indexOf(fTok, frEnd); frEnd = frBegin + fTok.length(); AnnotationFS engAnnot = engTcas.createAnnotation(annotationType, engBegin, engEnd); engTcas.getIndexRepository().addFS(engAnnot); AnnotationFS frAnnot = frTcas.createAnnotation(this.annotationType, frBegin, frEnd); frTcas.getIndexRepository().addFS(frAnnot); AnnotationFS gerAnnot = gerTcas.createAnnotation(this.crossType, gerBegin, gerEnd); gerAnnot.setFeatureValue(this.otherFeat, engAnnot); gerTcas.getIndexRepository().addFS(gerAnnot); } // Test that the annotations are in separate index spaces, and that // Sofas are indexed // FSIndex sofaIndex = // cas.getIndexRepository().getIndex(CAS.SOFA_INDEX_NAME); FSIterator sofaIter =this.cas.getSofaIterator(); int numSofas = 0; while (sofaIter.isValid()) { numSofas++; sofaIter.moveToNext(); } FSIndex engIndex = engTcas.getAnnotationIndex(); FSIndex gerIndex = gerTcas.getAnnotationIndex(); FSIndex frIndex = frTcas.getAnnotationIndex(); // assertTrue(sofaIndex.size() == 3); // 3 sofas assertTrue(numSofas == 3); assertTrue(engIndex.size() == 5); // 4 annots plus // documentAnnotation assertTrue(gerIndex.size() == 5); // 4 annots plus // documentAnnotation assertTrue(frIndex.size() == 5); // 4 annots plus // documentAnnotation // Test that the annotations are of the correct types FSIterator engIt = engIndex.iterator(); FSIterator gerIt = gerIndex.iterator(); FSIterator frIt = frIndex.iterator(); AnnotationFS engAnnot = engIt.get(); AnnotationFS gerAnnot = gerIt.get(); AnnotationFS frAnnot = frIt.get(); assertTrue(docAnnotationType.getName().equals(engAnnot.getType().getName())); assertTrue(docAnnotationType.getName().equals(gerAnnot.getType().getName())); assertTrue(docAnnotationType.getName().equals(frAnnot.getType().getName())); engIt.moveToNext(); gerIt.moveToNext(); frIt.moveToNext(); engAnnot = (AnnotationFS) engIt.get(); gerAnnot = (AnnotationFS) gerIt.get(); frAnnot = (AnnotationFS) frIt.get(); assertTrue(annotationType.getName().equals(engAnnot.getType().getName())); assertTrue(("this").equals(engAnnot.getCoveredText())); assertTrue(annotationType.getName().equals(frAnnot.getType().getName())); assertTrue(("cette").equals(frAnnot.getCoveredText())); assertTrue(crossType.getName().equals(gerAnnot.getType().getName())); assertTrue(("das").equals(gerAnnot.getCoveredText())); // Test that the other annotation feature of cross annotations works AnnotationFS crossAnnot = (AnnotationFS) gerAnnot.getFeatureValue(otherFeat); assertTrue(annotationType.getName().equals(crossAnnot.getType().getName())); assertTrue(("this").equals(crossAnnot.getCoveredText())); //Test equals method for same annotation obtained through different views assertEquals(engAnnot, crossAnnot); // Test that annotations accessed from a reference in the base CAS // work correctly ArrayFS anArray =this.cas.createArrayFS(3); anArray.set(0, engAnnot); anArray.set(1, frAnnot); anArray.set(2, gerAnnot); AnnotationFS tstAnnot = (AnnotationFS) anArray.get(0); assertTrue(("this").equals(tstAnnot.getCoveredText())); tstAnnot = (AnnotationFS) anArray.get(1); assertTrue(("cette").equals(tstAnnot.getCoveredText())); tstAnnot = (AnnotationFS) anArray.get(2); assertTrue(("das").equals(tstAnnot.getCoveredText())); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Test stream access to Sofa Data. * * @throws Exception */ public void testSofaDataStream() throws Exception { try { // Create Sofas // Create a local Sofa and set string feature // SofaID_impl id = new SofaID_impl(); // id.setSofaID("StringSofaData"); // SofaFS strSofa = cas.createSofa(id, "text"); // strSofa.setLocalSofaData("this beer is good"); CAS stringView =this.cas.createView("StringSofaData"); stringView.setDocumentText("this beer is good"); // create a int array fs IntArrayFS intArrayFS =this.cas.createIntArrayFS(5); intArrayFS.set(0, 1); intArrayFS.set(1, 2); intArrayFS.set(2, 3); intArrayFS.set(3, 4); intArrayFS.set(4, 5); // create a Sofa and set the SofaArray feature to an int array FS. // id = new SofaID_impl(); // id.setSofaID("intArraySofaData"); // SofaFS intarraySofaFS = cas.createSofa(id, "text"); // intarraySofaFS.setLocalSofaData(intArrayFS); CAS intArrayView =this.cas.createView("intArraySofaData"); intArrayView.setSofaDataArray(intArrayFS, "integers"); // create a string array fs StringArrayFS stringArrayFS =this.cas.createStringArrayFS(5); stringArrayFS.set(0, "This"); stringArrayFS.set(1, "beer"); stringArrayFS.set(2, "is"); stringArrayFS.set(3, "really"); stringArrayFS.set(4, "good"); CAS stringArrayView =this.cas.createView("stringArraySofaData"); stringArrayView.setSofaDataArray(stringArrayFS, "strings"); // create a float array fs FloatArrayFS floatArrayFS =this.cas.createFloatArrayFS(5); floatArrayFS.set(0, (float) 0.1); floatArrayFS.set(1, (float) 0.2); floatArrayFS.set(2, (float) 0.3); floatArrayFS.set(3, (float) 0.4); floatArrayFS.set(4, (float) 0.5); // create a sofa and set the SofaArray feature to the float array // id = new SofaID_impl(); // id.setSofaID("floatArraySofaData"); // SofaFS floatarraySofaFS = cas.createSofa(id,"text"); // floatarraySofaFS.setLocalSofaData(floatArrayFS); CAS floatArrayView =this.cas.createView("floatArraySofaData"); floatArrayView.setSofaDataArray(floatArrayFS, "floats"); // create a short array fs ShortArrayFS shortArrayFS =this.cas.createShortArrayFS(5); shortArrayFS.set(0, (short) 128); shortArrayFS.set(1, (short) 127); shortArrayFS.set(2, (short) 126); shortArrayFS.set(3, (short) 125); shortArrayFS.set(4, (short) 124); // create a Sofa and set the SofaArray feature to an int array FS. // id = new SofaID_impl(); // id.setSofaID("shortArraySofaData"); // SofaFS shortarraySofaFS = cas.createSofa(id, "text"); // shortarraySofaFS.setLocalSofaData(shortArrayFS); CAS shortArrayView =this.cas.createView("shortArraySofaData"); shortArrayView.setSofaDataArray(shortArrayFS, "shorts"); // create a byte array fs ByteArrayFS byteArrayFS =this.cas.createByteArrayFS(5); byteArrayFS.set(0, (byte) 8); byteArrayFS.set(1, (byte) 16); byteArrayFS.set(2, (byte) 64); byteArrayFS.set(3, (byte) 128); byteArrayFS.set(4, (byte) 255); // create a Sofa and set the SofaArray feature. // id = new SofaID_impl(); // id.setSofaID("byteArraySofaData"); // SofaFS bytearraySofaFS = cas.createSofa(id, "text"); // bytearraySofaFS.setLocalSofaData(byteArrayFS); CAS byteArrayView =this.cas.createView("byteArraySofaData"); byteArrayView.setSofaDataArray(byteArrayFS, "bytes"); // create a long array fs LongArrayFS longArrayFS =this.cas.createLongArrayFS(5); longArrayFS.set(0, Long.MAX_VALUE); longArrayFS.set(1, Long.MAX_VALUE - 1); longArrayFS.set(2, Long.MAX_VALUE - 2); longArrayFS.set(3, Long.MAX_VALUE - 3); longArrayFS.set(4, Long.MAX_VALUE - 4); // create a Sofa and set the SofaArray feature. // id = new SofaID_impl(); // id.setSofaID("longArraySofaData"); // SofaFS longarraySofaFS = cas.createSofa(id, "text"); // longarraySofaFS.setLocalSofaData(longArrayFS); CAS longArrayView =this.cas.createView("longArraySofaData"); longArrayView.setSofaDataArray(longArrayFS, "longs"); DoubleArrayFS doubleArrayFS =this.cas.createDoubleArrayFS(5); doubleArrayFS.set(0, Double.MAX_VALUE); doubleArrayFS.set(1, Double.MIN_VALUE); doubleArrayFS.set(2, Double.parseDouble("1.5555")); doubleArrayFS.set(3, Double.parseDouble("99.000000005")); doubleArrayFS.set(4, Double.parseDouble("4.44444444444444444")); // create a Sofa and set the SofaArray feature. // id = new SofaID_impl(); // id.setSofaID("doubleArraySofaData"); // SofaFS doublearraySofaFS = cas.createSofa(id, "text"); // doublearraySofaFS.setLocalSofaData(doubleArrayFS); CAS doubleArrayView =this.cas.createView("doubleArraySofaData"); doubleArrayView.setSofaDataArray(doubleArrayFS, "doubles"); // create remote sofa and set the SofaURI feature // id = new SofaID_impl(); // id.setSofaID("remoteSofaData"); // SofaFS remoteSofa = cas.createSofa(id, "text"); // remoteSofa.setRemoteSofaURI("file:.\\Sofa.xcas"); CAS remoteView =this.cas.createView("remoteSofaData"); String sofaFileName = "./Sofa.xcas"; remoteView.setSofaDataURI("file:" + sofaFileName, "text"); // read sofa data // InputStream is = strSofa.getSofaDataStream(); InputStream is = stringView.getSofaDataStream(); assertTrue(is != null); byte[] dest = new byte[1]; StringBuffer buf = new StringBuffer(); while (is.read(dest) != -1) { buf.append((char) dest[0]); } assertTrue(buf.toString().equals("this beer is good")); dest = new byte[4]; // is = intarraySofaFS.getSofaDataStream(); is.close(); is = intArrayView.getSofaDataStream(); assertTrue(is != null); int i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getInt() == intArrayFS.get(i++)); } is.close(); is = stringArrayView.getSofaDataStream(); assertTrue(is != null); BufferedReader br = new BufferedReader(new InputStreamReader(is)); i = 0; while (br.ready()) { assertTrue(stringArrayFS.get(i++).equals(br.readLine())); } // is = floatarraySofaFS.getSofaDataStream(); is.close(); is = floatArrayView.getSofaDataStream(); assertTrue(is != null); i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getFloat() == floatArrayFS.get(i++)); } dest = new byte[2]; // is = shortarraySofaFS.getSofaDataStream(); is.close(); is = shortArrayView.getSofaDataStream(); assertTrue(is != null); i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getShort() == shortArrayFS.get(i++)); } dest = new byte[1]; // is = bytearraySofaFS.getSofaDataStream(); is.close(); is = byteArrayView.getSofaDataStream(); assertTrue(is != null); i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).get() == byteArrayFS.get(i++)); } dest = new byte[8]; // is = longarraySofaFS.getSofaDataStream(); is.close(); is = longArrayView.getSofaDataStream(); assertTrue(is != null); i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getLong() == longArrayFS.get(i++)); } // is = doublearraySofaFS.getSofaDataStream(); is.close(); is = doubleArrayView.getSofaDataStream(); assertTrue(is != null); i = 0; while (is.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getDouble() == doubleArrayFS.get(i++)); } dest = new byte[1]; // is = remoteSofa.getSofaDataStream(); is = remoteView.getSofaDataStream(); assertTrue(is != null); is.close(); // Delete the generated file. File xcasFile = new File(sofaFileName); if (xcasFile.exists()) { assertTrue(xcasFile.delete()); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSetSofaDataString() { final String TEST_TEXT = "this is a test"; final String TEST_MIME = "text/plain"; CAS testView = this.cas.createView("TestView"); testView.setSofaDataString(TEST_TEXT, TEST_MIME); assertEquals(TEST_TEXT, testView.getSofa().getLocalStringData()); assertEquals(TEST_MIME, testView.getSofa().getSofaMime()); assertEquals(TEST_TEXT, testView.getSofaDataString()); } public void testSetSofaDataStringOnInitialView() { final String TEST_TEXT = "this is a test"; final String TEST_MIME = "text/plain"; this.cas.setSofaDataString(TEST_TEXT, TEST_MIME); assertEquals(TEST_TEXT, this.cas.getSofa().getLocalStringData()); assertEquals(TEST_MIME, this.cas.getSofa().getSofaMime()); assertEquals(TEST_TEXT, this.cas.getSofaDataString()); } public void testSetSofaDataURI() { final String TEST_URI = "file:/test"; final String TEST_MIME = "text/plain"; CAS testView = this.cas.createView("TestView"); testView.setSofaDataURI(TEST_URI, TEST_MIME); assertEquals(TEST_URI, testView.getSofa().getSofaURI()); assertEquals(TEST_MIME, testView.getSofa().getSofaMime()); } public void testSetSofaDataURIonInitialView() throws Exception { // This test uses platform encoding both for reading and writing. String someText="remote text."; String someTextFile="./someUriText.txt"; FileWriter output = new FileWriter(someTextFile); output.write(someText); output.close(); final String TEST_URI = "file:" + someTextFile; final String TEST_MIME = "text/plain"; this.cas.setSofaDataURI(TEST_URI, TEST_MIME); assertEquals(TEST_URI, this.cas.getSofa().getSofaURI()); assertEquals(TEST_MIME, this.cas.getSofa().getSofaMime()); InputStream is = this.cas.getSofaDataStream(); assertTrue(is != null); // This obviously can't work on all platforms // byte[] dest = new byte[1]; // StringBuffer buf = new StringBuffer(); // while (is.read(dest) != -1) { // buf.append((char) dest[0]); // } // is.close(); // assertTrue(buf.toString().equals(someText)); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String textFromFile = reader.readLine(); is.close(); assertTrue(textFromFile.equals(someText)); File testFile = new File(someTextFile); assertTrue(testFile.delete()); } public void testSetSofaDataArray() { final String TEST_MIME = "text/plain"; CAS testView = this.cas.createView("TestView"); ByteArrayFS sofaDataArray = testView.createByteArrayFS(2); sofaDataArray.set(0, (byte)0); sofaDataArray.set(1, (byte)42); testView.setSofaDataArray(sofaDataArray, TEST_MIME); assertEquals(sofaDataArray, testView.getSofa().getLocalFSData()); assertEquals(TEST_MIME, testView.getSofa().getSofaMime()); } public void testSetSofaDataArrayOnInitialView() { final String TEST_MIME = "text/plain"; ByteArrayFS sofaDataArray = this.cas.createByteArrayFS(2); sofaDataArray.set(0, (byte)0); sofaDataArray.set(1, (byte)42); this.cas.setSofaDataArray(sofaDataArray, TEST_MIME); assertEquals(sofaDataArray, this.cas.getSofa().getLocalFSData()); assertEquals(TEST_MIME, this.cas.getSofa().getSofaMime()); } public void testReset() { this.cas.reset(); this.cas.setDocumentText("setDocumentText creates the _InitialView Sofa"); CAS testView = this.cas.createView("TestView"); testView.setDocumentText("create a 2nd Sofa"); assertTrue( this.cas.getViewName().equals("_InitialView")); assertTrue( testView.getViewName().equals("TestView")); this.cas.reset(); SofaID_impl id = new SofaID_impl(); id.setSofaID("TestView"); SofaFS testSofa = this.cas.createSofa(id, "text"); CAS newView = this.cas.getView(testSofa); assertTrue( newView.getViewName().equals("TestView")); } public void testGetViewIterator() throws Exception { this.cas.reset(); CAS view1 = this.cas.createView("View1"); CAS view2 = this.cas.createView("View2"); Iterator iter = this.cas.getViewIterator(); assertEquals(this.cas, iter.next()); assertEquals(view1, iter.next()); assertEquals(view2, iter.next()); assertFalse(iter.hasNext()); CAS viewE1 = this.cas.createView("EnglishDocument"); CAS viewE2 = this.cas.createView("EnglishDocument.2"); iter = this.cas.getViewIterator("EnglishDocument"); assertEquals(viewE1, iter.next()); assertEquals(viewE2, iter.next()); assertFalse(iter.hasNext()); //try with Sofa mappings UimaContextAdmin rootCtxt = UIMAFramework.newUimaContext( UIMAFramework.getLogger(), UIMAFramework.newDefaultResourceManager(), UIMAFramework.newConfigurationManager()); Map sofamap = new HashMap(); sofamap.put("SourceDocument","EnglishDocument"); UimaContextAdmin childCtxt = rootCtxt.createChild("test", sofamap); cas.setCurrentComponentInfo(childCtxt.getComponentInfo()); iter = this.cas.getViewIterator("SourceDocument"); assertEquals(viewE1, iter.next()); assertEquals(viewE2, iter.next()); assertFalse(iter.hasNext()); this.cas.setCurrentComponentInfo(null); //repeat with JCas this.cas.reset(); JCas jcas = this.cas.getJCas(); JCas jview1 = jcas.createView("View1"); JCas jview2 = jcas.createView("View2"); Iterator jCasIter = jcas.getViewIterator(); assertEquals(jcas, jCasIter.next()); assertEquals(jview1, jCasIter.next()); assertEquals(jview2, jCasIter.next()); assertFalse(jCasIter.hasNext()); JCas jviewE1 = jcas.createView("EnglishDocument"); JCas jviewE2 = jcas.createView("EnglishDocument.2"); jCasIter = jcas.getViewIterator("EnglishDocument"); assertEquals(jviewE1, jCasIter.next()); assertEquals(jviewE2, jCasIter.next()); assertFalse(jCasIter.hasNext()); //try with Sofa mappings cas.setCurrentComponentInfo(childCtxt.getComponentInfo()); jCasIter = jcas.getViewIterator("SourceDocument"); assertEquals(jviewE1, jCasIter.next()); assertEquals(jviewE2, jCasIter.next()); assertFalse(jCasIter.hasNext()); this.cas.setCurrentComponentInfo(null); } public static void main(String[] args) { junit.textui.TestRunner.run(SofaTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationIteratorTest.java0000644000175000017500000002241111665471060031265 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas.text.AnnotationIndex; /** * Class comment for FilteredIteratorTest.java goes here. * */ public class AnnotationIteratorTest extends TestCase { private CAS cas; private TypeSystem ts; private Type stringType; private Type tokenType; private Type intType; private Type tokenTypeType; private Type wordType; private Type sepType; private Type eosType; private Feature tokenTypeFeat; private Feature lemmaFeat; private Feature sentLenFeat; private Feature tokenFloatFeat; private Feature startFeature; private Feature endFeature; private Type sentenceType; /** * Constructor for FilteredIteratorTest. * * @param arg0 */ public AnnotationIteratorTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); assertTrue(this.cas != null); this.ts = this.cas.getTypeSystem(); assertTrue(this.ts != null); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } this.stringType = this.ts.getType(CAS.TYPE_NAME_STRING); assertTrue(this.stringType != null); this.tokenType = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(this.stringType != null); this.intType = this.ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(this.intType != null); this.tokenTypeType = this.ts.getType(CASTestSetup.TOKEN_TYPE_TYPE); assertTrue(this.tokenTypeType != null); this.wordType = this.ts.getType(CASTestSetup.WORD_TYPE); assertTrue(this.wordType != null); this.sepType = this.ts.getType(CASTestSetup.SEP_TYPE); assertTrue(this.sepType != null); this.eosType = this.ts.getType(CASTestSetup.EOS_TYPE); assertTrue(this.eosType != null); this.tokenTypeFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_TYPE_FEAT_Q); assertTrue(this.tokenTypeFeat != null); this.lemmaFeat = this.ts.getFeatureByFullName(CASTestSetup.LEMMA_FEAT_Q); assertTrue(this.lemmaFeat != null); this.sentLenFeat = this.ts.getFeatureByFullName(CASTestSetup.SENT_LEN_FEAT_Q); assertTrue(this.sentLenFeat != null); this.tokenFloatFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_FLOAT_FEAT_Q); assertTrue(this.tokenFloatFeat != null); this.startFeature = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); assertTrue(this.startFeature != null); this.endFeature = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_END); assertTrue(this.endFeature != null); this.sentenceType = this.ts.getType(CASTestSetup.SENT_TYPE); assertTrue(this.sentenceType != null); } public void tearDown() { this.cas = null; this.ts = null; this.tokenType = null; this.intType = null; this.tokenTypeType = null; this.wordType = null; this.sepType = null; this.eosType = null; this.tokenTypeFeat = null; this.lemmaFeat = null; this.sentLenFeat = null; this.tokenFloatFeat = null; this.startFeature = null; this.endFeature = null; this.sentenceType = null; } public void testIterator1() { final String text = "aaaa bbbb cccc dddd aaaa bbbb cccc dddd aaaa bbbb cccc dddd "; try { this.cas.setDocumentText(text); } catch (CASRuntimeException e) { assertTrue(false); } int annotCount = 1; // Init with document annotation. // create token and sentence annotations for (int i = 0; i < text.length() - 5; i++) { ++annotCount; this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i, i + 5)); } // for (int i = 0; i < text.length() - 5; i++) { // cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i, i+5)); // } for (int i = 0; i < text.length() - 10; i += 5) { ++annotCount; this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.sentenceType, i, i + 10)); } int count; AnnotationIndex annotIndex = this.cas.getAnnotationIndex(); FSIterator it = annotIndex.iterator(true); count = 0; while (it.isValid()) { ++count; it.moveToNext(); } assertTrue(annotCount == count); // System.out.println("Size of ambiguous iterator: " + count); it = annotIndex.iterator(false); count = 0; while (it.isValid()) { ++count; it.moveToNext(); } assertTrue(count == 1); // System.out.println("Size of unambiguous iterator: " + count); AnnotationFS bigAnnot = this.cas.createAnnotation(this.sentenceType, 10, 41); it = annotIndex.subiterator(bigAnnot, true, true); count = 0; while (it.isValid()) { ++count; // AnnotationFS a = (AnnotationFS) it.get(); // System.out.println("Annotation from " + a.getBegin() + " to " + a.getEnd()); it.moveToNext(); } assertTrue(count == 32); count = 0; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { ++count; } assertTrue(count == 32); // System.out.println("Size of subiterator(true, true): " + count); it = annotIndex.subiterator(bigAnnot, false, true); count = 0; while (it.isValid()) { ++count; // AnnotationFS a = (AnnotationFS) it.get(); // System.out.println("Annotation from " + a.getBegin() + " to " + a.getEnd()); it.moveToNext(); } assertTrue(count == 3); // System.out.println("Size of subiterator(false, true): " + count); count = 0; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { ++count; } assertTrue(count == 3); it = annotIndex.subiterator(bigAnnot, true, false); count = 0; while (it.isValid()) { ++count; // AnnotationFS a = (AnnotationFS) it.get(); // System.out.println("Annotation from " + a.getBegin() + " to " + a.getEnd()); it.moveToNext(); } assertTrue(count == 39); // System.out.println("Size of subiterator(true, false): " + count); count = 0; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { ++count; } assertTrue(count == 39); it = annotIndex.subiterator(bigAnnot, false, false); count = 0; while (it.isValid()) { ++count; // AnnotationFS a = (AnnotationFS) it.get(); // System.out.println("Annotation from " + a.getBegin() + " to " + a.getEnd()); it.moveToNext(); } assertTrue(count == 4); // System.out.println("Size of subiterator(false, false): " + count); count = 0; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { ++count; } assertTrue(count == 4); AnnotationFS sent = (AnnotationFS) this.cas.getAnnotationIndex(this.sentenceType).iterator().get(); it = annotIndex.subiterator(sent, false, true); count = 0; while (it.isValid()) { ++count; // AnnotationFS a = (AnnotationFS) it.get(); // System.out.println("Annotation from " + a.getBegin() + " to " + a.getEnd()); it.moveToNext(); } assertTrue(count == 2); // System.out.println("Size of subiterator(false, false): " + count); count = 0; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { ++count; } assertTrue(count == 2); } public void testIncorrectIndexTypeException() { boolean caughtException = false; try { this.cas.getAnnotationIndex(this.stringType); } catch (CASRuntimeException e) { // e.printStackTrace(); caughtException = true; } assertTrue(caughtException); caughtException = false; try { AnnotationIndex ai = this.cas.getAnnotationIndex(ts.getType(CASTestSetup.TOKEN_TYPE_TYPE)); } catch (CASRuntimeException e) { caughtException = true; } assertTrue(caughtException); try { this.cas.getAnnotationIndex(this.tokenType); } catch (CASRuntimeException e) { assertTrue(false); } } public static void main(String[] args) { AnnotationIteratorTest test = new AnnotationIteratorTest(null); test.run(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CrossAnnotation_Type.java0000644000175000017500000000722211665471060030731 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation_Type; /** * This class is part of the JCas internals. The Get/Set accessors are for low-level CAS access, * only. */ public class CrossAnnotation_Type extends Annotation_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new CrossAnnotation(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new CrossAnnotation(addr, instanceOf_Type); } }; public final static int typeIndexID = CrossAnnotation.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("uima.tcas.CrossAnnotation"); final Feature casFeat_otherAnnotation; final int casFeatCode_otherAnnotation; public int getOtherAnnotation(int addr) { if (featOkTst && casFeat_otherAnnotation == null) this.jcas.throwFeatMissing("otherAnnotation", "uima.tcas.CrossAnnotation"); return ll_cas.ll_getRefValue(addr, casFeatCode_otherAnnotation); } public void setOtherAnnotation(int addr, int v) { if (featOkTst && casFeat_otherAnnotation == null) this.jcas.throwFeatMissing("otherAnnotation", "uima.tcas.CrossAnnotation"); ll_cas.ll_setRefValue(addr, casFeatCode_otherAnnotation, v); } // * initialize variables to correspond with Cas Type and Features public CrossAnnotation_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_otherAnnotation = jcas.getRequiredFeatureDE(casType, "otherAnnotation", "uima.tcas.Annotation", featOkTst); casFeatCode_otherAnnotation = (null == casFeat_otherAnnotation) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_otherAnnotation).getCode(); } protected CrossAnnotation_Type() { // block default new operator casFeat_otherAnnotation = null; casFeatCode_otherAnnotation = JCas.INVALID_FEATURE_CODE; throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationReinitTest.java0000644000175000017500000011445411665471060031442 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.ByteArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Marker; import org.apache.uima.cas.ShortArrayFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.CASSerializer; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas_data.impl.CasComparer; import org.apache.uima.internal.util.TextStringTokenizer; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.FileUtils; import org.apache.uima.util.XMLInputSource; /** * Class comment for TokenizerTest.java goes here. * */ public class SerializationReinitTest extends TestCase { public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; public static final String STRING_SUBTYPE_1 = "StringSubtype1"; public static final String[] STR_1_VALS = { "test1", "test2" }; public static final String OSTR_TYPE = "theType"; public static final String OSTR_TYPE_FEAT = "theString"; public static final String OBYTE_TYPE_FEAT = "theByte"; public static final String OSHORT_TYPE_FEAT = "theShort"; public static final String OBYTEA_TYPE_FEAT = "theByteArray"; public static final String OSHORTA_TYPE_FEAT = "theShortArray"; public static final String OLONG_TYPE_FEAT = "theLong"; private CASMgr casMgr; private CAS cas; private Type wordType; private Type separatorType; private Type eosType; private Type tokenType; private Feature tokenTypeFeature; private Type sentenceType; private Feature startFeature; private Feature endFeature; private Type strSub1; private Type theTypeType; private Feature theStringFeature; private Feature theByteFeature; private Feature theShortFeature; private Feature theByteArrayFeature; private Feature theShortArrayFeature; private Feature theLongFeature; private FsIndexDescription[] indexes; private TypeSystemDescription typeSystem; public SerializationReinitTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ public void setUp() throws Exception { super.setUp(); casMgr = initCAS(); cas = (CASImpl)casMgr; TypeSystem ts = cas.getTypeSystem(); wordType = ts.getType(WORD_TYPE); // assert(wordType != null); separatorType = ts.getType(SEP_TYPE); eosType = ts.getType(EOS_TYPE); tokenType = ts.getType(TOKEN_TYPE); tokenTypeFeature = ts.getFeatureByFullName(TOKEN_TYPE_FEAT_Q); startFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); endFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_END); sentenceType = ts.getType(SENT_TYPE); strSub1 = ts.getType(STRING_SUBTYPE_1); assertTrue(strSub1 != null); theTypeType = ts.getType(OSTR_TYPE); theStringFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OSTR_TYPE_FEAT); theByteFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OBYTE_TYPE_FEAT); theByteArrayFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OBYTEA_TYPE_FEAT); theShortFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OSHORT_TYPE_FEAT); theShortArrayFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OSHORTA_TYPE_FEAT); theLongFeature = ts.getFeatureByFullName(OSTR_TYPE + TypeSystem.FEATURE_SEPARATOR + OLONG_TYPE_FEAT); File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) .getFsIndexes(); } public void tearDown() { casMgr = null; cas = null; wordType = null; // assert(wordType != null); separatorType = null; eosType = null; tokenType = null; tokenTypeFeature = null; startFeature = null; endFeature = null; sentenceType = null; strSub1 = null; indexes = null; typeSystem = null; } // Initialize the first CAS. private static CASMgr initCAS() throws CASException { // Create an initial CASMgr from the factory. // CASMgr cas = CASFactory.createCAS(); // assert(tsa != null); // Create a CASMgr. Ensures existence of AnnotationFS type. // CASMgr tcas = CASFactory.createCAS(); CASMgr aCas = CASFactory.createCAS(); try { CasCreationUtils.setupTypeSystem(aCas, (TypeSystemDescription) null); } catch (ResourceInitializationException e) { e.printStackTrace(); } // Create a writable type system. TypeSystemMgr tsa = aCas.getTypeSystemMgr(); // Add new types and features. Type topType = tsa.getTopType(); Type annotType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); // assert(annotType != null); tsa.addType(SENT_TYPE, annotType); Type tokenType = tsa.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsa.addType(TOKEN_TYPE_TYPE, topType); tsa.addType(WORD_TYPE, tokenTypeType); tsa.addType(SEP_TYPE, tokenTypeType); tsa.addType(EOS_TYPE, tokenTypeType); tsa.addFeature(TOKEN_TYPE_FEAT, tokenType, tokenTypeType); tsa.addStringSubtype(STRING_SUBTYPE_1, STR_1_VALS); Type stringType = tsa.getType(CAS.TYPE_NAME_STRING); Type byteType = tsa.getType(CAS.TYPE_NAME_BYTE); Type byteArrayType = tsa.getType(CAS.TYPE_NAME_BYTE_ARRAY); Type shortType = tsa.getType(CAS.TYPE_NAME_SHORT); Type shortArrayType = tsa.getType(CAS.TYPE_NAME_SHORT_ARRAY); Type longType = tsa.getType(CAS.TYPE_NAME_LONG); Type theTypeType = tsa.addType(OSTR_TYPE, annotType); tsa.addFeature(OSTR_TYPE_FEAT, theTypeType, stringType); tsa.addFeature(OBYTE_TYPE_FEAT, theTypeType, byteType); tsa.addFeature(OSHORT_TYPE_FEAT, theTypeType, shortType); tsa.addFeature(OBYTEA_TYPE_FEAT, theTypeType, byteArrayType); tsa.addFeature(OSHORTA_TYPE_FEAT, theTypeType, shortArrayType); tsa.addFeature(OLONG_TYPE_FEAT, theTypeType, longType); // Commit the type system. ((CASImpl) aCas).commitTypeSystem(); // assert(tsa.isCommitted()); // // Create the CAS indexes. // tcas.initCASIndexes(); // Create the Base indexes. try { aCas.initCASIndexes(); } catch (CASException e) { e.printStackTrace(); } // Commit the index repository. aCas.getIndexRepositoryMgr().commit(); // assert(cas.getIndexRepositoryMgr().isCommitted()); // Create the default text Sofa and return CAS view return (CASMgr) aCas.getCAS().getCurrentView(); } public void testReset() { cas.reset(); casMgr.enableReset(false); boolean exc = false; try { cas.reset(); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.FLUSH_DISABLED); exc = true; } assertTrue(exc); casMgr.enableReset(true); cas.reset(); } // Tokenize text. private void tokenize() throws Exception { // System.out.println("Tokenizing text."); // Create FSs for the token types. FeatureStructure wordFS = cas.createFS(wordType); FeatureStructure sepFS = cas.createFS(separatorType); FeatureStructure eosFS = cas.createFS(eosType); String text = cas.getDocumentText(); TextStringTokenizer tokenizer = new TextStringTokenizer(text); tokenizer.setSeparators("/-*&@"); tokenizer.addWhitespaceChars(","); tokenizer.setEndOfSentenceChars(".!?"); tokenizer.setShowWhitespace(false); int tokenTypeCode; int wordCounter = 0; int sepCounter = 0; int endOfSentenceCounter = 0; AnnotationFS tokenAnnot; while (tokenizer.isValid()) { tokenAnnot = cas.createAnnotation(tokenType, tokenizer.getTokenStart(), tokenizer .getTokenEnd()); tokenTypeCode = tokenizer.getTokenType(); switch (tokenTypeCode) { case TextStringTokenizer.EOS: { ++endOfSentenceCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, eosFS); break; } case TextStringTokenizer.SEP: { ++sepCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, sepFS); break; } case TextStringTokenizer.WSP: { break; } case TextStringTokenizer.WCH: { ++wordCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, wordFS); // if ((wordCounter % 100000) == 0) { // System.out.println("Number of words tokenized: " + wordCounter); // } break; } default: { throw new Exception("Something went wrong, fire up that debugger!"); } } cas.getIndexRepository().addFS(tokenAnnot); tokenizer.setToNext(); // System.out.println("Token: " + tokenizer.nextToken()); } // time = System.currentTimeMillis() - time; // System.out.println("Number of words: " + wordCounter); // int allTokens = wordCounter + sepCounter + endOfSentenceCounter; // System.out.println("Number of tokens: " + allTokens); // System.out.println("Time used: " + new TimeSpan(time)); // FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); // int count = 0; // while (it.isValid()) { // ++count; // it.moveToNext(); // } // System.out.println("Number of tokens in index: " + count); } // Very (!) primitive EOS detection. private void createSentences() throws CASException { // TypeSystem ts = cas.getTypeSystem(); // Type eosType = ts.getType(EOS_TYPE); // Type tokenType = ts.getType(TOKEN_TYPE); // //assert(tokenType != null); // Type sentenceType = ts.getType(SENT_TYPE); // Feature tokenTypeFeature = ts.getFeature(TOKEN_TYPE_FEAT); // Feature startFeature = ts.getFeature(CAS.START_FEAT); // Feature endFeature = ts.getFeature(CAS.END_FEAT); // System.out.println("\nCreating sentence annotations."); // Get a handle to the index repository. FSIndexRepository indexRepository = cas.getIndexRepository(); // assert(indexRepository != null); Iterator labelIt = indexRepository.getLabels(); assertTrue(labelIt != null); // Get the standard index for tokens. FSIndex tokenIndex = cas.getAnnotationIndex(tokenType); // assert(tokenIndex != null); // Get an iterator over tokens. FSIterator it = tokenIndex.iterator(); // assert(it != null); // Now create sentences. We do this as follows: a sentence starts where // the first token after an EOS starts, and ends with an EOS. long time = System.currentTimeMillis(); int endOfSentenceCounter = 0; it.moveToFirst(); boolean lookForStart = true; int start = 0, end; // Initialize start to pacify compiler. FeatureStructure tokenFS, sentFS; while (it.isValid()) { if (lookForStart) { // If we're looking for the start of a sentence, just grab the start // of the current FS. start = it.get().getIntValue(startFeature); lookForStart = false; } else { // Check if we've reached the end of a sentence. tokenFS = it.get(); if (tokenFS.getFeatureValue(tokenTypeFeature).getType() == eosType) { end = tokenFS.getIntValue(endFeature); sentFS = cas.createFS(sentenceType); sentFS.setIntValue(startFeature, start); sentFS.setIntValue(endFeature, end); cas.getIndexRepository().addFS(sentFS); ++endOfSentenceCounter; lookForStart = true; } } it.moveToNext(); } time = System.currentTimeMillis() - time; // System.out.println("Created " + endOfSentenceCounter + " sentences: " + new TimeSpan(time)); } private static final Pattern nlPattern = Pattern.compile("(?m)(.*?$)"); /** * Test driver. */ public void testMain() throws Exception { // System.out.println("Setting up CAS."); // Create the initial CAS. long time = System.currentTimeMillis(); time = System.currentTimeMillis() - time; // System.out.println("CAS set up: " + new TimeSpan(time)); time = System.currentTimeMillis(); // Read the document into a String. I'm sure there are better ways to File textFile = JUnitExtension.getFile("data/moby.txt"); String moby = FileUtils.file2String(textFile); // String moby = file2String(System.getProperty("cas.data.test") + "moby.txt"); String line; // BufferedReader br = new BufferedReader(new StringReader(moby)); StringBuffer buf = new StringBuffer(10000); List docs = new ArrayList(); Matcher m = nlPattern.matcher(moby); while (m.find()) { line = m.group(); if (line.startsWith(".. 0); // System.out.println(" Number of tokens: " + numTok); // System.out.println("Serializing..."); cs = Serialization.serializeCAS(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); createSentences(); numSent = cas.getAnnotationIndex(sentenceType).size(); assertTrue(numSent > 0); // System.out.println(" Number of sentences: " + numSent); // System.out.println("Serializing..."); cs = Serialization.serializeCAS(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println("Serializing..."); cs = Serialization.serializeCAS(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println(" Verify: " + numTok + " tokens, " + numSent + " sentences."); casMgr.reset(); ++docCount; } // System.out.println("Number of documents processed: " + docCount); } overallTime = System.currentTimeMillis() - overallTime; // System.out.println("Time taken over all: " + new TimeSpan(overallTime)); } /** * Test setCAS(). */ public void testSetCAS() throws Exception { // Read the document into a String. File textFile = JUnitExtension.getFile("data/moby.txt"); String moby = FileUtils.file2String(textFile); // String moby = file2String(System.getProperty("cas.data.test") + "moby.txt"); String line; // BufferedReader br = new BufferedReader(new StringReader(moby)); StringBuffer buf = new StringBuffer(10000); List docs = new ArrayList(); Matcher m = nlPattern.matcher(moby); while (m.find()) { line = m.group(); if (line.startsWith(".. 0); // System.out.println(" Number of tokens: " + numTok); // System.out.println("Serializing..."); // CASMgr casMgr = CASFactory.createCAS(); // casMgr.setCAS(cas); // cas = (CAS) casMgr.getCAS(); /* setCAS is no longer used or implemented * You cannot use this method to set up a new cas with a copy of * the contents of another cas, including its indexes CASMgr realCasMgr = CASFactory.createCAS(cas.getTypeSystem()); realCasMgr.setCAS(((CASImpl) cas).getBaseCAS()); cas = ((CASImpl) realCasMgr).getCurrentView(); casMgr = (CASMgr) cas; */ assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); createSentences(); numSent = cas.getAnnotationIndex(sentenceType).size(); assertTrue(numSent > 0); // System.out.println(" Number of sentences: " + numSent); // System.out.println("Serializing..."); // casMgr = CASFactory.createCAS(); // casMgr.setCAS(cas); // cas = (CAS) casMgr.getCAS(); /* setCAS is no longer used or implemented * You cannot use this method to set up a new cas with a copy of * the contents of another cas, including its indexes realCasMgr = CASFactory.createCAS(); realCasMgr.setCAS(((CASImpl) cas).getBaseCAS()); cas = ((CASImpl) realCasMgr).getCurrentView(); casMgr = (CASMgr) cas; */ assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println("Serializing..."); // casMgr = CASFactory.createCAS(); // casMgr.setCAS(cas); // cas = (CAS) casMgr.getCAS(); /* setCAS is no longer used or implemented * You cannot use this method to set up a new cas with a copy of * the contents of another cas, including its indexes realCasMgr = CASFactory.createCAS(); realCasMgr.setCAS(((CASImpl) cas).getBaseCAS()); cas = ((CASImpl) realCasMgr).getCurrentView(); casMgr = (CASMgr) cas; */ assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println(" Verify: " + numTok + " tokens, " + numSent + " sentences."); casMgr.reset(); ++docCount; } // System.out.println("Number of documents processed: " + docCount); } overallTime = System.currentTimeMillis() - overallTime; // System.out.println("Time taken over all: " + new TimeSpan(overallTime)); } /** Test basic blob serialization */ public void testBlob() throws Exception { /* * Test that FS, indexes and strings work after repeated blob serialization * For each iteration, add two new FS, serialize and test all created so * The first FS sets the string feature using standard API => goes into stringlist * The second FS sets the string feature using lowlevel API => goes into stringheap * * Throw in tests of the byte, short and long heaps as well * */ String testString = "testString"; cas.reset(); LowLevelCAS ll_cas = cas.getLowLevelCAS(); FSIndexRepository ir = cas.getIndexRepository(); int ll_strfeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theStringFeature); int ll_bytefeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theByteFeature); int ll_shortfeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theShortFeature); int ll_bytearrayfeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theByteArrayFeature); int ll_shortarrayfeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theShortArrayFeature); int ll_longfeatcode = ll_cas.ll_getTypeSystem().ll_getCodeForFeature(theLongFeature); for (int cycle=0; cycle<10; cycle+=2) { FeatureStructure newFS1 = cas.createFS(theTypeType); ir.addFS(newFS1); newFS1.setIntValue(startFeature, cycle); newFS1.setIntValue(endFeature, cycle+1); // set string using normal string feature create newFS1.setStringValue(theStringFeature, testString); newFS1.setByteValue(theByteFeature, (byte)cycle); newFS1.setShortValue(theShortFeature, (short)cycle); newFS1.setLongValue(theLongFeature, (long)cycle); ByteArrayFS newBA1 = cas.createByteArrayFS(1); ShortArrayFS newSA1 = cas.createShortArrayFS(1); newBA1.set(0, (byte)cycle); newSA1.set(0, (short)cycle); newFS1.setFeatureValue(theByteArrayFeature, newBA1); newFS1.setFeatureValue(theShortArrayFeature, newSA1); FeatureStructure newFS2 = cas.createFS(theTypeType); ByteArrayFS newBA2 = cas.createByteArrayFS(1); ShortArrayFS newSA2 = cas.createShortArrayFS(1); newFS2.setIntValue(startFeature, cycle+1); newFS2.setIntValue(endFeature, cycle+2); ir.addFS(newFS2); // set string using lowlevel string create API final int llfs2 = ll_cas.ll_getFSRef(newFS2); final int llba2 = ll_cas.ll_getFSRef(newBA2); final int llsa2 = ll_cas.ll_getFSRef(newSA2); ll_cas.ll_setCharBufferValue(llfs2, ll_strfeatcode, testString.toCharArray(), 0, testString.length()); ll_cas.ll_setByteValue(llfs2, ll_bytefeatcode, (byte)(cycle+1)); ll_cas.ll_setShortValue(llfs2, ll_shortfeatcode, (short)(cycle+1)); ll_cas.ll_setLongValue(llfs2, ll_longfeatcode, (long)(cycle+1)); ll_cas.ll_setByteArrayValue(llba2, 0, (byte)(cycle+1)); ll_cas.ll_setShortArrayValue(llsa2, 0, (short)(cycle+1)); newFS2.setFeatureValue(theByteArrayFeature, newBA2); newFS2.setFeatureValue(theShortArrayFeature, newSA2); ByteArrayOutputStream fos = new ByteArrayOutputStream(); Serialization.serializeCAS(cas, fos); cas.reset(); ByteArrayInputStream fis = new ByteArrayInputStream(fos.toByteArray()); Serialization.deserializeCAS(cas, fis); FSIndex idx = cas.getAnnotationIndex(theTypeType); FSIterator iter = idx.iterator(); for (int tc=0; tc tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 5); //doc annot plus 4 annots FeatureStructure entityFS = cas1.createFS(entityType); cas1.getIndexRepository().addFS(entityFS); StringArrayFS strArrayFS = cas1.createStringArrayFS(5); strArrayFS.set(0, "class1"); entityFS.setFeatureValue(classesFeat, strArrayFS); //create listFS and set the link feature FeatureStructure emptyNode = cas1.createFS(emptyFsListType); FeatureStructure secondNode = cas1.createFS(nonEmptyFsListType); secondNode.setFeatureValue(headFeat, anAnnot2); secondNode.setFeatureValue(tailFeat, emptyNode); FeatureStructure firstNode = cas1.createFS(nonEmptyFsListType); firstNode.setFeatureValue(headFeat, anAnnot1); firstNode.setFeatureValue(tailFeat, secondNode); entityFS.setFeatureValue(linksFeat, firstNode); // create a view w/o setting document text CAS view1 = cas1.createView("View1"); // create another view CAS preexistingView = cas1.createView("preexistingView"); String preexistingViewText = "John Smith blah blah blah"; preexistingView.setDocumentText(preexistingViewText); AnnotationFS person1Annot = createPersonAnnot(preexistingView, 0, 10); person1Annot.setStringValue(componentIdFeat, "deltacas1"); AnnotationFS person2Annot = createPersonAnnot(preexistingView, 0, 5); AnnotationFS orgAnnot = preexistingView.createAnnotation(orgType, 16, 24); preexistingView.addFsToIndexes(orgAnnot); AnnotationFS ownerAnnot = preexistingView.createAnnotation(ownerType, 0, 24); preexistingView.addFsToIndexes(ownerAnnot); FeatureStructure relArgs = cas1.createFS(relArgsType); relArgs.setFeatureValue(domainFeat, person1Annot); ownerAnnot.setFeatureValue(argsFeat, relArgs); //serialize complete ByteArrayOutputStream fos = new ByteArrayOutputStream(); Serialization.serializeCAS(cas1, fos); //deserialize into cas2 ByteArrayInputStream fis = new ByteArrayInputStream(fos.toByteArray()); Serialization.deserializeCAS(cas2, fis); CasComparer.assertEquals(cas1, cas2); //======================================================================= //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); CAS cas2preexistingView = cas2.getView("preexistingView"); FSIndex cas2personIndex = cas2preexistingView.getAnnotationIndex(personType); FSIndex cas2orgIndex = cas2preexistingView.getAnnotationIndex(orgType); FSIndex cas2ownerIndex = cas2preexistingView.getAnnotationIndex(ownerType); // create an annotation and add to index AnnotationFS cas2anAnnot5 = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2anAnnot5); assertTrue(cas2tIndex.size() == 6); // prev annots and this new one // set document text of View1 CAS cas2view1 = cas2.getView("View1"); cas2view1.setDocumentText("This is the View1 document."); //create an annotation in View1 AnnotationFS cas2view1Annot = cas2view1.createAnnotation(cas2.getAnnotationType(), 1, 5); cas2view1.getIndexRepository().addFS(cas2view1Annot); FSIndex cas2view1Index = cas2view1.getAnnotationIndex(); assertTrue(cas2view1Index.size() == 2); //document annot and this annot //modify an existing annotation Iterator tIndexIter = cas2tIndex.iterator(); AnnotationFS docAnnot = tIndexIter.next(); //doc annot AnnotationFS modAnnot1 = tIndexIter.next(); AnnotationFS delAnnot = tIndexIter.next(); //modify language feature Feature languageF = cas2.getDocumentAnnotation().getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_LANGUAGE); docAnnot.setStringValue(languageF, "en"); //index update - reindex cas2.getIndexRepository().removeFS(modAnnot1); Feature endF = cas2.getAnnotationType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END); modAnnot1.setIntValue(endF, 4); cas2.getIndexRepository().addFS(modAnnot1); //index update - remove annotation from index cas2.getIndexRepository().removeFS(delAnnot); //modify FS - string feature and FS feature. Iterator personIter = cas2personIndex.iterator(); AnnotationFS cas2person1 = (AnnotationFS) personIter.next(); AnnotationFS cas2person2 = (AnnotationFS) personIter.next(); cas2person1.setFloatValue(confidenceFeat, (float) 99.99); cas2person1.setStringValue(mentionTypeFeat, "FULLNAME"); cas2person2.setStringValue(componentIdFeat, "delataCas2"); cas2person2.setStringValue(mentionTypeFeat, "FIRSTNAME"); Iterator orgIter = cas2orgIndex.iterator(); AnnotationFS cas2orgAnnot = (AnnotationFS) orgIter.next(); cas2orgAnnot.setStringValue(mentionTypeFeat, "ORGNAME"); //modify FS feature Iterator ownerIter = cas2ownerIndex.iterator(); AnnotationFS cas2ownerAnnot = (AnnotationFS) ownerIter.next(); FeatureStructure cas2relArgs = cas2ownerAnnot.getFeatureValue(argsFeat); cas2relArgs.setFeatureValue(rangeFeat, cas2orgAnnot); //Test modification of a nonshared multivalued feature. //This should serialize the encompassing FS. Iterator iter = cas2.getIndexRepository().getIndex("testEntityIndex").iterator(); FeatureStructure cas2EntityFS = iter.next(); StringArrayFS cas2strarrayFS = (StringArrayFS) cas2EntityFS.getFeatureValue(classesFeat); cas2strarrayFS.set(1, "class2"); cas2strarrayFS.set(2, "class3"); cas2strarrayFS.set(3, "class4"); cas2strarrayFS.set(4, "class5"); //add to FSList FeatureStructure cas2linksFS = cas2EntityFS.getFeatureValue(linksFeat); FeatureStructure cas2secondNode = cas2linksFS.getFeatureValue(tailFeat); FeatureStructure cas2emptyNode = cas2secondNode.getFeatureValue(tailFeat); FeatureStructure cas2thirdNode = cas2.createFS(nonEmptyFsListType); cas2thirdNode.setFeatureValue(headFeat, cas2anAnnot5); cas2thirdNode.setFeatureValue(tailFeat, cas2emptyNode); cas2secondNode.setFeatureValue(tailFeat, cas2thirdNode); // serialize cas2 in delta format ByteArrayOutputStream fosDelta = new ByteArrayOutputStream(); Serialization.serializeCAS(cas2, fosDelta, marker); //====================================================================== //deserialize delta xmi into cas1 ByteArrayInputStream fisDelta = new ByteArrayInputStream(fosDelta.toByteArray()); Serialization.deserializeCAS(cas1, fisDelta); //====================================================================== //serialize complete cas and deserialize into cas3 and compare with cas1. ByteArrayOutputStream fosFull = new ByteArrayOutputStream(); Serialization.serializeCAS(cas2, fosFull); ByteArrayInputStream fisFull = new ByteArrayInputStream(fosFull.toByteArray()); Serialization.deserializeCAS(cas3, fisFull); CasComparer.assertEquals(cas1, cas3); //System.out.println("CAS1 " + serialize(cas1, new XmiSerializationSharedData())); //System.out.println("CAS2 " + serialize(cas2, new XmiSerializationSharedData())); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaBlobWithInvalidMarker() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); boolean serfailed = false; Marker mark1 = cas1.createMarker(); // Marker mark2 = cas1.createMarker(); // multiple markers not supported, tested in other test case cas1.reset(); try { ByteArrayOutputStream fos = new ByteArrayOutputStream(); Serialization.serializeCAS(cas1, fos, mark1); } catch (CASRuntimeException e) { serfailed = true; } assertTrue(serfailed); // serfailed = false; // try { // ByteArrayOutputStream fos = new ByteArrayOutputStream(); // Serialization.serializeCAS(cas1, fos, mark2); // } catch (CASRuntimeException e) { // serfailed = true; // } // assertTrue(serfailed); } catch (Exception e) { JUnitExtension.handleException(e); } } private AnnotationFS createPersonAnnot(CAS cas, int begin, int end) { Type personType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Person"); AnnotationFS person = cas.createAnnotation(personType, begin, end); cas.addFsToIndexes(person); return person; } public static void main(String[] args) { junit.textui.TestRunner.run(SerializationReinitTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/NewPrimitiveTypesTest.java0000644000175000017500000005543211665471060031121 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.StringReader; import java.io.StringWriter; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import org.apache.uima.cas.BooleanArrayFS; import org.apache.uima.cas.ByteArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.DoubleArrayFS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FloatArrayFS; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.LongArrayFS; import org.apache.uima.cas.ShortArrayFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.CASSerializer; import org.apache.uima.cas.impl.FeatureStructureImplC; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.impl.XCASSerializer; import org.apache.uima.cas.impl.XmiCasDeserializer; import org.apache.uima.cas.impl.XmiCasSerializer; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLSerializer; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; public class NewPrimitiveTypesTest extends TestCase { private CASMgr casMgr; private CAS cas; private Type annotationType; private Type exampleType; private Feature floatFeature; private Feature stringFeature; private Feature byteFeature; private Feature booleanFeature; private Feature shortFeature; private Feature longFeature; private Feature doubleFeature; private Feature intArrayFeature; private Feature floatArrayFeature; private Feature stringArrayFeature; private Feature byteArrayFeature; private Feature booleanArrayFeature; private Feature shortArrayFeature; private Feature longArrayFeature; private Feature doubleArrayFeature; public NewPrimitiveTypesTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); casMgr = CASFactory.createCAS(); CasCreationUtils.setupTypeSystem(casMgr, (TypeSystemDescription) null); // Create a writable type system. TypeSystemMgr tsa = casMgr.getTypeSystemMgr(); // Add new types and features. annotationType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(annotationType != null); // new primitive types exampleType = tsa.addType("test.primitives.Example", annotationType); floatFeature = tsa.addFeature("floatFeature", exampleType, tsa.getType(CAS.TYPE_NAME_FLOAT)); stringFeature = tsa.addFeature("stringFeature", exampleType, tsa .getType(CAS.TYPE_NAME_STRING)); booleanFeature = tsa.addFeature("boolFeature", exampleType, tsa .getType(CAS.TYPE_NAME_BOOLEAN)); byteFeature = tsa.addFeature("byteFeature", exampleType, tsa.getType(CAS.TYPE_NAME_BYTE)); shortFeature = tsa.addFeature("shortFeature", exampleType, tsa.getType(CAS.TYPE_NAME_SHORT)); longFeature = tsa.addFeature("longFeature", exampleType, tsa.getType(CAS.TYPE_NAME_LONG)); doubleFeature = tsa.addFeature("doubleFeature", exampleType, tsa .getType(CAS.TYPE_NAME_DOUBLE)); intArrayFeature = tsa.addFeature("intArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_INTEGER_ARRAY)); floatArrayFeature = tsa.addFeature("floatArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_FLOAT_ARRAY), false); stringArrayFeature = tsa.addFeature("stringArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_STRING_ARRAY), false); booleanArrayFeature = tsa.addFeature("boolArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_BOOLEAN_ARRAY)); byteArrayFeature = tsa.addFeature("byteArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_BYTE_ARRAY), false); shortArrayFeature = tsa.addFeature("shortArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_SHORT_ARRAY)); longArrayFeature = tsa.addFeature("longArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_LONG_ARRAY)); doubleArrayFeature = tsa.addFeature("doubleArrayFeature", exampleType, tsa .getType(CAS.TYPE_NAME_DOUBLE_ARRAY), false); // Commit the type system. ((CASImpl) casMgr).commitTypeSystem(); // Create the Base indexes. casMgr.initCASIndexes(); // create custom indexes to test new primitive keys FSIndexRepositoryMgr irm = casMgr.getIndexRepositoryMgr(); FSIndexComparator comp = irm.createComparator(); comp.setType(tsa.getType("test.primitives.Example")); comp.addKey(tsa.getFeatureByFullName("test.primitives.Example:doubleFeature"), FSIndexComparator.STANDARD_COMPARE); irm.createIndex(comp, "doubleIndex"); comp = irm.createComparator(); comp.setType(tsa.getType("test.primitives.Example")); comp.addKey(tsa.getFeatureByFullName("test.primitives.Example:longFeature"), FSIndexComparator.REVERSE_STANDARD_COMPARE); irm.createIndex(comp, "longIndex"); comp = irm.createComparator(); comp.setType(tsa.getType("test.primitives.Example")); comp.addKey(tsa.getFeatureByFullName("test.primitives.Example:shortFeature"), FSIndexComparator.STANDARD_COMPARE); irm.createIndex(comp, "shortIndex"); irm.commit(); cas = casMgr.getCAS().getView(CAS.NAME_DEFAULT_SOFA); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateFS() throws Exception { // create FS createExampleFS(cas); // check values validateFSData(cas); } public void testBlobSerialization() throws Exception { // create FS createExampleFS(cas); // serialize ByteArrayOutputStream fos = new ByteArrayOutputStream(); Serialization.serializeCAS(cas, fos); // reset cas.reset(); // deserialize ByteArrayInputStream fis = new ByteArrayInputStream(fos.toByteArray()); Serialization.deserializeCAS(cas, fis); // check values validateFSData(cas); } public void testJavaSerialization() throws Exception { // create FS createExampleFS(cas); // serialize CASSerializer cs = Serialization.serializeNoMetaData(cas); // reset cas.reset(); // deserialize cas = Serialization.createCAS(casMgr, cs); // check values validateFSData(cas); } public void testXCASSerialization() throws Exception { // create FS createExampleFS(cas); // serialize XCASSerializer ser = new XCASSerializer(cas.getTypeSystem()); OutputStream outputXCAS = new FileOutputStream(JUnitExtension .getFile("ExampleCas/newprimitives.xcas")); XMLSerializer xmlSer = new XMLSerializer(outputXCAS); ser.serialize(cas, xmlSer.getContentHandler()); // reset cas.reset(); // deserialize InputStream inputXCAS = new FileInputStream(JUnitExtension .getFile("ExampleCas/newprimitives.xcas")); XCASDeserializer.deserialize(inputXCAS, cas, false); // check values validateFSData(cas); } public void testXmiSerialization() throws Exception { // create FS createExampleFS(cas); // serialize StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem()); xmiSer.serialize(cas, xmlSer.getContentHandler()); String xml = sw.getBuffer().toString(); // System.out.println(xml); // reset cas.reset(); // deserialize XmiCasDeserializer deser = new XmiCasDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXmiCasHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(new StringReader(xml))); // check values validateFSData(cas); } public void testFSPrettyPrint() throws Exception { // create FS createExampleFS(cas); // prettyPrint CAS englishView = cas.getView("EnglishDocument"); assertNotNull(englishView); assertNotNull(englishView.getSofa()); FSIndex index = englishView.getAnnotationIndex(); FSIterator iter = index.iterator(); // skip document annotation AnnotationFS fs = (AnnotationFS) iter.get(); iter.moveToNext(); // the exampleType fs fs = (AnnotationFS) iter.get(); FeatureStructureImplC fsImpl = (FeatureStructureImplC) fs; StringBuffer sb = new StringBuffer(1024); fsImpl.prettyPrint(2, 1, sb, true); // System.out.println(sb.toString()); } public void testClone() throws Exception { createExampleFS(cas); // get the example FS CAS englishView = cas.getView("EnglishDocument"); FSIterator iter = englishView.getAnnotationIndex().iterator(); // skip document annotation iter.moveToNext(); // the exampleType fs AnnotationFS fs = (AnnotationFS) iter.get(); // clone it AnnotationFS clone = (AnnotationFS) fs.clone(); // subsitute the clone for the original in the index, // and validate that it was correctly copied englishView.removeFsFromIndexes(fs); englishView.addFsToIndexes(clone); validateFSData(cas); // editing the original FS should not change the clone fs.setStringValue(stringFeature, "foo"); fs.setFloatValue(floatFeature, -1f); fs.setByteValue(byteFeature, (byte) -1); fs.setBooleanValue(booleanFeature, false); fs.setShortValue(shortFeature, (short) -1); fs.setLongValue(longFeature, -1); fs.setDoubleValue(doubleFeature, -1); validateFSData(cas); } private void validateFSData(CAS parmCas) throws Exception { CAS englishView = parmCas.getView("EnglishDocument"); assertNotNull(englishView); assertNotNull(englishView.getSofa()); FSIndex index = englishView.getAnnotationIndex(); FSIterator iter = index.iterator(); // skip document annotation AnnotationFS fs = (AnnotationFS) iter.get(); iter.moveToNext(); // the exampleType fs fs = (AnnotationFS) iter.get(); // System.out.print(fs.toString()); // check the scalar values assertTrue(1 == fs.getBegin()); assertTrue(5 == fs.getEnd()); assertTrue(fs.getStringValue(stringFeature).equals("aaaaaaa")); assertTrue(fs.getFloatValue(floatFeature) == (float) 99.99); assertTrue(fs.getByteValue(byteFeature) == (byte) 'z'); assertTrue(fs.getBooleanValue(booleanFeature) == true); assertTrue(fs.getShortValue(shortFeature) == Short.MIN_VALUE); assertTrue(fs.getLongValue(longFeature) == Long.MIN_VALUE); assertTrue(fs.getDoubleValue(doubleFeature) == Double.MAX_VALUE); // check the array values StringArrayFS strArrayFS = (StringArrayFS) fs.getFeatureValue(stringArrayFeature); assertTrue(strArrayFS.get(0).equals("zzzzzz")); assertTrue(strArrayFS.get(1).equals("yyyyyy")); assertTrue(strArrayFS.get(2).equals("xxxxxx")); assertTrue(strArrayFS.get(3).equals("wwwwww")); assertTrue(strArrayFS.get(4).equals("vvvvvv")); IntArrayFS intArrayFS = (IntArrayFS) fs.getFeatureValue(intArrayFeature); assertTrue(intArrayFS.get(0) == Integer.MAX_VALUE); assertTrue(intArrayFS.get(1) == Integer.MAX_VALUE - 1); assertTrue(intArrayFS.get(2) == 42); assertTrue(intArrayFS.get(3) == Integer.MIN_VALUE + 1); assertTrue(intArrayFS.get(4) == Integer.MIN_VALUE); FloatArrayFS floatArrayFS = (FloatArrayFS) fs.getFeatureValue(floatArrayFeature); assertTrue(floatArrayFS.get(0) == Float.MAX_VALUE); assertTrue(floatArrayFS.get(1) == (float) (Float.MAX_VALUE / 1000.0)); assertTrue(floatArrayFS.get(2) == 42); assertTrue(floatArrayFS.get(3) == (float) (Float.MIN_VALUE * 1000.0)); assertTrue(floatArrayFS.get(4) == Float.MIN_VALUE); ByteArrayFS byteArrayFS = (ByteArrayFS) fs.getFeatureValue(byteArrayFeature); assertTrue(byteArrayFS.get(0) == (byte) 8); assertTrue(byteArrayFS.get(1) == (byte) 16); assertTrue(byteArrayFS.get(2) == (byte) 64); assertTrue(byteArrayFS.get(3) == (byte) 128); assertTrue(byteArrayFS.get(4) == (byte) 255); BooleanArrayFS boolArrayFS = (BooleanArrayFS) fs.getFeatureValue(booleanArrayFeature); assertTrue(boolArrayFS.get(0)); assertTrue(!boolArrayFS.get(1)); assertTrue(boolArrayFS.get(2)); assertTrue(!boolArrayFS.get(3)); assertTrue(boolArrayFS.get(4)); ShortArrayFS shortArrayFS = (ShortArrayFS) fs.getFeatureValue(shortArrayFeature); assertTrue(shortArrayFS.get(0) == Short.MAX_VALUE); assertTrue(shortArrayFS.get(1) == Short.MAX_VALUE - 1); assertTrue(shortArrayFS.get(2) == Short.MAX_VALUE - 2); assertTrue(shortArrayFS.get(3) == Short.MAX_VALUE - 3); assertTrue(shortArrayFS.get(4) == Short.MAX_VALUE - 4); LongArrayFS longArrayFS = (LongArrayFS) fs.getFeatureValue(longArrayFeature); assertTrue(longArrayFS.get(0) == Long.MAX_VALUE); assertTrue(longArrayFS.get(1) == Long.MAX_VALUE - 1); assertTrue(longArrayFS.get(2) == Long.MAX_VALUE - 2); assertTrue(longArrayFS.get(3) == Long.MAX_VALUE - 3); assertTrue(longArrayFS.get(4) == Long.MAX_VALUE - 4); DoubleArrayFS doubleArrayFS = (DoubleArrayFS) fs.getFeatureValue(doubleArrayFeature); assertTrue(doubleArrayFS.get(0) == Double.MAX_VALUE); assertTrue(doubleArrayFS.get(1) == Double.MIN_VALUE); assertTrue(doubleArrayFS.get(2) == Double.parseDouble("1.5555")); assertTrue(doubleArrayFS.get(3) == Double.parseDouble("99.000000005")); assertTrue(doubleArrayFS.get(4) == Double.parseDouble("4.44444444444444444")); } private void createExampleFS(CAS parmCas) throws Exception { // Create a view CAS englishView = parmCas.createView("EnglishDocument"); // Set the document text englishView.setDocumentText("this beer is good"); // create an FS of exampleType and index it AnnotationFS fs = englishView.createAnnotation(exampleType, 1, 5); englishView.getIndexRepository().addFS(fs); // create Array FSs StringArrayFS strArrayFS = parmCas.createStringArrayFS(5); strArrayFS.set(0, "zzzzzz"); strArrayFS.set(1, "yyyyyy"); strArrayFS.set(2, "xxxxxx"); strArrayFS.set(3, "wwwwww"); strArrayFS.set(4, "vvvvvv"); IntArrayFS intArrayFS = parmCas.createIntArrayFS(5); intArrayFS.set(0, Integer.MAX_VALUE); intArrayFS.set(1, Integer.MAX_VALUE - 1); intArrayFS.set(2, 42); intArrayFS.set(3, Integer.MIN_VALUE + 1); intArrayFS.set(4, Integer.MIN_VALUE); FloatArrayFS floatArrayFS = parmCas.createFloatArrayFS(5); floatArrayFS.set(0, Float.MAX_VALUE); floatArrayFS.set(1, (float) (Float.MAX_VALUE / 1000.0)); floatArrayFS.set(2, 42); floatArrayFS.set(3, (float) (Float.MIN_VALUE * 1000.0)); floatArrayFS.set(4, Float.MIN_VALUE); ByteArrayFS byteArrayFS = parmCas.createByteArrayFS(5); byteArrayFS.set(0, (byte) 8); byteArrayFS.set(1, (byte) 16); byteArrayFS.set(2, (byte) 64); byteArrayFS.set(3, (byte) 128); byteArrayFS.set(4, (byte) 255); BooleanArrayFS boolArrayFS = parmCas.createBooleanArrayFS(20); boolean val = false; for (int i = 0; i < 20; i++) { boolArrayFS.set(i, val = !val); } ShortArrayFS shortArrayFS = parmCas.createShortArrayFS(5); shortArrayFS.set(0, Short.MAX_VALUE); shortArrayFS.set(1, (short) (Short.MAX_VALUE - 1)); shortArrayFS.set(2, (short) (Short.MAX_VALUE - 2)); shortArrayFS.set(3, (short) (Short.MAX_VALUE - 3)); shortArrayFS.set(4, (short) (Short.MAX_VALUE - 4)); LongArrayFS longArrayFS = parmCas.createLongArrayFS(5); longArrayFS.set(0, Long.MAX_VALUE); longArrayFS.set(1, Long.MAX_VALUE - 1); longArrayFS.set(2, Long.MAX_VALUE - 2); longArrayFS.set(3, Long.MAX_VALUE - 3); longArrayFS.set(4, Long.MAX_VALUE - 4); DoubleArrayFS doubleArrayFS = parmCas.createDoubleArrayFS(5); doubleArrayFS.set(0, Double.MAX_VALUE); doubleArrayFS.set(1, Double.MIN_VALUE); doubleArrayFS.set(2, Double.parseDouble("1.5555")); doubleArrayFS.set(3, Double.parseDouble("99.000000005")); doubleArrayFS.set(4, Double.parseDouble("4.44444444444444444")); // set features of fs fs.setStringValue(stringFeature, "aaaaaaa"); fs.setFloatValue(floatFeature, (float) 99.99); fs.setFeatureValue(intArrayFeature, intArrayFS); fs.setFeatureValue(floatArrayFeature, floatArrayFS); fs.setFeatureValue(stringArrayFeature, strArrayFS); // fs.setByteValue(byteFeature, Byte.MAX_VALUE); fs.setByteValue(byteFeature, (byte) 'z'); fs.setFeatureValue(byteArrayFeature, byteArrayFS); fs.setBooleanValue(booleanFeature, true); fs.setFeatureValue(booleanArrayFeature, boolArrayFS); fs.setShortValue(shortFeature, Short.MIN_VALUE); fs.setFeatureValue(shortArrayFeature, shortArrayFS); fs.setLongValue(longFeature, Long.MIN_VALUE); fs.setFeatureValue(longArrayFeature, longArrayFS); fs.setDoubleValue(doubleFeature, Double.MAX_VALUE); fs.setFeatureValue(doubleArrayFeature, doubleArrayFS); } public void testNewPrimitiveTypeKeys() throws Exception { // Create FS with features set in reverse order for (int i=0; i<5; i++) { AnnotationFS fs = cas.createAnnotation(exampleType, 0, 0); fs.setDoubleValue(doubleFeature, 5.0 - i ); fs.setLongValue(longFeature, (long)1+i ); fs.setShortValue(shortFeature, (short)(5 - i) ); cas.getIndexRepository().addFS(fs); } // test double as key FSIterator iter = cas.getIndexRepository().getIndex("doubleIndex", exampleType).iterator(); // System.out.println("\nDouble"); for (int i=0; i<5; i++) { AnnotationFS testfs = (AnnotationFS)iter.get(); // System.out.println("exampleType has double=" + testfs.getDoubleValue(doubleFeature) // + " long=" + testfs.getLongValue(longFeature) // + " short=" + testfs.getShortValue(shortFeature)); assertTrue(1+i == testfs.getDoubleValue(doubleFeature)); assertTrue(5-i == testfs.getLongValue(longFeature)); assertTrue(1+i == testfs.getShortValue(shortFeature)); iter.moveToNext(); } // test long as key iter = cas.getIndexRepository().getIndex("longIndex", exampleType).iterator(); // System.out.println("\nLong"); for (int i=0; i<5; i++) { AnnotationFS testfs = (AnnotationFS)iter.get(); // System.out.println("exampleType has double=" + testfs.getDoubleValue(doubleFeature) // + " long=" + testfs.getLongValue(longFeature) // + " short=" + testfs.getShortValue(shortFeature)); assertTrue(1+i == testfs.getDoubleValue(doubleFeature)); assertTrue(5-i == testfs.getLongValue(longFeature)); assertTrue(1+i == testfs.getShortValue(shortFeature)); iter.moveToNext(); } // test short as key iter = cas.getIndexRepository().getIndex("shortIndex", exampleType).iterator(); // System.out.println("\nShort"); for (int i=0; i<5; i++) { AnnotationFS testfs = (AnnotationFS)iter.get(); // System.out.println("exampleType has double=" + testfs.getDoubleValue(doubleFeature) // + " long=" + testfs.getLongValue(longFeature) // + " short=" + testfs.getShortValue(shortFeature)); assertTrue(1+i == testfs.getDoubleValue(doubleFeature)); assertTrue(5-i == testfs.getLongValue(longFeature)); assertTrue(1+i == testfs.getShortValue(shortFeature)); iter.moveToNext(); } } // public void testUimaTypeSystem2Ecore() throws Exception // { // //register default resource factory // Resource.Factory.Registry.INSTANCE. // getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl()); // //create Ecore Resource // ResourceSet resourceSet = new ResourceSetImpl(); // URI outputURI = URI.createFileURI("test.ecore"); // Resource outputResource = resourceSet.createResource(outputURI); // // //Convert UIMA Type System to Ecore // TypeSystemDescription ts = // TypeSystemUtil.typeSystem2TypeSystemDescription(cas.getTypeSystem()); // UimaTypeSystem2Ecore.uimaTypeSystem2Ecore(ts, outputResource, null); // //outputResource.save(null); //for debugging only // //Convert back // TypeSystemDescription result = Ecore2UimaTypeSystem.ecore2UimaTypeSystem(outputResource, null); // ts.toXML(System.out); // result.toXML(System.out); //for debugging only // //Should be the same // UimaTypeSystem2EcoreTest.assertTypeSystemsEqual(ts, result); // // //we need to do this to reset the the EMF package registry to its default state, // //otherwise subsequent tests won't be starting from scratch // EPackage.Registry.INSTANCE.clear(); // EcorePackage ecore = EcorePackage.eINSTANCE; // EPackage.Registry.INSTANCE.put(ecore.getNsURI(), ecore); // } public static void main(String[] args) { junit.textui.TestRunner.run(NewPrimitiveTypesTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java0000644000175000017500000001147111665471060026053 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.Heap; import org.apache.uima.cas.text.AnnotationIndex; /** * Class comment for CASTest.java goes here. * */ public class CASTest extends TestCase { private CAS cas; private TypeSystem ts; /** * Constructor for CASTest. * * @param arg0 */ public CASTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); this.ts = this.cas.getTypeSystem(); } catch (Exception e) { assertTrue(false); } } public void tearDown() { this.cas = null; this.ts = null; } public void testGetTypeSystem() { assertTrue(this.cas.getTypeSystem() != null); } public void testGetAnnotationIndex() { AnnotationIndex index = this.cas.getAnnotationIndex(); assertNotNull(index); assertTrue(index.iterator() != null); boolean caughtException = false; try { this.cas.getAnnotationIndex(this.cas.getTypeSystem().getType(CAS.TYPE_NAME_TOP)); } catch (CASRuntimeException e) { caughtException = true; } assertTrue(caughtException); } public void testCreateFS() { // Can create FS of type "Top" assertTrue(this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_TOP)) != null); boolean caughtExc = false; // Can't create int FS. try { this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_INTEGER)); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.NON_CREATABLE_TYPE)); } assertTrue(caughtExc); caughtExc = false; // Can't create array with CAS.createFS(). try { this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_FS_ARRAY)); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.NON_CREATABLE_TYPE)); } assertTrue(caughtExc); caughtExc = false; // Check that we can create structures that are larger than the internal // heap page size. final int arraySize = 1000000; // Make sure that the structure we're trying to create is actually larger // than the page size we're testing with. assertTrue(arraySize > Heap.DEFAULT_SIZE); IntArrayFS array = null; try { array = this.cas.createIntArrayFS(arraySize); } catch (CASRuntimeException e) { assertTrue(false); } try { array.set(arraySize - 1, 1); } catch (ArrayIndexOutOfBoundsException e) { assertTrue(false); } // Can't create array subtype with CAS.createFS(). // try { // this.cas.createFS(this.ts.getType(CASTestSetup.INT_ARRAY_SUB)); // } catch (CASRuntimeException e) { // caughtExc = true; // assertTrue(e.getError() == CASRuntimeException.NON_CREATABLE_TYPE); // } // assertTrue(caughtExc); } public void testCreateCAS() { TypeSystemMgr tsm = CASFactory.createTypeSystem(); tsm.commit(); } public void testCreateArrayFS() { // Has its own test class. } public void testCreateIntArrayFS() { // Has its own test class. } public void testCreateStringArrayFS() { // Has its own test class. } // public void testCreateFilteredIterator() { // } // // public void testCommitFS() { // } // // public void testGetConstraintFactory() { // } // // public void testCreateFeaturePath() { // } // // public void testGetIndexRepository() { // } // // public void testFs2listIterator() { // } // public static void main(String[] args) { junit.textui.TestRunner.run(CASTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/StringSubtypeTest.java0000644000175000017500000001225011665471060030263 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.JTextAnnotator_ImplBase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.LowLevelTypeSystem; import org.apache.uima.jcas.JCas; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class StringSubtypeTest extends TestCase { private static final String specifier = "./CASTests/desc/StringSubtypeTest.xml"; private static final String definedValue1 = "aa"; private static final String definedValue2 = "bb"; private static final String definedValue3 = "cc"; private static final String undefinedValue = "dd"; private static final String annotationTypeName = "org.apache.uima.cas.test.StringSubtypeAnnotation"; private static final String stringSetFeatureName = "stringSetFeature"; private JCas jcas; private AnalysisEngine ae; public static class Annotator extends JTextAnnotator_ImplBase { public void process(JCas aJCas, ResultSpecification aResultSpec) { // Does nothing, not used in this test. } } public StringSubtypeTest(String arg0) { super(arg0); } protected void setUp() throws Exception { super.setUp(); File specifierFile = JUnitExtension.getFile(specifier); XMLInputSource in = new XMLInputSource(specifierFile); ResourceSpecifier resourceSpecifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); this.ae = UIMAFramework.produceAnalysisEngine(resourceSpecifier); this.jcas = this.ae.newJCas(); } protected void tearDown() throws Exception { super.tearDown(); this.ae.destroy(); this.jcas = null; } public void testJcas() { StringSubtypeAnnotation annot = new StringSubtypeAnnotation(this.jcas); annot.setStringSetFeature(definedValue1); annot.setStringSetFeature(definedValue2); annot.setStringSetFeature(definedValue3); boolean exCaught = false; try { annot.setStringSetFeature(undefinedValue); } catch (CASRuntimeException e) { exCaught = true; } assertTrue(exCaught); } public void testLowLevelCas() { LowLevelCAS cas = this.jcas.getLowLevelCas(); LowLevelTypeSystem ts = cas.ll_getTypeSystem(); final int annotType = ts.ll_getCodeForTypeName(annotationTypeName); final int addr = cas.ll_createFS(annotType); final int stringSetFeat = ts.ll_getCodeForFeatureName(annotationTypeName + TypeSystem.FEATURE_SEPARATOR + stringSetFeatureName); cas.ll_setStringValue(addr, stringSetFeat, definedValue1); cas.ll_setStringValue(addr, stringSetFeat, definedValue2); cas.ll_setStringValue(addr, stringSetFeat, definedValue3); // next should be ok https://issues.apache.org/jira/browse/UIMA-1839 cas.ll_setStringValue(addr, stringSetFeat, null); boolean exCaught = false; try { cas.ll_setStringValue(addr, stringSetFeat, undefinedValue); } catch (CASRuntimeException e) { exCaught = true; } assertTrue(exCaught); } public void testCas() { CAS cas = this.jcas.getCas(); TypeSystem ts = cas.getTypeSystem(); Type annotType = ts.getType(annotationTypeName); FeatureStructure fs = cas.createFS(annotType); Feature stringSetFeat = ts.getFeatureByFullName(annotationTypeName + TypeSystem.FEATURE_SEPARATOR + stringSetFeatureName); fs.setStringValue(stringSetFeat, definedValue1); fs.setStringValue(stringSetFeat, definedValue2); fs.setStringValue(stringSetFeat, definedValue3); // next should be ok https://issues.apache.org/jira/browse/UIMA-1839 fs.setStringValue(stringSetFeat, null); boolean exCaught = false; try { fs.setStringValue(stringSetFeat, undefinedValue); } catch (CASRuntimeException e) { exCaught = true; } assertTrue(exCaught); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java0000644000175000017500000001211311665471060030143 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import java.util.Properties; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CASException; import org.apache.uima.jcas.JCas; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.FileUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Class comment for IteratorTest.java goes here. * */ public class GrowingTheCasTest extends TestCase { private AnalysisEngine ae = null; private JCas smallHeapCas = null; public GrowingTheCasTest(String arg0) { super(arg0); } public void setUp() { File descriptorFile = JUnitExtension.getFile("CASTests/desc/TokensAndSentences.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile .exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); AnalysisEngineDescription spec = (AnalysisEngineDescription) parser.parse(new XMLInputSource( descriptorFile)); this.ae = UIMAFramework.produceAnalysisEngine(spec); Properties props = new Properties(); props.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "0"); this.smallHeapCas = CasCreationUtils.createCas(spec, props).getJCas(); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } catch (CASException e) { e.printStackTrace(); assertTrue(false); } } public void tearDown() { if (this.ae != null) { this.ae.destroy(); this.ae = null; } } public void testAnnotator() { File textFile = JUnitExtension.getFile("data/moby.txt"); String text = null; try { text = FileUtils.file2String(textFile, "utf-8"); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } StringBuffer buf = new StringBuffer(text.length() * 10); for (int i = 0; i < 10; i++) { buf.append(text); } JCas jcas = null; try { jcas = this.ae.newJCas(); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } text = buf.toString(); jcas.setDocumentText(text); int numberOfSentences = 0; int numberOfTokens = 0; try { // long time = System.currentTimeMillis(); this.ae.process(jcas); // time = System.currentTimeMillis() - time; // System.out.println("Time for large CAS: " + new TimeSpan(time)); numberOfSentences = jcas.getAnnotationIndex(Sentence.type).size(); numberOfTokens = jcas.getAnnotationIndex(Token.type).size(); // System.out.println(numberOfSentences); // System.out.println(numberOfTokens); } catch (AnalysisEngineProcessException e) { e.printStackTrace(); assertTrue(false); } this.smallHeapCas.setDocumentText(text); try { // long time = System.currentTimeMillis(); this.ae.process(this.smallHeapCas); // time = System.currentTimeMillis() - time; // System.out.println("Time for small CAS: " + new TimeSpan(time)); assertTrue(this.getClass().toString() + ": number of sentences does not match", numberOfSentences == this.smallHeapCas.getAnnotationIndex(Sentence.type).size()); assertTrue(this.getClass().toString() + ": number of tokens does not match", numberOfTokens == this.smallHeapCas.getAnnotationIndex(Token.type).size()); } catch (AnalysisEngineProcessException e) { e.printStackTrace(); assertTrue(false); } } public static void main(String[] args) { junit.textui.TestRunner.run(GrowingTheCasTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexComparitorTest.java0000644000175000017500000003635211665471060030561 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.LinearTypeOrder; import org.apache.uima.cas.admin.LinearTypeOrderBuilder; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.LinearTypeOrderBuilderImpl; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Test the variations possible for index compare functions * */ public class IndexComparitorTest extends TestCase { CAS cas; TypeSystem ts; Type topType; Type integerType; Type type1; Type type1Sub1; Type type1Sub2; Feature type1Used; Feature type1Ignored; Feature type1Sub1Used; Feature type1Sub1Ignored; Feature type1Sub2Used; Feature type1Sub2Ignored; FSIndexRepositoryMgr irm; FSIndexRepository ir; FeatureStructure fss[][][]; FSIndex sortedType1; FSIndex sortedType1TypeOrder; private FSIndex setType1; private FSIndex bagType1; private FSIndex sortedType1Sub1; private FSIndex setType1Sub1; private FSIndex bagType1Sub1; private FSIndex setType1TypeOrder; private FSIndex bagType1TypeOrder; private FSIndex sortedType1Sub1TypeOrder; private FSIndex setType1Sub1TypeOrder; private FSIndex bagType1Sub1TypeOrder; public IndexComparitorTest(String arg0) { super(arg0); } /** * class which sets up */ private class SetupForIndexCompareTesting implements AnnotatorInitializer { /** * @see org.apache.uima.cas.test.AnnotatorInitializer#initTypeSystem(TypeSystemMgr) */ public void initTypeSystem(TypeSystemMgr tsm) { // Add new types and features. topType = tsm.getTopType(); integerType = tsm.getType("uima.cas.Integer"); type1 = tsm.addType("Type1", topType); type1Sub1 = tsm.addType("Type1Sub1", type1); type1Sub2 = tsm.addType("Type1Sub2", type1); type1Used = tsm.addFeature("used", type1, integerType); type1Ignored = tsm.addFeature("ignored", type1, integerType); type1Sub1Used = tsm.addFeature("used", type1Sub1, integerType); type1Sub1Ignored = tsm.addFeature("ignored", type1Sub1, integerType); type1Sub2Used = tsm.addFeature("used", type1Sub2, integerType); type1Sub2Ignored = tsm.addFeature("ignored", type1Sub2, integerType); } /** * */ public void initIndexes(FSIndexRepositoryMgr parmIrm, TypeSystem parmTs) { IndexComparitorTest.this.ts = parmTs; IndexComparitorTest.this.irm = parmIrm; parmIrm.createIndex(newComparator(type1), "SortedType1", FSIndex.SORTED_INDEX); parmIrm.createIndex(newComparator(type1), "SetType1", FSIndex.SET_INDEX); parmIrm.createIndex(newComparator(type1), "BagType1", FSIndex.BAG_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1), "SortedType1TypeOrder", FSIndex.SORTED_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1), "SetType1TypeOrder", FSIndex.SET_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1), "BagType1TypeOrder", FSIndex.BAG_INDEX); parmIrm.createIndex(newComparator(type1Sub1), "SortedType1Sub1", FSIndex.SORTED_INDEX); parmIrm.createIndex(newComparator(type1Sub1), "SetType1Sub1", FSIndex.SET_INDEX); parmIrm.createIndex(newComparator(type1Sub1), "BagType1Sub1", FSIndex.BAG_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1Sub1), "SortedType1Sub1TypeOrder", FSIndex.SORTED_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1Sub1), "SetType1Sub1TypeOrder", FSIndex.SET_INDEX); parmIrm.createIndex(newComparatorTypePriority(type1Sub1), "BagType1Sub1TypeOrder", FSIndex.BAG_INDEX); } private FSIndexComparator newComparator(Type type) { FSIndexComparator c = irm.createComparator(); c.setType(type); c.addKey(type1Used, FSIndexComparator.STANDARD_COMPARE); return c; } private FSIndexComparator newComparatorTypePriority(Type type) { FSIndexComparator comp = newComparator(type); comp.addKey(newTypeOrder(), FSIndexComparator.STANDARD_COMPARE); return comp; } private LinearTypeOrder newTypeOrder() { LinearTypeOrderBuilder ltob = new LinearTypeOrderBuilderImpl(ts); LinearTypeOrder order; try { ltob.add(new String[] { "Type1", "Type1Sub1", "Type1Sub2" }); order = ltob.getOrder(); } catch (CASException e) { throw new Error(e); } return order; } } public void setUp() throws Exception { try { this.cas = CASInitializer.initCas(new SetupForIndexCompareTesting()); assertNotNull(cas); ir = cas.getIndexRepository(); sortedType1 = ir.getIndex("SortedType1"); setType1 = ir.getIndex("SetType1"); bagType1 = ir.getIndex("BagType1"); sortedType1Sub1 = ir.getIndex("SortedType1Sub1"); setType1Sub1 = ir.getIndex("SetType1Sub1"); bagType1Sub1 = ir.getIndex("BagType1Sub1"); sortedType1TypeOrder = ir.getIndex("SortedType1TypeOrder"); setType1TypeOrder = ir.getIndex("SetType1TypeOrder"); bagType1TypeOrder = ir.getIndex("BagType1TypeOrder"); sortedType1Sub1TypeOrder = ir.getIndex("SortedType1Sub1TypeOrder"); setType1Sub1TypeOrder = ir.getIndex("SetType1Sub1TypeOrder"); bagType1Sub1TypeOrder = ir.getIndex("BagType1Sub1TypeOrder"); fss = new FeatureStructure[3][2][2]; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { ir.addFS(fss[0][i][j] = createFs(type1, i, j)); ir.addFS(fss[1][i][j] = createFs(type1Sub1, i, j)); ir.addFS(fss[2][i][j] = createFs(type1Sub2, i, j)); } } } catch (Exception e) { JUnitExtension.handleException(e); } } private FeatureStructure createFs(Type type, int i, int j) { FeatureStructure f = cas.createFS(type); f.setIntValue(type.getFeatureByBaseName("used"), i); f.setIntValue(type.getFeatureByBaseName("ignored"), j); return f; } public void tearDown() { fss = null; this.cas = null; this.ts = null; topType = null; integerType = null; type1 = null; type1Sub1 = null; type1Sub2 = null; type1Used = null; type1Ignored = null; type1Sub1Used = null; type1Sub1Ignored = null; type1Sub2Used = null; type1Sub2Ignored = null; } public void testCompare() throws Exception { try { assertTrue(0 == sortedType1.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == sortedType1.compare(fss[0][1][0], fss[0][0][0])); // type ignored in showing equals assertTrue(0 == sortedType1.compare(fss[1][0][0], fss[0][0][0])); assertTrue(0 == sortedType1.compare(fss[1][0][0], fss[2][0][0])); // type not ignored if type-order included assertTrue(0 == sortedType1TypeOrder.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == sortedType1TypeOrder.compare(fss[1][0][0], fss[0][0][0])); assertTrue(0 == setType1.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == setType1.compare(fss[0][1][0], fss[0][0][0])); // type ignored in showing equals assertTrue(0 == setType1.compare(fss[1][0][0], fss[0][0][0])); assertTrue(0 == setType1.compare(fss[1][0][0], fss[2][0][0])); // type not ignored if type-order included assertTrue(0 == setType1TypeOrder.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == setType1TypeOrder.compare(fss[1][0][0], fss[0][0][0])); assertTrue(-1 == bagType1.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == bagType1.compare(fss[0][1][0], fss[0][0][0])); assertTrue(1 == bagType1.compare(fss[1][0][0], fss[0][0][0])); assertTrue(-1 == bagType1.compare(fss[1][0][0], fss[2][0][0])); assertTrue(-1 == bagType1TypeOrder.compare(fss[0][0][0], fss[0][0][1])); assertTrue(1 == bagType1TypeOrder.compare(fss[1][0][0], fss[0][0][0])); // test contains FeatureStructure testType1_0_0 = createFs(type1, 0, 0); FeatureStructure testType1_1_0 = createFs(type1, 1, 0); FeatureStructure testType1_0_x = createFs(type1, 0, 17); FeatureStructure testTypeSub1_0_x = createFs(type1Sub1, 0, 17); FeatureStructure testTypeSub1_0_0 = createFs(type1Sub1, 0, 0); assertTrue(sortedType1.contains(testType1_0_0)); assertTrue(sortedType1.contains(testType1_0_x)); assertTrue(sortedType1.contains(testTypeSub1_0_x)); assertTrue(setType1.contains(testType1_0_0)); assertTrue(setType1.contains(testType1_0_x)); assertTrue(setType1.contains(testTypeSub1_0_x)); assertFalse(bagType1.contains(testType1_0_0)); assertFalse(bagType1.contains(testType1_0_x)); assertFalse(bagType1.contains(testTypeSub1_0_x)); assertTrue(sortedType1TypeOrder.contains(testType1_0_0)); assertTrue(sortedType1TypeOrder.contains(testType1_0_x)); // assertTrue(sortedType1TypeOrder.contains(testTypeSub1_0_x)); assertTrue(setType1TypeOrder.contains(testType1_0_0)); assertTrue(setType1TypeOrder.contains(testType1_0_x)); // assertTrue(setType1TypeOrder.contains(testTypeSub1_0_x)); assertFalse(bagType1TypeOrder.contains(testType1_0_0)); assertFalse(bagType1TypeOrder.contains(testType1_0_x)); assertFalse(bagType1TypeOrder.contains(testTypeSub1_0_x)); // for (Iterator it = sortedType1TypeOrder.iterator(); it.hasNext();) { // System.out.println(it.next().toString()); // } // assertTrue(sortedType1TypeOrder.contains(testTypeSub1_0_0)); // assertTrue(sortedType1TypeOrder.contains(testTypeSub1_0_x)); // test find assertNotNull(sortedType1.find(testType1_0_0)); assertNotNull(sortedType1.find(testType1_0_x)); assertNotNull(sortedType1.find(testTypeSub1_0_x)); assertNotNull(setType1.find(testType1_0_0)); assertNotNull(setType1.find(testType1_0_x)); assertNotNull(setType1.find(testTypeSub1_0_x)); assertNull(bagType1.find(testType1_0_0)); assertNull(bagType1.find(testType1_0_x)); assertNull(bagType1.find(testTypeSub1_0_x)); assertNotNull(sortedType1TypeOrder.find(testType1_0_0)); assertNotNull(sortedType1TypeOrder.find(testType1_0_x)); // assertNotNull(sortedType1TypeOrder.find(testTypeSub1_0_x)); assertNotNull(setType1TypeOrder.find(testType1_0_0)); assertNotNull(setType1TypeOrder.find(testType1_0_x)); // assertNotNull(setType1TypeOrder.find(testTypeSub1_0_x)); assertNull(bagType1TypeOrder.find(testType1_0_0)); assertNull(bagType1TypeOrder.find(testType1_0_x)); assertNull(bagType1TypeOrder.find(testTypeSub1_0_x)); // test iterator(fs) assertTrue(sortedType1.iterator(testType1_0_0).isValid()); assertTrue(sortedType1.iterator(testType1_0_x).isValid()); assertTrue(sortedType1.iterator(testTypeSub1_0_x).isValid()); assertTrue(setType1.iterator(testType1_0_0).isValid()); assertTrue(setType1.iterator(testType1_0_x).isValid()); assertTrue(setType1.iterator(testTypeSub1_0_x).isValid()); assertTrue(bagType1.iterator(testType1_0_0).isValid()); assertTrue(bagType1.iterator(testType1_0_x).isValid()); assertTrue(bagType1.iterator(testTypeSub1_0_x).isValid()); assertTrue(sortedType1TypeOrder.iterator(testType1_0_0).isValid()); assertTrue(sortedType1TypeOrder.iterator(testType1_0_x).isValid()); assertTrue(sortedType1TypeOrder.iterator(testTypeSub1_0_x).isValid()); assertTrue(setType1TypeOrder.iterator(testType1_0_0).isValid()); assertTrue(setType1TypeOrder.iterator(testType1_0_x).isValid()); assertTrue(setType1TypeOrder.iterator(testTypeSub1_0_x).isValid()); assertTrue(bagType1TypeOrder.iterator(testType1_0_0).isValid()); assertTrue(bagType1TypeOrder.iterator(testType1_0_x).isValid()); assertTrue(bagType1TypeOrder.iterator(testTypeSub1_0_x).isValid()); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testType1_0_0).get())); assertTrue(fss[0][1][0].equals(sortedType1.iterator(testType1_1_0).get())); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testType1_0_x).get())); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testTypeSub1_0_x).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testType1_0_0).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testType1_0_x).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testTypeSub1_0_x).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testType1_0_0).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testType1_0_x).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testTypeSub1_0_x).get())); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testType1_0_0).get())); assertTrue(fss[0][1][0].equals(sortedType1.iterator(testType1_1_0).get())); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testType1_0_x).get())); // assertTrue(fss[0][0][0].equals(sortedType1.iterator(testTypeSub1_0_x).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testType1_0_0).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testType1_0_x).get())); assertTrue(fss[0][0][0].equals(setType1.iterator(testTypeSub1_0_x).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testType1_0_0).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testType1_0_x).get())); assertTrue(fss[0][0][0].equals(bagType1.iterator(testTypeSub1_0_x).get())); } catch (Exception e) { JUnitExtension.handleException(e); } } public static void main(String[] args) { junit.textui.TestRunner.run(IndexComparitorTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/SerializationNoMDTest.java0000644000175000017500000004100211665471060030771 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.CASSerializer; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.internal.util.TextStringTokenizer; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; /** * Class comment for TokenizerTest.java goes here. * */ public class SerializationNoMDTest extends TestCase { public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; private CASMgr casMgr; private CAS cas; private Type wordType; private Type separatorType; private Type eosType; private Type tokenType; private Feature tokenTypeFeature; private Type sentenceType; private Feature startFeature; private Feature endFeature; public SerializationNoMDTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ public void setUp() throws Exception { super.setUp(); casMgr = initCAS(); cas = (CASImpl)casMgr; TypeSystem ts = cas.getTypeSystem(); wordType = ts.getType(WORD_TYPE); // assert(wordType != null); separatorType = ts.getType(SEP_TYPE); eosType = ts.getType(EOS_TYPE); tokenType = ts.getType(TOKEN_TYPE); tokenTypeFeature = ts.getFeatureByFullName(TOKEN_TYPE_FEAT_Q); startFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); endFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_END); sentenceType = ts.getType(SENT_TYPE); } public void tearDown() { casMgr = null; cas = null; wordType = null; separatorType = null; eosType = null; tokenType = null; tokenTypeFeature = null; startFeature = null; endFeature = null; sentenceType = null; } // Initialize the first CAS. private static CASMgr initCAS() { // Create an initial CASMgr from the factory. // CASMgr cas = CASFactory.createCAS(); // assert(tsa != null); // Create a CASMgr. Ensures existence of AnnotationFS type. // CASMgr tcas = CASFactory.createCAS(); CASMgr aCas = CASFactory.createCAS(); try { CasCreationUtils.setupTypeSystem(aCas, (TypeSystemDescription) null); } catch (ResourceInitializationException e) { e.printStackTrace(); } // Create a writable type system. TypeSystemMgr tsa = aCas.getTypeSystemMgr(); // Add new types and features. Type topType = tsa.getTopType(); Type annotType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); // assert(annotType != null); tsa.addType(SENT_TYPE, annotType); Type tokenType = tsa.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsa.addType(TOKEN_TYPE_TYPE, topType); tsa.addType(WORD_TYPE, tokenTypeType); tsa.addType(SEP_TYPE, tokenTypeType); tsa.addType(EOS_TYPE, tokenTypeType); tsa.addFeature(TOKEN_TYPE_FEAT, tokenType, tokenTypeType); // Commit the type system. ((CASImpl) aCas).commitTypeSystem(); // assert(tsa.isCommitted()); // // Create the CAS indexes. // tcas.initCASIndexes(); // Create the Base indexes. try { aCas.initCASIndexes(); } catch (CASException e) { e.printStackTrace(); } // Commit the index repository. aCas.getIndexRepositoryMgr().commit(); // assert(cas.getIndexRepositoryMgr().isCommitted()); // Create the default text Sofa and return CAS view return (CASMgr) aCas.getCAS().getCurrentView(); } // Tokenize text. private void tokenize() throws Exception { // System.out.println("Tokenizing text."); // Create FSs for the token types. FeatureStructure wordFS = cas.createFS(wordType); FeatureStructure sepFS = cas.createFS(separatorType); FeatureStructure eosFS = cas.createFS(eosType); String text = cas.getDocumentText(); TextStringTokenizer tokenizer = new TextStringTokenizer(text); tokenizer.setSeparators("/-*&@"); tokenizer.addWhitespaceChars(","); tokenizer.setEndOfSentenceChars(".!?"); tokenizer.setShowWhitespace(false); int tokenTypeCode; int wordCounter = 0; int sepCounter = 0; int endOfSentenceCounter = 0; AnnotationFS tokenAnnot; while (tokenizer.isValid()) { tokenAnnot = cas.createAnnotation(tokenType, tokenizer.getTokenStart(), tokenizer .getTokenEnd()); tokenTypeCode = tokenizer.getTokenType(); switch (tokenTypeCode) { case TextStringTokenizer.EOS: { ++endOfSentenceCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, eosFS); break; } case TextStringTokenizer.SEP: { ++sepCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, sepFS); break; } case TextStringTokenizer.WSP: { break; } case TextStringTokenizer.WCH: { ++wordCounter; tokenAnnot.setFeatureValue(tokenTypeFeature, wordFS); // if ((wordCounter % 100000) == 0) { // System.out.println("Number of words tokenized: " + wordCounter); // } break; } default: { throw new Exception("Something went wrong, fire up that debugger!"); } } cas.getIndexRepository().addFS(tokenAnnot); tokenizer.setToNext(); // System.out.println("Token: " + tokenizer.nextToken()); } // time = System.currentTimeMillis() - time; // System.out.println("Number of words: " + wordCounter); // int allTokens = wordCounter + sepCounter + endOfSentenceCounter; // System.out.println("Number of tokens: " + allTokens); // System.out.println("Time used: " + new TimeSpan(time)); // FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); // int count = 0; // while (it.isValid()) { // ++count; // it.moveToNext(); // } // System.out.println("Number of tokens in index: " + count); } // Very (!) primitive EOS detection. private void createSentences() { // TypeSystem ts = cas.getTypeSystem(); // Type eosType = ts.getType(EOS_TYPE); // Type tokenType = ts.getType(TOKEN_TYPE); // //assert(tokenType != null); // Type sentenceType = ts.getType(SENT_TYPE); // Feature tokenTypeFeature = ts.getFeature(TOKEN_TYPE_FEAT); // Feature startFeature = ts.getFeature(CAS.START_FEAT); // Feature endFeature = ts.getFeature(CAS.END_FEAT); // System.out.println("\nCreating sentence annotations."); // Get a handle to the index repository. FSIndexRepository indexRepository = cas.getIndexRepository(); // assert(indexRepository != null); Iterator labelIt = indexRepository.getLabels(); assertTrue(labelIt != null); // Get the standard index for tokens. FSIndex tokenIndex = cas.getAnnotationIndex(tokenType); // assert(tokenIndex != null); // Get an iterator over tokens. FSIterator it = tokenIndex.iterator(); // assert(it != null); // Now create sentences. We do this as follows: a sentence starts where // the first token after an EOS starts, and ends with an EOS. long time = System.currentTimeMillis(); int endOfSentenceCounter = 0; it.moveToFirst(); boolean lookForStart = true; int start = 0, end; // Initialize start to pacify compiler. FeatureStructure tokenFS, sentFS; while (it.isValid()) { if (lookForStart) { // If we're looking for the start of a sentence, just grab the start // of the current FS. start = it.get().getIntValue(startFeature); lookForStart = false; } else { // Check if we've reached the end of a sentence. tokenFS = it.get(); if (tokenFS.getFeatureValue(tokenTypeFeature).getType() == eosType) { end = tokenFS.getIntValue(endFeature); sentFS = cas.createFS(sentenceType); sentFS.setIntValue(startFeature, start); sentFS.setIntValue(endFeature, end); cas.getIndexRepository().addFS(sentFS); ++endOfSentenceCounter; lookForStart = true; } } it.moveToNext(); } time = System.currentTimeMillis() - time; // System.out.println("Created " + endOfSentenceCounter + " sentences: " + new TimeSpan(time)); } // Check results. private void checkSentences() { TypeSystem ts = cas.getTypeSystem(); Type localSentenceType = ts.getType(SENT_TYPE); // Feature tokenTypeFeature = ts.getFeatureByFullName(TOKEN_TYPE_FEAT); // Feature startFeature = ts.getFeatureByFullName(CAS.FEATURE_BASE_NAME_BEGIN); // Feature endFeature = ts.getFeatureByFullName(CAS.FEATURE_BASE_NAME_END); // Print the first few sentences. // System.out.println("\nThe first 10 sentences:\n"); FSIndex sentenceIndex = cas.getAnnotationIndex(localSentenceType); FSIterator it = sentenceIndex.iterator(); AnnotationFS sentFS; if (it.isValid()) { sentFS = (AnnotationFS) it.get(); assertTrue(sentFS.getCoveredText() != null); } // int counter = 0; String text = cas.getDocumentText(); assertTrue(text != null); // while (it.isValid() && counter < 10) { // sentFS = (AnnotationFS)it.get(); // System.out.println( // "Sentence: " // + sentFS.getCoveredText()); // it.moveToNext(); // ++counter; // } // Now get an iterator over all annotations. FSIndex annotIndex = cas.getAnnotationIndex(); // System.out.println("\nNumber of annotations in index: " + annotIndex.size()); // Print the first few sentences. // System.out.println("The first 50 annotations:\n"); it = annotIndex.iterator(); // assert(it.isValid()); // counter = 0; // AnnotationFS fs; // while (it.isValid() && counter < 50) { // fs = (AnnotationFS)it.get(); // System.out.print(fs.getType().getName() + ": "); // if (fs.getType().getName().equals(CASMgr.DOCUMENT_TYPE)) { // // When we see the document, we don't print the whole text ;-) // System.out.println("..."); // } else { // System.out.println( // fs.getCoveredText()); // } // it.moveToNext(); // ++counter; // } } // private static String file2String(String file) throws IOException { // return file2String(new File(file)); // } /** * Read the contents of a file into a string, using the default platform encoding. * * @param file * The file to be read in. * @return String The contents of the file. * @throws IOException * Various I/O errors. */ public static String file2String(File file) throws IOException { // Read the file into a string using a char buffer. FileReader reader = null; int bufSize = (int) file.length(); // length in bytes >= length in chars due to encoding char[] buf = new char[bufSize]; int read_so_far = 0; try { reader = new FileReader(file); while (read_so_far < bufSize) { int count = reader.read(buf, read_so_far, bufSize - read_so_far); if (count < 0) { break; } read_so_far += count; } } finally { if (null != reader) reader.close(); } return new String(buf, 0, read_so_far); } /** * Test driver. */ public void testMain() throws Exception { // Read the document into a String. I'm sure there are better ways to // do this. File textFile = JUnitExtension.getFile("data/moby.txt"); String moby = file2String(textFile); // String moby = file2String(System.getProperty("cas.data.test") + "moby.txt"); String line; BufferedReader br = new BufferedReader(new StringReader(moby)); StringBuffer buf = new StringBuffer(); List docs = new ArrayList(); while ((line = br.readLine()) != null) { if (line.startsWith(".. 0); // System.out.println(" Number of tokens: " + numTok); // System.out.println("Serializing..."); cs = Serialization.serializeNoMetaData(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); createSentences(); numSent = cas.getAnnotationIndex(sentenceType).size(); assertTrue(numSent > 0); // System.out.println(" Number of sentences: " + numSent); // System.out.println("Serializing..."); cs = Serialization.serializeNoMetaData(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println(" Number of tokens: " + numTok); checkSentences(); // System.out.println("Serializing..."); cs = Serialization.serializeNoMetaData(cas); cas = Serialization.createCAS(casMgr, cs); assertTrue(numTok == cas.getAnnotationIndex(tokenType).size()); assertTrue(numSent == cas.getAnnotationIndex(sentenceType).size()); // System.out.println(" Verify: " + numTok + " tokens, " + numSent + " sentences."); casMgr.reset(); ++docCount; } // System.out.println("Number of documents processed: " + docCount); } overallTime = System.currentTimeMillis() - overallTime; // System.out.println("Time taken over all: " + new TimeSpan(overallTime)); } public static void main(String[] args) { junit.textui.TestRunner.run(SerializationNoMDTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TypePriorityTest.java0000644000175000017500000002217211665471060030130 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.util.Properties; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.LinearTypeOrder; import org.apache.uima.cas.admin.LinearTypeOrderBuilder; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; /** * tests of type priorities * * These tests set up various type priorities, and then test that the total linear order gives the * expected type order * * Types: For this tests, we use types whose names encode their position in a type tree. * * Encoding: Each type name has a root based on a single letter, e.g. a, b, c name of type is its * root preceeded by its ancestors to the top */ public class TypePriorityTest extends TestCase { public static final Properties casCreateProperties = new Properties(); static { casCreateProperties.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "200"); } private CASMgr casMgr; private CAS cas; private FSIndexRepositoryMgr irm; private TypeSystem ts; public TypePriorityTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); casMgr = initCAS(); cas = casMgr.getCAS().getCurrentView(); irm = casMgr.getIndexRepositoryMgr(); ts = cas.getTypeSystem(); } public void tearDown() { casMgr = null; cas = null; irm = null; ts = null; } private String[] makeTypeName(String[] roots) { String[] r = new String[roots.length * 2]; for (int i = 0; i < roots.length; i++) { r[2 * i] = roots[i] + "a"; r[2 * i + 1] = roots[i] + "b"; } return r; } private String[] makeTypeName(int level) { if (level == 0) return new String[] { "" }; return makeTypeName(makeTypeName(level - 1)); } private void addTypesForLevel(TypeSystemMgr tsm, int level) { int rootLevel = level - 1; if (rootLevel >= 0) addTypesForLevel(tsm, rootLevel); String[] roots = makeTypeName(level); for (int i = 0; i < roots.length; i++) { Type parent = roots[i].equals("") ? tsm.getTopType() : tsm.getType(roots[i]); tsm.addType(roots[i] + "a", parent); tsm.addType(roots[i] + "b", parent); // System.out.println("added type " + roots[i] + "a and b"); } // special type for another test tsm.addType("ac", tsm.getType("a")); } // Initialize the first CAS. private CASMgr initCAS() { // Create a CASMgr. Ensures existence of AnnotationFS type. CASMgr localCas = CASFactory.createCAS(200); // Create a writable type system. TypeSystemMgr tsa = localCas.getTypeSystemMgr(); // Add new types and features. addTypesForLevel(tsa, 4); // Commit the type system. ((CASImpl) localCas).commitTypeSystem(); try { localCas.initCASIndexes(); } catch (CASException e2) { e2.printStackTrace(); assertTrue(false); } localCas.getIndexRepositoryMgr().commit(); // assert(cas.getIndexRepositoryMgr().isCommitted()); return localCas; } private void check(LinearTypeOrder lo, String[] o) { for (int i = 0; i < o.length - 1; i++) { check(lo, o[i], o[i + 1]); } } private void checkBackwards(LinearTypeOrder lo, String[] o) { for (int i = 0; i < o.length - 1; i++) { checkBackwards(lo, o[i], o[i + 1]); } } private void check(LinearTypeOrder lo, String t1, String t2) { assertTrue(lo.lessThan(ts.getType(t1), ts.getType(t2))); } private void checkBackwards(LinearTypeOrder lo, String t1, String t2) { assertFalse(lo.lessThan(ts.getType(t1), ts.getType(t2))); } /* * Diagram to figure out what the answers should be * a b * aa ab ba ... * aaa aab aba abb baa ... * aaaa aaab aaba aabb abaa abab abba abbb baaa ... * aaaaa aaaab aaaba aaabb aabaa aabab aabba aabbb abaaa abaab ababa ababb abbaa abbab abbba abbbb baaaa ... */ /** * Test driver. */ public void testMain() throws Exception { LinearTypeOrderBuilder order = irm.createTypeSortOrder(); order = irm.createTypeSortOrder(); LinearTypeOrder lo; try { order.add(new String[] { "aaa", "bbb" }); lo = order.getOrder(); check(lo, "aaa", "bbb"); } catch (CASException e) { assertTrue(false); } } public void testN1() throws Exception { LinearTypeOrderBuilder order = irm.createTypeSortOrder(); order = irm.createTypeSortOrder(); LinearTypeOrder lo; try { // aaa (and all its subtypes) come before bbb (and all its subtypes) order.add(new String[] { "aaa", "bbb" }); // aa (and all its subtypes) come before // abaa (and all its subtypes) come before // abbbb (and all its subtypes) order.add(new String[] { "aa", "abaa", "abbbb" }); lo = order.getOrder(); check(lo, new String[] { "aa", "abaa", "abbbb" }); check(lo, "aaa", "bbb"); check(lo, "aaa", "abaaa"); check(lo, "aaab", "abaab"); check(lo, "aa", "abbbb"); check(lo, "abaa", "abbbb"); } catch (CASException e) { assertTrue(false); } } public void testLoop2() throws Exception { try { LinearTypeOrderBuilder obuilder; LinearTypeOrder order; obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "a", "b" }); check(order = obuilder.getOrder(), "aa", "bb"); checkBackwards(order, "bb", "aa"); check(order, "ab", "bb"); check(order, "aa", "ba"); check(order, "ab", "ba"); obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "b", "a" }); check(order = obuilder.getOrder(), "ba", "aa"); check(order, "bb", "aa"); check(order, "ba", "ab"); check(order, "bb", "ab"); obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "a", "b" }); obuilder.add(new String[] { "bb", "a" }); check(order = obuilder.getOrder(), "bb", "aa"); // these two forced to reverse check(order, "bb", "ab"); // these two forced to reverse check(order, "aa", "ba"); check(order, "ab", "ba"); // set a child in front of the sib of its parent, // and one in front of the child of its prev sib. obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "aba", "aa" }); obuilder.add(new String[] { "b", "aa" }); check(order = obuilder.getOrder(), "aba", "aa"); check(order, "bb", "aa"); // child of b dragged along? check(order, "b", "aaa"); // child of aa dragged? // siblings children dragged obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "ab", "aa" }); obuilder.add(new String[] { "b", "aa" }); check(order = obuilder.getOrder(), "ab", "aa"); check(order, "b", "aa"); check(order, "bb", "aa"); // child of b dragged along? check(order, "b", "aaa"); // child of aa dragged? // siblings children dragged obuilder = irm.createTypeSortOrder(); obuilder.add(new String[] { "ab", "aa" }); obuilder.add(new String[] { "b", "aa" }); obuilder.add(new String[] { "a", "b" }); check(order = obuilder.getOrder(), "ab", "aa"); check(order, "b", "aa"); check(order, "bb", "aa"); // child of b dragged along? check(order, "b", "aaa"); // child of aa dragged? check(order, "ac", "b"); } catch (CASException e) { assertTrue(false); } } public static void main(String[] args) { junit.textui.TestRunner.run(TypePriorityTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/Token_Type.java0000644000175000017500000000501511665471060026663 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Thu Jun 21 11:28:13 MDT 2007 */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.cas.Type; import org.apache.uima.jcas.tcas.Annotation_Type; /** * Updated by JCasGen Thu Jun 21 12:00:34 MDT 2007 * @generated */ public class Token_Type extends Annotation_Type { /** @generated */ protected FSGenerator getFSGenerator() {return fsGenerator;} /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (Token_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = Token_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Token(addr, Token_Type.this); Token_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Token(addr, Token_Type.this); } }; /** @generated */ public final static int typeIndexID = Token.typeIndexID; /** @generated @modifiable */ public final static boolean featOkTst = JCasRegistry.getFeatOkTst("uima464.Token"); /** initialize variables to correspond with Cas Type and Features * @generated */ public Token_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl)this.casType, getFSGenerator()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CASInitializer.java0000644000175000017500000000517311665471060027421 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.util.CasCreationUtils; /** * Use this as your CAS factory. */ public class CASInitializer { public static CAS initCas(AnnotatorInitializer init) { // Create an initial CASMgr from the factory. CASMgr casMgr0 = CASFactory.createCAS(); CASMgr casMgr = null; try { // this call does nothing: because 2nd arg is null CasCreationUtils.setupTypeSystem(casMgr0, (TypeSystemDescription) null); // Create a writable type system. TypeSystemMgr tsa = casMgr0.getTypeSystemMgr(); // Next not needed, type system is already uncommitted // ((TypeSystemImpl) tsa).setCommitted(false); // do the type system tests init.initTypeSystem(tsa); // Commit the type system. ((CASImpl) casMgr0).commitTypeSystem(); casMgr = CASFactory.createCAS(tsa); // Create the Base indexes. casMgr.initCASIndexes(); // Commit the index repository. FSIndexRepositoryMgr irm = casMgr.getIndexRepositoryMgr(); init.initIndexes(irm, casMgr.getTypeSystemMgr()); irm.commit(); } catch (ResourceInitializationException e) { e.printStackTrace(); } catch (CASException e) { e.printStackTrace(); } // Create the default text Sofa and return CAS view return casMgr.getCAS().getCurrentView(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/UimacppDeserializationTest.java0000644000175000017500000001157611665471060032120 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; /** * Class comment for UimacppDeserializationTest.java goes here. * */ public class UimacppDeserializationTest extends TestCase { /** * Constructor for UimacppDeserializationTest. * * @param arg0 */ public UimacppDeserializationTest(String arg0) { super(arg0); } // Test case does not work: need serialized TAF form // keep a null test here to avoid having suite complain there are no tests here public void testNothing() { assertTrue(true); } /* * public void testDeserialization() { // Get file handle to serialized CAS. File dataDir = new * File(TestPropertyReader.getJUnitTestBasePath()); assertTrue(dataDir.exists()); * assertTrue(dataDir.isDirectory()); File serializedForm = new File(dataDir, "cascomplete.ser"); // * Deserialize ObjectInputStream ois = null; CASCompleteSerializer ser = null; try { ois = new * ObjectInputStream(new FileInputStream(serializedForm)); ser = (CASCompleteSerializer) * ois.readObject(); ois.close(); } catch (IOException e) { e.printStackTrace(); * assertTrue(false); } catch (ClassNotFoundException e) { assertTrue(false); } CAS cas = null; * try { CASMgr casMgr = CASFactory.createCAS(); Serialization.deserializeCASComplete(ser, * casMgr); cas = casMgr.getCurrentView(); } catch (CASException e) { assertTrue(false); } * assertTrue(cas != null); System.out.println("Document text:"); * System.out.println(cas.getDocumentText()); * * System.out.println("Type system:\n" + cas.getTypeSystem().toString()); * * TypeSystem ts = cas.getTypeSystem(); Type ttDocType = ts.getType("uima.tt.DocumentAnnotation"); * assertTrue(ttDocType != null); Type annotType = ts.getType(CAS.TYPE_NAME_ANNOTATION); * assertTrue(annotType != null); assertTrue(ts.subsumes(annotType, ttDocType)); Feature beginFeat = * ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); * assertTrue(ttDocType.getAppropriateFeatures().contains(beginFeat)); Vector feats = * ttDocType.getAppropriateFeatures(); System.out.println("Features defined for " + * ttDocType.getName()); for (int i = 0; i < feats.size(); i++) { System.out.println(" " + * ((Feature)feats.get(i)).getName()); } * * FSIndex annotationIndex = cas.getAnnotationIndex(); assertTrue(annotationIndex != null); * System.out.println( "Number of annotations in index: " + annotationIndex.size()); Feature * markupFeat = cas.getTypeSystem().getFeatureByFullName( * "uima.tt.DocStructureAnnotation:markupTag"); System.out.println("Annotations: "); FSIterator it = * annotationIndex.iterator(); AnnotationFS annot; for (it.moveToFirst(); it.isValid(); * it.moveToNext()) { annot = (AnnotationFS) it.get(); System.out.println( annot.getType() + ": " + * annot.getBegin() + " - " + annot.getEnd() + ": " + annot.getCoveredText()); } * * FSIndexRepository ir = cas.getIndexRepository(); Iterator labelIt = ir.getLabels(); * System.out.println("Index labels: "); while (labelIt.hasNext()) { System.out.println(" " + * (String) labelIt.next()); } * * Type docType = cas.getTypeSystem().getType(CASMgr.DOCUMENT_TYPE); FSIndex docIndex = * cas.getAnnotationIndex(docType); Vector featVector = docType.getAppropriateFeatures(); * System.out.println("Features defined for docType: "); for (int i = 0; i < featVector.size(); * i++) { System.out.println(" " + ((Feature)featVector.get(i)).getShortName()); } * assertTrue(docIndex != null); it = docIndex.iterator(); for (it.moveToFirst(); it.isValid(); * it.moveToNext()) { annot = (AnnotationFS) it.get(); System.out.println( annot.getType() + ": " + * annot.getBegin() + " - " + annot.getEnd()); System.out.println(" " + annot.getCoveredText()); } // * String text = null; // try { // text = cas.getDocumentText(); // } catch (CASException e) { // * assertTrue(false); // } // assertTrue(text != null); } */ public static void main(String[] args) { junit.textui.TestRunner.run(UimacppDeserializationTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/StringArrayTest.java0000644000175000017500000001521511665471060027712 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.LowLevelCAS; /** * Class comment for StringArrayTest.java goes here. * */ public class StringArrayTest extends TestCase { private CAS cas; private TypeSystem ts; /** * Constructor for ArrayFSTest. * * @param arg0 */ public StringArrayTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); this.ts = this.cas.getTypeSystem(); } catch (Exception e) { assertTrue(false); } } public void tearDown() { this.cas = null; this.ts = null; } public static void main(String[] args) { junit.textui.TestRunner.run(StringArrayTest.class); } public void testSet() { StringArrayFS array = this.cas.createStringArrayFS(0); assertTrue(array != null); assertTrue(array.size() == 0); boolean exceptionCaught = false; try { array.get(0); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); array = this.cas.createStringArrayFS(3); try { array.set(0, "1"); array.set(1, "2"); array.set(2, "3"); } catch (ArrayIndexOutOfBoundsException e) { assertTrue(false); } String[] stringArray = array.toStringArray(); assertTrue(array.size() == stringArray.length); for (int i = 0; i < stringArray.length; i++) { assertTrue(stringArray[i].equals(array.get(i))); } exceptionCaught = false; try { array.set(-1, "1"); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.set(4, "1"); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); assertTrue(array.get(0).equals("1")); assertTrue(array.get(1).equals("2")); assertTrue(array.get(2).equals("3")); exceptionCaught = false; try { array.get(-1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.get(4); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); // Check that we can't create arrays smaller than 0. exceptionCaught = false; try { array = this.cas.createStringArrayFS(-1); } catch (CASRuntimeException e) { exceptionCaught = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_ARRAY_SIZE)); } assertTrue(exceptionCaught); } public void testToArray() { // From CAS array to Java array. StringArrayFS array = this.cas.createStringArrayFS(3); String[] fsArray = array.toArray(); for (int i = 0; i < 3; i++) { assertTrue(fsArray[i] == null); } array.set(0, "1"); array.set(1, "2"); array.set(2, "3"); fsArray = array.toArray(); assertTrue(fsArray.length == 3); assertTrue(fsArray[0].equals("1")); assertTrue(fsArray[1].equals("2")); assertTrue(fsArray[2].equals("3")); // From Java array to CAS array. array = this.cas.createStringArrayFS(3); assertTrue(array.get(0) == null); assertTrue(array.get(1) == null); assertTrue(array.get(2) == null); for (int i = 0; i < 3; i++) { array.set(i, fsArray[i]); } assertTrue(array.get(0).equals("1")); assertTrue(array.get(1).equals("2")); assertTrue(array.get(2).equals("3")); array.set(0, null); assertTrue(array.get(0) == null); } public void testStringArrayValue() { String lemmaListName = CASTestSetup.TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + CASTestSetup.LEMMA_LIST_FEAT; final Feature lemmaList = this.ts.getFeatureByFullName(lemmaListName); assertTrue(lemmaList != null); String[] javaArray = { "1", "2", "3" }; StringArrayFS casArray = this.cas.createStringArrayFS(3); casArray.copyFromArray(javaArray, 0, 0, 3); FeatureStructure token = this.cas.createFS(this.ts.getType(CASTestSetup.TOKEN_TYPE)); assertTrue(token.getFeatureValue(lemmaList) == null); token.setFeatureValue(lemmaList, casArray); assertTrue(((StringArrayFS) token.getFeatureValue(lemmaList)).get(0) == "1"); String hello = "Hello."; casArray.set(0, hello); assertTrue(((StringArrayFS) token.getFeatureValue(lemmaList)).get(0) == hello); } public void testStringArrayNullValue() throws Exception{ String lemmaListName = CASTestSetup.TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + CASTestSetup.LEMMA_LIST_FEAT; final Feature lemmaList = this.ts.getFeatureByFullName(lemmaListName); assertTrue(lemmaList != null); StringArrayFS casArray = this.cas.createStringArrayFS(3); casArray.set(0, "1"); casArray.set(1, null); casArray.set(2, "3"); FeatureStructure token = this.cas.createFS(this.ts.getType(CASTestSetup.TOKEN_TYPE)); assertTrue(token.getFeatureValue(lemmaList) == null); token.setFeatureValue(lemmaList, casArray); this.cas.addFsToIndexes(token); assertTrue(((StringArrayFS) token.getFeatureValue(lemmaList)).get(0) == "1"); assertTrue(((StringArrayFS) token.getFeatureValue(lemmaList)).get(1) == null); LowLevelCAS llc = casArray.getCAS().getLowLevelCAS(); assertTrue(llc.ll_getIntArrayValue(llc.ll_getFSRef(casArray), 1) == LowLevelCAS.NULL_FS_REF); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TypeSystemReinitTest.java0000644000175000017500000001176111665471060030750 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.impl.CASCompleteSerializer; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; public class TypeSystemReinitTest extends TestCase { public void testReinitCASCompleteSerializer() throws Exception { try { AnalysisEngineDescription aed = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml"))); TypeSystemDescription tsd = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(getClass().getResource("/org/apache/uima/examples/SourceDocumentInformation.xml"))); List l = new ArrayList(); l.add(aed); l.add(tsd); CAS cas1 = CasCreationUtils.createCas(l); cas1.setDocumentText("foo"); CASCompleteSerializer ser = Serialization.serializeCASComplete((CASMgr) cas1); CAS tcas2 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); CASImpl cas2 = ((CASImpl) tcas2).getBaseCAS(); tcas2.setDocumentText("bar"); // reinit // This uses cas2 which only has a base type system to start, // and loads it from a complete serialization which has other new types cas2.reinit(ser); CAS tcas3 = cas2.getCurrentView(); assertTrue(tcas2 == tcas3); assertNotNull(cas1.getTypeSystem().getType("NamedEntity")); assertNotNull(tcas3.getTypeSystem().getType("NamedEntity")); FeatureStructure fs = tcas3.createFS(tcas3.getTypeSystem().getType("NamedEntity")); tcas3.getIndexRepository().addFS(fs); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testReinitCASCompleteSerializerWithArrays() throws Exception { try { AnalysisEngineDescription aed = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(JUnitExtension .getFile("ExampleTae/arrayTypeSerialization.xml"))); CAS cas1 = CasCreationUtils.createCas(aed); cas1.setDocumentText("foo"); CASCompleteSerializer ser = Serialization.serializeCASComplete((CASMgr) cas1); CAS tcas2 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); CASImpl cas2 = ((CASImpl) tcas2).getBaseCAS(); tcas2.setDocumentText("bar"); // reinit // This uses cas2 which only has a base type system to start, // and loads it from a complete serialization which has other new types cas2.reinit(ser); CAS tcas3 = cas2.getCurrentView(); assertTrue(tcas2 == tcas3); assertNotNull(cas1.getTypeSystem().getType("Test.ArrayType")); assertNotNull(tcas3.getTypeSystem().getType("Test.ArrayType")); TypeSystemImpl ts = (TypeSystemImpl)cas2.getTypeSystem(); Type arrayType = ts.getType("Test.ArrayType"); Feature arrayFeat = arrayType.getFeatureByBaseName("arrayFeature"); TypeImpl featRange = (TypeImpl)(arrayFeat.getRange()); assertTrue(ts.ll_isArrayType(featRange.getCode())); assertFalse(arrayFeat.isMultipleReferencesAllowed()); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java0000644000175000017500000001733011665471060027074 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.LinearTypeOrderBuilder; import org.apache.uima.cas.admin.TypeSystemMgr; public class CASTestSetup implements AnnotatorInitializer { // Type system constants. public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String ARRAYFSWITHSUBTYPE_TYPE = "ArrayFsWithSubtype"; public static final String ARRAYFSWITHSUBTYPE_TYPE_FEAT = "subArrayOfAnnot"; public static final String ARRAYFSWITHSUBTYPE_TYPE_FEAT_Q = ARRAYFSWITHSUBTYPE_TYPE + TypeSystem.FEATURE_SEPARATOR + ARRAYFSWITHSUBTYPE_TYPE_FEAT; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; // public static final String INT_ARRAY_SUB = "IntArraySub"; public static final String INT_SUB_NAME = "intArrayName"; public static final String LEMMA_FEAT = "lemma"; public static final String LEMMA_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + LEMMA_FEAT; public static final String SENT_LEN_FEAT = "sentenceLength"; public static final String SENT_LEN_FEAT_Q = SENT_TYPE + TypeSystem.FEATURE_SEPARATOR + SENT_LEN_FEAT; public static final String TOKEN_FLOAT_FEAT = "tokenFloatFeat"; public static final String TOKEN_FLOAT_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_FLOAT_FEAT; public static final String LEMMA_LIST_FEAT = "lemmaList"; public static final String LEMMA_LIST_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + LEMMA_LIST_FEAT; public static final String LANG_PAIR = "org.apache.lang.LanguagePair"; public static final String LANG1 = "lang1"; public static final String LANG2 = "lang2"; public static final String DESCR_FEAT = "description"; public static final String GROUP_1 = "org.apache.lang.Group1"; public static final String GROUP_2 = "org.apache.lang.Group2"; public static final String[] GROUP_1_LANGUAGES = { "Chinese", "Japanese", "Korean", "English", "French", "German", "Italian", "Spanish", "Portuguese" }; public static final String[] GROUP_2_LANGUAGES = { "Arabic", "Czech", "Danish", "Dutch", "Finnish", "Greek", "Hebrew", "Hungarian", "Norwegian", "Polish", "Portuguese", "Russian", "Turkish" }; // Index name constants. public static final String ANNOT_SET_INDEX = "Annotation Set Index"; public static final String ANNOT_BAG_INDEX = "Annotation Bag Index"; public static final String ANNOT_SORT_INDEX = "Annotation Sort Index"; /** * Constructor for CASTestSetup. */ public CASTestSetup() { super(); } /** * @see org.apache.uima.cas.test.AnnotatorInitializer#initTypeSystem(TypeSystemMgr) */ /* Types: * TOP * Token TOKEN_TYPE * Word * Separator * EndOfSentence * ArrayFSwithSubtype * Annotation * Sentence * */ public void initTypeSystem(TypeSystemMgr tsm) { // Add new types and features. Type topType = tsm.getTopType(); Type annotType = tsm.getType(CAS.TYPE_NAME_ANNOTATION); // assert(annotType != null); tsm.addType(SENT_TYPE, annotType); Type tokenType = tsm.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsm.addType(TOKEN_TYPE_TYPE, topType); tsm.addType(WORD_TYPE, tokenTypeType); Type arrayFsWithSubtypeType = tsm.addType(ARRAYFSWITHSUBTYPE_TYPE, topType); Type arrayOfAnnot = tsm.getArrayType(annotType); tsm.addFeature(ARRAYFSWITHSUBTYPE_TYPE_FEAT, arrayFsWithSubtypeType, arrayOfAnnot); tsm.addType(SEP_TYPE, tokenTypeType); tsm.addType(EOS_TYPE, tokenTypeType); tsm.addFeature(TOKEN_TYPE_FEAT, tokenType, tokenTypeType); tsm.addFeature(TOKEN_FLOAT_FEAT, tokenType, tsm.getType(CAS.TYPE_NAME_FLOAT)); // Add a type that inherits from IntArray. // tsm.addType(INT_ARRAY_SUB, tsm.getType(CAS.TYPE_NAME_INTEGER_ARRAY)); // tsm.addFeature( // INT_SUB_NAME, // tsm.getType(INT_ARRAY_SUB), // tsm.getType(CAS.TYPE_NAME_STRING)); tsm.addFeature(LEMMA_FEAT, tokenType, tsm.getType(CAS.TYPE_NAME_STRING)); tsm.addFeature(SENT_LEN_FEAT, tsm.getType(SENT_TYPE), tsm.getType(CAS.TYPE_NAME_INTEGER)); tsm.addFeature(LEMMA_LIST_FEAT, tsm.getType(TOKEN_TYPE), tsm .getType(CAS.TYPE_NAME_STRING_ARRAY)); Type group1 = tsm.addStringSubtype(GROUP_1, GROUP_1_LANGUAGES); Type group2 = tsm.addStringSubtype(GROUP_2, GROUP_2_LANGUAGES); Type langPair = tsm.addType(LANG_PAIR, topType); tsm.addFeature(LANG1, langPair, group1); tsm.addFeature(LANG2, langPair, group2); Type stringType = tsm.getType(CAS.TYPE_NAME_STRING); tsm.addFeature(DESCR_FEAT, langPair, stringType); boolean exc = false; try { tsm.addType("some.new.Name", group1); } catch (CASAdminException e) { TestCase.assertTrue(e.getError() == CASAdminException.TYPE_IS_INH_FINAL); exc = true; } TestCase.assertTrue(exc); exc = false; try { tsm.addFeature("some.new.Name", group1, stringType); } catch (CASAdminException e) { TestCase.assertTrue(e.getError() == CASAdminException.TYPE_IS_FEATURE_FINAL); exc = true; } TestCase.assertTrue(exc); } public void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts) { FSIndexComparator comp = irm.createComparator(); Type annotation = ts.getType(CAS.TYPE_NAME_ANNOTATION); comp.setType(annotation); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_BEGIN), FSIndexComparator.STANDARD_COMPARE); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END), FSIndexComparator.REVERSE_STANDARD_COMPARE); LinearTypeOrderBuilder tob = irm.createTypeSortOrder(); try { tob.add(new String[] { CAS.TYPE_NAME_ANNOTATION, SENT_TYPE, TOKEN_TYPE }); comp.addKey(tob.getOrder(), FSIndexComparator.STANDARD_COMPARE); } catch (CASException e) { TestCase.assertTrue(false); } irm.createIndex(comp, ANNOT_BAG_INDEX, FSIndex.BAG_INDEX); irm.createIndex(comp, ANNOT_SET_INDEX, FSIndex.SET_INDEX); irm.createIndex(comp, ANNOT_SORT_INDEX, FSIndex.SORTED_INDEX); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TestAnnotator.java0000644000175000017500000000301111665471060027401 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.analysis_component.CasAnnotator_ImplBase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FeatureStructure; /** * Annotator for CAS test cases. Does nothing. Its only purpose is to load a type system and * provide a CAS for testing. */ public class TestAnnotator extends CasAnnotator_ImplBase { public TestAnnotator() { super(); } public void process(CAS cas) { FeatureStructure fs = cas.createFS(cas.getTypeSystem().getType(CAS.TYPE_NAME_ANNOTATION_BASE)); cas.addFsToIndexes(fs); fs = cas.createFS(cas.getTypeSystem().getType("OtherAnnotation")); cas.addFsToIndexes(fs); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/FloatArrayFSTest.java0000644000175000017500000000775211665471060027751 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FloatArrayFS; public class FloatArrayFSTest extends TestCase { private CAS cas; /** * Constructor for ArrayFSTest. * * @param arg0 */ public FloatArrayFSTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); } catch (Exception e) { assertTrue(false); } } public void tearDown() { this.cas = null; } public static void main(String[] args) { junit.textui.TestRunner.run(FloatArrayFSTest.class); } public void testSet() { FloatArrayFS array = this.cas.createFloatArrayFS(0); assertTrue(array != null); assertTrue(array.size() == 0); boolean exceptionCaught = false; try { array.get(0); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); array = this.cas.createFloatArrayFS(3); try { array.set(0, 1.0f); array.set(1, 2.0f); array.set(2, 3.0f); } catch (ArrayIndexOutOfBoundsException e) { assertTrue(false); } exceptionCaught = false; try { array.set(-1, 1.0f); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.set(4, 1.0f); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); assertTrue(array.get(0) == 1f); assertTrue(array.get(1) == 2f); assertTrue(array.get(2) == 3f); exceptionCaught = false; try { array.get(-1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.get(4); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); // Check that we can't create arrays smaller than 0. exceptionCaught = false; try { array = this.cas.createFloatArrayFS(-1); } catch (CASRuntimeException e) { exceptionCaught = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_ARRAY_SIZE)); } assertTrue(exceptionCaught); } public void testToArray() { // From CAS array to Java array. FloatArrayFS array = this.cas.createFloatArrayFS(3); float[] fsArray = array.toArray(); for (int i = 0; i < 3; i++) { assertTrue(fsArray[i] == 0f); } array.set(0, 1f); array.set(1, 2f); array.set(2, 3f); fsArray = array.toArray(); assertTrue(fsArray.length == 3); assertTrue(fsArray[0] == 1f); assertTrue(fsArray[1] == 2f); assertTrue(fsArray[2] == 3f); // From Java array to CAS array. array = this.cas.createFloatArrayFS(3); assertTrue(array.get(0) == 0f); assertTrue(array.get(1) == 0f); assertTrue(array.get(2) == 0f); for (int i = 0; i < 3; i++) { array.set(i, fsArray[i]); } assertTrue(array.get(0) == 1f); assertTrue(array.get(1) == 2f); assertTrue(array.get(2) == 3f); array.set(0, 0f); assertTrue(array.get(0) == 0f); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/ArrayFSTest.java0000644000175000017500000001756411665471060026765 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; public class ArrayFSTest extends TestCase { private CAS cas; private TypeSystem ts; /** * Constructor for ArrayFSTest. * * @param arg0 */ public ArrayFSTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); this.ts = this.cas.getTypeSystem(); } catch (Exception e) { assertTrue(false); } } public void tearDown() { this.cas = null; this.ts = null; } public static void main(String[] args) { junit.textui.TestRunner.run(ArrayFSTest.class); } public void testSet() { // Check that we can't create arrays of size smaller than 0. boolean exceptionCaught = false; try { ArrayFS array = this.cas.createArrayFS(-1); assertTrue(array != null); } catch (CASRuntimeException e) { exceptionCaught = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_ARRAY_SIZE)); } assertTrue(exceptionCaught); ArrayFS array = this.cas.createArrayFS(0); assertTrue(array.size() == 0); assertTrue(array != null); assertTrue(array.size() == 0); exceptionCaught = false; try { array.get(0); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); FeatureStructure fs1 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_ANNOTATION)); FeatureStructure fs2 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_TOP)); FeatureStructure fs3 = this.cas.createFS(this.ts.getType(CASTestSetup.TOKEN_TYPE)); array = this.cas.createArrayFS(3); try { array.set(0, fs1); array.set(1, fs2); array.set(2, fs3); String[] stringArray = array.toStringArray(); assertTrue(stringArray.length == 3); for (int i = 0; i < array.size(); i++) { assertNotNull(stringArray[i]); } } catch (ArrayIndexOutOfBoundsException e) { assertTrue(false); } exceptionCaught = false; try { array.set(-1, fs1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.set(4, fs1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); assertTrue(array.get(0).equals(fs1)); assertTrue(array.get(1).equals(fs2)); assertTrue(array.get(2).equals(fs3)); exceptionCaught = false; try { array.get(-1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.get(4); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); } public void testToArray() { // From CAS array to Java array. FeatureStructure fs1 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_ANNOTATION)); FeatureStructure fs2 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_TOP)); FeatureStructure fs3 = this.cas.createFS(this.ts.getType(CASTestSetup.TOKEN_TYPE)); ArrayFS array = this.cas.createArrayFS(3); FeatureStructure[] fsArray = array.toArray(); for (int i = 0; i < 3; i++) { assertTrue(fsArray[i] == null); } array.set(0, fs1); array.set(1, fs2); array.set(2, fs3); fsArray = array.toArray(); assertTrue(fsArray.length == 3); assertTrue(fsArray[0].equals(fs1)); assertTrue(fsArray[1].equals(fs2)); assertTrue(fsArray[2].equals(fs3)); // From Java array to CAS array. array = this.cas.createArrayFS(3); assertTrue(array.get(0) == null); assertTrue(array.get(1) == null); assertTrue(array.get(2) == null); for (int i = 0; i < 3; i++) { array.set(i, fsArray[i]); } assertTrue(array.get(0).equals(fs1)); assertTrue(array.get(1).equals(fs2)); assertTrue(array.get(2).equals(fs3)); array.set(0, null); assertTrue(array.get(0) == null); } public void testCopyToArray() { FeatureStructure fs1 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_ANNOTATION)); FeatureStructure fs2 = this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_TOP)); FeatureStructure fs3 = this.cas.createFS(this.ts.getType(CASTestSetup.TOKEN_TYPE)); ArrayFS array = this.cas.createArrayFS(4); array.set(0, fs1); array.set(1, fs2); array.set(2, fs3); // We now have an FS array with the last element being null final int destinationOffset = 2; final int destiniationSize = 10; FeatureStructure[] fsArray = new FeatureStructure[destiniationSize]; String[] stringArray = new String[destiniationSize]; // Copy to array, skipping first element // This must not throw an NPE, see UIMA-726 array.copyToArray(1, fsArray, destinationOffset, array.size() - 1); array.copyToArray(1, stringArray, destinationOffset, array.size() - 1); assertTrue(fs2.equals(fsArray[destinationOffset])); assertTrue(fs3.equals(fsArray[destinationOffset+1])); assertNotNull(stringArray[destinationOffset]); assertNotNull(stringArray[destinationOffset+1]); for (int i = 0; i < destinationOffset; i++) { assertNull(fsArray[i]); assertNull(stringArray[i]); } for (int i = (destinationOffset + 2); i < destiniationSize; i++) { assertNull(fsArray[i]); assertNull(stringArray[i]); } } public void testArraysOfArrays() { Type annotationType = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); AnnotationFS annot = this.cas.createAnnotation(annotationType, 0, 5); IntArrayFS intArray = this.cas.createIntArrayFS(3); intArray.set(0, 1); intArray.set(1, 2); intArray.set(2, -10); ArrayFS subArray1 = this.cas.createArrayFS(1); ArrayFS subArray2 = this.cas.createArrayFS(2); subArray1.set(0, subArray2); subArray2.set(1, annot); ArrayFS superArray = this.cas.createArrayFS(3); superArray.set(0, subArray1); superArray.set(1, subArray2); superArray.set(2, intArray); assertTrue(superArray.get(0).equals(subArray1)); assertTrue(superArray.get(1).equals(subArray2)); assertTrue(superArray.get(2).equals(intArray)); assertTrue(((ArrayFS) superArray.get(0)).get(0).equals(subArray2)); assertTrue(((ArrayFS) superArray.get(1)).get(0) == null); assertTrue(((ArrayFS) superArray.get(1)).get(1).equals(annot)); assertTrue(((IntArrayFS) superArray.get(2)).get(0) == 1); assertTrue(((IntArrayFS) superArray.get(2)).get(1) == 2); assertTrue(((IntArrayFS) superArray.get(2)).get(2) == -10); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorTest.java0000644000175000017500000001032011665471060027740 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.impl.UnambiguousIteratorImpl; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas.text.AnnotationIndex; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.FileUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Class comment for IteratorTest.java goes here. * */ public class SubiteratorTest extends TestCase { private AnalysisEngine ae = null; public SubiteratorTest(String arg0) { super(arg0); } public void setUp() { File descriptorFile = JUnitExtension.getFile("CASTests/desc/TokensAndSentences.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile .exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); this.ae = UIMAFramework.produceAnalysisEngine(spec); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } } public void tearDown() { if (this.ae != null) { this.ae.destroy(); this.ae = null; } } public void testAnnotator() { File textFile = JUnitExtension.getFile("CASTests/verjuice.txt"); String text = null; try { text = FileUtils.file2String(textFile, "utf-8"); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } JCas jcas = null; try { jcas = this.ae.newJCas(); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } jcas.setDocumentText(text); try { this.ae.process(jcas); AnnotationIndex tokenIndex = jcas.getAnnotationIndex(jcas.getCasType(Token.type)); Annotation sentence = jcas.getAnnotationIndex(jcas.getCasType(Sentence.type)).iterator().next(); FSIterator tokenIterator = tokenIndex.subiterator(sentence); Annotation token = tokenIndex.iterator().next(); tokenIterator.moveTo(token); //throws ClassCastException UnambiguousIteratorImpl it = new UnambiguousIteratorImpl(tokenIndex.iterator()); it.moveTo(token); } catch (AnalysisEngineProcessException e) { e.printStackTrace(); assertTrue(false); } catch (ClassCastException e) { // UIMA-464: Subiterator.moveTo() throws ClassCastException. assertTrue(false); } } public static void main(String[] args) { junit.textui.TestRunner.run(SubiteratorTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TypeOrderTest.java0000644000175000017500000002112511665471060027357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.LinearTypeOrderBuilder; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.FileCompare; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; public class TypeOrderTest extends TestCase { // Index name constants. public static final String ANNOT_SET_INDEX = "Annotation Set Index"; public static final String ANNOT_BAG_INDEX = "Annotation Bag Index"; public static final String TYPE_ORDER_INDEX = "TypeOrderIndex"; public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; // private CASMgr casMgr; private CAS cas; private Type annotationType; private Type tokenType; private Type sentenceType; public TypeOrderTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); // this.casMgr = initCAS(); File descriptorFile = JUnitExtension.getFile("CASTests/desc/typePriorityTestCaseDescriptor.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile.exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(spec); this.cas = ae.newCAS(); assertTrue(this.cas != null); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } TypeSystem ts = this.cas.getTypeSystem(); // assert(wordType != null); this.tokenType = ts.getType(TOKEN_TYPE); this.sentenceType = ts.getType(SENT_TYPE); this.annotationType = ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(this.annotationType != null); } public void tearDown() { // this.casMgr = null; this.cas = null; this.tokenType = null; this.sentenceType = null; this.annotationType = null; } // Initialize the first CAS. public void testInitCAS() { // Create a CASMgr. Ensures existence of AnnotationFS type. CASMgr cas1 = CASFactory.createCAS(); // Create a writable type system. TypeSystemMgr tsa = cas1.getTypeSystemMgr(); // Add new types and features. Type topType = tsa.getTopType(); Type annotType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); // assert(annotType != null); tsa.addType(SENT_TYPE, annotType); tsa.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsa.addType(TOKEN_TYPE_TYPE, topType); tsa.addType(WORD_TYPE, tokenTypeType); tsa.addType(SEP_TYPE, tokenTypeType); tsa.addType(EOS_TYPE, tokenTypeType); // Commit the type system. ((CASImpl) cas1).commitTypeSystem(); // Create the Base indexes. try { cas1.initCASIndexes(); } catch (CASException e2) { e2.printStackTrace(); assertTrue(false); } FSIndexRepositoryMgr irm = cas1.getIndexRepositoryMgr(); // Check that appropriate exception is thrown on unknown types. LinearTypeOrderBuilder order = irm.createTypeSortOrder(); boolean excCaught = false; try { order.add(new String[] { "foo", "bar" }); order.getOrder(); } catch (NullPointerException e) { assertTrue(false); } catch (CASException e) { excCaught = true; } assertTrue(excCaught); // Create an alternative annotation index using a type sort order. order = irm.createTypeSortOrder(); try { order.add(new String[] { TOKEN_TYPE, SENT_TYPE, CAS.TYPE_NAME_ANNOTATION }); order.getOrder(); } catch (CASException e) { assertTrue(false); } } /** * Test driver. */ public void testMain() throws Exception { File refFile = JUnitExtension.getFile("CASTests/CasTypeOrderTestRef.txt"); Assert.assertNotNull(refFile); File outputFile = new File(JUnitExtension.getFile("CASTests"), "CasTypeOderTest_testouput.txt"); OutputStreamWriter fileWriter = new OutputStreamWriter(new FileOutputStream( outputFile , false), "UTF-8"); Assert.assertNotNull(fileWriter); for (int i = 0; i < 10; i++) { this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); } for (int i = 19; i >= 10; i--) { this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS(this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); } FSIterator it = this.cas.getIndexRepository().getIndex(TYPE_ORDER_INDEX).iterator(); // it = cas.getAnnotationIndex().iterator(); AnnotationFS fs; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { fs = (AnnotationFS) it.get(); fileWriter.write( fs.getType().getName() + ": " + fs.getBegin() + " - " + fs.getEnd() + "\n"); } fileWriter.close(); //System.out.println(refFile.getAbsolutePath()); //System.out.println(outputFile.getAbsolutePath()); Assert.assertTrue("Comparing ref " + refFile.getAbsolutePath() + " and output " + outputFile.getAbsolutePath(), FileCompare.compare(refFile, outputFile)); } public static void main(String[] args) { junit.textui.TestRunner.run(TypeOrderTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TypeSystemTest.java0000644000175000017500000005012011665471060027565 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.TypeSystem2Xml; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; import org.xml.sax.SAXException; /** * Class comment for TypeSystemTest.java goes here. * */ public class TypeSystemTest extends TestCase { private class SetupTest implements AnnotatorInitializer { /** * @see org.apache.uima.cas.test.AnnotatorInitializer#initTypeSystem(org.apache.uima.cas.admin.TypeSystemMgr) */ public void initTypeSystem(TypeSystemMgr tsm) { // /////////////////////////////////////////////////////////////////////// // Check type names. boolean exc = false; Type annot = tsm.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(annot != null); // Check for some illegal characters in type names. try { tsm.addType("TestWithADash-", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; try { tsm.addType("test.with.a.slash/", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; // Check for empty identifiers (period at beginning or end, two or // more // periods in a row). try { tsm.addType("test.empty.identifier.", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; try { tsm.addType(".test.empty.identifier", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; try { tsm.addType("test.empty..identifier", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; // Test underscore behavior (leading underscores are out, other ones // in). try { tsm.addType("test._leading.Underscore", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertTrue(exc); exc = false; try { tsm.addType("test_embedded.Under__Score", annot); } catch (CASAdminException e) { assertTrue(e.getError() == CASAdminException.BAD_TYPE_SYNTAX); exc = true; } assertFalse(exc); exc = false; // Test (un)qualified names. String qualName = "this.is.a.NameTestType"; String shortName = "NameTestType"; Type nameTest = tsm.addType(qualName, annot); assertTrue(nameTest != null); assertTrue(qualName.equals(nameTest.getName())); assertTrue(shortName.equals(nameTest.getShortName())); // /////////////////////////////////////////////////////////////////////// // Test features (names and inheritance // Set up: add two new annotation types, one inheriting from the // other. Type annot1 = tsm.addType("Annot1", annot); assertTrue(annot1 != null); String annot2name = "Annot2"; Type annot2 = tsm.addType(annot2name, annot1); assertTrue(annot2 != null); // Another name test. assertTrue(annot1.getName().equals(annot1.getShortName())); String annot3name = "Annot3"; Type annot3 = tsm.addType(annot3name, annot2); assertTrue(annot3 != null); // Check for bug reported by Marshall: feature names can not be // retrieved // by name on types more than one level removed from the introducing // type. assertTrue(tsm.getFeatureByFullName(annot2name + TypeSystem.FEATURE_SEPARATOR + CAS.FEATURE_BASE_NAME_BEGIN) != null); String inhTestFeat = "inhTestFeat"; tsm.addFeature(inhTestFeat, annot1, nameTest); assertTrue(tsm.getFeatureByFullName(annot2name + TypeSystem.FEATURE_SEPARATOR + inhTestFeat) != null); // Test illegal feature names. Feature feat = null; try { feat = tsm.addFeature("_testLeadingUnderscore", annot1, annot); } catch (CASAdminException e) { exc = true; } assertTrue(exc); exc = false; try { feat = tsm.addFeature("test space", annot1, annot); } catch (CASAdminException e) { exc = true; } assertTrue(exc); exc = false; try { feat = tsm.addFeature("test.Qualified:name", annot1, annot); } catch (CASAdminException e) { exc = true; } assertTrue(exc); exc = false; // Now actually create a feature. String featName = "testInheritanceFeat"; try { feat = tsm.addFeature(featName, annot2, annot); } catch (CASAdminException e) { assertTrue(false); } assertTrue(feat != null); // Check that a feature of the same name can not be created on a // supertype. Feature feat2 = null; try { feat2 = tsm.addFeature(featName, annot1, annot); } catch (CASAdminException e) { e.printStackTrace(); assertTrue(false); } assertTrue(feat2 == null); // Check that a feature of the same name can not be created on a // subtype. /* * Test commented out with defect 3351: it's ok to want to create the same feature on a * subtype. try { feat2 = tsm.addFeature(featName, annot3, annot); } catch (CASAdminException * e) { assertTrue(false); } assertTrue(feat2 == null); */ // Check that trying to create the same feature on a subtype with a // different // range type will raise an exception. exc = false; try { feat2 = tsm.addFeature(featName, annot2, annot2); } catch (CASAdminException e) { exc = true; assertTrue(e.getError() == CASAdminException.DUPLICATE_FEATURE); } assertTrue(exc); // Check that a feature of the same name _can_ be created on a // different // type. String annot4Name = "Annot4"; Type annot4 = tsm.addType(annot4Name, annot); assertTrue(annot4 != null); feat = tsm.addFeature(featName, annot4, annot1); assertTrue(feat != null); assertTrue(featName.equals(feat.getShortName())); assertTrue(feat.getName().equals(annot4Name + TypeSystem.FEATURE_SEPARATOR + featName)); // Check that we can't add features to top, inherit from arrays etc. Type top = tsm.getTopType(); Type intT = tsm.getType(CAS.TYPE_NAME_INTEGER); exc = false; try { tsm.addFeature("testFeature", top, intT); } catch (CASAdminException e) { exc = true; assertTrue(e.getError() == CASAdminException.TYPE_IS_FEATURE_FINAL); } assertTrue(exc); exc = false; try { tsm.addFeature("testFeature", intT, intT); } catch (CASAdminException e) { exc = true; assertTrue(e.getError() == CASAdminException.TYPE_IS_FEATURE_FINAL); } assertTrue(exc); exc = false; try { tsm.addType("newType", intT); } catch (CASAdminException e) { exc = true; assertTrue(e.getError() == CASAdminException.TYPE_IS_INH_FINAL); } assertTrue(exc); exc = false; try { tsm.addType("newType", tsm.getType(CAS.TYPE_NAME_FLOAT_ARRAY)); } catch (CASAdminException e) { exc = true; assertTrue(e.getError() == CASAdminException.TYPE_IS_INH_FINAL); } assertTrue(exc); } /** * @see org.apache.uima.cas.test.AnnotatorInitializer#initIndexes(org.apache.uima.cas.admin.FSIndexRepositoryMgr, * org.apache.uima.cas.TypeSystem) */ public void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ats) { // Do nothing for the purposes of this test. } } private CAS cas; private TypeSystem ts; /** * Constructor for TypeSystemTest. * * @param arg0 */ public TypeSystemTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); try { this.cas = CASInitializer.initCas(new CASTestSetup()); this.ts = this.cas.getTypeSystem(); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } public void tearDown() { this.cas = null; this.ts = null; } public void testNameChecking() { CAS tcas = CASInitializer.initCas(new SetupTest()); assertTrue(tcas != null); } public void testGetParent() { assertTrue(this.ts.getParent(this.ts.getType(CAS.TYPE_NAME_TOP)) == null); Type annotBase = this.ts.getType(CAS.TYPE_NAME_ANNOTATION_BASE); assertTrue(this.ts.getParent(annotBase) == this.ts.getTopType()); Type annot = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(this.ts.getParent(annot) == this.ts.getType(CAS.TYPE_NAME_ANNOTATION_BASE)); assertTrue(this.ts.getParent(this.ts.getType(CASTestSetup.TOKEN_TYPE)) == annot); } public void testGetType() { Type top = this.ts.getTopType(); assertTrue(top != null); assertTrue(top.getName().equals(CAS.TYPE_NAME_TOP)); Type annot = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(annot != null); Type token = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(token != null); } /* * Test for Feature getFeature(String) */ public void testGetFeature() { Type annot = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); Feature start = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); Feature end = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_END); Type integer = this.ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(start.getDomain() == annot); assertTrue(end.getDomain() == annot); assertTrue(start.getRange() == integer); assertTrue(end.getRange() == integer); Feature start1 = annot.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_BEGIN); assertTrue(start == start1); Feature start2 = this.ts.getType(CASTestSetup.TOKEN_TYPE).getFeatureByBaseName( CAS.FEATURE_BASE_NAME_BEGIN); assertTrue(start == start2); } public void testGetTypeIterator() { Iterator it = this.ts.getTypeIterator(); // Put the type names in a vector and do some spot checks. ArrayList v = new ArrayList(); while (it.hasNext()) { v.add(it.next().getName()); } assertTrue(v.contains(CAS.TYPE_NAME_TOP)); assertTrue(v.contains(CAS.TYPE_NAME_FLOAT)); assertTrue(v.contains(CAS.TYPE_NAME_FS_ARRAY)); assertTrue(v.contains(CAS.TYPE_NAME_ANNOTATION)); assertTrue(v.contains(CASTestSetup.SENT_TYPE)); } public void testGetFeatures() { Iterator it = this.ts.getFeatures(); // Put feature names in vector and test for some known features. List v = new ArrayList(); while (it.hasNext()) { v.add(it.next().getName()); } String annotPrefix = CAS.TYPE_NAME_ANNOTATION + TypeSystem.FEATURE_SEPARATOR; String arrayPrefix = CAS.TYPE_NAME_ARRAY_BASE + TypeSystem.FEATURE_SEPARATOR; assertTrue(arrayPrefix != null); String tokenPrefix = CASTestSetup.TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR; assertTrue(v.contains(annotPrefix + CAS.FEATURE_BASE_NAME_BEGIN)); assertTrue(v.contains(annotPrefix + CAS.FEATURE_BASE_NAME_END)); assertTrue(v.contains(tokenPrefix + CASTestSetup.TOKEN_TYPE_FEAT)); // assertTrue(v.contains(arrayPrefix + CAS.ARRAY_LENGTH_FEAT)); } public void testGetTopType() { Type top = this.ts.getTopType(); assertTrue(top != null); assertTrue(top.getName().equals(CAS.TYPE_NAME_TOP)); } public void testGetDirectlySubsumedTypes() { List subTypes = this.ts.getDirectSubtypes(this.ts.getType(CAS.TYPE_NAME_TOP)); Type intType = this.ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(subTypes.contains(intType)); Type annotBaseType = this.ts.getType(CAS.TYPE_NAME_ANNOTATION_BASE); assertTrue(subTypes.contains(annotBaseType)); Type annotType = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(!subTypes.contains(annotType)); Type tokenType = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(!subTypes.contains(tokenType)); } /* * Test for boolean subsumes(Type, Type) */ public void testSubsumes() { Type top = this.ts.getTopType(); Type intType = this.ts.getType(CAS.TYPE_NAME_INTEGER); Type annotType = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); Type tokenType = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(this.ts.subsumes(top, intType)); assertTrue(this.ts.subsumes(top, annotType)); assertTrue(this.ts.subsumes(top, tokenType)); assertTrue(this.ts.subsumes(annotType, tokenType)); assertTrue(!this.ts.subsumes(tokenType, annotType)); assertTrue(!this.ts.subsumes(tokenType, top)); } /** * Test presence of builtin types and their properties. */ public void testBuiltinTypes() { assertTrue(this.cas.getTypeSystem().getType(CAS.TYPE_NAME_FLOAT).isInheritanceFinal()); assertTrue(this.cas.getTypeSystem().getType(CAS.TYPE_NAME_FLOAT).isFeatureFinal()); assertTrue(this.cas.getTypeSystem().getTopType().isFeatureFinal()); assertFalse(this.cas.getTypeSystem().getTopType().isInheritanceFinal()); } /** * Test creation of type system with static [T]CASFactory methods. */ public void testCreateTypeSystem() { // Test creation of CAS type system. TypeSystemMgr tsMgr = CASFactory.createTypeSystem(); Type top = tsMgr.getTopType(); assertNotNull(top); assertTrue(tsMgr.getType(CAS.TYPE_NAME_FLOAT).isInheritanceFinal()); assertTrue(tsMgr.getType(CAS.TYPE_NAME_FLOAT).isFeatureFinal()); assertTrue(tsMgr.getTopType().isFeatureFinal()); assertFalse(tsMgr.getTopType().isInheritanceFinal()); Type someType = tsMgr.addType("some.type", top); assertNotNull(someType); } /** * Test array types. * */ public void testArrayTypes() { // Our version of object arrays. Type is built-in and has special name, // for backwards compatibility. Type fsArrayType = this.ts.getType(CAS.TYPE_NAME_FS_ARRAY); assertNotNull(fsArrayType); assertTrue(fsArrayType.isArray()); assertNotNull(fsArrayType.getComponentType()); assertTrue(fsArrayType.getComponentType().equals(this.ts.getTopType())); assertTrue(fsArrayType.equals(this.ts.getArrayType(this.ts.getTopType()))); // Int arrays are also built-in, but are primitive-valued. Type intArrayType = this.ts.getType(CAS.TYPE_NAME_INTEGER_ARRAY); assertNotNull(intArrayType); assertTrue(intArrayType.isArray()); assertNotNull(intArrayType.getComponentType()); assertTrue(intArrayType.getComponentType().equals(this.ts.getType(CAS.TYPE_NAME_INTEGER))); assertTrue(intArrayType.equals(this.ts.getArrayType(this.ts.getType(CAS.TYPE_NAME_INTEGER)))); // Negative tests: make sure regular types are not classified as arrays. Type stringType = this.ts.getType(CAS.TYPE_NAME_STRING); assertFalse(stringType.isArray()); assertNull(stringType.getComponentType()); Type topType = this.ts.getTopType(); assertFalse(topType.isArray()); assertNull(topType.getComponentType()); // Create an array of arrays. Type intMatrix = this.ts.getArrayType(intArrayType); assertNotNull(intMatrix); assertTrue(intMatrix.isArray()); assertTrue(intMatrix.getComponentType().equals(intArrayType)); // Check array inheritance. Type annotationArray = this.ts.getArrayType(this.ts.getType(CAS.TYPE_NAME_ANNOTATION)); assertTrue(this.ts.subsumes(fsArrayType, annotationArray)); // assertFalse(this.ts.subsumes(annotationArray, fsArrayType)); } public void testSerializeTypeSystem() { File descriptorFile = JUnitExtension.getFile("CASTests/desc/arrayValueDescriptor.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile .exists()); TypeSystem typeSystem = null; try { XMLParser parser = UIMAFramework.getXMLParser(); AnalysisEngineDescription spec = (AnalysisEngineDescription) parser.parse(new XMLInputSource( descriptorFile)); typeSystem = UIMAFramework.produceAnalysisEngine(spec).newCAS().getTypeSystem(); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } ByteArrayOutputStream os = new ByteArrayOutputStream(); try { TypeSystem2Xml.typeSystem2Xml(typeSystem, os); } catch (SAXException e) { assertTrue(false); } catch (IOException e) { assertTrue(false); } try { os.close(); } catch (IOException e) { assertTrue(false); } InputStream is = new ByteArrayInputStream(os.toByteArray()); // System.out.println(os.toString()); XMLInputSource xis = new XMLInputSource(is, new File(".")); Object descriptor = null; try { descriptor = UIMAFramework.getXMLParser().parse(xis); } catch (InvalidXMLException e) { assertTrue(false); } // instantiate CAS to get type system. Also build style // map file if there is none. TypeSystemDescription tsDesc = (TypeSystemDescription) descriptor; try { tsDesc.resolveImports(); } catch (InvalidXMLException e) { assertTrue(false); } try { CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[] {}); } catch (ResourceInitializationException e) { assertTrue(false); } } public static void main(String[] args) { junit.textui.TestRunner.run(TypeSystemTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/FeatureStructureTest.java0000644000175000017500000003166111665471060030764 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.LowLevelTypeSystem; import org.apache.uima.cas.text.AnnotationFS; /** * Class comment for FeatureStructureTest.java goes here. * */ public class FeatureStructureTest extends TestCase { private CAS cas; private TypeSystem ts; private Type topType; private Type stringType; private Type tokenType; private Type intType; private Type tokenTypeType; private Type wordType; private Type arrayFsWithSubtypeType; private Feature arrayFsWithSubtypeTypeFeat; private Type group1Type; private Type group2Type; private Type langPairType; private Type neListType; private Feature lang1; private Feature lang2; private Feature descr; private Feature tokenTypeFeat; private Feature lemmaFeat; private Feature sentLenFeat; private Feature tokenFloatFeat; private Feature startFeature; private Feature tlFeature; private Feature hdFeature; /** * Constructor for FeatureStructureTest. * * @param arg0 */ public FeatureStructureTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); assertTrue(this.cas != null); this.ts = this.cas.getTypeSystem(); assertTrue(this.ts != null); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } this.topType = this.ts.getType(CAS.TYPE_NAME_TOP); assertTrue(this.topType != null); this.stringType = this.ts.getType(CAS.TYPE_NAME_STRING); assertTrue(this.stringType != null); this.tokenType = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(this.stringType != null); this.intType = this.ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(this.intType != null); this.tokenTypeType = this.ts.getType(CASTestSetup.TOKEN_TYPE_TYPE); assertTrue(this.tokenTypeType != null); this.wordType = this.ts.getType(CASTestSetup.WORD_TYPE); assertTrue(this.wordType != null); this.arrayFsWithSubtypeType = this.ts.getType(CASTestSetup.ARRAYFSWITHSUBTYPE_TYPE); assertTrue(this.arrayFsWithSubtypeType != null); this.arrayFsWithSubtypeTypeFeat = this.ts .getFeatureByFullName(CASTestSetup.ARRAYFSWITHSUBTYPE_TYPE_FEAT_Q); this.group1Type = this.ts.getType(CASTestSetup.GROUP_1); assertTrue(this.group1Type != null); this.group2Type = this.ts.getType(CASTestSetup.GROUP_2); assertTrue(this.group2Type != null); this.tokenTypeFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_TYPE_FEAT_Q); assertTrue(this.tokenTypeFeat != null); this.lemmaFeat = this.ts.getFeatureByFullName(CASTestSetup.LEMMA_FEAT_Q); assertTrue(this.lemmaFeat != null); this.sentLenFeat = this.ts.getFeatureByFullName(CASTestSetup.SENT_LEN_FEAT_Q); assertTrue(this.sentLenFeat != null); this.tokenFloatFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_FLOAT_FEAT_Q); assertTrue(this.tokenFloatFeat != null); this.startFeature = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); assertTrue(this.startFeature != null); this.langPairType = this.ts.getType(CASTestSetup.LANG_PAIR); assertTrue(this.langPairType != null); this.lang1 = this.langPairType.getFeatureByBaseName(CASTestSetup.LANG1); assertTrue(this.lang1 != null); this.lang2 = this.langPairType.getFeatureByBaseName(CASTestSetup.LANG2); assertTrue(this.lang2 != null); this.descr = this.langPairType.getFeatureByBaseName(CASTestSetup.DESCR_FEAT); assertTrue(this.descr != null); this.neListType = this.ts.getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST); assertTrue(this.neListType != null); this.tlFeature = this.neListType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_TAIL); assertTrue(this.tlFeature != null); this.hdFeature = this.neListType.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_HEAD); assertTrue(this.hdFeature != null); } public void tearDown() { this.cas = null; this.ts = null; this.topType = null; this.stringType = null; this.tokenType = null; this.intType = null; this.tokenTypeType = null; this.wordType = null; this.group1Type = null; this.group2Type = null; this.tokenTypeFeat = null; this.lemmaFeat = null; this.sentLenFeat = null; this.tokenFloatFeat = null; this.startFeature = null; this.langPairType = null; this.lang1 = null; this.lang2 = null; this.descr = null; } public void testGetType() { Type tokenType1 = this.ts.getType(CASTestSetup.TOKEN_TYPE); Type wordType1 = this.ts.getType(CASTestSetup.WORD_TYPE); FeatureStructure word = this.cas.createFS(wordType1); FeatureStructure token = this.cas.createFS(tokenType1); assertTrue(word.getType().equals(wordType1)); assertTrue(token.getType().equals(tokenType1)); } public void testSetArrayValuedFeature() { FeatureStructure testFS = this.cas.createFS(this.arrayFsWithSubtypeType); assertTrue(testFS.getFeatureValue(this.arrayFsWithSubtypeTypeFeat) == null); ArrayFS arrayFS = this.cas.createArrayFS(1); testFS.setFeatureValue(this.arrayFsWithSubtypeTypeFeat, arrayFS); assertTrue(true); boolean caughtExc = false; try { testFS.setFeatureValue(this.arrayFsWithSubtypeTypeFeat, testFS); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_RANGE)); } assertTrue(caughtExc); } public void testSetFeatureValue() { FeatureStructure token = this.cas.createFS(this.tokenType); assertTrue(token.getFeatureValue(this.tokenTypeFeat) == null); assertTrue(token.getStringValue(this.lemmaFeat) == null); boolean caughtExc = false; try { token.getFeatureValue(this.sentLenFeat); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_FEAT)); } assertTrue(caughtExc); FeatureStructure word = this.cas.createFS(this.wordType); token.setFeatureValue(this.tokenTypeFeat, word); caughtExc = false; try { token.setFeatureValue(this.lemmaFeat, word); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_RANGE)); } assertTrue(caughtExc); try { token.setFeatureValue(this.tokenTypeFeat, null); } catch (CASRuntimeException e) { assertTrue(false); } caughtExc = false; try { token.setFeatureValue(this.startFeature, null); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.PRIMITIVE_VAL_FEAT)); caughtExc = true; } assertTrue(caughtExc); assertTrue(token.getStringValue(this.lemmaFeat) == null); String testString = "test"; token.setStringValue(this.lemmaFeat, testString); assertTrue(token.getStringValue(this.lemmaFeat).equals(testString)); testString = ""; token.setStringValue(this.lemmaFeat, testString); assertTrue(token.getStringValue(this.lemmaFeat).equals(testString)); } public void testSetFloatValue() { AnnotationFS token = (AnnotationFS) this.cas.createFS(this.tokenType); assertTrue(token.getFloatValue(this.tokenFloatFeat) == 0.0f); float f = -3.2f; token.setFloatValue(this.tokenFloatFeat, f); assertTrue(token.getFloatValue(this.tokenFloatFeat) == f); f = 51234.132f; token.setFloatValue(this.tokenFloatFeat, f); assertTrue(token.getFloatValue(this.tokenFloatFeat) == f); boolean caughtExc = false; try { token.setFloatValue(this.tokenTypeFeat, 0.0f); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_RANGE)); } assertTrue(caughtExc); assertTrue(token.getFloatValue(this.tokenFloatFeat) == f); caughtExc = false; try { token.setFloatValue(this.sentLenFeat, 0.0f); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_FEAT)); } assertTrue(caughtExc); assertTrue(token.getFloatValue(this.tokenFloatFeat) == f); } public void testSetIntValue() { AnnotationFS token = (AnnotationFS) this.cas.createFS(this.tokenType); assertTrue(token.getIntValue(this.startFeature) == 0); int i = 3; token.setIntValue(this.startFeature, i); assertTrue(token.getIntValue(this.startFeature) == i); i = -123456; token.setIntValue(this.startFeature, i); assertTrue(token.getIntValue(this.startFeature) == i); boolean caughtExc = false; try { token.setIntValue(this.tokenTypeFeat, 0); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_RANGE)); } assertTrue(caughtExc); assertTrue(token.getIntValue(this.startFeature) == i); caughtExc = false; try { token.setIntValue(this.sentLenFeat, 0); } catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_FEAT)); } assertTrue(caughtExc); assertTrue(token.getIntValue(this.startFeature) == i); } public void testStrings() { FeatureStructure lp = this.cas.createFS(this.langPairType); assertTrue(lp != null); // Check that all strings are initially null. try { assertTrue(lp.getStringValue(this.lang1) == null); } catch (Exception e) { assertTrue(false); } try { assertTrue(lp.getStringValue(this.lang2) == null); } catch (Exception e) { assertTrue(false); } try { assertTrue(lp.getStringValue(this.descr) == null); } catch (Exception e) { assertTrue(false); } // FeatureStructure topFS = cas.createFS(topType); String val = "Some string."; try { lp.setStringValue(this.descr, val); assertTrue(val.equals(lp.getStringValue(this.descr))); } catch (CASRuntimeException e) { assertTrue(false); } try { lp.setStringValue(this.descr, null); assertTrue(lp.getStringValue(this.descr) == null); } catch (CASRuntimeException e) { assertTrue(false); } try { lp.setStringValue(this.lang1, CASTestSetup.GROUP_1_LANGUAGES[0]); lp.setStringValue(this.lang2, CASTestSetup.GROUP_2_LANGUAGES[2]); } catch (Exception e) { assertTrue(false); } boolean exc = false; try { lp.setStringValue(this.lang1, CASTestSetup.GROUP_2_LANGUAGES[0]); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_STRING_VALUE)); exc = true; } assertTrue(exc); exc = false; try { lp.setStringValue(this.lang2, val); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_STRING_VALUE)); exc = true; } assertTrue(exc); // Regression: toString() used to fail because string subtypes were // incorrectly classified as ref types. lp.toString(); LowLevelCAS llc = this.cas.getLowLevelCAS(); LowLevelTypeSystem llts = llc.ll_getTypeSystem(); final int tokenTypeCode = llts.ll_getCodeForType(this.tokenType); final int addr = llc.ll_createFS(tokenTypeCode); final int lemmaFeatCode = llts.ll_getCodeForFeature(this.lemmaFeat); llc.ll_setStringValue(addr, lemmaFeatCode, "test", true); assertTrue(llc.ll_getCharBufferValueSize(addr, lemmaFeatCode) == 4); } public void testEquals() { // ??? } public void testToString() { FeatureStructure listFS = this.cas.createFS(this.neListType); listFS.setFeatureValue(this.tlFeature, listFS); // System.out.println(listFS.toString()); FeatureStructure value = this.cas.createFS(this.tokenType); FeatureStructure newList = this.cas.createFS(this.neListType); newList.setFeatureValue(this.tlFeature, listFS); newList.setFeatureValue(this.hdFeature, value); listFS.setFeatureValue(this.hdFeature, value); // System.out.println("\n" + newList.toString()); } public static void main(String[] args) { junit.textui.TestRunner.run(FeatureStructureTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/TypeSystemUtilsTest.java0000644000175000017500000001034111665471060030607 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.TypeSystemUtils; import org.apache.uima.cas.impl.TypeSystemUtils.PathValid; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Class comment for IteratorTest.java goes here. * */ public class TypeSystemUtilsTest extends TestCase { private CAS cas; public TypeSystemUtilsTest(String arg0) { super(arg0); } public void setUp() { File descriptorFile = JUnitExtension.getFile("CASTests/desc/pathValidationTS.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile .exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); TypeSystemDescription spec = (TypeSystemDescription) parser.parse(new XMLInputSource( descriptorFile)); this.cas = CasCreationUtils.createCas(spec, null, new FsIndexDescription[] {}); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } } public void testPathValidation() { Type type1 = this.cas.getTypeSystem().getType("Type1"); // Type1, f0/begin, always List path = new ArrayList(); path.add("f0"); path.add("begin"); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.ALWAYS); // Type1, f1, possible path = new ArrayList(); path.add("f1"); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.POSSIBLE); // Type1, f1/tail/tail, possible path = new ArrayList(); path.add("f1"); path.add("tail"); path.add("tail"); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.POSSIBLE); // Type1, f2, possible path = new ArrayList(); path.add("f2"); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.POSSIBLE); // Type1, nosuchfeature, never path = new ArrayList(); path.add("nosuchfeature"); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.NEVER); // Type1, , always path = new ArrayList(); assertTrue(TypeSystemUtils.isPathValid(type1, path) == PathValid.ALWAYS); // t1, f1/f2/f3, always Type t1 = this.cas.getTypeSystem().getType("t1"); path = new ArrayList(); path.add("f1"); path.add("f2"); path.add("f3"); assertTrue(TypeSystemUtils.isPathValid(t1, path) == PathValid.ALWAYS); } public void tearDown() { this.cas = null; } public static void main(String[] args) { junit.textui.TestRunner.run(TypeSystemUtilsTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotatorInitializer.java0000644000175000017500000000243011665471060030751 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; /** * Implement this interface to create types, features and indexes. Use in conjunction with * CASInitializer. */ public interface AnnotatorInitializer { void initTypeSystem(TypeSystemMgr tsm); void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts); } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/StringSubtypeAnnotation_Type.java0000644000175000017500000000753011665471060032464 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Fri Dec 22 14:02:31 CET 2006 */ package org.apache.uima.cas.test; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation_Type; /** * Updated by JCasGen Fri Dec 22 14:02:31 CET 2006 * @generated */ public class StringSubtypeAnnotation_Type extends Annotation_Type { /** @generated */ protected FSGenerator getFSGenerator() {return fsGenerator;} /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (StringSubtypeAnnotation_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = StringSubtypeAnnotation_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new StringSubtypeAnnotation(addr, StringSubtypeAnnotation_Type.this); StringSubtypeAnnotation_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new StringSubtypeAnnotation(addr, StringSubtypeAnnotation_Type.this); } }; /** @generated */ public final static int typeIndexID = StringSubtypeAnnotation.typeIndexID; /** @generated @modifiable */ public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("org.apache.uima.cas.test.StringSubtypeAnnotation"); /** @generated */ final Feature casFeat_stringSetFeature; /** @generated */ final int casFeatCode_stringSetFeature; /** @generated */ public String getStringSetFeature(int addr) { if (featOkTst && casFeat_stringSetFeature == null) this.jcas.throwFeatMissing("stringSetFeature", "org.apache.uima.cas.test.StringSubtypeAnnotation"); return ll_cas.ll_getStringValue(addr, casFeatCode_stringSetFeature); } /** @generated */ public void setStringSetFeature(int addr, String v) { if (featOkTst && casFeat_stringSetFeature == null) this.jcas.throwFeatMissing("stringSetFeature", "org.apache.uima.cas.test.StringSubtypeAnnotation"); ll_cas.ll_setStringValue(addr, casFeatCode_stringSetFeature, v);} /** initialize variables to correspond with Cas Type and Features * @generated */ public StringSubtypeAnnotation_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl)this.casType, getFSGenerator()); casFeat_stringSetFeature = jcas.getRequiredFeatureDE(casType, "stringSetFeature", "org.apache.uima.cas.test.StringSubtype", featOkTst); casFeatCode_stringSetFeature = (null == casFeat_stringSetFeature) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl)casFeat_stringSetFeature).getCode(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/GetAllIndexedTest.java0000644000175000017500000001707411665471060030123 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; public class GetAllIndexedTest extends TestCase { // Index name constants. public static final String ANNOT_SET_INDEX = "Annotation Set Index"; public static final String ANNOT_BAG_INDEX = "Annotation Bag Index"; public static final String TYPE_ORDER_INDEX = "TypeOrderIndex"; public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; public static final String OTHER_ANNOT_TYPE = "OtherAnnotation"; private CAS cas; private Type annotationType; private Type otherAnnotationType; private Type annotationBaseType; // Count the number of FSs created in a test case. private int fsCount = 0; // private Type tokenType; // private Type sentenceType; public GetAllIndexedTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); File descriptorFile = JUnitExtension.getFile("CASTests/desc/typePriorityTestCaseDescriptor.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile.exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(spec); this.cas = ae.newCAS(); assertTrue(this.cas != null); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } TypeSystem ts = this.cas.getTypeSystem(); // assert(wordType != null); // this.tokenType = ts.getType(TOKEN_TYPE); // this.sentenceType = ts.getType(SENT_TYPE); this.annotationType = ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(this.annotationType != null); this.otherAnnotationType = ts.getType(OTHER_ANNOT_TYPE); assertTrue(this.otherAnnotationType != null); this.annotationBaseType = ts.getType(CAS.TYPE_NAME_ANNOTATION_BASE); assertTrue(this.annotationBaseType != null); } public void tearDown() { this.cas = null; // this.tokenType = null; // this.sentenceType = null; this.annotationType = null; this.annotationBaseType = null; this.otherAnnotationType = null; } private final FSIterator getAllIndexed() { return getAllIndexed(this.cas.getTypeSystem().getTopType()); } private final FSIterator getAllIndexed(Type type) { return this.cas.getIndexRepository().getAllIndexedFS(type); } private final int getIteratorSize(FSIterator it) { int count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } return count; } private final void addFS(FeatureStructure fs) { this.cas.getIndexRepository().addFS(fs); ++this.fsCount; assertTrue(getIteratorSize(getAllIndexed()) == this.fsCount); } private final FeatureStructure createAnnot(int from, int to) { return this.cas.createAnnotation(this.annotationType, from, to); } private final void initTest() { this.cas.reset(); this.fsCount = 0; } /** * Test driver. */ public void testGetAllIndexed() throws Exception { initTest(); FeatureStructure docAnnotation = this.cas.getDocumentAnnotation(); assertNotNull(docAnnotation); ++this.fsCount; assertTrue(getIteratorSize(getAllIndexed()) == this.fsCount); final FeatureStructure otherAnnotationFS = this.cas.createFS(this.otherAnnotationType); FeatureStructure annotationFS = this.cas.createFS(this.annotationType); final FeatureStructure annotationBaseFS = this.cas.createFS(this.annotationBaseType); addFS(annotationFS); addFS(otherAnnotationFS); addFS(annotationBaseFS); addFS(this.cas.createFS(this.cas.getTypeSystem().getTopType())); assertTrue(getIteratorSize(this.cas.getAnnotationIndex().iterator()) == 2); addFS(createAnnot(0, 1)); addFS(createAnnot(1, 2)); addFS(createAnnot(2, 3)); addFS(createAnnot(3, 4)); // Iterate backwards, check only that it returns correct number of FSs FSIterator it = getAllIndexed(); int down = this.fsCount; for (it.moveToLast(); it.isValid(); it.moveToPrevious()) { --down; } assertTrue(down == 0); // Get all indexed, create copy and iterate in parallel. it = getAllIndexed(); FSIterator copy = it.copy(); copy.moveToFirst(); for (it.moveToFirst(); it.isValid(); it.moveToNext()) { assertTrue(copy.isValid()); assertTrue(it.get().equals(copy.get())); copy.moveToNext(); } assertFalse(copy.isValid()); // Iterate over all indexed, create a copy at each stage, check that it gets same FS. for (it.moveToFirst(); it.isValid(); it.moveToNext()) { copy = it.copy(); assertTrue(it.get().equals(copy.get())); } copy = it.copy(); assertFalse(it.isValid()); assertFalse(copy.isValid()); //test getAllIndexed(Type) Type tokenType = this.cas.getTypeSystem().getType(TOKEN_TYPE); assertNotNull(tokenType); FSIterator tokenIter = this.cas.getIndexRepository().getAllIndexedFS(tokenType); assertFalse(tokenIter.hasNext()); } public static void main(String[] args) { junit.textui.TestRunner.run(GetAllIndexedTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/Sentence.java0000644000175000017500000000445711665471060026357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Thu Jun 21 11:28:13 MDT 2007 */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /** * Updated by JCasGen Thu Jun 21 12:00:34 MDT 2007 * XML source: C:/Documents and Settings/Philip/My Documents/CSLR/workspace/UIMA-464/desc/TokensAndSentences.xml * @generated */ public class Sentence extends Annotation { /** @generated * @ordered */ public final static int typeIndexID = JCasRegistry.register(Sentence.class); /** @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() {return typeIndexID;} /** Never called. Disable default constructor * @generated */ protected Sentence() {} /** Internal - constructor used by generator * @generated */ public Sentence(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public Sentence(JCas jcas) { super(jcas); readObject(); } /** @generated */ public Sentence(JCas jcas, int begin, int end) { super(jcas); setBegin(begin); setEnd(end); readObject(); } /** * Write your own initialization here * @generated modifiable */ private void readObject() {} } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexSerializationTest.java0000644000175000017500000002272611665471060031257 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASCompleteSerializer; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.util.CasCreationUtils; public class IndexSerializationTest extends TestCase { // Index name constants. public static final String ANNOT_SET_INDEX = "Annotation Set Index"; public static final String ANNOT_BAG_INDEX = "Annotation Bag Index"; public static final String TOKEN_TYPE = "Token"; public static final String TOKEN_TYPE_FEAT = "type"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "TokenType"; public static final String WORD_TYPE = "Word"; public static final String SEP_TYPE = "Separator"; public static final String EOS_TYPE = "EndOfSentence"; public static final String SENT_TYPE = "Sentence"; private CASMgr casMgr; private CAS cas; private Type annotationType; private Type wordType; private Type separatorType; private Type eosType; private Type tokenType; private Feature tokenTypeFeature; private Type sentenceType; private Feature startFeature; private Feature endFeature; public IndexSerializationTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); casMgr = initCAS(); cas = (CASImpl)casMgr; TypeSystem ts = cas.getTypeSystem(); wordType = ts.getType(WORD_TYPE); // assert(wordType != null); separatorType = ts.getType(SEP_TYPE); eosType = ts.getType(EOS_TYPE); tokenType = ts.getType(TOKEN_TYPE); tokenTypeFeature = ts.getFeatureByFullName(TOKEN_TYPE_FEAT_Q); startFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); endFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_END); sentenceType = ts.getType(SENT_TYPE); annotationType = ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(annotationType != null); } // Initialize the first CAS. private static CASMgr initCAS() { // // Create a CASMgr. Ensures existence of AnnotationFS type. // CASMgr tcas = CASFactory.createCAS(); CASMgr casMgr = CASFactory.createCAS(); try { CasCreationUtils.setupTypeSystem(casMgr, (TypeSystemDescription) null); } catch (ResourceInitializationException e) { e.printStackTrace(); } // Create a writable type system. TypeSystemMgr tsa = casMgr.getTypeSystemMgr(); // Add new types and features. Type topType = tsa.getTopType(); Type annotType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); // assert(annotType != null); tsa.addType(SENT_TYPE, annotType); Type tokenType = tsa.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsa.addType(TOKEN_TYPE_TYPE, topType); tsa.addType(WORD_TYPE, tokenTypeType); tsa.addType(SEP_TYPE, tokenTypeType); tsa.addType(EOS_TYPE, tokenTypeType); tsa.addFeature(TOKEN_TYPE_FEAT, tokenType, tokenTypeType); // Commit the type system. ((CASImpl) casMgr).commitTypeSystem(); // assert(tsa.isCommitted()); // // Create the CAS indexes. // tcas.initCASIndexes(); // Create the Base indexes. try { casMgr.initCASIndexes(); } catch (CASException e) { e.printStackTrace(); } FSIndexRepositoryMgr irm = casMgr.getIndexRepositoryMgr(); FSIndexComparator comp = irm.createComparator(); Type annotation = tsa.getType(CAS.TYPE_NAME_ANNOTATION); comp.setType(annotation); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_BEGIN), FSIndexComparator.STANDARD_COMPARE); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END), FSIndexComparator.REVERSE_STANDARD_COMPARE); irm.createIndex(comp, ANNOT_BAG_INDEX, FSIndex.BAG_INDEX); irm.createIndex(comp, ANNOT_SET_INDEX, FSIndex.SET_INDEX); // Commit the index repository. irm.commit(); // assert(cas.getIndexRepositoryMgr().isCommitted()); // Create the default text Sofa and return CAS view return (CASMgr) casMgr.getCAS().getCurrentView(); } /** * Test driver. */ public void testMain() throws Exception { for (int i = 0; i < 10; i++) { cas.getIndexRepository().addFS(cas.createAnnotation(annotationType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(sentenceType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); } for (int i = 19; i >= 10; i--) { cas.getIndexRepository().addFS(cas.createAnnotation(annotationType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(sentenceType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, i * 2, (i * 2) + 1)); } AnnotationFS searchAnnot = cas.createAnnotation(annotationType, 0, 1); assertTrue(cas.getAnnotationIndex().find(searchAnnot) != null); assertTrue(cas.getIndexRepository().getIndex(ANNOT_SET_INDEX).find(searchAnnot) != null); // find() does not produce useful results on bag indexes, since the comparator // is not defined. // assertTrue(cas.getIndexRepository().getIndex(ANNOT_BAG_INDEX).find(searchAnnot) != null); searchAnnot.setIntValue(endFeature, 4); assertTrue(cas.getAnnotationIndex().find(searchAnnot) == null); assertTrue(cas.getIndexRepository().getIndex(ANNOT_SET_INDEX).find(searchAnnot) == null); assertTrue(cas.getIndexRepository().getIndex(ANNOT_BAG_INDEX).find(searchAnnot) == null); final int ordSize = cas.getAnnotationIndex().size(); final int setSize = cas.getIndexRepository().getIndex(ANNOT_SET_INDEX).size(); final int bagSize = cas.getIndexRepository().getIndex(ANNOT_BAG_INDEX).size(); // System.out.println("Before serialization\n"); // System.out.println("Size of ordered index: " + ordSize); // System.out.println("Size of set index: " + setSize); // System.out.println("Size of bag index: " + bagSize); CASCompleteSerializer cs; cs = Serialization.serializeCASComplete(casMgr); // casMgr = CASFactory.createCAS(); CASMgr realCasMgr = CASFactory.createCAS(); ((CASImpl) realCasMgr).commitTypeSystem(); Serialization.deserializeCASComplete(cs, realCasMgr); cas = ((CASImpl) realCasMgr).getCurrentView(); casMgr = (CASMgr) cas; // System.out.println("After serialization\n"); FSIndex index = cas.getAnnotationIndex(); assertTrue(index != null); assertTrue(index.getIndexingStrategy() == FSIndex.SORTED_INDEX); // System.out.println("Size of ordered index: " + index.size()); assertTrue(index.size() == ordSize); index = cas.getIndexRepository().getIndex(ANNOT_BAG_INDEX); assertTrue(index != null); assertTrue(index.getIndexingStrategy() == FSIndex.BAG_INDEX); // System.out.println("Size of bag index: " + index.size()); assertTrue(index.size() == bagSize); index = cas.getIndexRepository().getIndex(ANNOT_SET_INDEX); assertTrue(index != null); assertTrue(index.getIndexingStrategy() == FSIndex.SET_INDEX); // System.out.println("Size of set index: " + index.size()); // System.out.println("Should be: " + setSize); assertTrue(index.size() == setSize); } public static void main(String[] args) { junit.textui.TestRunner.run(IndexSerializationTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTestNoJcasCache.java0000644000175000017500000001357511665471060032202 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.jcas.JCas; import org.apache.uima.resource.Resource; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.FileUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Class comment for IteratorTest.java goes here. * */ public class GrowingTheCasTestNoJcasCache extends TestCase { private AnalysisEngine ae = null; private JCas smallHeapCas = null; public GrowingTheCasTestNoJcasCache(String arg0) { super(arg0); } public void setUp() { File descriptorFile = JUnitExtension.getFile("CASTests/desc/TokensAndSentences.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile .exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); ResourceSpecifier spec = parser.parseResourceSpecifier(new XMLInputSource( descriptorFile)); // Create a new properties object to hold the settings. Properties performanceTuningSettings = new Properties(); // Set the initial CAS heap size. performanceTuningSettings.setProperty( UIMAFramework.CAS_INITIAL_HEAP_SIZE, "1000000"); // Disable JCas cache. performanceTuningSettings.setProperty( UIMAFramework.JCAS_CACHE_ENABLED, "false"); // Create a wrapper properties object that can // be passed to the framework. Map additionalParams = new HashMap(); // Set the performance tuning properties as value to // the appropriate parameter. additionalParams.put( Resource.PARAM_PERFORMANCE_TUNING_SETTINGS, performanceTuningSettings); // Create the analysis engine with the parameters. // The second, unused argument here is a custom // resource manager. this.ae = UIMAFramework.produceAnalysisEngine( spec, null, additionalParams); this.smallHeapCas = this.ae.newJCas(); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } } public void tearDown() { if (this.ae != null) { this.ae.destroy(); this.ae = null; } } public void testAnnotator() { File textFile = JUnitExtension.getFile("data/moby.txt"); String text = null; try { text = FileUtils.file2String(textFile, "utf-8"); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } StringBuffer buf = new StringBuffer(text.length() * 10); for (int i = 0; i < 10; i++) { buf.append(text); } JCas jcas = null; try { jcas = this.ae.newJCas(); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } text = buf.toString(); jcas.setDocumentText(text); int numberOfSentences = 0; int numberOfTokens = 0; try { // long time = System.currentTimeMillis(); this.ae.process(jcas); // time = System.currentTimeMillis() - time; // System.out.println("Time for large CAS: " + new TimeSpan(time)); numberOfSentences = jcas.getAnnotationIndex(Sentence.type).size(); numberOfTokens = jcas.getAnnotationIndex(Token.type).size(); // System.out.println(numberOfSentences); // System.out.println(numberOfTokens); } catch (AnalysisEngineProcessException e) { e.printStackTrace(); assertTrue(false); } this.smallHeapCas.setDocumentText(text); try { // long time = System.currentTimeMillis(); this.ae.process(this.smallHeapCas); // time = System.currentTimeMillis() - time; // System.out.println("Time for small CAS: " + new TimeSpan(time)); assertTrue(this.getClass().toString() + ": number of sentences does not match", numberOfSentences == this.smallHeapCas.getAnnotationIndex(Sentence.type).size()); assertTrue(this.getClass().toString() + ": number of tokens does not match", numberOfTokens == this.smallHeapCas.getAnnotationIndex(Token.type).size()); } catch (AnalysisEngineProcessException e) { e.printStackTrace(); assertTrue(false); } } public static void main(String[] args) { junit.textui.TestRunner.run(GrowingTheCasTestNoJcasCache.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/JcasSofaTest.java0000644000175000017500000004634511665471060027146 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.ByteBuffer; import java.util.Iterator; import java.util.StringTokenizer; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.SofaFS; import org.apache.uima.cas.SofaID; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.CASSerializer; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.impl.XCASSerializer; import org.apache.uima.impl.SofaID_impl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JFSIndexRepository; import org.apache.uima.jcas.cas.ByteArray; import org.apache.uima.jcas.cas.DoubleArray; import org.apache.uima.jcas.cas.FSArray; import org.apache.uima.jcas.cas.FloatArray; import org.apache.uima.jcas.cas.IntegerArray; import org.apache.uima.jcas.cas.LongArray; import org.apache.uima.jcas.cas.ShortArray; import org.apache.uima.jcas.cas.Sofa; import org.apache.uima.jcas.tcas.Annotation; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.xml.sax.SAXException; public class JcasSofaTest extends TestCase { private CASMgr casMgr; private CAS cas; private JCas jcas; public JcasSofaTest(String arg) { super(arg); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); casMgr = CASFactory.createCAS(); CasCreationUtils.setupTypeSystem(casMgr, (TypeSystemDescription) null); // Create a writable type system. TypeSystemMgr tsa = casMgr.getTypeSystemMgr(); // Add new types and features. Type annotType = tsa.getType(CAS.TYPE_NAME_ANNOTATION); Type crossType = tsa.addType("org.apache.uima.cas.test.CrossAnnotation", annotType); tsa.addFeature("otherAnnotation", crossType, annotType); // Commit the type system. ((CASImpl) casMgr).commitTypeSystem(); // Create the Base indexes. casMgr.initCASIndexes(); FSIndexRepositoryMgr irm = casMgr.getIndexRepositoryMgr(); // init.initIndexes(irm, casMgr.getTypeSystemMgr()); irm.commit(); cas = casMgr.getCAS().getView(CAS.NAME_DEFAULT_SOFA); jcas = cas.getJCas(); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Test driver. */ public void testMain() throws Exception { try { // Create a Sofa using OLD APIs for now SofaID_impl id = new SofaID_impl(); id.setSofaID("EnglishDocument"); Sofa es = new Sofa(jcas, id, "text"); // Initial View is #1!!! assertTrue(2 == es.getSofaRef()); // Set the document text es.setLocalSofaData("this beer is good"); // Test Multiple Sofas across XCAS serialization XCASSerializer ser = new XCASSerializer(cas.getTypeSystem()); OutputStream outputXCAS = new FileOutputStream("Sofa.xcas"); XMLSerializer xmlSer = new XMLSerializer(outputXCAS); try { ser.serialize(cas, xmlSer.getContentHandler()); outputXCAS.close(); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } // Deserialize XCAS cas.reset(); InputStream inputXCAS = new FileInputStream("Sofa.xcas"); try { XCASDeserializer.deserialize(inputXCAS, cas, false); inputXCAS.close(); } catch (SAXException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } // Add a new Sofa // id.setSofaID("GermanDocument"); // Sofa gs = new Sofa(jcas, id, "text"); JCas gerJcas = jcas.createView("GermanDocument"); Sofa gs = gerJcas.getSofa(); assertTrue(3 == gs.getSofaRef()); // Set the document text // gs.setLocalSofaData("das bier ist gut"); gerJcas.setDocumentText("das bier ist gut"); // Test multiple Sofas across binary serialization CASSerializer cs = Serialization.serializeNoMetaData(cas); cas = Serialization.createCAS(casMgr, cs); // Add a new Sofa // id.setSofaID("FrenchDocument"); // Sofa fs = new Sofa(jcas, id, "text"); CAS frCas = jcas.getCas().createView("FrenchDocument"); SofaFS fs = frCas.getSofa(); assertTrue(4 == fs.getSofaRef()); // Open JCas views of some Sofas JCas engJcas = cas.getJCas(es); JCas frJcas = jcas.getView("FrenchDocument"); // Set the document text after the Jcas view exists using JCas.setDocumentText method frJcas.setSofaDataString("cette biere est bonne", "text"); // Create standard annotations against eng & fr and cross annotations against ger int engEnd = 0; int gerEnd = 0; int frEnd = 0; String engText = engJcas.getDocumentText(); String gerText = gerJcas.getDocumentText(); String frText = frJcas.getDocumentText(); StringTokenizer est = new StringTokenizer(engText); StringTokenizer gst = new StringTokenizer(gerText); StringTokenizer fst = new StringTokenizer(frText); while (est.hasMoreTokens()) { assertTrue(gst.hasMoreTokens()); assertTrue(fst.hasMoreTokens()); String eTok = est.nextToken(); int engBegin = engText.indexOf(eTok, engEnd); engEnd = engBegin + eTok.length(); String gTok = gst.nextToken(); int gerBegin = gerText.indexOf(gTok, gerEnd); gerEnd = gerBegin + gTok.length(); String fTok = fst.nextToken(); int frBegin = frText.indexOf(fTok, frEnd); frEnd = frBegin + fTok.length(); Annotation engAnnot = new Annotation(engJcas, engBegin, engEnd); engAnnot.addToIndexes(); Annotation frAnnot = new Annotation(frJcas, frBegin, frEnd); frAnnot.addToIndexes(); CrossAnnotation gerAnnot = new CrossAnnotation(gerJcas); gerAnnot.setBegin(gerBegin); gerAnnot.setEnd(gerEnd); gerAnnot.setOtherAnnotation(engAnnot); gerAnnot.addToIndexes(); } // Test that the annotations are in separate index spaces, and that Sofas are indexed JFSIndexRepository indexes = jcas.getJFSIndexRepository(); // FSIndex sofaIndex = indexes.getIndex(CAS.SOFA_INDEX_NAME); indexes = engJcas.getJFSIndexRepository(); FSIndex engIndex = indexes.getAnnotationIndex(Annotation.type); indexes = gerJcas.getJFSIndexRepository(); FSIndex gerIndex = indexes.getAnnotationIndex(Annotation.type); indexes = frJcas.getJFSIndexRepository(); FSIndex frIndex = indexes.getAnnotationIndex(Annotation.type); FSIterator sofaIter = jcas.getSofaIterator(); int numSofas = 0; while (sofaIter.isValid()) { numSofas++; sofaIter.moveToNext(); } // assertTrue(sofaIndex.size() == 3); // 3 sofas assertTrue(numSofas == 3); assertTrue(engIndex.size() == 5); // 4 annots plus documentAnnotation assertTrue(gerIndex.size() == 5); // 4 annots plus documentAnnotation assertTrue(frIndex.size() == 5); // 4 annots plus documentAnnotation // Test that the annotations are of the correct types FSIterator engIt = engIndex.iterator(); FSIterator gerIt = gerIndex.iterator(); FSIterator frIt = frIndex.iterator(); Annotation engAnnot = (Annotation) engIt.get(); Annotation gerAnnot = (Annotation) gerIt.get(); Annotation frAnnot = (Annotation) frIt.get(); assertTrue((CAS.TYPE_NAME_DOCUMENT_ANNOTATION).equals(engAnnot.getType().getName())); assertTrue((CAS.TYPE_NAME_DOCUMENT_ANNOTATION).equals(gerAnnot.getType().getName())); assertTrue((CAS.TYPE_NAME_DOCUMENT_ANNOTATION).equals(frAnnot.getType().getName())); engIt.moveToNext(); gerIt.moveToNext(); frIt.moveToNext(); engAnnot = (Annotation) engIt.get(); CrossAnnotation gerCrossAnnot = (CrossAnnotation) gerIt.get(); frAnnot = (Annotation) frIt.get(); assertTrue((CAS.TYPE_NAME_ANNOTATION).equals(engAnnot.getType().getName())); assertTrue(("this").equals(engAnnot.getCoveredText())); assertTrue((CAS.TYPE_NAME_ANNOTATION).equals(frAnnot.getType().getName())); assertTrue(("cette").equals(frAnnot.getCoveredText())); assertTrue(("org.apache.uima.cas.test.CrossAnnotation").equals(gerCrossAnnot.getType() .getName())); assertTrue(("das").equals(gerCrossAnnot.getCoveredText())); // Test that the other annotation feature of cross annotations works Annotation crossAnnot = gerCrossAnnot.getOtherAnnotation(); assertTrue((CAS.TYPE_NAME_ANNOTATION).equals(crossAnnot.getType().getName())); assertTrue(("this").equals(crossAnnot.getCoveredText())); // Test that annotations accessed from a reference in the base CAS work correctly FSArray anArray = new FSArray(jcas, 3); anArray.set(0, engAnnot); anArray.set(1, frAnnot); anArray.set(2, gerCrossAnnot); Annotation tstAnnot = (Annotation) anArray.get(0); assertTrue(("this").equals(tstAnnot.getCoveredText())); tstAnnot = (Annotation) anArray.get(1); assertTrue(("cette").equals(tstAnnot.getCoveredText())); tstAnnot = (Annotation) anArray.get(2); assertTrue(("das").equals(tstAnnot.getCoveredText())); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Test stream access to Sofa Data. * * @throws Exception */ public void testSofaDataStream() throws Exception { try { // Create Sofas // Create a local Sofa and set string feature // SofaID_impl id = new SofaID_impl(); // id.setSofaID("StringSofaData"); // Sofa strSofa = new Sofa(jcas, id, "text"); // strSofa.setLocalSofaData("this beer is good"); JCas stringView = jcas.createView("StringSofaData"); stringView.setDocumentText("this beer is good"); // create a int array fs IntegerArray intArrayFS = new IntegerArray(jcas, 5); intArrayFS.set(0, 1); intArrayFS.set(1, 2); intArrayFS.set(2, 3); intArrayFS.set(3, 4); intArrayFS.set(4, 5); // create a Sofa and set the SofaArray feature to an int array FS. // id = new SofaID_impl(); // id.setSofaID("intArraySofaData"); // SofaFS intarraySofaFS = new Sofa(jcas, id, "text"); // intarraySofaFS.setLocalSofaData(intArrayFS); JCas intArrayView = jcas.createView("intArraySofaData"); intArrayView.setSofaDataArray(intArrayFS, "integers"); // create a float array fs FloatArray floatArrayFS = new FloatArray(jcas, 5); floatArrayFS.set(0, (float) 0.1); floatArrayFS.set(1, (float) 0.2); floatArrayFS.set(2, (float) 0.3); floatArrayFS.set(3, (float) 0.4); floatArrayFS.set(4, (float) 0.5); // create a sofa and set the SofaArray feature to the float array // id = new SofaID_impl(); // id.setSofaID("floatArraySofaData"); // SofaFS floatarraySofaFS = new Sofa(jcas, id, "text"); // floatarraySofaFS.setLocalSofaData(floatArrayFS); JCas floatArrayView = jcas.createView("floatArraySofaData"); floatArrayView.setSofaDataArray(floatArrayFS, "floats"); // create a short array fs ShortArray shortArrayFS = new ShortArray(jcas, 5); shortArrayFS.set(0, (short) 128); shortArrayFS.set(1, (short) 127); shortArrayFS.set(2, (short) 126); shortArrayFS.set(3, (short) 125); shortArrayFS.set(4, (short) 124); // create a Sofa and set the SofaArray feature to an int array FS. JCas shortArrayView = jcas.createView("shortArraySofaData"); shortArrayView.setSofaDataArray(shortArrayFS, "shorts"); // create a byte array fs ByteArray byteArrayFS = new ByteArray(jcas, 5); byteArrayFS.set(0, (byte) 8); byteArrayFS.set(1, (byte) 16); byteArrayFS.set(2, (byte) 64); byteArrayFS.set(3, (byte) 128); byteArrayFS.set(4, (byte) 255); // create a Sofa and set the SofaArray feature. JCas byteArrayView = jcas.createView("byteArraySofaData"); byteArrayView.setSofaDataArray(byteArrayFS, "bytes"); // create a long array fs LongArray longArrayFS = new LongArray(jcas, 5); longArrayFS.set(0, Long.MAX_VALUE); longArrayFS.set(1, Long.MAX_VALUE - 1); longArrayFS.set(2, Long.MAX_VALUE - 2); longArrayFS.set(3, Long.MAX_VALUE - 3); longArrayFS.set(4, Long.MAX_VALUE - 4); // create a Sofa and set the SofaArray feature. JCas longArrayView = jcas.createView("longArraySofaData"); longArrayView.setSofaDataArray(longArrayFS, "longs"); DoubleArray doubleArrayFS = new DoubleArray(jcas, 5); doubleArrayFS.set(0, Double.MAX_VALUE); doubleArrayFS.set(1, Double.MIN_VALUE); doubleArrayFS.set(2, Double.parseDouble("1.5555")); doubleArrayFS.set(3, Double.parseDouble("99.000000005")); doubleArrayFS.set(4, Double.parseDouble("4.44444444444444444")); // create a Sofa and set the SofaArray feature. JCas doubleArrayView = jcas.createView("doubleArraySofaData"); doubleArrayView.setSofaDataArray(doubleArrayFS, "doubles"); // create remote sofa and set the SofaURI feature JCas remoteView = jcas.createView("remoteSofaData"); String sofaFileName = "./Sofa.xcas"; remoteView.setSofaDataURI("file:" + sofaFileName, "text"); // read sofa data InputStream is = stringView.getSofaDataStream(); assertTrue(is != null); byte[] dest = new byte[1]; StringBuffer buf = new StringBuffer(); while (is.read(dest) != -1) { buf.append((char) dest[0]); } assertTrue(buf.toString().equals("this beer is good")); dest = new byte[4]; is.close(); is = intArrayView.getSofaDataStream(); assertTrue(is != null); BufferedInputStream bis = new BufferedInputStream(is); int i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getInt() == intArrayFS.get(i++)); } bis.close(); is = floatArrayView.getSofaDataStream(); assertTrue(is != null); bis = new BufferedInputStream(is); i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getFloat() == floatArrayFS.get(i++)); } dest = new byte[2]; bis.close(); is = shortArrayView.getSofaDataStream(); assertTrue(is != null); bis = new BufferedInputStream(is); i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getShort() == shortArrayFS.get(i++)); } dest = new byte[1]; bis.close(); is = byteArrayView.getSofaDataStream(); assertTrue(is != null); bis = new BufferedInputStream(is); i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).get() == byteArrayFS.get(i++)); } dest = new byte[8]; bis.close(); is = longArrayView.getSofaDataStream(); assertTrue(is != null); bis = new BufferedInputStream(is); i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getLong() == longArrayFS.get(i++)); } bis.close(); is = doubleArrayView.getSofaDataStream(); assertTrue(is != null); bis = new BufferedInputStream(is); i = 0; while (bis.read(dest) != -1) { assertTrue(ByteBuffer.wrap(dest).getDouble() == doubleArrayFS.get(i++)); } dest = new byte[1]; bis.close(); is = remoteView.getSofaDataStream(); assertTrue(is != null); is.close(); // Delete the generated file. File xcasFile = new File(sofaFileName); if (xcasFile.exists()) { assertTrue(xcasFile.delete()); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testIndexTwice() throws Exception { try { CAS newCas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); JCas newJCas = newCas.getJCas(); CAS view = newCas.createView("DetaggedView"); view.getJCas(); Annotation annot = new Annotation(newJCas); annot.addToIndexes(); Iterator annotIter = newJCas.getAnnotationIndex(Annotation.type).iterator(); Annotation annot2 = annotIter.next(); assertEquals(annot, annot2); assertEquals(annot2.getSofa(), annot2.getCASImpl().getSofa()); annot2.addToIndexes(); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetSofa() throws Exception { try { File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); TypeSystemDescription typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); CAS newCas = CasCreationUtils.createCas(typeSystem, null, null); File xcasFile = JUnitExtension.getFile("ExampleCas/multiSofaCas.xml"); XCASDeserializer.deserialize(new FileInputStream(xcasFile), newCas); JCas newJCas = newCas.getJCas(); SofaID sofaId = new SofaID_impl("EnglishDocument"); JCas view = newJCas.getView(newJCas.getSofa(sofaId)); } catch (Exception e) { JUnitExtension.handleException(e); } } public static void main(String[] args) { junit.textui.TestRunner.run(JcasSofaTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/IntArrayFSTest.java0000644000175000017500000001021611665471060027423 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.IntArrayFS; public class IntArrayFSTest extends TestCase { private CAS cas; /** * Constructor for ArrayFSTest. * * @param arg0 */ public IntArrayFSTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); } catch (Exception e) { assertTrue(false); } } public void tearDown() { this.cas = null; } public static void main(String[] args) { junit.textui.TestRunner.run(IntArrayFSTest.class); } public void testSet() { IntArrayFS array = this.cas.createIntArrayFS(0); assertTrue(array != null); assertTrue(array.size() == 0); boolean exceptionCaught = false; try { array.get(0); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); array = this.cas.createIntArrayFS(3); try { array.set(0, 1); array.set(1, 2); array.set(2, 3); } catch (ArrayIndexOutOfBoundsException e) { assertTrue(false); } exceptionCaught = false; try { array.set(-1, 1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.set(4, 1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); assertTrue(array.get(0) == 1); assertTrue(array.get(1) == 2); assertTrue(array.get(2) == 3); exceptionCaught = false; try { array.get(-1); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); exceptionCaught = false; try { array.get(4); } catch (ArrayIndexOutOfBoundsException e) { exceptionCaught = true; } assertTrue(exceptionCaught); // Check that we can't create arrays smaller than 0. exceptionCaught = false; try { array = this.cas.createIntArrayFS(-1); } catch (CASRuntimeException e) { exceptionCaught = true; assertTrue(e.getMessageKey().equals(CASRuntimeException.ILLEGAL_ARRAY_SIZE)); } assertTrue(exceptionCaught); } public void testToArray() { // From CAS array to Java array. IntArrayFS array = this.cas.createIntArrayFS(3); int[] fsArray = array.toArray(); for (int i = 0; i < 3; i++) { assertTrue(fsArray[i] == 0); } array.set(0, 1); array.set(1, 2); array.set(2, 3); fsArray = array.toArray(); assertTrue(fsArray.length == 3); assertTrue(fsArray[0] == 1); assertTrue(fsArray[1] == 2); assertTrue(fsArray[2] == 3); // From Java array to CAS array. array = this.cas.createIntArrayFS(3); assertTrue(array.get(0) == 0); assertTrue(array.get(1) == 0); assertTrue(array.get(2) == 0); for (int i = 0; i < 3; i++) { array.set(i, fsArray[i]); } assertTrue(array.get(0) == 1); assertTrue(array.get(1) == 2); assertTrue(array.get(2) == 3); array.set(0, 0); assertTrue(array.get(0) == 0); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/AnnotationTreeTest.java0000644000175000017500000000745011665471060030401 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.text.AnnotationTreeNode; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; public class AnnotationTreeTest extends TestCase { private static final String casDataDirName = "CASTests"; private static final String xcasSampleDirName = "xcas"; private static final String sampleXcas1FileName = "sample1.xcas"; private static final String sampleTsFileName = "sample.ts"; public AnnotationTreeTest(String desc) { super(desc); } public void testTree() throws Exception { // The two XCASes used in this test contain the same data, but the // second one contains all annotations twice. So in that case, every // other annotation is filtered by the unambiguous iterator. File dataDir = JUnitExtension.getFile(casDataDirName); File xcasDir = new File(dataDir, xcasSampleDirName); try { File tsFile = new File(xcasDir, sampleTsFileName); Object descriptor = UIMAFramework.getXMLParser().parse(new XMLInputSource(tsFile)); // instantiate CAS to get type system. Also build style // map file if there is none. TypeSystemDescription tsDesc = (TypeSystemDescription) descriptor; CAS cas = CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[0]); SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); XCASDeserializer xcasDeserializer = new XCASDeserializer(cas.getTypeSystem()); File xcasFile = new File(xcasDir, sampleXcas1FileName); parser.parse(xcasFile, xcasDeserializer.getXCASHandler(cas)); AnnotationTreeNode root = cas.getAnnotationIndex().tree(cas.getDocumentAnnotation()) .getRoot(); // There are 7 paragraph annotations in the CAS. assertTrue("There should be 7 paragraphs, but are: " + root.getChildCount(), root .getChildCount() == 7); // The first paragraph contains 19 sentences, each subsequent one // contains only one sentence. assertTrue(root.getChild(0).getChildCount() == 19); for (int i = 1; i < root.getChildCount(); i++) { assertTrue(root.getChild(i).getChildCount() == 1); } // First sentence contains 8 tokens. assertTrue(root.getChild(0).getChild(0).getChildCount() == 8); // Same for only sentence in second paragraph. assertTrue(root.getChild(1).getChild(0).getChildCount() == 8); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java0000644000175000017500000000530311665471060030611 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; /** * */ public class IndexRepositoryTest extends TestCase { CAS cas; TypeSystem typeSystem; FSIndexRepository indexRep; /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); this.cas = CASInitializer.initCas(new CASTestSetup()); this.typeSystem = this.cas.getTypeSystem(); this.indexRep = this.cas.getIndexRepository(); } public void testDefaultBagIndex() throws Exception { // create an instance of a non-annotation type Type tokenTypeType = this.typeSystem.getType(CASTestSetup.TOKEN_TYPE_TYPE); FeatureStructure tokenTypeFs1 = this.cas.createFS(tokenTypeType); assertFalse(tokenTypeFs1 instanceof AnnotationFS); // add to indexes this.indexRep.addFS(tokenTypeFs1); // now try to retrieve FSIterator iter = this.indexRep.getAllIndexedFS(tokenTypeType); assertTrue(iter.hasNext()); assertEquals(tokenTypeFs1, iter.next()); assertFalse(iter.hasNext()); // add a second instance FeatureStructure tokenTypeFs2 = this.cas.createFS(tokenTypeType); assertFalse(tokenTypeFs2 instanceof AnnotationFS); this.indexRep.addFS(tokenTypeFs2); // now there should be two instances in the index FSIterator iter2 = this.indexRep.getAllIndexedFS(tokenTypeType); assertTrue(iter2.hasNext()); iter2.next(); assertTrue(iter2.hasNext()); iter2.next(); assertFalse(iter.hasNext()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java0000644000175000017500000006153211665471060027241 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.internal.util.IntVector; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; /** * Class comment for IteratorTest.java goes here. * */ public class IteratorTest extends TestCase { private CASImpl cas; private TypeSystem ts; private Type annotationType; private Type stringType; private Type tokenType; private Type intType; private Type tokenTypeType; private Type wordType; private Feature tokenTypeFeat; private Feature lemmaFeat; private Feature sentLenFeat; private Feature tokenFloatFeat; private Feature startFeature; private Type sentenceType; /** * Constructor for FilteredIteratorTest. * * @param arg0 */ public IteratorTest(String arg0) { super(arg0); } public void setUp() { // try { // this.cas = (CASImpl) CASInitializer.initCas(new CASTestSetup()); // assertTrue(this.cas != null); // this.ts = this.cas.getTypeSystem(); // assertTrue(this.ts != null); // } catch (Exception e) { // e.printStackTrace(); // assertTrue(false); // } File descriptorFile = JUnitExtension.getFile("CASTests/desc/casTestCaseDescriptor.xml"); assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile.exists()); try { XMLParser parser = UIMAFramework.getXMLParser(); ResourceSpecifier spec = (ResourceSpecifier) parser.parse(new XMLInputSource(descriptorFile)); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(spec); this.cas = (CASImpl) ae.newCAS(); assertTrue(this.cas != null); this.ts = this.cas.getTypeSystem(); assertTrue(this.ts != null); } catch (IOException e) { e.printStackTrace(); assertTrue(false); } catch (InvalidXMLException e) { e.printStackTrace(); assertTrue(false); } catch (ResourceInitializationException e) { e.printStackTrace(); assertTrue(false); } this.stringType = this.ts.getType(CAS.TYPE_NAME_STRING); assertTrue(this.stringType != null); this.tokenType = this.ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(this.stringType != null); this.intType = this.ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(this.intType != null); this.tokenTypeType = this.ts.getType(CASTestSetup.TOKEN_TYPE_TYPE); assertTrue(this.tokenTypeType != null); this.wordType = this.ts.getType(CASTestSetup.WORD_TYPE); assertTrue(this.wordType != null); this.tokenTypeFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_TYPE_FEAT_Q); assertTrue(this.tokenTypeFeat != null); this.lemmaFeat = this.ts.getFeatureByFullName(CASTestSetup.LEMMA_FEAT_Q); assertTrue(this.lemmaFeat != null); this.sentLenFeat = this.ts.getFeatureByFullName(CASTestSetup.SENT_LEN_FEAT_Q); assertTrue(this.sentLenFeat != null); this.tokenFloatFeat = this.ts.getFeatureByFullName(CASTestSetup.TOKEN_FLOAT_FEAT_Q); assertTrue(this.tokenFloatFeat != null); this.startFeature = this.ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); assertTrue(this.startFeature != null); this.sentenceType = this.ts.getType(CASTestSetup.SENT_TYPE); assertTrue(this.sentenceType != null); this.annotationType = this.ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(this.annotationType != null); } public void tearDown() { this.cas = null; this.ts = null; this.stringType = null; this.tokenType = null; this.intType = null; this.tokenTypeType = null; this.wordType = null; this.tokenTypeFeat = null; this.lemmaFeat = null; this.sentLenFeat = null; this.tokenFloatFeat = null; this.startFeature = null; this.sentenceType = null; this.annotationType = null; } public void testGetIndexes() { Iterator> it = this.cas.getIndexRepository().getIndexes(); while (it.hasNext()) { assertNotNull(it.next()); } } public void testMoveTo() { // Add some arbitrary annotations for (int i = 0; i < 10; i++) { this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); } final int start = 5; final int end = 7; FSIndexRepository repo = this.cas.getIndexRepository(); for (int i = 0; i < 10; i++) { AnnotationFS annotation = this.cas.createAnnotation(this.annotationType, start, end); repo.addFS(annotation); } AnnotationFS match = this.cas.createAnnotation(this.annotationType, start, end); FSIndex index = this.cas.getAnnotationIndex(); FSIterator it = index.iterator(); it.moveTo(match); assertTrue(index.compare(match, it.get()) == 0); // The contract of moveTo() says that any preceding FS must be smaller. it.moveToPrevious(); assertTrue(index.compare(match, it.get()) > 0); } public void testIterator() { for (int i = 0; i < 10; i++) { this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); } for (int i = 19; i >= 10; i--) { this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); this.cas.getIndexRepository().addFS( this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1)); } // ///////////////////////////////////////////////////////////////////////// // Create a reverse iterator for the set index and check that the result // is the same as for forward iteration. IntVector v = new IntVector(); FSIndex bagIndex = this.cas.getIndexRepository().getIndex( CASTestSetup.ANNOT_BAG_INDEX); FSIndex setIndex = this.cas.getIndexRepository().getIndex( CASTestSetup.ANNOT_SET_INDEX); FSIndex sortedIndex = this.cas.getIndexRepository().getIndex( CASTestSetup.ANNOT_SORT_INDEX); FSIterator it = setIndex.iterator(); AnnotationFS a, b = null; while (it.isValid()) { a = (AnnotationFS) it.get(); if (b != null) { assertTrue(setIndex.compare(b, a) <= 0); } b = a; // System.out.println( // a.getType().getName() + " - " + a.getStart() + " - " + // a.getEnd()); v.add(it.get().hashCode()); it.moveToNext(); } // System.out.println("Number of annotations: " + v.size()); assertTrue(v.size() == ((10 * 3) + (10 * 3))); it = setIndex.iterator(); it.moveToLast(); int current = v.size() - 1; while (it.isValid() && (current >= 0)) { // System.out.println("Current: " + current); a = (AnnotationFS) it.get(); // System.out.println( // a.getType().getName() + " - " + a.getStart() + " - " + // a.getEnd()); assertTrue(it.get().hashCode() == v.get(current)); it.moveToPrevious(); --current; } assertTrue(current == -1); assertFalse(it.isValid()); // ///////////////////////////////////////////////////////////////////////// // Use an iterator to move forwards and backwards and make sure the // sequence // remains constant. it = setIndex.iterator(); it.moveToFirst(); // This is redundant. current = 1; // System.out.println("Codes: " + v); while (current < (v.size() - 1)) { it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current + 1)); it.moveToPrevious(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); ++current; } // also test Java-style iteration Iterator javaIt = setIndex.iterator(); current = 0; while (javaIt.hasNext()) { assertEquals(javaIt.next().hashCode(), v.get(current++)); } // test find() AnnotationFS annot = (AnnotationFS) setIndex.iterator().get(); assertNotNull(setIndex.find(annot)); assertNull(setIndex.find(this.cas.createAnnotation(this.annotationType, -1, -1))); // do same for JCas JCas jcas = null; try { jcas = this.cas.getJCas(); } catch (CASException e1) { // TODO Auto-generated catch block e1.printStackTrace(); assertTrue(false); } FSIndex jcasSetIndex = jcas.getJFSIndexRepository().getIndex(CASTestSetup.ANNOT_SET_INDEX); Annotation jcasAnnotation = (Annotation) jcasSetIndex.find(annot); assertNotNull(jcasAnnotation); assertNull(jcasSetIndex.find(this.cas.createAnnotation(this.annotationType, -1, -1))); // ///////////////////////////////////////////////////////////////////////// // Test fast fail. it = bagIndex.iterator(); // use bag index, remove add last one // (preserves order for other tests). it.moveToLast(); a = (AnnotationFS) it.get(); it = setIndex.iterator(); // back to set iterator to do testing this.cas.getIndexRepository().removeFS(a); this.cas.getIndexRepository().addFS(a); boolean ok = false; try { it.next(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); ok = false; try { it.next(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); it.moveTo(a); ok = false; try { it.next(); // should not throw ok = true; } catch (ConcurrentModificationException e) { // checking this with the ok variable } assertTrue(ok); // Test find() Type wType = this.cas.getTypeSystem().getType("org.apache.uima.cas.test.types.Word"); Feature wordFeat = wType.getFeatureByBaseName("word"); for (int i = 0; i < 20; i++) { FeatureStructure fs = this.cas.createFS(wType); fs.setStringValue(wordFeat, "word" + i); this.cas.getIndexRepository().addFS(fs); } FSIndex wordSetIndex = this.cas.getIndexRepository().getIndex( "Word Set Index"); it = wordSetIndex.iterator(); FeatureStructure fs = this.cas.createFS(wType); fs.setStringValue(wordFeat, "word1"); // TEST moveTo() and get() it.moveTo(fs); assertSame(fs.getType(), it.get().getType()); Type t1 = fs.getType(); Type t2 = wordSetIndex.find(fs).getType(); assertSame(t1, t2); // ///////////////////////////////////////////////////////////////////////// // Test sorted index. // FSIndex sortedIndex = cas.getAnnotationIndex(); // using different // typeOrder // System.out.println("Number of annotations: " + sortedIndex.size()); // for (it = sortedIndex.iterator(); it.hasNext(); it.next()) { // System.out.println(it.get()); // } assertTrue(sortedIndex.size() == 100); v = new IntVector(); it = sortedIndex.iterator(); it.moveToFirst(); b = null; while (it.isValid()) { a = (AnnotationFS) it.get(); // System.out.println(a); assertTrue(a != null); if (b != null) { // System.out.println("b = " + b); assertTrue(sortedIndex.compare(b, a) <= 0); } b = a; v.add(a.hashCode()); it.moveToNext(); } assertTrue(sortedIndex.size() == v.size()); // Test moveTo() List list = new ArrayList(); FSIterator it2 = this.cas.getAnnotationIndex().iterator(); for (it2.moveToFirst(); it2.isValid(); it2.moveToNext()) { list.add(it2.get()); } // AnnotationFS an; for (int i = 0; i < list.size(); i++) { // System.out.println("Iteration: " + i); it2.moveToFirst(); it2.moveTo(list.get(i)); assertTrue(((AnnotationFS) it2.get()).getBegin() == ((AnnotationFS) list.get(i)).getBegin()); assertTrue(((AnnotationFS) it2.get()).getEnd() == ((AnnotationFS) list.get(i)).getEnd()); } // Check that reverse iterator produces reverse sequence. // Note: this test is not valid. It is by no means guaranteed that reverse iteration of a // sorted index will produce the reverse result of forward iteration. I no two annotations // are equal wrt the sort order, this works of course. However, if some FSs are equal wrt // the sort order, those may be returned in any order. // it.moveToLast(); // System.out.println(it.get()); // for (int i = v.size() - 1; i >= 0; i--) { // assertTrue(it.isValid()); // assertTrue(it.get().hashCode() == v.get(i)); // it.moveToPrevious(); // } // ///////////////////////////////////////////////////////////////////////// // Use an iterator to move forwards and backwards and make sure the // sequence // remains constant. it = sortedIndex.iterator(); it.moveToFirst(); // This is redundant. current = 1; // System.out.println("Codes: " + v); while (current < (v.size() - 1)) { it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current + 1)); it.moveToPrevious(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); ++current; } // also test Java-style iteration javaIt = sortedIndex.iterator(); current = 0; while (javaIt.hasNext()) { assertEquals(javaIt.next().hashCode(), v.get(current++)); } // ///////////////////////////////////////////////////////////////////////// // Test fast fail. it = bagIndex.iterator(); // use bag index, remove add last one // (preserves order for other tests). it.moveToLast(); a = (AnnotationFS) it.get(); // for (it = sortedIndex.iterator(); it.hasNext(); it.next()) { // System.out.println(it.get()); // } it = sortedIndex.iterator(); it.next(); it.next(); this.cas.getIndexRepository().removeFS(a); this.cas.getIndexRepository().addFS(a); ok = false; try { it.get(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); ok = false; try { it.next(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); ok = false; try { it.moveToNext(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); it.moveTo(a); ok = false; try { it.next(); // should not throw ok = true; } catch (ConcurrentModificationException e) { // checking with boolean "ok" } assertTrue(ok); sortedIndex = null; // ///////////////////////////////////////////////////////////////////////// // Test bag index. // System.out.println("Number of annotations: " + sortedIndex.size()); assertTrue(bagIndex.size() == 100); v = new IntVector(); it = bagIndex.iterator(); b = null; while (it.isValid()) { a = (AnnotationFS) it.get(); assertTrue(a != null); if (b != null) { assertTrue(bagIndex.compare(b, a) <= 0); } b = a; v.add(a.hashCode()); it.moveToNext(); } assertTrue(bagIndex.size() == v.size()); // Check that reverse iterator produces reverse sequence. it.moveToLast(); for (int i = v.size() - 1; i >= 0; i--) { assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(i)); it.moveToPrevious(); } // ///////////////////////////////////////////////////////////////////////// // Use an iterator to move forwards and backwards and make sure the // sequence // remains constant. it = bagIndex.iterator(); it.moveToFirst(); // This is redundant. current = 1; // System.out.println("Codes: " + v); while (current < (v.size() - 1)) { it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); it.moveToNext(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current + 1)); it.moveToPrevious(); assertTrue(it.isValid()); assertTrue(it.get().hashCode() == v.get(current)); ++current; } // also test Java-style iteration javaIt = bagIndex.iterator(); current = 0; while (javaIt.hasNext()) { assertEquals(javaIt.next().hashCode(), v.get(current++)); } // Test iterator copy. FSIterator source, copy; source = this.cas.getAnnotationIndex().iterator(); // Count items. int count = 0; for (source.moveToFirst(); source.isValid(); source.moveToNext()) { ++count; } final int max = count; count = 0; source.moveToFirst(); copy = source.copy(); copy.moveToFirst(); // System.out.println("Max: " + max); while (count < max) { // System.out.println("Count: " + count); assertTrue(source.isValid()); assertTrue(copy.isValid()); String out = source.get().toString() + copy.get().toString(); assertTrue(out, source.get().equals(copy.get())); source.moveToNext(); copy.moveToNext(); ++count; } // ///////////////////////////////////////////////////////////////////////// // Test fast fail. it = bagIndex.iterator(); // use bag index, remove add last one // (preserves order for other tests). it.moveToLast(); a = (AnnotationFS) it.get(); this.cas.getIndexRepository().removeFS(a); this.cas.getIndexRepository().addFS(a); ok = false; try { it.get(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); it.moveToLast(); it.moveToPrevious(); it.moveToPrevious(); it.moveToPrevious(); it.moveToNext(); this.cas.getIndexRepository().removeFS(a); this.cas.getIndexRepository().addFS(a); ok = false; try { it.moveToNext(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); ok = false; try { it.moveToPrevious(); // should throw } catch (ConcurrentModificationException e) { ok = true; } assertTrue(ok); it.moveTo(a); ok = false; try { it.next(); // should not throw ok = true; } catch (ConcurrentModificationException e) { // checking with boolean "ok" } assertTrue(ok); } /** * Test deleting FSs from indexes. */ public void testDelete() { // Create a bunch of FSs. AnnotationFS[] fsArray = new AnnotationFS[100]; FSIndexRepository ir = this.cas.getIndexRepository(); for (int i = 0; i < fsArray.length; i++) { fsArray[i] = this.cas.createAnnotation(this.tokenType, i * 5, (i * 5) + 4); ir.addFS(fsArray[i]); } FSIndex setIndex = this.cas.getIndexRepository().getIndex( CASTestSetup.ANNOT_SET_INDEX, this.tokenType); FSIterator setIt = setIndex.iterator(); FSIndex sortedIndex = this.cas.getAnnotationIndex(this.tokenType); FSIterator sortedIt = sortedIndex.iterator(); FSIndex bagIndex = ir.getIndex(CASTestSetup.ANNOT_BAG_INDEX, this.tokenType); FSIterator bagIt = bagIndex.iterator(); // For each index, check that the FSs are actually in the index. for (int i = 0; i < fsArray.length; i++) { setIt.moveTo(fsArray[i]); assertTrue(setIt.isValid()); assertTrue(setIt.get().equals(fsArray[i])); bagIt.moveTo(fsArray[i]); assertTrue(bagIt.isValid()); assertTrue(bagIt.get().equals(fsArray[i])); sortedIt.moveTo(fsArray[i]); assertTrue(sortedIt.isValid()); assertTrue(sortedIt.get().equals(fsArray[i])); } // Remove an annotation, then add it again. Try setting the iterators to // that FS. The iterator should either be invalid, or point to a // different FS. for (int i = 0; i < fsArray.length; i++) { ir.removeFS(fsArray[i]); setIt.moveTo(fsArray[i]); if (setIt.isValid()) { int oldRef = this.cas.ll_getFSRef(fsArray[i]); int newRef = this.cas.ll_getFSRef(setIt.get()); assertTrue(oldRef != newRef); assertTrue(!setIt.get().equals(fsArray[i])); } bagIt.moveTo(fsArray[i]); if (bagIt.isValid()) { assertTrue(!bagIt.get().equals(fsArray[i])); } sortedIt.moveTo(fsArray[i]); if (sortedIt.isValid()) { assertTrue(!sortedIt.get().equals(fsArray[i])); } ir.addFS(fsArray[i]); } // Remove all annotations. for (int i = 0; i < fsArray.length; i++) { ir.removeFS(fsArray[i]); } // All iterators should be invalidated when being reset. bagIt.moveToFirst(); assertFalse(bagIt.isValid()); setIt.moveToFirst(); assertFalse(setIt.isValid()); sortedIt.moveToFirst(); assertFalse(sortedIt.isValid()); } public void testInvalidIndexRequest() { boolean exc = false; try { this.cas.getIndexRepository().getIndex(CASTestSetup.ANNOT_BAG_INDEX, this.stringType); } catch (CASRuntimeException e) { exc = true; } assertTrue(exc); } public static void main(String[] args) { junit.textui.TestRunner.run(IteratorTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/Sentence_Type.java0000644000175000017500000000505611665471060027354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Thu Jun 21 11:28:13 MDT 2007 */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.cas.Type; import org.apache.uima.jcas.tcas.Annotation_Type; /** * Updated by JCasGen Thu Jun 21 12:00:34 MDT 2007 * @generated */ public class Sentence_Type extends Annotation_Type { /** @generated */ protected FSGenerator getFSGenerator() {return fsGenerator;} /** @generated */ private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (Sentence_Type.this.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = Sentence_Type.this.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Sentence(addr, Sentence_Type.this); Sentence_Type.this.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Sentence(addr, Sentence_Type.this); } }; /** @generated */ public final static int typeIndexID = Sentence.typeIndexID; /** @generated @modifiable */ public final static boolean featOkTst = JCasRegistry.getFeatOkTst("uima464.Sentence"); /** initialize variables to correspond with Cas Type and Features * @generated */ public Sentence_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl)this.casType, getFSGenerator()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/Token.java0000644000175000017500000000443511665471060025667 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Thu Jun 21 11:28:13 MDT 2007 */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JCasRegistry; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /** * Updated by JCasGen Thu Jun 21 12:00:34 MDT 2007 * XML source: C:/Documents and Settings/Philip/My Documents/CSLR/workspace/UIMA-464/desc/TokensAndSentences.xml * @generated */ public class Token extends Annotation { /** @generated * @ordered */ public final static int typeIndexID = JCasRegistry.register(Token.class); /** @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() {return typeIndexID;} /** Never called. Disable default constructor * @generated */ protected Token() {} /** Internal - constructor used by generator * @generated */ public Token(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public Token(JCas jcas) { super(jcas); readObject(); } /** @generated */ public Token(JCas jcas, int begin, int end) { super(jcas); setBegin(begin); setEnd(end); readObject(); } /** * Write your own initialization here * @generated modifiable */ private void readObject() {} } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/SubiteratorAnnotator.java0000644000175000017500000000421711665471060030776 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.analysis_component.JCasAnnotator_ImplBase; import org.apache.uima.jcas.JCas; public class SubiteratorAnnotator extends JCasAnnotator_ImplBase { public SubiteratorAnnotator() { super(); } public void process(JCas jCas) { String text = jCas.getDocumentText(); boolean isInToken = false; int tokenStart = 0; for (int i = 0; i < text.length(); i++) { char c = text.charAt(i); if (Character.isLetterOrDigit(c)) { if (!isInToken) { isInToken = true; tokenStart = i; } } else { if (isInToken) { isInToken = false; Token token = new Token(jCas); token.setBegin(tokenStart); token.setEnd(i); token.addToIndexes(); } } } if (isInToken) { Token token = new Token(jCas); token.setBegin(tokenStart); token.setEnd(text.length()); token.addToIndexes(); } int sentenceStart = 0; for (int i = 0; i < text.length(); i++) { if (text.charAt(i) == '.') { Sentence sentence = new Sentence(jCas); sentence.setBegin(sentenceStart); sentence.setEnd(i+1); sentence.addToIndexes(); sentenceStart = i + 1; } } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/ArrayIndexTest.java0000644000175000017500000001060611665471060027512 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException; import org.apache.uima.analysis_engine.annotator.AnnotatorContext; import org.apache.uima.analysis_engine.annotator.AnnotatorInitializationException; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.TextAnnotator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ArrayIndexTest extends TestCase implements TextAnnotator { private static final String idxId = "ArrayIndex"; private AnalysisEngine ae = null; protected void setUp() throws Exception { super.setUp(); // Start up TAE XMLInputSource input = new XMLInputSource(JUnitExtension .getFile("CASTests/desc/ArrayIndexTest.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(input); this.ae = UIMAFramework.produceAnalysisEngine(desc); } public void testArrayIndex() { try { CAS cas = this.ae.newCAS(); FSIndexRepository ir = cas.getIndexRepository(); TypeSystem ts = cas.getTypeSystem(); Type annotationType = ts.getType(CAS.TYPE_NAME_ANNOTATION); Type annotArrayType = ts.getArrayType(annotationType); FSIndex arrayIndexAll = ir.getIndex(idxId); assertEquals(countIndexMembers(arrayIndexAll), 0); FSIndex arrayIndexFSArray = ir.getIndex(idxId, ts.getType(CAS.TYPE_NAME_FS_ARRAY)); assertEquals(countIndexMembers(arrayIndexFSArray), 0); FSIndex arrayIndexAnnotArray = ir.getIndex(idxId, annotArrayType); assertNull(arrayIndexAnnotArray); } catch (ResourceInitializationException e) { assertTrue(false); } } private static final int countIndexMembers(FSIndex idx) { FSIterator it = idx.iterator(); int count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } return count; } protected void tearDown() throws Exception { super.tearDown(); this.ae.destroy(); } public void process(CAS aCAS, ResultSpecification aResultSpec) throws AnnotatorProcessException { // Do nothing. } public void initialize(AnnotatorContext aContext) throws AnnotatorInitializationException, AnnotatorConfigurationException { // do nothing } public void typeSystemInit(TypeSystem aTypeSystem) throws AnnotatorInitializationException, AnnotatorConfigurationException { // do nothing } public void reconfigure() throws AnnotatorConfigurationException, AnnotatorInitializationException { // do nothing } public void destroy() { // do nothing } public static void main(String[] args) { junit.textui.TestRunner.run(ArrayIndexTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CompleteSerializationTest.java0000644000175000017500000000606111665471060031752 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.impl.CASCompleteSerializer; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.Serialization; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; /** * CAS complete serialization test class * */ public class CompleteSerializationTest extends TestCase { /** * Constructor for CASTest. * * @param arg0 */ public CompleteSerializationTest(String arg0) { super(arg0); } public void testSerialization() throws Exception { try { CASMgr cas = null; try { cas = (CASMgr) CASInitializer.initCas(new CASTestSetup()); } catch (Exception e) { assertTrue(false); } ((CAS) cas).setDocumentText("Create the sofa for the inital view"); assertTrue(((CASImpl) cas).isBackwardCompatibleCas()); CASCompleteSerializer ser = Serialization.serializeCASComplete(cas); // deserialize into a new CAS with a type system that only contains the builtins CAS newCas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); try { Serialization.deserializeCASComplete(ser, (CASImpl) newCas); } catch (Exception e) { assertTrue(false); } assertTrue(cas.getTypeSystemMgr().getType(CASTestSetup.GROUP_1) != null); assertTrue(((CASImpl) newCas).isBackwardCompatibleCas()); assertEquals("Create the sofa for the inital view", newCas.getDocumentText()); // make sure JCas can be created newCas.getJCas(); // deserialize into newCas a second time (OF bug found 7/7/2006) try { Serialization.deserializeCASComplete(ser, (CASImpl) newCas); } catch (Exception e) { assertTrue(false); } assertTrue(cas.getTypeSystemMgr().getType(CASTestSetup.GROUP_1) != null); assertTrue(((CASImpl) newCas).isBackwardCompatibleCas()); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/FilteredIteratorTest.java0000644000175000017500000005066311665471060030723 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import java.util.ArrayList; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.ConstraintFactory; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FSMatchConstraint; import org.apache.uima.cas.FSStringConstraint; import org.apache.uima.cas.FSTypeConstraint; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeaturePath; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.text.AnnotationFS; /** * Class comment for FilteredIteratorTest.java goes here. * */ public class FilteredIteratorTest extends TestCase { private CAS cas; private TypeSystem ts; private Type stringType; private Type tokenType; private Type intType; private Type tokenTypeType; private Type wordType; private Type sepType; private Type eosType; private Feature tokenTypeFeat; private Feature lemmaFeat; private Feature sentLenFeat; private Feature tokenFloatFeat; private Feature startFeature; private Type sentenceType; private Type annotationType; /** * Constructor for FilteredIteratorTest. * * @param arg0 */ public FilteredIteratorTest(String arg0) { super(arg0); } public void setUp() { try { this.cas = CASInitializer.initCas(new CASTestSetup()); assertTrue(cas != null); this.ts = this.cas.getTypeSystem(); assertTrue(ts != null); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } this.stringType = ts.getType(CAS.TYPE_NAME_STRING); assertTrue(stringType != null); this.tokenType = ts.getType(CASTestSetup.TOKEN_TYPE); assertTrue(stringType != null); this.intType = ts.getType(CAS.TYPE_NAME_INTEGER); assertTrue(intType != null); this.tokenTypeType = ts.getType(CASTestSetup.TOKEN_TYPE_TYPE); assertTrue(tokenTypeType != null); this.wordType = ts.getType(CASTestSetup.WORD_TYPE); assertTrue(wordType != null); this.sepType = ts.getType(CASTestSetup.SEP_TYPE); assertTrue(sepType != null); this.eosType = ts.getType(CASTestSetup.EOS_TYPE); assertTrue(eosType != null); this.tokenTypeFeat = ts.getFeatureByFullName(CASTestSetup.TOKEN_TYPE_FEAT_Q); assertTrue(tokenTypeFeat != null); this.lemmaFeat = ts.getFeatureByFullName(CASTestSetup.LEMMA_FEAT_Q); assertTrue(lemmaFeat != null); this.sentLenFeat = ts.getFeatureByFullName(CASTestSetup.SENT_LEN_FEAT_Q); assertTrue(sentLenFeat != null); this.tokenFloatFeat = ts.getFeatureByFullName(CASTestSetup.TOKEN_FLOAT_FEAT_Q); assertTrue(tokenFloatFeat != null); this.startFeature = ts.getFeatureByFullName(CAS.FEATURE_FULL_NAME_BEGIN); assertTrue(startFeature != null); this.sentenceType = ts.getType(CASTestSetup.SENT_TYPE); assertTrue(sentenceType != null); this.annotationType = ts.getType(CAS.TYPE_NAME_ANNOTATION); assertTrue(annotationType != null); } public void tearDown() { this.cas = null; this.ts = null; this.stringType = null; this.tokenType = null; this.intType = null; this.tokenTypeType = null; this.wordType = null; this.sepType = null; this.eosType = null; this.tokenTypeFeat = null; this.lemmaFeat = null; this.sentLenFeat = null; this.tokenFloatFeat = null; this.startFeature = null; this.sentenceType = null; this.annotationType = null; } public void testIterator1() { try { // cas.setDocumentText("A test."); can't set document text twice } catch (CASRuntimeException e) { assertTrue(false); } try { cas.setDocumentText("This is a test."); } catch (CASRuntimeException e) { assertTrue(false); } // create token and sentence annotations cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 0, 4)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 5, 7)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 8, 9)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 10, 14)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 14, 15)); cas.getIndexRepository().addFS(cas.createAnnotation(sentenceType, 0, 15)); // create filtered iterator over Tokens only FSIterator it = cas.getAnnotationIndex().iterator(); FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint(); constraint.add(tokenType); it = cas.createFilteredIterator(it, constraint); // do iteration while (it.isValid()) { AnnotationFS a = (AnnotationFS) it.get(); assertTrue(a.getType().equals(tokenType)); // System.out.println("Annotation type: " + a.getType().getName()); // System.out.println("Covered text: " + a.getCoveredText()); it.moveToNext(); } // Count number of annotations. it = cas.getAnnotationIndex().iterator(); int countAll = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++countAll; } // create filtered iterator over annotations it = cas.getAnnotationIndex().iterator(); constraint = cas.getConstraintFactory().createTypeConstraint(); constraint.add(annotationType); it = cas.createFilteredIterator(it, constraint); // do iteration int countFiltered = 0; while (it.isValid()) { AnnotationFS a = (AnnotationFS) it.get(); assertTrue(ts.subsumes(annotationType, a.getType())); // System.out.println("Annotation type: " + a.getType().getName()); // System.out.println("Covered text: " + a.getCoveredText()); it.moveToNext(); ++countFiltered; } assertTrue(countAll == countFiltered); } public void testIterator1a() { try { // cas.setDocumentText("A test."); can't set document text twice! } catch (CASRuntimeException e) { assertTrue(false); } try { cas.setDocumentText("This is a test."); } catch (CASRuntimeException e) { assertTrue(false); } // create token and sentence annotations cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 0, 4)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 5, 7)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 8, 9)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 10, 14)); cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 14, 15)); cas.getIndexRepository().addFS(cas.createAnnotation(sentenceType, 0, 15)); // create filtered iterator over Tokens only FSIterator it = cas.getAnnotationIndex().iterator(); FSTypeConstraint constraint = cas.getConstraintFactory().createTypeConstraint(); constraint.add(tokenType.getName()); it = cas.createFilteredIterator(it, constraint); // do iteration while (it.isValid()) { AnnotationFS a = (AnnotationFS) it.get(); assertTrue(a.getType().equals(tokenType)); // System.out.println("Annotation type: " + a.getType().getName()); // System.out.println("Covered text: " + a.getCoveredText()); it.moveToNext(); } } // test uses constraint compiler /* * public void testIterator1b() { * * try { cas.setDocumentText("A test."); } catch (CASRuntimeException e) { assertTrue(false); } * ((CASMgr) cas).enableSetText(false); boolean exc = false; try { cas.setDocumentText("A * test."); } catch (CASRuntimeException e) { assertTrue(e.getError() == * CASRuntimeException.SET_DOC_TEXT_DISABLED); exc = true; } assertTrue(exc); ((CASMgr) * cas).enableSetText(true); * * try { ((CASMgr) cas).setDocumentText("This is a test."); } catch (CASRuntimeException e) { * assertTrue(false); } //create token and sentence annotations * cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 0, 4)); * cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 5, 7)); * cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 8, 9)); * cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 10, 14)); * cas.getIndexRepository().addFS(cas.createAnnotation(tokenType, 14, 15)); * cas.getIndexRepository().addFS(cas.createAnnotation(sentenceType, 0, 15)); * * //create filtered iterator over Tokens only FSIterator it = * cas.getAnnotationIndex().iterator(); // FSTypeConstraint constraint = // * cas.getConstraintFactory().createTypeConstraint(); // constraint.add(tokenType.getName()); * * FSMatchConstraint constraint = null; try { ConstraintParser parser = * ConstraintParserFactory.getDefaultConstraintParser(); constraint = parser.parse("isa " + * tokenType.getName()); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } * * it = cas.createFilteredIterator(it, constraint); * * //do iteration while (it.isValid()) { AnnotationFS a = (AnnotationFS) it.get(); * assertTrue(a.getType().equals(tokenType)); // System.out.println("Annotation type: " + * a.getType().getName()); // System.out.println("Covered text: " + a.getCoveredText()); * it.moveToNext(); } } */ public void testIterator2() { try { cas.setDocumentText("This is a test with the word \"the\" in it."); // create token and sentence annotations String type1 = "type1"; String type2 = "type2"; AnnotationFS token; token = cas.createAnnotation(tokenType, 0, 4); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 5, 7); token.setStringValue(lemmaFeat, "the"); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 8, 9); token.setStringValue(lemmaFeat, type2); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 10, 14); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 14, 15); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 0, 15); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); String lemma = "the"; // create filtered iterator over Tokens of type 1 FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); FSStringConstraint type1Constraint = cas.getConstraintFactory().createStringConstraint(); type1Constraint.equals(lemma); FeaturePath path = cas.createFeaturePath(); path.addFeature(lemmaFeat); FSMatchConstraint cons = cas.getConstraintFactory().embedConstraint(path, type1Constraint); it = cas.createFilteredIterator(it, cons); int count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } // ///////////////////////////////////////////////////////////// // Count instances of tokens with lemma "the". // Create an iterator over Token annotations. FSIndex tokenIndex = cas.getAnnotationIndex(tokenType); FSIterator tokenIt = tokenIndex.iterator(); // Create a counter. int theCount = 0; // Iterate over the tokens. for (tokenIt.moveToFirst(); tokenIt.isValid(); tokenIt.moveToNext()) { AnnotationFS tok = (AnnotationFS) tokenIt.get(); if (tok.getStringValue(lemmaFeat).equals(lemma)) { ++theCount; // System.out.println("Found token: " + tok.getCoveredText()); } } assertTrue(count == theCount); // System.out.println( // "Number of tokens with \"" + lemma + "\": " + theCount); // System.out.println("Number of tokens overall: " + tokenIndex.size()); // System.out.println("Count: " + count); // assertTrue(count == 4); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } public void testIterator2a() { try { cas.setDocumentText("This is a test with the word \"the\" in it."); // create token and sentence annotations String type1 = "type1"; String type2 = "type2"; AnnotationFS token; token = cas.createAnnotation(tokenType, 0, 4); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 5, 7); token.setStringValue(lemmaFeat, "the"); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 8, 9); token.setStringValue(lemmaFeat, type2); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 10, 14); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 14, 15); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 0, 15); token.setStringValue(lemmaFeat, type1); cas.getIndexRepository().addFS(token); String lemma = "the"; FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); FSStringConstraint type1Constraint = cas.getConstraintFactory().createStringConstraint(); type1Constraint.equals(lemma); ArrayList path = new ArrayList(); path.add(lemmaFeat.getShortName()); FSMatchConstraint cons = cas.getConstraintFactory().embedConstraint(path, type1Constraint); it = cas.createFilteredIterator(it, cons); int count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } // ///////////////////////////////////////////////////////////// // Count instances of tokens with lemma "the". // Create an iterator over Token annotations. FSIndex tokenIndex = cas.getAnnotationIndex(tokenType); FSIterator tokenIt = tokenIndex.iterator(); // Create a counter. int theCount = 0; // Iterate over the tokens. for (tokenIt.moveToFirst(); tokenIt.isValid(); tokenIt.moveToNext()) { AnnotationFS tok = (AnnotationFS) tokenIt.get(); if (tok.getStringValue(lemmaFeat).equals(lemma)) { ++theCount; // System.out.println("Found token: " + tok.getCoveredText()); } } assertTrue(count == theCount); // System.out.println( // "Number of tokens with \"" + lemma + "\": " + theCount); // System.out.println("Number of tokens overall: " + tokenIndex.size()); // System.out.println("Count: " + count); // assertTrue(count == 4); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } public void testIterator2b() { try { cas.setDocumentText("This is a test with the word \"the\" in it."); FeatureStructure wordFS = this.cas.createFS(wordType); FeatureStructure sepFS = this.cas.createFS(sepType); FeatureStructure eosFS = this.cas.createFS(eosType); // create token and sentence annotations String type1 = "type1"; String type2 = "type2"; AnnotationFS token; token = cas.createAnnotation(tokenType, 0, 4); token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, wordFS); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 5, 7); token.setStringValue(lemmaFeat, "the"); token.setFeatureValue(tokenTypeFeat, sepFS); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 8, 9); token.setStringValue(lemmaFeat, type2); token.setFeatureValue(tokenTypeFeat, eosFS); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 10, 14); token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, wordFS); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 14, 15); token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, sepFS); cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 0, 15); token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, eosFS); cas.getIndexRepository().addFS(token); FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); ConstraintFactory cf = this.cas.getConstraintFactory(); FSTypeConstraint tc = cf.createTypeConstraint(); tc.add(sepType); tc.add(eosType.getName()); ArrayList path = new ArrayList(); path.add(tokenTypeFeat.getShortName()); FSMatchConstraint cons = cf.embedConstraint(path, tc); it = this.cas.createFilteredIterator(it, cons); int count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } assertTrue(count == 4); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } // test uses constraint compiler /* * public void testIterator2c() { try { ((CASMgr) cas).setDocumentText( "This is a test with the * word \"the\" in it."); * * FeatureStructure wordFS = this.cas.createFS(wordType); FeatureStructure sepFS = * this.cas.createFS(sepType); FeatureStructure eosFS = this.cas.createFS(eosType); * * //create token and sentence annotations String type1 = "type1"; String type2 = "type2"; * AnnotationFS token; token = cas.createAnnotation(tokenType, 0, 4); * token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, wordFS); * cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 5, 7); * token.setStringValue(lemmaFeat, "the"); token.setFeatureValue(tokenTypeFeat, sepFS); * cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 8, 9); * token.setStringValue(lemmaFeat, type2); token.setFeatureValue(tokenTypeFeat, eosFS); * cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 10, 14); * token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, wordFS); * cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 14, 15); * token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, sepFS); * cas.getIndexRepository().addFS(token); token = cas.createAnnotation(tokenType, 0, 15); * token.setStringValue(lemmaFeat, type1); token.setFeatureValue(tokenTypeFeat, eosFS); * cas.getIndexRepository().addFS(token); * * FSIterator it = cas.getAnnotationIndex(tokenType).iterator(); * * FSMatchConstraint cons = null; try { ConstraintParser parser = * ConstraintParserFactory.getDefaultConstraintParser(); cons = parser.parse( * tokenTypeFeat.getShortName() + " isa (" + sepType.getName() + "|" + eosType.getName() + ")"); } * catch (Exception e) { assertTrue(false); } it = this.cas.createFilteredIterator(it, cons); int * count = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++count; } assertTrue(count == * 4); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } * * public static void main(String[] args) { FilteredIteratorTest test = new * FilteredIteratorTest(null); test.run(); } */ } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/StringSubtypeAnnotation.java0000644000175000017500000000653511665471060031467 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* First created by JCasGen Fri Dec 22 14:02:31 CET 2006 */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /** * Updated by JCasGen Fri Dec 22 14:02:31 CET 2006 * XML source: C:/code/trunk/uimaj-core/src/test/resources/CASTests/desc/StringSubtypeTest.xml * @generated */ public class StringSubtypeAnnotation extends Annotation { /** @generated * @ordered */ public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(StringSubtypeAnnotation.class); /** @generated * @ordered */ public final static int type = typeIndexID; /** @generated */ public int getTypeIndexID() {return typeIndexID;} /** Never called. Disable default constructor * @generated */ protected StringSubtypeAnnotation() {} /** Internal - constructor used by generator * @generated */ public StringSubtypeAnnotation(int addr, TOP_Type type) { super(addr, type); readObject(); } /** @generated */ public StringSubtypeAnnotation(JCas jcas) { super(jcas); readObject(); } /** @generated */ public StringSubtypeAnnotation(JCas jcas, int begin, int end) { super(jcas); setBegin(begin); setEnd(end); readObject(); } /** * Write your own initialization here * @generated modifiable */ private void readObject() {} //*--------------* //* Feature: stringSetFeature /** getter for stringSetFeature - gets * @generated */ public String getStringSetFeature() { if (StringSubtypeAnnotation_Type.featOkTst && ((StringSubtypeAnnotation_Type)jcasType).casFeat_stringSetFeature == null) this.jcasType.jcas.throwFeatMissing("stringSetFeature", "org.apache.uima.cas.test.StringSubtypeAnnotation"); return jcasType.ll_cas.ll_getStringValue(addr, ((StringSubtypeAnnotation_Type)jcasType).casFeatCode_stringSetFeature);} /** setter for stringSetFeature - sets * @generated */ public void setStringSetFeature(String v) { if (StringSubtypeAnnotation_Type.featOkTst && ((StringSubtypeAnnotation_Type)jcasType).casFeat_stringSetFeature == null) this.jcasType.jcas.throwFeatMissing("stringSetFeature", "org.apache.uima.cas.test.StringSubtypeAnnotation"); jcasType.ll_cas.ll_setStringValue(addr, ((StringSubtypeAnnotation_Type)jcasType).casFeatCode_stringSetFeature, v);} } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/test/CrossAnnotation.java0000644000175000017500000000513611665471060027732 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.test; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /** * An annotation holding another annotation. */ public class CrossAnnotation extends Annotation { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(CrossAnnotation.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected CrossAnnotation() { //do nothing } /** Internal - Constructor used by generator */ public CrossAnnotation(int addr, TOP_Type type) { super(addr, type); } public CrossAnnotation(JCas jcas) { super(jcas); } // *------------------* // * Feature: otherAnnotation /** getter for otherAnnotation * */ public Annotation getOtherAnnotation() { if (CrossAnnotation_Type.featOkTst && ((CrossAnnotation_Type) jcasType).casFeat_otherAnnotation == null) this.jcasType.jcas.throwFeatMissing("otherAnnotation", "uima.tcas.CrossAnnotation"); return (Annotation) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((CrossAnnotation_Type) jcasType).casFeatCode_otherAnnotation))); } /** setter for otherAnnotation * */ public void setOtherAnnotation(Annotation v) { if (CrossAnnotation_Type.featOkTst && ((CrossAnnotation_Type) jcasType).casFeat_otherAnnotation == null) this.jcasType.jcas.throwFeatMissing("otherAnnotation", "uima.tcas.CrossAnnotation"); jcasType.ll_cas.ll_setRefValue(addr, ((CrossAnnotation_Type) jcasType).casFeatCode_otherAnnotation, jcasType.ll_cas .ll_getFSRef(v)); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/0000755000175000017500000000000011665471060023720 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasDeserializerTest.java0000644000175000017500000025116711665471060031166 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.Iterator; import java.util.List; import java.util.Stack; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.UIMARuntimeException; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.Marker; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.XmiSerializationSharedData.OotsElementData; import org.apache.uima.cas.impl.XmiSerializationSharedData.XmiArrayElement; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas_data.impl.CasComparer; import org.apache.uima.internal.util.XmlAttribute; import org.apache.uima.internal.util.XmlElementNameAndContents; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCopier; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.FileUtils; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.DefaultHandler; public class XmiCasDeserializerTest extends TestCase { private FsIndexDescription[] indexes; private TypeSystemDescription typeSystem; /** * Constructor for XCASDeserializerTest. * * @param arg0 */ public XmiCasDeserializerTest(String arg0) throws IOException { super(arg0); } protected void setUp() throws Exception { File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) .getFsIndexes(); } public void testDeserializeAndReserialize() throws Exception { try { File tsWithNoMultiRefs = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); doTestDeserializeAndReserialize(tsWithNoMultiRefs,false); File tsWithMultiRefs = JUnitExtension.getFile("ExampleCas/testTypeSystem_withMultiRefs.xml"); doTestDeserializeAndReserialize(tsWithMultiRefs,false); //also test with JCas initialized doTestDeserializeAndReserialize(tsWithNoMultiRefs,true); doTestDeserializeAndReserialize(tsWithMultiRefs,true); } catch (Exception e) { JUnitExtension.handleException(e); } } private void doTestDeserializeAndReserialize(File typeSystemDescriptorFile, boolean useJCas) throws Exception { // deserialize a complex CAS from XCAS TypeSystemDescription typeSystemDescription = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemDescriptorFile)); CAS cas = CasCreationUtils.createCas(typeSystemDescription, new TypePriorities_impl(), indexes); if (useJCas) { cas.getJCas(); } InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // reserialize as XMI String xml = serialize(cas, null); // System.out.println(xml); // deserialize into another CAS CAS cas2 = CasCreationUtils.createCas(typeSystemDescription, new TypePriorities_impl(), indexes); if (useJCas) { cas2.getJCas(); } XmiCasDeserializer deser2 = new XmiCasDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXmiCasHandler(cas2); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // compare assertEquals(cas.getAnnotationIndex().size(), cas2.getAnnotationIndex().size()); assertEquals(cas.getDocumentText(), cas2.getDocumentText()); CasComparer.assertEquals(cas,cas2); // check that array refs are not null Type entityType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity"); Feature classesFeat = entityType.getFeatureByBaseName("classes"); Iterator iter = cas2.getIndexRepository().getIndex("testEntityIndex").iterator(); assertTrue(iter.hasNext()); while (iter.hasNext()) { FeatureStructure fs = iter.next(); StringArrayFS arrayFS = (StringArrayFS) fs.getFeatureValue(classesFeat); assertNotNull(arrayFS); for (int i = 0; i < arrayFS.size(); i++) { assertNotNull(arrayFS.get(i)); } } Type annotArrayTestType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.AnnotationArrayTest"); Feature annotArrayFeat = annotArrayTestType.getFeatureByBaseName("arrayOfAnnotations"); Iterator iter2 = cas2.getAnnotationIndex(annotArrayTestType).iterator(); assertTrue(iter2.hasNext()); while (iter2.hasNext()) { FeatureStructure fs = iter2.next(); ArrayFS arrayFS = (ArrayFS) fs.getFeatureValue(annotArrayFeat); assertNotNull(arrayFS); for (int i = 0; i < arrayFS.size(); i++) { assertNotNull(arrayFS.get(i)); } } // test that lenient mode does not report errors CAS cas3 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), new TypePriorities_impl(), new FsIndexDescription[0]); if (useJCas) { cas3.getJCas(); } XmiCasDeserializer deser3 = new XmiCasDeserializer(cas3.getTypeSystem()); ContentHandler deserHandler3 = deser3.getXmiCasHandler(cas3, true); xmlReader.setContentHandler(deserHandler3); xmlReader.parse(new InputSource(new StringReader(xml))); } public void testMultiThreadedSerialize() throws Exception { try { File tsWithNoMultiRefs = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); doTestMultiThreadedSerialize(tsWithNoMultiRefs); File tsWithMultiRefs = JUnitExtension.getFile("ExampleCas/testTypeSystem_withMultiRefs.xml"); doTestMultiThreadedSerialize(tsWithMultiRefs); } catch (Exception e) { JUnitExtension.handleException(e); } } private static class DoSerialize implements Runnable{ private CAS cas; DoSerialize(CAS aCas) { cas = aCas; } public void run() { try { serialize(cas, null); // serialize(cas, null); // serialize(cas, null); // serialize(cas, null); } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } } } private static int MAX_THREADS = 16; // do as sequence 1, 2, 4, 8, 16 and measure elapsed time private static int [] threadsToUse = new int[] {1, 2, 4, 8, 16/*, 32, 64*/}; private void doTestMultiThreadedSerialize(File typeSystemDescriptor) throws Exception { // deserialize a complex CAS from XCAS CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // make n copies of the cas, so they all share // the same type system final CAS [] cases = new CAS[MAX_THREADS]; for (int i = 0; i < MAX_THREADS; i++) { cases[i] = CasCreationUtils.createCas(cas.getTypeSystem(), new TypePriorities_impl(), indexes, null); CasCopier.copyCas(cas, cases[i], true); } // start n threads, serializing as XMI for (int i = 0; i < threadsToUse.length; i++) { Thread [] threads = new Thread[MAX_THREADS]; long startTime = System.currentTimeMillis(); for (int ti = 0; ti < threadsToUse[i]; ti++) { threads[ti] = new Thread(new DoSerialize(cases[ti])); threads[ti].start(); } for (int ti = 0; ti < threadsToUse[i]; ti++) { threads[ti].join(); //System.out.print(" "+ ti); } System.out.println("\nNumber of threads serializing: " + threadsToUse[i] + " Normalized millisecs (should be close to the same): " + (System.currentTimeMillis() - startTime) / threadsToUse[i]); } } public void testDeltaCasIndexExistingFsInView() throws Exception { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); cas1.setDocumentText("This is a test document in the initial view"); Type referentType = cas1.getTypeSystem().getType("org.apache.uima.testTypeSystem.Referent"); FeatureStructure fs1 = cas1.createFS(referentType); cas1.getIndexRepository().addFS(fs1); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); System.out.println(xml); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); //create View CAS view = cas2.createView("NewView"); //add FS to index Type referentType2 = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Referent"); Iterator fsIter = cas2.getIndexRepository().getAllIndexedFS(referentType2); while (fsIter.hasNext()) { FeatureStructure fs = fsIter.next(); view.getIndexRepository().addFS(fs); } AnnotationFS cas2newAnnot = view.createAnnotation(cas2.getAnnotationType(), 6, 8); view.getIndexRepository().addFS(cas2newAnnot); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); System.out.println(deltaxml1); //deserialize delta xmi into cas1 this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.allow); //check that new View contains the FS CAS deserView = cas1.getView("NewView"); Iterator deserFsIter = deserView.getIndexRepository().getAllIndexedFS(referentType); assertTrue(deserFsIter.hasNext()); } public void testDeltaCasIndexExistingFsInNewView() throws Exception { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); cas1.setDocumentText("This is a test document in the initial view"); Type referentType = cas1.getTypeSystem().getType("org.apache.uima.testTypeSystem.Referent"); FeatureStructure fs1 = cas1.createFS(referentType); cas1.getIndexRepository().addFS(fs1); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); System.out.println(xml); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); //create View CAS view = cas2.createView("NewView"); //add FS to index Type referentType2 = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Referent"); Iterator fsIter = cas2.getIndexRepository().getAllIndexedFS(referentType2); while (fsIter.hasNext()) { FeatureStructure fs = fsIter.next(); view.getIndexRepository().addFS(fs); } AnnotationFS cas2newAnnot = view.createAnnotation(cas2.getAnnotationType(), 6, 8); view.getIndexRepository().addFS(cas2newAnnot); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); System.out.println(deltaxml1); //deserialize delta xmi into cas1 this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.allow); //check that new View contains the FS CAS deserView = cas1.getView("NewView"); Iterator deserFsIter = deserView.getIndexRepository().getAllIndexedFS(referentType); assertTrue(deserFsIter.hasNext()); } public void testMultipleSofas() throws Exception { try { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); // set document text for the initial view cas.setDocumentText("This is a test"); // create a new view and set its document text CAS cas2 = cas.createView("OtherSofa"); cas2.setDocumentText("This is only a test"); // create an annotation and add to index of both views AnnotationFS anAnnot = cas.createAnnotation(cas.getAnnotationType(), 0, 5); cas.getIndexRepository().addFS(anAnnot); cas2.getIndexRepository().addFS(anAnnot); FSIndex tIndex = cas.getAnnotationIndex(); FSIndex t2Index = cas2.getAnnotationIndex(); assertTrue(tIndex.size() == 2); // document annot and this one assertTrue(t2Index.size() == 2); // ditto // serialize StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem()); xmiSer.serialize(cas, xmlSer.getContentHandler()); String xml = sw.getBuffer().toString(); // deserialize into another CAS (repeat twice to check it still works after reset) CAS newCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); for (int i = 0; i < 2; i++) { XmiCasDeserializer newDeser = new XmiCasDeserializer(newCas.getTypeSystem()); ContentHandler newDeserHandler = newDeser.getXmiCasHandler(newCas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(newDeserHandler); xmlReader.parse(new InputSource(new StringReader(xml))); // check sofas assertEquals("This is a test", newCas.getDocumentText()); CAS newCas2 = newCas.getView("OtherSofa"); assertEquals("This is only a test", newCas2.getDocumentText()); // check that annotation is still indexed in both views assertTrue(tIndex.size() == 2); // document annot and this one assertTrue(t2Index.size() == 2); // ditto newCas.reset(); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testTypeSystemFiltering() throws Exception { try { // deserialize a complex CAS from XCAS CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // now read in a TypeSystem that's a subset of those types TypeSystemDescription partialTypeSystemDesc = UIMAFramework.getXMLParser() .parseTypeSystemDescription( new XMLInputSource(JUnitExtension .getFile("ExampleCas/partialTestTypeSystem.xml"))); TypeSystem partialTypeSystem = CasCreationUtils.createCas(partialTypeSystemDesc, null, null) .getTypeSystem(); // reserialize as XMI, filtering out anything that doesn't fit in the // partialTypeSystem StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XmiCasSerializer xmiSer = new XmiCasSerializer(partialTypeSystem); xmiSer.serialize(cas, xmlSer.getContentHandler()); String xml = sw.getBuffer().toString(); // System.out.println(xml); // deserialize into another CAS (which has the whole type system) CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); XmiCasDeserializer deser2 = new XmiCasDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXmiCasHandler(cas2); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // check that types have been filtered out Type orgType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Organization"); assertNotNull(orgType); assertTrue(cas2.getAnnotationIndex(orgType).size() == 0); assertTrue(cas.getAnnotationIndex(orgType).size() > 0); // but that some types are still there Type personType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Person"); FSIndex personIndex = cas2.getAnnotationIndex(personType); assertTrue(personIndex.size() > 0); // check that mentionType has been filtered out (set to null) FeatureStructure somePlace = personIndex.iterator().get(); Feature mentionTypeFeat = personType.getFeatureByBaseName("mentionType"); assertNotNull(mentionTypeFeat); assertNull(somePlace.getStringValue(mentionTypeFeat)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testNoInitialSofa() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); // create non-annotation type so as not to create the _InitialView Sofa IntArrayFS intArrayFS = cas.createIntArrayFS(5); intArrayFS.set(0, 1); intArrayFS.set(1, 2); intArrayFS.set(2, 3); intArrayFS.set(3, 4); intArrayFS.set(4, 5); cas.getIndexRepository().addFS(intArrayFS); // serialize the CAS StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem()); xmiSer.serialize(cas, xmlSer.getContentHandler()); String xml = sw.getBuffer().toString(); // deserialize into another CAS CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); XmiCasDeserializer deser2 = new XmiCasDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXmiCasHandler(cas2); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); //test that index is correctly populated Type intArrayType = cas2.getTypeSystem().getType(CAS.TYPE_NAME_INTEGER_ARRAY); Iterator iter = cas2.getIndexRepository().getAllIndexedFS(intArrayType); assertTrue(iter.hasNext()); IntArrayFS intArrayFS2 = (IntArrayFS)iter.next(); assertFalse(iter.hasNext()); assertEquals(5, intArrayFS2.size()); assertEquals(1, intArrayFS2.get(0)); assertEquals(2, intArrayFS2.get(1)); assertEquals(3, intArrayFS2.get(2)); assertEquals(4, intArrayFS2.get(3)); assertEquals(5, intArrayFS2.get(4)); // test that serializing the new CAS produces the same XML sw = new StringWriter(); xmlSer = new XMLSerializer(sw, false); xmiSer = new XmiCasSerializer(cas2.getTypeSystem()); xmiSer.serialize(cas2, xmlSer.getContentHandler()); String xml2 = sw.getBuffer().toString(); assertTrue(xml2.equals(xml)); } public void testv1FormatXcas() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); CAS v1cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); // get a complex CAS InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // test it assertTrue(CAS.NAME_DEFAULT_SOFA.equals(cas.getSofa().getSofaID())); // get a v1 XMI version of the same CAS serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/v1xmiCas.xml")); XmiCasDeserializer deser2 = new XmiCasDeserializer(v1cas.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXmiCasHandler(v1cas); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // compare assertEquals(cas.getAnnotationIndex().size(), v1cas.getAnnotationIndex().size()); assertTrue(CAS.NAME_DEFAULT_SOFA.equals(v1cas.getSofa().getSofaID())); // now a v1 XMI version of a multiple Sofa CAS v1cas.reset(); serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/xmiMsCasV1.xml")); deser2 = new XmiCasDeserializer(v1cas.getTypeSystem()); deserHandler2 = deser2.getXmiCasHandler(v1cas); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // test it CAS engView = v1cas.getView("EnglishDocument"); assertTrue(engView.getDocumentText().equals("this beer is good")); assertTrue(engView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation CAS gerView = v1cas.getView("GermanDocument"); assertTrue(gerView.getDocumentText().equals("das bier ist gut")); assertTrue(gerView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation assertTrue(CAS.NAME_DEFAULT_SOFA.equals(v1cas.getSofa().getSofaID())); assertTrue(v1cas.getDocumentText().equals("some text for the default text sofa.")); // reserialize as XMI StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XmiCasSerializer xmiSer = new XmiCasSerializer(v1cas.getTypeSystem()); xmiSer.serialize(v1cas, xmlSer.getContentHandler()); String xml = sw.getBuffer().toString(); cas.reset(); // deserialize into another CAS deser2 = new XmiCasDeserializer(cas.getTypeSystem()); deserHandler2 = deser2.getXmiCasHandler(cas); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // test it engView = cas.getView("EnglishDocument"); assertTrue(engView.getDocumentText().equals("this beer is good")); assertTrue(engView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation gerView = cas.getView("GermanDocument"); assertTrue(gerView.getDocumentText().equals("das bier ist gut")); assertTrue(gerView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation assertTrue(CAS.NAME_DEFAULT_SOFA.equals(v1cas.getSofa().getSofaID())); assertTrue(v1cas.getDocumentText().equals("some text for the default text sofa.")); } public void testDuplicateNsPrefixes() throws Exception { TypeSystemDescription ts = new TypeSystemDescription_impl(); ts.addType("org.bar.foo.Foo", "", "uima.tcas.Annotation"); ts.addType("org.baz.foo.Foo", "", "uima.tcas.Annotation"); CAS cas = CasCreationUtils.createCas(ts, null, null); cas.setDocumentText("Foo"); Type t1 = cas.getTypeSystem().getType("org.bar.foo.Foo"); Type t2 = cas.getTypeSystem().getType("org.baz.foo.Foo"); AnnotationFS a1 = cas.createAnnotation(t1,0,3); cas.addFsToIndexes(a1); AnnotationFS a2 = cas.createAnnotation(t2,0,3); cas.addFsToIndexes(a2); ByteArrayOutputStream baos = new ByteArrayOutputStream(); XmiCasSerializer.serialize(cas, baos); baos.close(); byte[] bytes = baos.toByteArray(); CAS cas2 = CasCreationUtils.createCas(ts, null, null); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); XmiCasDeserializer.deserialize(bais, cas2); bais.close(); CasComparer.assertEquals(cas, cas2); } public void testMerging() throws Exception { testMerging(false); } public void testDeltaCasMerging() throws Exception { testMerging(true); } // Test merging with or without using delta CASes private void testMerging(boolean useDeltas) throws Exception { // deserialize a complex CAS from XCAS CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer.deserialize(serCasStream, cas); serCasStream.close(); int numAnnotations = cas.getAnnotationIndex().size(); //for comparison later String docText = cas.getDocumentText(); //for comparison later //add a new Sofa to test that multiple Sofas in original CAS work CAS preexistingView = cas.createView("preexistingView"); String preexistingViewText = "John Smith blah blah blah"; preexistingView.setDocumentText(preexistingViewText); createPersonAnnot(preexistingView, 0, 10); // do XMI serialization to a string, using XmiSerializationSharedData // to keep track of maximum ID generated XmiSerializationSharedData serSharedData = new XmiSerializationSharedData(); String xmiStr = serialize(cas, serSharedData); int maxOutgoingXmiId = serSharedData.getMaxXmiId(); // deserialize into two new CASes, each with its own instance of XmiSerializationSharedData // so we can get consistent IDs later when serializing back. CAS newCas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); XmiSerializationSharedData deserSharedData1 = new XmiSerializationSharedData(); deserialize(xmiStr, newCas1, deserSharedData1, false, -1); CAS newCas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); XmiSerializationSharedData deserSharedData2 = new XmiSerializationSharedData(); deserialize(xmiStr, newCas2, deserSharedData2, false, -1); Marker marker1 = null; Marker marker2 = null; if (useDeltas) { // create Marker before adding new FSs marker1 = newCas1.createMarker(); marker2 = newCas2.createMarker(); } //add new FS to each new CAS createPersonAnnot(newCas1, 0, 10); createPersonAnnot(newCas1, 20, 30); createPersonAnnot(newCas2, 40, 50); AnnotationFS person = createPersonAnnot(newCas2, 60, 70); //add an Owner relation that points to an organization in the original CAS, //to test links across merge boundary Type orgType = newCas2.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Organization"); AnnotationFS org = (AnnotationFS)newCas2.getAnnotationIndex(orgType).iterator().next(); Type ownerType = newCas2.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Owner"); Feature argsFeat = ownerType.getFeatureByBaseName("relationArgs"); Feature componentIdFeat = ownerType.getFeatureByBaseName("componentId"); Type relArgsType = newCas2.getTypeSystem().getType( "org.apache.uima.testTypeSystem.BinaryRelationArgs"); Feature domainFeat = relArgsType.getFeatureByBaseName("domainValue"); Feature rangeFeat = relArgsType.getFeatureByBaseName("rangeValue"); AnnotationFS ownerAnnot = newCas2.createAnnotation(ownerType, 0, 70); FeatureStructure relArgs = newCas2.createFS(relArgsType); relArgs.setFeatureValue(domainFeat, person); relArgs.setFeatureValue(rangeFeat, org); ownerAnnot.setFeatureValue(argsFeat, relArgs); ownerAnnot.setStringValue(componentIdFeat, "XCasDeserializerTest"); newCas2.addFsToIndexes(ownerAnnot); int orgBegin = org.getBegin(); int orgEnd = org.getEnd(); //add Sofas CAS newView1 = newCas1.createView("newSofa1"); final String sofaText1 = "This is a new Sofa, created in CAS 1."; newView1.setDocumentText(sofaText1); final String annotText = "Sofa"; int annotStart1 = sofaText1.indexOf(annotText); AnnotationFS annot1 = newView1.createAnnotation(orgType, annotStart1, annotStart1 + annotText.length()); newView1.addFsToIndexes(annot1); CAS newView2 = newCas2.createView("newSofa2"); final String sofaText2 = "This is another new Sofa, created in CAS 2."; newView2.setDocumentText(sofaText2); int annotStart2 = sofaText2.indexOf(annotText); AnnotationFS annot2 = newView2.createAnnotation(orgType, annotStart2, annotStart2 + annotText.length()); newView2.addFsToIndexes(annot2); // Add an FS with an array of existing annotations in another view int nToks = 3; ArrayFS array = newView2.createArrayFS(nToks); Type thingType = newCas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Thing"); FSIterator thingIter = newCas2.getAnnotationIndex(thingType).iterator(); for (int i = 0; i < nToks; ++i) array.set(i, (FeatureStructure)thingIter.next()); Type annotArrayTestType = newView2.getTypeSystem().getType("org.apache.uima.testTypeSystem.AnnotationArrayTest"); Feature annotArrayFeat = annotArrayTestType.getFeatureByBaseName("arrayOfAnnotations"); AnnotationFS fsArrayTestAnno = newView2.createAnnotation(annotArrayTestType, 13, 27); fsArrayTestAnno.setFeatureValue(annotArrayFeat,array); newView2.addFsToIndexes(fsArrayTestAnno); // re-serialize each new CAS back to XMI, keeping consistent ids String newSerCas1 = serialize(newCas1, deserSharedData1, marker1); String newSerCas2 = serialize(newCas2, deserSharedData2, marker2); // merge the two XMI CASes back into the original CAS // the shared data will be reset and recreated if not using deltaCas if (useDeltas) { deserialize(newSerCas1, cas, serSharedData, false, maxOutgoingXmiId); } else { deserialize(newSerCas1, cas, serSharedData, false, -1); } assertEquals(numAnnotations + 2, cas.getAnnotationIndex().size()); deserialize(newSerCas2, cas, serSharedData, false, maxOutgoingXmiId); assertEquals(numAnnotations + 5, cas.getAnnotationIndex().size()); assertEquals(docText, cas.getDocumentText()); // Serialize/deserialize again in case merge created duplicate ids String newSerCasMerged = serialize(cas, serSharedData); deserialize(newSerCasMerged, cas, serSharedData, false, -1); //check covered text of annotations FSIterator iter = cas.getAnnotationIndex().iterator(); while (iter.hasNext()) { AnnotationFS annot = (AnnotationFS)iter.next(); assertEquals(cas.getDocumentText().substring( annot.getBegin(), annot.getEnd()), annot.getCoveredText()); } //check Owner annotation we created to test link across merge boundary iter = cas.getAnnotationIndex(ownerType).iterator(); while (iter.hasNext()) { AnnotationFS annot = (AnnotationFS)iter.next(); String componentId = annot.getStringValue(componentIdFeat); if ("XCasDeserializerTest".equals(componentId)) { FeatureStructure targetRelArgs = annot.getFeatureValue(argsFeat); AnnotationFS targetDomain = (AnnotationFS)targetRelArgs.getFeatureValue(domainFeat); assertEquals(60, targetDomain.getBegin()); assertEquals(70, targetDomain.getEnd()); AnnotationFS targetRange = (AnnotationFS)targetRelArgs.getFeatureValue(rangeFeat); assertEquals(orgBegin, targetRange.getBegin()); assertEquals(orgEnd, targetRange.getEnd()); } } //check Sofas CAS targetView1 = cas.getView("newSofa1"); assertEquals(sofaText1, targetView1.getDocumentText()); CAS targetView2 = cas.getView("newSofa2"); assertEquals(sofaText2, targetView2.getDocumentText()); AnnotationFS targetAnnot1 = (AnnotationFS) targetView1.getAnnotationIndex(orgType).iterator().get(); assertEquals(annotText, targetAnnot1.getCoveredText()); AnnotationFS targetAnnot2 = (AnnotationFS) targetView2.getAnnotationIndex(orgType).iterator().get(); assertEquals(annotText, targetAnnot2.getCoveredText()); assertTrue(targetView1.getSofa().getSofaRef() != targetView2.getSofa().getSofaRef()); CAS checkPreexistingView = cas.getView("preexistingView"); assertEquals(preexistingViewText, checkPreexistingView.getDocumentText()); Type personType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Person"); AnnotationFS targetAnnot3 = (AnnotationFS) checkPreexistingView.getAnnotationIndex(personType).iterator().get(); assertEquals("John Smith", targetAnnot3.getCoveredText()); // Check the FS with an array of pre-existing FSs iter = targetView2.getAnnotationIndex(annotArrayTestType).iterator(); componentIdFeat = thingType.getFeatureByBaseName("componentId"); while (iter.hasNext()) { AnnotationFS annot = (AnnotationFS)iter.next(); ArrayFS fsArray = (ArrayFS)annot.getFeatureValue(annotArrayFeat); assertTrue(fsArray.size() == 3); for (int i = 0; i < fsArray.size(); ++i) { AnnotationFS refAnno = (AnnotationFS)fsArray.get(i); assertEquals(thingType.getName(), refAnno.getType().getName()); assertEquals("JResporator", refAnno.getStringValue(componentIdFeat)); assertTrue(cas == refAnno.getView()); } } //try an initial CAS that contains multiple Sofas } public void testDeltaCasIgnorePreexistingFS() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); cas1.setDocumentText("This is a test document in the initial view"); AnnotationFS anAnnot1 = cas1.createAnnotation(cas1.getAnnotationType(), 0, 4); cas1.getIndexRepository().addFS(anAnnot1); AnnotationFS anAnnot2 = cas1.createAnnotation(cas1.getAnnotationType(), 5, 10); cas1.getIndexRepository().addFS(anAnnot2); FSIndex tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 3); //doc annot plus annots //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = this.serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); //XmiCasDeserializer.deserialize(new StringBufferInputStream(xml), cas2, true, sharedData2); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); //create an annotation and add to index AnnotationFS cas2newAnnot = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2newAnnot); assertTrue(cas2tIndex.size() == 4); // prev annots and this new one //modify an existing annotation Iterator tIndexIter = cas2tIndex.iterator(); AnnotationFS docAnnot = (AnnotationFS) tIndexIter.next(); //doc annot //delete from index AnnotationFS delAnnot = (AnnotationFS) tIndexIter.next(); //annot cas2.getIndexRepository().removeFS(delAnnot); assertTrue(cas2.getAnnotationIndex().size() == 3); //modify language feature Feature languageF = cas2.getDocumentAnnotation().getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_LANGUAGE); docAnnot.setStringValue(languageF, "en"); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println("delta cas"); //System.out.println(deltaxml1); //deserialize delta xmi into cas1 this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.ignore); //check language feature of doc annot is not changed. //System.out.println(cas1.getDocumentAnnotation().getStringValue(languageF)); assertTrue( ((FeatureStructure) cas1.getAnnotationIndex().iterator().next()).getStringValue(languageF).equals("x-unspecified")); //check new annotation exists and preexisting is not deleted assertTrue(cas1.getAnnotationIndex().size()==4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasDisallowPreexistingFSMod() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); cas1.setDocumentText("This is a test document in the initial view"); AnnotationFS anAnnot1 = cas1.createAnnotation(cas1.getAnnotationType(), 0, 4); cas1.getIndexRepository().addFS(anAnnot1); AnnotationFS anAnnot2 = cas1.createAnnotation(cas1.getAnnotationType(), 5, 10); cas1.getIndexRepository().addFS(anAnnot2); FSIndex tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 3); //doc annot plus 2 annots //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); //create an annotation and add to index AnnotationFS cas2newAnnot = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2newAnnot); assertTrue(cas2tIndex.size() == 4); // prev annots and this new one //modify language feature Iterator tIndexIter = cas2tIndex.iterator(); AnnotationFS docAnnot = (AnnotationFS) tIndexIter.next(); Feature languageF = cas2.getDocumentAnnotation().getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_LANGUAGE); docAnnot.setStringValue(languageF, "en"); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println(deltaxml1); //deserialize delta xmi into cas1 try { this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.disallow); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey() == CASRuntimeException.DELTA_CAS_PREEXISTING_FS_DISALLOWED); } //check language feature of doc annot is not changed. //System.out.println(cas1.getDocumentAnnotation().getStringValue(languageF)); assertTrue( ((FeatureStructure) cas1.getAnnotationIndex().iterator().next()).getStringValue(languageF).equals("x-unspecified")); //check new annotation exists assertTrue(cas1.getAnnotationIndex().size() == 3); // cas2 should be unchanged. } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasInvalidMarker() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); boolean caughtMutlipleMarker = false; try { Marker marker2 = cas2.createMarker(); } catch (UIMARuntimeException e) { caughtMutlipleMarker = true; System.out.format("Should catch MultipleCreateMarker message: %s%n", e.getMessage()); } assertTrue(caughtMutlipleMarker); //reset cas cas2.reset(); boolean serfailed = false; try { serialize(cas2, sharedData2, marker); } catch (CASRuntimeException e) { serfailed = true; } assertTrue(serfailed); // serfailed = false; // try { // serialize(cas2, sharedData2, marker2); // } catch (CASRuntimeException e) { // serfailed = true; // } // assertTrue(serfailed); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasNoChanges() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println(deltaxml1); //deserialize delta xmi into cas1 try { this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.disallow); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey() == CASRuntimeException.DELTA_CAS_PREEXISTING_FS_DISALLOWED); } //check new annotation index assertTrue(cas1.getAnnotationIndex().size() == 0); // cas2 should be unchanged. } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasDisallowPreexistingFSViewMod() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); cas1.setDocumentText("This is a test document in the initial view"); AnnotationFS anAnnot1 = cas1.createAnnotation(cas1.getAnnotationType(), 0, 4); cas1.getIndexRepository().addFS(anAnnot1); AnnotationFS anAnnot2 = cas1.createAnnotation(cas1.getAnnotationType(), 5, 10); cas1.getIndexRepository().addFS(anAnnot2); FSIndex tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 3); //doc annot plus 2 annots //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); //create an annotation and add to index AnnotationFS cas2newAnnot = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2newAnnot); assertTrue(cas2tIndex.size() == 4); // prev annots and this new one //modify language feature Iterator tIndexIter = cas2tIndex.iterator(); AnnotationFS docAnnot = (AnnotationFS) tIndexIter.next(); //delete annotation from index AnnotationFS delAnnot = (AnnotationFS) tIndexIter.next(); //annot cas2.getIndexRepository().removeFS(delAnnot); assertTrue(cas2.getAnnotationIndex().size() == 3); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println(deltaxml1); //deserialize delta xmi into cas1 try { this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.disallow); } catch (CASRuntimeException e) { assertTrue(e.getMessageKey() == CASRuntimeException.DELTA_CAS_PREEXISTING_FS_DISALLOWED); } //check new annotation added and preexisitng FS not removed from index assertTrue(cas1.getAnnotationIndex().size() == 4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasAllowPreexistingFS() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas3 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); Type personType = cas1.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Person"); Feature componentIdFeat = personType.getFeatureByBaseName("componentId"); Feature confidenceFeat = personType.getFeatureByBaseName("confidence"); Type orgType = cas1.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Organization"); Type ownerType = cas1.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Owner"); Type entityAnnotType = cas1.getTypeSystem().getType( "org.apache.uima.testTypeSystem.EntityAnnotation"); Feature mentionTypeFeat = entityAnnotType.getFeatureByBaseName("mentionType"); Feature argsFeat = ownerType.getFeatureByBaseName("relationArgs"); Type relArgsType = cas1.getTypeSystem().getType( "org.apache.uima.testTypeSystem.BinaryRelationArgs"); Feature domainFeat = relArgsType.getFeatureByBaseName("domainValue"); Feature rangeFeat = relArgsType.getFeatureByBaseName("rangeValue"); Type entityType = cas1.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity"); Feature classesFeat = entityType.getFeatureByBaseName("classes"); Feature linksFeat = entityType.getFeatureByBaseName("links"); Feature canonicalFormFeat = entityType.getFeatureByBaseName("canonicalForm"); Type nonEmptyFsListType = cas1.getTypeSystem().getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST); Type emptyFsListType = cas1.getTypeSystem().getType(CAS.TYPE_NAME_EMPTY_FS_LIST); Feature headFeat = nonEmptyFsListType.getFeatureByBaseName("head"); Feature tailFeat = nonEmptyFsListType.getFeatureByBaseName("tail"); //cas1 //initial set of feature structures // set document text for the initial view and create Annotations cas1.setDocumentText("This is a test document in the initial view"); AnnotationFS anAnnot1 = cas1.createAnnotation(cas1.getAnnotationType(), 0, 4); cas1.getIndexRepository().addFS(anAnnot1); AnnotationFS anAnnot2 = cas1.createAnnotation(cas1.getAnnotationType(), 5, 6); cas1.getIndexRepository().addFS(anAnnot2); AnnotationFS anAnnot3 = cas1.createAnnotation(cas1.getAnnotationType(), 8, 13); cas1.getIndexRepository().addFS(anAnnot3); AnnotationFS anAnnot4 = cas1.createAnnotation(cas1.getAnnotationType(), 15, 30); cas1.getIndexRepository().addFS(anAnnot4); FSIndex tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 5); //doc annot plus 4 annots FeatureStructure entityFS = cas1.createFS(entityType); cas1.getIndexRepository().addFS(entityFS); StringArrayFS strArrayFS = cas1.createStringArrayFS(5); strArrayFS.set(0, "class1"); entityFS.setFeatureValue(classesFeat, strArrayFS); //create listFS and set the link feature FeatureStructure emptyNode = cas1.createFS(emptyFsListType); FeatureStructure secondNode = cas1.createFS(nonEmptyFsListType); secondNode.setFeatureValue(headFeat, anAnnot2); secondNode.setFeatureValue(tailFeat, emptyNode); FeatureStructure firstNode = cas1.createFS(nonEmptyFsListType); firstNode.setFeatureValue(headFeat, anAnnot1); firstNode.setFeatureValue(tailFeat, secondNode); entityFS.setFeatureValue(linksFeat, firstNode); // create a view w/o setting document text CAS view1 = cas1.createView("View1"); // create another view CAS preexistingView = cas1.createView("preexistingView"); String preexistingViewText = "John Smith blah blah blah"; preexistingView.setDocumentText(preexistingViewText); AnnotationFS person1Annot = createPersonAnnot(preexistingView, 0, 10); person1Annot.setStringValue(componentIdFeat, "deltacas1"); AnnotationFS person2Annot = createPersonAnnot(preexistingView, 0, 5); AnnotationFS orgAnnot = preexistingView.createAnnotation(orgType, 16, 24); preexistingView.addFsToIndexes(orgAnnot); AnnotationFS ownerAnnot = preexistingView.createAnnotation(ownerType, 0, 24); preexistingView.addFsToIndexes(ownerAnnot); FeatureStructure relArgs = cas1.createFS(relArgsType); relArgs.setFeatureValue(domainFeat, person1Annot); ownerAnnot.setFeatureValue(argsFeat, relArgs); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //System.out.println("CAS1 " + xml); //System.out.println("MaxOutgoingXmiId " + maxOutgoingXmiId); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //======================================================================= //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); CAS cas2preexistingView = cas2.getView("preexistingView"); FSIndex cas2personIndex = cas2preexistingView.getAnnotationIndex(personType); FSIndex cas2orgIndex = cas2preexistingView.getAnnotationIndex(orgType); FSIndex cas2ownerIndex = cas2preexistingView.getAnnotationIndex(ownerType); // create an annotation and add to index AnnotationFS cas2anAnnot5 = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2anAnnot5); assertTrue(cas2tIndex.size() == 6); // prev annots and this new one // set document text of View1 CAS cas2view1 = cas2.getView("View1"); cas2view1.setDocumentText("This is the View1 document."); //create an annotation in View1 AnnotationFS cas2view1Annot = cas2view1.createAnnotation(cas2.getAnnotationType(), 1, 5); cas2view1.getIndexRepository().addFS(cas2view1Annot); FSIndex cas2view1Index = cas2view1.getAnnotationIndex(); assertTrue(cas2view1Index.size() == 2); //document annot and this annot //modify an existing annotation Iterator tIndexIter = cas2tIndex.iterator(); AnnotationFS docAnnot = (AnnotationFS) tIndexIter.next(); //doc annot AnnotationFS modAnnot1 = (AnnotationFS) tIndexIter.next(); AnnotationFS delAnnot = (AnnotationFS) tIndexIter.next(); //modify language feature Feature languageF = cas2.getDocumentAnnotation().getType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_LANGUAGE); docAnnot.setStringValue(languageF, "en"); //index update - reindex cas2.getIndexRepository().removeFS(modAnnot1); Feature endF = cas2.getAnnotationType().getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END); modAnnot1.setIntValue(endF, 4); cas2.getIndexRepository().addFS(modAnnot1); //index update - remove annotation from index cas2.getIndexRepository().removeFS(delAnnot); //modify FS - string feature and FS feature. Iterator personIter = cas2personIndex.iterator(); AnnotationFS cas2person1 = (AnnotationFS) personIter.next(); AnnotationFS cas2person2 = (AnnotationFS) personIter.next(); cas2person1.setFloatValue(confidenceFeat, (float) 99.99); cas2person1.setStringValue(mentionTypeFeat, "FULLNAME"); cas2person2.setStringValue(componentIdFeat, "delataCas2"); cas2person2.setStringValue(mentionTypeFeat, "FIRSTNAME"); Iterator orgIter = cas2orgIndex.iterator(); AnnotationFS cas2orgAnnot = (AnnotationFS) orgIter.next(); cas2orgAnnot.setStringValue(mentionTypeFeat, "ORGNAME"); //modify FS feature Iterator ownerIter = cas2ownerIndex.iterator(); AnnotationFS cas2ownerAnnot = (AnnotationFS) ownerIter.next(); FeatureStructure cas2relArgs = cas2ownerAnnot.getFeatureValue(argsFeat); cas2relArgs.setFeatureValue(rangeFeat, cas2orgAnnot); //Test modification of a nonshared multivalued feature. //This should serialize the encompassing FS. Iterator iter = cas2.getIndexRepository().getIndex("testEntityIndex").iterator(); FeatureStructure cas2EntityFS = (FeatureStructure) iter.next(); StringArrayFS cas2strarrayFS = (StringArrayFS) cas2EntityFS.getFeatureValue(classesFeat); cas2strarrayFS.set(1, "class2"); cas2strarrayFS.set(2, "class3"); cas2strarrayFS.set(3, "class4"); cas2strarrayFS.set(4, "class5"); //add to FSList FeatureStructure cas2linksFS = cas2EntityFS.getFeatureValue(linksFeat); FeatureStructure cas2secondNode = cas2linksFS.getFeatureValue(tailFeat); FeatureStructure cas2emptyNode = cas2secondNode.getFeatureValue(tailFeat); FeatureStructure cas2thirdNode = cas2.createFS(nonEmptyFsListType); cas2thirdNode.setFeatureValue(headFeat, cas2anAnnot5); cas2thirdNode.setFeatureValue(tailFeat, cas2emptyNode); cas2secondNode.setFeatureValue(tailFeat, cas2thirdNode); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println("delta cas"); //System.out.println(deltaxml1); //====================================================================== //deserialize delta xmi into cas1 this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.allow); //====================================================================== //serialize complete cas and deserialize into cas3 and compare with cas1. String fullxml = serialize(cas2, sharedData2); XmiSerializationSharedData sharedData3 = new XmiSerializationSharedData(); this.deserialize(fullxml, cas3, sharedData3, true,-1); CasComparer.assertEquals(cas1, cas3); //System.out.println("CAS1 " + serialize(cas1, new XmiSerializationSharedData())); //System.out.println("CAS2 " + serialize(cas2, new XmiSerializationSharedData())); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDeltaCasListFS() throws Exception { try { CAS cas1 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS cas3 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); Type entityType = cas1.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity"); Feature classesFeat = entityType.getFeatureByBaseName("classes"); Feature linksFeat = entityType.getFeatureByBaseName("links"); Feature canonicalFormFeat = entityType.getFeatureByBaseName("canonicalForm"); Type nonEmptyFsListType = cas1.getTypeSystem().getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST); Type emptyFsListType = cas1.getTypeSystem().getType(CAS.TYPE_NAME_EMPTY_FS_LIST); Feature headFeat = nonEmptyFsListType.getFeatureByBaseName("head"); Feature tailFeat = nonEmptyFsListType.getFeatureByBaseName("tail"); //cas1 //initial set of feature structures // set document text for the initial view and create Annotations cas1.setDocumentText("This is a test document in the initial view"); AnnotationFS anAnnot1 = cas1.createAnnotation(cas1.getAnnotationType(), 0, 4); cas1.getIndexRepository().addFS(anAnnot1); AnnotationFS anAnnot2 = cas1.createAnnotation(cas1.getAnnotationType(), 5, 6); cas1.getIndexRepository().addFS(anAnnot2); AnnotationFS anAnnot3 = cas1.createAnnotation(cas1.getAnnotationType(), 8, 13); cas1.getIndexRepository().addFS(anAnnot3); AnnotationFS anAnnot4 = cas1.createAnnotation(cas1.getAnnotationType(), 15, 30); cas1.getIndexRepository().addFS(anAnnot4); FSIndex tIndex = cas1.getAnnotationIndex(); assertTrue(tIndex.size() == 5); //doc annot plus 4 annots FeatureStructure entityFS = cas1.createFS(entityType); cas1.getIndexRepository().addFS(entityFS); StringArrayFS strArrayFS = cas1.createStringArrayFS(5); strArrayFS.set(0, "class1"); entityFS.setFeatureValue(classesFeat, strArrayFS); //create listFS and set the link feature FeatureStructure emptyNode = cas1.createFS(emptyFsListType); FeatureStructure secondNode = cas1.createFS(nonEmptyFsListType); secondNode.setFeatureValue(headFeat, anAnnot2); secondNode.setFeatureValue(tailFeat, emptyNode); FeatureStructure firstNode = cas1.createFS(nonEmptyFsListType); firstNode.setFeatureValue(headFeat, anAnnot1); firstNode.setFeatureValue(tailFeat, secondNode); entityFS.setFeatureValue(linksFeat, firstNode); // create a view w/o setting document text CAS view1 = cas1.createView("View1"); //serialize complete XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); String xml = serialize(cas1, sharedData); int maxOutgoingXmiId = sharedData.getMaxXmiId(); //System.out.println("CAS1 " + xml); //System.out.println("MaxOutgoingXmiId " + maxOutgoingXmiId); //deserialize into cas2 XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); this.deserialize(xml, cas2, sharedData2, true, -1); CasComparer.assertEquals(cas1, cas2); //======================================================================= //create Marker, add/modify fs and serialize in delta xmi format. Marker marker = cas2.createMarker(); FSIndex cas2tIndex = cas2.getAnnotationIndex(); // create an annotation and add to index AnnotationFS cas2anAnnot5 = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2anAnnot5); assertTrue(cas2tIndex.size() == 6); // prev annots and this new one // create an annotation and add to index AnnotationFS cas2anAnnot6 = cas2.createAnnotation(cas2.getAnnotationType(), 6, 8); cas2.getIndexRepository().addFS(cas2anAnnot6); assertTrue(cas2tIndex.size() == 7); // prev annots and twonew one //add to FSList Iterator iter = cas2.getIndexRepository().getIndex("testEntityIndex").iterator(); FeatureStructure cas2EntityFS = iter.next(); FeatureStructure cas2linksFS = cas2EntityFS.getFeatureValue(linksFeat); FeatureStructure cas2secondNode = cas2linksFS.getFeatureValue(tailFeat); FeatureStructure cas2emptyNode = cas2secondNode.getFeatureValue(tailFeat); FeatureStructure cas2thirdNode = cas2.createFS(nonEmptyFsListType); FeatureStructure cas2fourthNode = cas2.createFS(nonEmptyFsListType); cas2secondNode.setFeatureValue(tailFeat, cas2thirdNode); cas2thirdNode.setFeatureValue(headFeat, cas2anAnnot5); cas2thirdNode.setFeatureValue(tailFeat, cas2fourthNode); cas2fourthNode.setFeatureValue(headFeat, cas2anAnnot6); cas2fourthNode.setFeatureValue(tailFeat, cas2emptyNode); // serialize cas2 in delta format String deltaxml1 = serialize(cas2, sharedData2, marker); //System.out.println("delta cas"); //System.out.println(deltaxml1); //====================================================================== //deserialize delta xmi into cas1 this.deserialize(deltaxml1, cas1, sharedData, true, maxOutgoingXmiId, AllowPreexistingFS.allow); CasComparer.assertEquals(cas2linksFS, entityFS.getFeatureValue(linksFeat)); //====================================================================== //serialize complete cas and deserialize into cas3 and compare with cas1. String fullxml = serialize(cas2, sharedData2); XmiSerializationSharedData sharedData3 = new XmiSerializationSharedData(); this.deserialize(fullxml, cas3, sharedData3, true,-1); CasComparer.assertEquals(cas1, cas3); //System.out.println("CAS1 " + serialize(cas1, new XmiSerializationSharedData())); //System.out.println("CAS2 " + serialize(cas2, new XmiSerializationSharedData())); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testOutOfTypeSystemData() throws Exception { // deserialize a simple XMI into a CAS with no TypeSystem CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), new TypePriorities_impl(), new FsIndexDescription[0]); File xmiFile = JUnitExtension.getFile("ExampleCas/simpleCas.xmi"); String xmiStr = FileUtils.file2String(xmiFile, "UTF-8"); XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); deserialize(xmiStr, cas, sharedData, true, -1); //do some checks on the out-of-type system data List ootsElems = sharedData.getOutOfTypeSystemElements(); assertEquals(9, ootsElems.size()); List ootsViewMembers = sharedData.getOutOfTypeSystemViewMembers("1"); assertEquals(7, ootsViewMembers.size()); // now reserialize including OutOfTypeSystem data String xmiStr2 = serialize(cas, sharedData); //deserialize both original and new XMI into CASes that do have the full typesystem CAS newCas1 = CasCreationUtils.createCas(typeSystem, null, indexes); deserialize(xmiStr, newCas1, null, false, -1); CAS newCas2 = CasCreationUtils.createCas(typeSystem, null, indexes); deserialize(xmiStr2, newCas2, null, false, -1); CasComparer.assertEquals(newCas1, newCas2); //Test a partial type system with a missing some missing features and //missing "Organization" type File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml"); TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(partialTypeSystemFile)); CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, indexes); XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); deserialize(xmiStr, partialTsCas, sharedData2, true, -1); assertEquals(1,sharedData2.getOutOfTypeSystemElements().size()); OotsElementData ootsFeats3 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(3)); assertEquals(1, ootsFeats3.attributes.size()); XmlAttribute ootsAttr = (XmlAttribute)ootsFeats3.attributes.get(0); assertEquals("mentionType", ootsAttr.name); assertEquals("NAME", ootsAttr.value); OotsElementData ootsFeats5 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(5)); assertEquals(0, ootsFeats5.attributes.size()); assertEquals(1, ootsFeats5.childElements.size()); XmlElementNameAndContents ootsChildElem = (XmlElementNameAndContents) ootsFeats5.childElements.get(0); assertEquals("mentionType", ootsChildElem.name.qName); assertEquals("NAME", ootsChildElem.contents); OotsElementData ootsFeats8 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(8)); assertEquals(1, ootsFeats8.attributes.size()); OotsElementData ootsFeats10 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(10)); assertEquals(1, ootsFeats10.attributes.size()); OotsElementData ootsFeats11 = sharedData2.getOutOfTypeSystemFeatures(sharedData2.getFsAddrForXmiId(11)); assertEquals(4, ootsFeats11.childElements.size()); String xmiStr3 = serialize(partialTsCas, sharedData2); newCas2.reset(); deserialize(xmiStr3, newCas2, null, false, -1); CasComparer.assertEquals(newCas1, newCas2); } public void testOutOfTypeSystemArrayElement() throws Exception { //add to type system an annotation type that has an FSArray feature TypeDescription testAnnotTypeDesc = typeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation"); testAnnotTypeDesc.addFeature("arrayFeat", "", "uima.cas.FSArray"); //populate a CAS with such an array CAS cas = CasCreationUtils.createCas(typeSystem, null, null); Type testAnnotType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation"); Type orgType = cas.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Organization"); AnnotationFS orgAnnot1 = cas.createAnnotation(orgType, 0, 10); cas.addFsToIndexes(orgAnnot1); AnnotationFS orgAnnot2 = cas.createAnnotation(orgType, 10, 20); cas.addFsToIndexes(orgAnnot2); AnnotationFS testAnnot = cas.createAnnotation(testAnnotType, 0, 20); cas.addFsToIndexes(testAnnot); ArrayFS arrayFs = cas.createArrayFS(2); arrayFs.set(0, orgAnnot1); arrayFs.set(1, orgAnnot2); Feature arrayFeat = testAnnotType.getFeatureByBaseName("arrayFeat"); testAnnot.setFeatureValue(arrayFeat, arrayFs); //serialize to XMI String xmiStr = serialize(cas, null); //deserialize into a CAS that's missing the Organization type File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml"); TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(partialTypeSystemFile)); testAnnotTypeDesc = partialTypeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation"); testAnnotTypeDesc.addFeature("arrayFeat", "", "uima.cas.FSArray"); CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, null); XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); deserialize(xmiStr, partialTsCas, sharedData, true, -1); //check out of type system data Type testAnnotType2 = partialTsCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation"); FeatureStructure testAnnot2 = partialTsCas.getAnnotationIndex(testAnnotType2).iterator().get(); Feature arrayFeat2 = testAnnotType2.getFeatureByBaseName("arrayFeat"); FeatureStructure arrayFs2 = testAnnot2.getFeatureValue(arrayFeat2); List ootsElems = sharedData.getOutOfTypeSystemElements(); assertEquals(2, ootsElems.size()); List ootsArrayElems = sharedData.getOutOfTypeSystemArrayElements(arrayFs2.hashCode()); assertEquals(2, ootsArrayElems.size()); for (int i = 0; i < 2; i++) { OotsElementData oed = (OotsElementData)ootsElems.get(i); XmiArrayElement arel = (XmiArrayElement)ootsArrayElems.get(i); assertEquals(oed.xmiId, arel.xmiId); } //reserialize along with out of type system data String xmiStr2 = serialize(partialTsCas, sharedData); //deserialize into a new CAS and compare CAS cas2 = CasCreationUtils.createCas(typeSystem, null, null); deserialize(xmiStr2, cas2, null, false, -1); CasComparer.assertEquals(cas, cas2); } public void testOutOfTypeSystemListElement() throws Exception { //add to type system an annotation type that has an FSList feature TypeDescription testAnnotTypeDesc = typeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation"); testAnnotTypeDesc.addFeature("listFeat", "", "uima.cas.FSList"); //populate a CAS with such an list CAS cas = CasCreationUtils.createCas(typeSystem, null, null); Type testAnnotType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation"); Type orgType = cas.getTypeSystem().getType( "org.apache.uima.testTypeSystem.Organization"); AnnotationFS orgAnnot1 = cas.createAnnotation(orgType, 0, 10); cas.addFsToIndexes(orgAnnot1); AnnotationFS orgAnnot2 = cas.createAnnotation(orgType, 10, 20); cas.addFsToIndexes(orgAnnot2); AnnotationFS testAnnot = cas.createAnnotation(testAnnotType, 0, 20); cas.addFsToIndexes(testAnnot); Type nonEmptyFsListType = cas.getTypeSystem().getType(CAS.TYPE_NAME_NON_EMPTY_FS_LIST); Type emptyFsListType = cas.getTypeSystem().getType(CAS.TYPE_NAME_EMPTY_FS_LIST); Feature headFeat = nonEmptyFsListType.getFeatureByBaseName("head"); Feature tailFeat = nonEmptyFsListType.getFeatureByBaseName("tail"); FeatureStructure emptyNode = cas.createFS(emptyFsListType); FeatureStructure secondNode = cas.createFS(nonEmptyFsListType); secondNode.setFeatureValue(headFeat, orgAnnot2); secondNode.setFeatureValue(tailFeat, emptyNode); FeatureStructure firstNode = cas.createFS(nonEmptyFsListType); firstNode.setFeatureValue(headFeat, orgAnnot1); firstNode.setFeatureValue(tailFeat, secondNode); Feature listFeat = testAnnotType.getFeatureByBaseName("listFeat"); testAnnot.setFeatureValue(listFeat, firstNode); //serialize to XMI String xmiStr = serialize(cas, null); // System.out.println(xmiStr); //deserialize into a CAS that's missing the Organization type File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml"); TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(partialTypeSystemFile)); testAnnotTypeDesc = partialTypeSystem.addType("org.apache.uima.testTypeSystem.TestAnnotation", "", "uima.tcas.Annotation"); testAnnotTypeDesc.addFeature("listFeat", "", "uima.cas.FSList"); CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, null); XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); deserialize(xmiStr, partialTsCas, sharedData, true, -1); //check out of type system data Type testAnnotType2 = partialTsCas.getTypeSystem().getType("org.apache.uima.testTypeSystem.TestAnnotation"); FeatureStructure testAnnot2 = partialTsCas.getAnnotationIndex(testAnnotType2).iterator().get(); Feature listFeat2 = testAnnotType2.getFeatureByBaseName("listFeat"); FeatureStructure listFs = testAnnot2.getFeatureValue(listFeat2); List ootsElems = sharedData.getOutOfTypeSystemElements(); assertEquals(2, ootsElems.size()); OotsElementData oed = sharedData.getOutOfTypeSystemFeatures(listFs.hashCode()); XmlAttribute attr = (XmlAttribute)oed.attributes.get(0); assertNotNull(attr); assertEquals(CAS.FEATURE_BASE_NAME_HEAD, attr.name); assertEquals(attr.value, ((OotsElementData)ootsElems.get(0)).xmiId); //reserialize along with out of type system data String xmiStr2 = serialize(partialTsCas, sharedData); // System.out.println(xmiStr2); //deserialize into a new CAS and compare CAS cas2 = CasCreationUtils.createCas(typeSystem, null, null); deserialize(xmiStr2, cas2, null, false, -1); CasComparer.assertEquals(cas, cas2); } public void testOutOfTypeSystemDataComplexCas() throws Exception { // deserialize a complex XCAS CAS originalCas = CasCreationUtils.createCas(typeSystem, null, indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer.deserialize(serCasStream, originalCas); serCasStream.close(); //serialize to XMI String xmiStr = serialize(originalCas, null); //deserialize into a CAS with no type system CAS casWithNoTs = CasCreationUtils.createCas(new TypeSystemDescription_impl(), new TypePriorities_impl(), new FsIndexDescription[0]); XmiSerializationSharedData sharedData = new XmiSerializationSharedData(); deserialize(xmiStr, casWithNoTs, sharedData, true, -1); // now reserialize including OutOfTypeSystem data String xmiStr2 = serialize(casWithNoTs, sharedData); //deserialize into a new CAS that has the full type system CAS newCas = CasCreationUtils.createCas(typeSystem, null, indexes); deserialize(xmiStr2, newCas, null, false, -1); //compare CasComparer.assertEquals(originalCas, newCas); //Test a partial type system with a missing some missing features and //missing "Organization" type File partialTypeSystemFile = JUnitExtension.getFile("ExampleCas/partialTestTypeSystem.xml"); TypeSystemDescription partialTypeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(partialTypeSystemFile)); CAS partialTsCas = CasCreationUtils.createCas(partialTypeSystem, null, indexes); XmiSerializationSharedData sharedData2 = new XmiSerializationSharedData(); deserialize(xmiStr, partialTsCas, sharedData2, true, -1); String xmiStr3 = serialize(partialTsCas, sharedData2); newCas.reset(); deserialize(xmiStr3, newCas, null, false, -1); CasComparer.assertEquals(originalCas, newCas); } public void testGetNumChildren() throws Exception { // deserialize a complex XCAS CAS cas = CasCreationUtils.createCas(typeSystem, null, indexes); // InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); // XCASDeserializer.deserialize(serCasStream, cas); // serCasStream.close(); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/simpleCas.xmi")); XmiCasDeserializer.deserialize(serCasStream, cas); serCasStream.close(); // call serializer with a ContentHandler that checks numChildren XmiCasSerializer xmiSer = new XmiCasSerializer(cas.getTypeSystem()); GetNumChildrenTestHandler handler = new GetNumChildrenTestHandler(xmiSer); xmiSer.serialize(cas, handler); } /** Utility method for serializing a CAS to an XMI String * */ private static String serialize(CAS cas, XmiSerializationSharedData serSharedData) throws IOException, SAXException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); XmiCasSerializer.serialize(cas, null, baos, false, serSharedData); baos.close(); String xmiStr = new String(baos.toByteArray(), "UTF-8"); //note by default XmiCasSerializer generates UTF-8 //workaround for newline serialization problem in Sun Java 1.4.2 //this test file should contain CRLF line endings, but Sun Java loses them //when it serializes XML. if(!builtInXmlSerializationSupportsCRs()) { xmiStr = xmiStr.replaceAll(" ", " "); } return xmiStr; } /** Utility method for serializing a Delta CAS to XMI String * */ private static String serialize(CAS cas, XmiSerializationSharedData serSharedData, Marker marker) throws IOException, SAXException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); XmiCasSerializer.serialize(cas, null, baos, false, serSharedData, marker); baos.close(); String xmiStr = new String(baos.toByteArray(), "UTF-8"); //note by default XmiCasSerializer generates UTF-8 //workaround for newline serialization problem in Sun Java 1.4.2 //this test file should contain CRLF line endings, but Sun Java loses them //when it serializes XML. if(!builtInXmlSerializationSupportsCRs()) { xmiStr = xmiStr.replaceAll(" ", " "); } return xmiStr; } /** Utility method for deserializing a CAS from an XMI String */ private void deserialize(String xmlStr, CAS cas, XmiSerializationSharedData sharedData, boolean lenient, int mergePoint) throws FactoryConfigurationError, ParserConfigurationException, SAXException, IOException { byte[] bytes = xmlStr.getBytes("UTF-8"); //this assumes the encoding is UTF-8, which is the default output encoding of the XmiCasSerializer ByteArrayInputStream bais = new ByteArrayInputStream(bytes); XmiCasDeserializer.deserialize(bais, cas, lenient, sharedData, mergePoint); bais.close(); } private void deserialize(String xmlStr, CAS cas, XmiSerializationSharedData sharedData, boolean lenient, int mergePoint, AllowPreexistingFS allow) throws FactoryConfigurationError, ParserConfigurationException, SAXException, IOException { byte[] bytes = xmlStr.getBytes("UTF-8"); //this assumes the encoding is UTF-8, which is the default output encoding of the XmiCasSerializer ByteArrayInputStream bais = new ByteArrayInputStream(bytes); XmiCasDeserializer.deserialize(bais, cas, lenient, sharedData, mergePoint, allow); bais.close(); } private AnnotationFS createPersonAnnot(CAS cas, int begin, int end) { Type personType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Person"); AnnotationFS person = cas.createAnnotation(personType, begin, end); cas.addFsToIndexes(person); return person; } /** * Checks the Java vendor and version and returns true if running a version * of Java whose built-in XSLT support can properly serialize carriage return * characters, and false if not. It seems to be the case that Sun JVMs prior * to 1.5 do not properly serialize carriage return characters. We have to * modify our test case to account for this. * @return true if XML serialization of CRs behave properly in the current JRE */ private static boolean builtInXmlSerializationSupportsCRs() { String javaVendor = System.getProperty("java.vendor"); if( javaVendor.startsWith("Sun") ) { String javaVersion = System.getProperty("java.version"); if( javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") ) return false; } return true; } static class GetNumChildrenTestHandler extends DefaultHandler { XmiCasSerializer xmiSer; Stack childCountStack = new Stack(); GetNumChildrenTestHandler(XmiCasSerializer xmiSer) { this.xmiSer = xmiSer; childCountStack.push(Integer.valueOf(1)); } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub super.startElement(uri, localName, qName, attributes); childCountStack.push(Integer.valueOf(xmiSer.getNumChildren())); } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); //check that we've seen the expected number of child elements //(count on top of stack should be 0) Integer count = (Integer)childCountStack.pop(); assertEquals(0, count.intValue()); //decremenet child count of our parent count = (Integer)childCountStack.pop(); childCountStack.push(Integer.valueOf(count.intValue() - 1)); } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { // text node is considered a child if (length > 0) { Integer count = (Integer)childCountStack.pop(); childCountStack.push(Integer.valueOf(count.intValue() - 1)); } } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasPerformanceTuningSettingsTest.java0000644000175000017500000000600611665471060033223 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.util.HashMap; import java.util.Map; import java.util.Properties; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.TaeDescription; import org.apache.uima.analysis_engine.TextAnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.resource.Resource; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CasPerformanceTuningSettingsTest extends TestCase { /** * Constructor for CasPerformanceTuningSettingsTest. * * @param arg0 */ public CasPerformanceTuningSettingsTest(String arg0) { super(arg0); } public void testInitialHeapSize() throws Exception { try { Properties defaultProps = UIMAFramework.getDefaultPerformanceTuningProperties(); int expectedHeapSizeDefault = Integer.parseInt(defaultProps .getProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE)); Properties newProps = UIMAFramework.getDefaultPerformanceTuningProperties(); newProps.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "100000"); TaeDescription testDescriptor = UIMAFramework.getXMLParser().parseTaeDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml"))); // check default setting TextAnalysisEngine taeDefault = UIMAFramework.produceTAE(testDescriptor); CAS tcasDefault = taeDefault.newCAS(); int heapSize = ((CASImpl) tcasDefault).getHeap().heap.length; Assert.assertEquals(expectedHeapSizeDefault, heapSize); // check override Map params = new HashMap(); params.put(Resource.PARAM_PERFORMANCE_TUNING_SETTINGS, newProps); TextAnalysisEngine taeOverride = UIMAFramework.produceTAE(testDescriptor, params); CAS tcasOverride = taeOverride.newCAS(); heapSize = ((CASImpl) tcasOverride).getHeap().heap.length; Assert.assertEquals(100000, heapSize); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/XmiCasSerializerTest.java0000644000175000017500000001161111665471060030641 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; import javax.xml.transform.OutputKeys; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.xml.sax.SAXParseException; /** * Test case for XMI serialization, in particular, invalid XML 1.0 characters. Other aspects of XMI * serialization are tested elsewhere. */ public class XmiCasSerializerTest extends TestCase { private TypeSystemDescription typeSystemDesc = null; private File outputFile = null; /** * @param arg0 */ public XmiCasSerializerTest(String arg0) { super(arg0); } /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); // Temp output file, deleted on exit. this.outputFile = new File(JUnitExtension.getFile("ExampleCas"), "xmiSerializerInvalidCharsTestOutput.xmi"); this.typeSystemDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); } public void testInvalidCharsInDocumentText() throws Exception { CAS cas = CasCreationUtils.createCas(this.typeSystemDesc, null, null); char badChar = 0x1A; cas.setDocumentText("Text with bad char: " + badChar); OutputStream out = new FileOutputStream(this.outputFile); XMLSerializer xmlSerializer = new XMLSerializer(out); XmiCasSerializer xmiCasSerializer = new XmiCasSerializer(cas.getTypeSystem()); boolean caughtException = false; try { xmiCasSerializer.serialize(cas, xmlSerializer.getContentHandler()); } catch (SAXParseException e) { caughtException = true; } out.close(); assertTrue("XMI serialization of document text with bad XML 1.0 char should throw exception", caughtException); //but when XML 1.1 output is being generated, don't fail on control chracters which are valid in 1.1. out = new FileOutputStream(this.outputFile); try { XMLSerializer xml11Serializer = new XMLSerializer(out); xml11Serializer.setOutputProperty(OutputKeys.VERSION,"1.1"); xmiCasSerializer.serialize(cas, xml11Serializer.getContentHandler()); } finally { out.close(); } } public void testInvalidCharsInFeatureValue() throws Exception { CAS cas = CasCreationUtils.createCas(this.typeSystemDesc, null, null); char badChar = 0x1A; cas.setDocumentLanguage("a" + badChar); OutputStream out = new FileOutputStream(this.outputFile); XMLSerializer xmlSerializer = new XMLSerializer(out); XmiCasSerializer xmiCasSerializer = new XmiCasSerializer(cas.getTypeSystem()); boolean caughtException = false; try { xmiCasSerializer.serialize(cas, xmlSerializer.getContentHandler()); } catch (SAXParseException e) { caughtException = true; } out.close(); assertTrue("XMI serialization of document text with bad XML 1.0 char should throw exception", caughtException); //but when XML 1.1 output is being generated, don't fail on control chracters which are valid in 1.1. out = new FileOutputStream(this.outputFile); try { XMLSerializer xml11Serializer = new XMLSerializer(out); xml11Serializer.setOutputProperty(OutputKeys.VERSION,"1.1"); xmiCasSerializer.serialize(cas, xml11Serializer.getContentHandler()); } finally { out.close(); } } /* * (non-Javadoc) * * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { if ((this.outputFile != null) && this.outputFile.exists()) { this.outputFile.delete(); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/ComponentInfoTest.java0000644000175000017500000000451411665471060030205 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * */ public class ComponentInfoTest extends TestCase { public void testComponentInfo() throws Exception { //test the CAS.getCurrentComponentInfo() is null after a component has //been processed File descFile = JUnitExtension.getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(desc); CAS cas = ae.newCAS(); ae.process(cas); assertNull(((CASImpl)cas).getCurrentComponentInfo()); //same test for aggregate //test the CAS.getCurrentComponentInfo() is null after a component has //been processed descFile = JUnitExtension.getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml"); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); ae = UIMAFramework.produceAnalysisEngine(desc); cas = ae.newCAS(); ae.process(cas); assertNull(((CASImpl)cas).getCurrentComponentInfo()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasPoolTest.java0000644000175000017500000000510711665471060026766 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.impl.UimaContext_ImplBase; import org.apache.uima.resource.CasManager; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CasPoolTest extends TestCase { // verify that several CASes in a pool in different views share the same type system public void testPool() throws Exception { try { AnalysisEngineDescription aed = (AnalysisEngineDescription)UIMAFramework.getXMLParser().parse( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml"))); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(aed); // define a caspool of size 2 CasManager cm = ((UimaContext_ImplBase)ae.getUimaContext()).getResourceManager().getCasManager(); cm.defineCasPool("uniqueString", 2, null); CAS c1 = cm.getCas("uniqueString"); CAS c2 = cm.getCas("uniqueString"); c1.getJCas(); CAS c1v2 = c1.createView("view2"); CAS c2v2 = c2.createView("view3"); c2v2.getJCas(); TypeSystem ts = c1.getTypeSystem(); Assert.assertTrue(ts == c2.getTypeSystem()); Assert.assertTrue(ts == c1v2.getTypeSystem()); Assert.assertTrue(ts == c2v2.getTypeSystem()); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/FeaturePathTest.java0000644000175000017500000012046311665471060027641 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.BooleanArrayFS; import org.apache.uima.cas.ByteArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.DoubleArrayFS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeaturePath; import org.apache.uima.cas.FloatArrayFS; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.LongArrayFS; import org.apache.uima.cas.ShortArrayFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeClass; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; public class FeaturePathTest extends TestCase { /** * Tests all primitive feature path types. * * @throws Exception */ public void testPrimitiveFeaturePathTypes() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); // test string feature Feature stringFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringFeature"); cas.getDocumentAnnotation().setStringValue(stringFeat, "TestString"); String path = "/stringFeature"; FeaturePath featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("TestString", featurePath.getStringValue(cas .getDocumentAnnotation())); assertEquals("TestString", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_STRING, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(stringFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertTrue(featurePath.size() == 1); assertTrue(featurePath.getFeature(0) == stringFeat); // test short feature Feature shortFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("shortFeature"); cas.getDocumentAnnotation().setShortValue(shortFeat, (short) 12); path = "/shortFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Short.valueOf((short) 12), featurePath.getShortValue(cas .getDocumentAnnotation())); assertEquals("12", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_SHORT, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(shortFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getStringValue(null)); // test float feature Feature floatFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("floatFeature"); cas.getDocumentAnnotation().setFloatValue(floatFeat, 1.12f); path = "/floatFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Float.valueOf(1.12f), featurePath.getFloatValue(cas .getDocumentAnnotation())); assertEquals("1.12", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_FLOAT, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(floatFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getFloatValue(null)); // test double feature Feature doubleFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("doubleFeature"); cas.getDocumentAnnotation().setDoubleValue(doubleFeat, 100.5); path = "/doubleFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Double.valueOf(100.5), featurePath.getDoubleValue(cas .getDocumentAnnotation())); assertEquals("100.5", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_DOUBLE, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(doubleFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getDoubleValue(null)); // test long feature Feature longFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("longFeature"); cas.getDocumentAnnotation().setLongValue(longFeat, 2000); path = "/longFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Long.valueOf(2000), featurePath.getLongValue(cas .getDocumentAnnotation())); assertEquals("2000", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_LONG, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(longFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getLongValue(null)); // test int feature Feature intFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("intFeature"); cas.getDocumentAnnotation().setIntValue(intFeat, 5); path = "/intFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Integer.valueOf(5), featurePath.getIntValue(cas .getDocumentAnnotation())); assertEquals("5", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_INT, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(intFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getIntValue(null)); // test boolean feature Feature boolFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("booleanFeature"); cas.getDocumentAnnotation().setBooleanValue(boolFeat, true); path = "/booleanFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Boolean.valueOf(true), featurePath.getBooleanValue(cas .getDocumentAnnotation())); assertEquals("true", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_BOOLEAN, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(boolFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getBooleanValue(null)); // test byte feature Feature byteFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("byteFeature"); cas.getDocumentAnnotation().setByteValue(byteFeat, (byte) 127); path = "/byteFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(Byte.valueOf((byte) 127), featurePath.getByteValue(cas .getDocumentAnnotation())); assertEquals("127", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_BYTE, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(byteFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getByteValue(null)); } /** * Tests advanced feature paths. * * @throws Exception */ public void testAdvancedFeaturePaths() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); // test feature path not set String path = "/refFeature2"; FeaturePath featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(TypeClass.TYPE_CLASS_FS, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(cas.getDocumentAnnotation().getType(), featurePath .getType(cas.getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getFSValue(cas.getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getFSValue(null)); // test feature path not set path = "/refFeature/refFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(null, featurePath.getTypClass(cas.getDocumentAnnotation())); assertEquals(null, featurePath.getType(cas.getDocumentAnnotation())); assertEquals(null, featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(null, featurePath.getFSValue(cas.getDocumentAnnotation())); // test reference feature path (slow lookup - path not always valid) Feature stringFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringFeature"); Feature refFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature"); cas.getDocumentAnnotation().setStringValue(stringFeat, "MyExample"); cas.getDocumentAnnotation().setFeatureValue(refFeat, cas.getDocumentAnnotation()); path = "/refFeature/refFeature/stringFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(TypeClass.TYPE_CLASS_STRING, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(stringFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test reference feature path (fast lookup - path always valid) Feature ref2Feat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature2"); cas.getDocumentAnnotation().setFeatureValue(ref2Feat, cas.getDocumentAnnotation()); path = "/refFeature2/refFeature2/stringFeature"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(TypeClass.TYPE_CLASS_STRING, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(stringFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test reference feature path = "/refFeature2/refFeature2"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(TypeClass.TYPE_CLASS_FS, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(cas.getDocumentAnnotation().getType(), featurePath .getType(cas.getDocumentAnnotation())); // test empty featurePath featurePath = new FeaturePathImpl(); featurePath.initialize(""); assertEquals("", featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(cas.getDocumentAnnotation().toString(), featurePath .getValueAsString(cas.getDocumentAnnotation())); // test "/" featurePath featurePath = new FeaturePathImpl(); featurePath.initialize("/"); assertEquals("/", featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(cas.getDocumentAnnotation().toString(), featurePath .getValueAsString(cas.getDocumentAnnotation())); // check init() with super type and call getValue() with subtype featurePath = new FeaturePathImpl(); featurePath.initialize("/stringFeature"); Type testAnnotType = cas.getTypeSystem() .getType("uima.tt.TestAnnotation"); featurePath.typeInit(testAnnotType); Type testAnnotSubType = cas.getTypeSystem().getType( "uima.tt.TestAnnotSub"); AnnotationFS fs = cas.createAnnotation(testAnnotSubType, 0, 1); cas.addFsToIndexes(fs); featurePath.getValueAsString(fs); } /** * Tests the supported built-in functions for the feature path * * @throws Exception */ public void testBuiltInFeaturePathFunctions() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); Feature refFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature"); cas.getDocumentAnnotation().setFeatureValue(refFeat, cas.getDocumentAnnotation()); // test fsId() String path = "/refFeature:fsId()"; FeaturePath featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("8", featurePath.getValueAsString(cas .getDocumentAnnotation())); // test fsId() path = "/refFeature/refFeature/refFeature/refFeature:fsId()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("8", featurePath.getValueAsString(cas .getDocumentAnnotation())); // test coveredText() path = "/refFeature:coveredText()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("Sample Text", featurePath.getValueAsString(cas .getDocumentAnnotation())); // test coveredText() path = "/refFeature/refFeature/refFeature/refFeature/refFeature/refFeature:coveredText()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("Sample Text", featurePath.getValueAsString(cas .getDocumentAnnotation())); // test typeName() path = "/refFeature:typeName()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("uima.tcas.DocumentAnnotation", featurePath .getValueAsString(cas.getDocumentAnnotation())); // test typeName() path = "/refFeature/refFeature/refFeature/refFeature/refFeature/refFeature/refFeature:typeName()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("uima.tcas.DocumentAnnotation", featurePath .getValueAsString(cas.getDocumentAnnotation())); // test typeName() on root path = ":typeName()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("uima.tcas.DocumentAnnotation", featurePath .getValueAsString(cas.getDocumentAnnotation())); // test coveredText() on root path = "/:coveredText()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(cas.getDocumentText(), featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(cas.getDocumentText(), featurePath.ll_getValueAsString(cas.getLowLevelCAS().ll_getFSRef( cas.getDocumentAnnotation()), cas.getLowLevelCAS())); assertEquals(cas.getDocumentAnnotation().getType(), featurePath.getType(cas.getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_FS, featurePath.getTypClass(cas.getDocumentAnnotation())); // test fsId() on root path = "/:fsId()"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); assertEquals(path, featurePath.getFeaturePath()); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("8", featurePath.getValueAsString(cas .getDocumentAnnotation())); } /** * Tests some error conditions for the feature path implementation * * @throws Exception */ public void testErrorCases() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); Feature stringFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringFeature"); Feature refFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature"); cas.getDocumentAnnotation().setStringValue(stringFeat, "MyExample"); cas.getDocumentAnnotation().setFeatureValue(refFeat, cas.getDocumentAnnotation()); // test featurePath = null FeaturePath featurePath = new FeaturePathImpl(); try { featurePath.initialize(null); } catch (CASException ex) { assertTrue(ex.getMessage().indexOf("Invalid featurePath") > -1); } // test featurePath syntax error featurePath = new FeaturePathImpl(); try { featurePath.initialize("feature//path"); } catch (CASException ex) { assertTrue(ex.getMessage().indexOf("//") > -1); } // test non supported built-in function featurePath = new FeaturePathImpl(); try { featurePath.initialize("feature/path:test()"); } catch (CASException ex) { assertTrue(ex.getMessage().indexOf("test()") > -1); } // test featurePath contains primitive feature in path featurePath = new FeaturePathImpl(); try { featurePath.initialize("/refFeature/stringFeature/refFeature"); // featurePath.typeSystemInit(cas.getDocumentAnnotation().getType()); System.out.println(featurePath.getStringValue(cas .getDocumentAnnotation())); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("stringFeature") > -1); } // test featurePath feature not defined featurePath = new FeaturePathImpl(); try { featurePath.initialize("/refFeature/refFeatureNotDef"); // featurePath.typeSystemInit(cas.getDocumentAnnotation().getType()); featurePath.getValueAsString(cas.getDocumentAnnotation()); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("refFeatureNotDef") > -1); } // test featurePath function not supported featurePath = new FeaturePathImpl(); try { featurePath.initialize("/stringFeature:coveredText()"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); featurePath.getValueAsString(cas.getDocumentAnnotation()); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("uima.cas.String") > -1); } // test featurePath function not supported featurePath = new FeaturePathImpl(); try { featurePath.initialize("/byteFeature:coveredText()"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); featurePath.getValueAsString(cas.getDocumentAnnotation()); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("uima.cas.Byte") > -1); } // test array featurePath featurePath = new FeaturePathImpl(); try { featurePath.initialize("/refFeature/fsArray/refFeature"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); featurePath.getValueAsString(cas.getDocumentAnnotation()); } catch (CASException ex) { assertTrue(ex.getMessage().indexOf("uima.tcas.DocumentAnnotation") > -1); } // try to add a feature to the feature path with a built-in function featurePath = new FeaturePathImpl(); try { featurePath.initialize("/refFeature:coveredText()"); featurePath.addFeature(refFeat); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("refFeature") > -1); } // use featurePath object with an different type than used for typeInit() // and the case that type used for typeInit() has and featurePath that is // not always valid featurePath = new FeaturePathImpl(); try { featurePath.initialize("/refFeature/stringFeature"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); Type testAnnotType = cas.getTypeSystem().getType( "uima.tt.TestAnnotation"); AnnotationFS fs = cas.createAnnotation(testAnnotType, 0, 1); cas.addFsToIndexes(fs); featurePath.getValueAsString(fs); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("uima.tt.TestAnnotation") > -1); } // use featurePath object with an different type than used for typeInit() // and the case that type used for typeInit() has and featurePath that is // always valid featurePath = new FeaturePathImpl(); try { featurePath.initialize("/stringFeature"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); Type testAnnotType = cas.getTypeSystem().getType( "uima.tt.TestAnnotation"); AnnotationFS fs = cas.createAnnotation(testAnnotType, 0, 1); cas.addFsToIndexes(fs); featurePath.getValueAsString(fs); } catch (CASRuntimeException ex) { assertTrue(ex.getMessage().indexOf("uima.tt.TestAnnotation") > -1); } // pass null as FS featurePath = new FeaturePathImpl(); featurePath.initialize("/refFeature:coveredText()"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(null, featurePath.getValueAsString(null)); assertEquals(null, featurePath.getTypClass(null)); assertEquals(null, featurePath.getType(null)); } /** * Tests the addFeature() API * * @throws Exception */ public void testAddAPI() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); Feature stringFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringFeature"); Feature refFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature"); cas.getDocumentAnnotation().setStringValue(stringFeat, "MyExample"); cas.getDocumentAnnotation().setFeatureValue(refFeat, cas.getDocumentAnnotation()); // create featurePath with add() API FeaturePath featurePath = new FeaturePathImpl(); featurePath.addFeature(refFeat); featurePath.addFeature(stringFeat); assertEquals("MyExample", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals("/refFeature/stringFeature", featurePath.getFeaturePath()); assertTrue(featurePath.size() == 2); assertTrue(featurePath.getFeature(1) == stringFeat); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("MyExample", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals("MyExample", featurePath.getStringValue(cas .getDocumentAnnotation())); assertTrue(featurePath.size() == 2); assertTrue(featurePath.getFeature(1) == stringFeat); // test path always valid after addFeature() featurePath = new FeaturePathImpl(); featurePath.initialize("/refFeature2"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); featurePath.addFeature(stringFeat); // test path possible valid after addFeature() featurePath = new FeaturePathImpl(); featurePath.initialize("/refFeature2"); featurePath.typeInit(cas.getDocumentAnnotation().getType()); featurePath.addFeature(refFeat); featurePath.addFeature(stringFeat); } /** * Tests the addFeature() API together with initialize() * * @throws Exception */ public void testInitializeWithAddAPI() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); Feature stringFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringFeature"); Feature refFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("refFeature2"); cas.getDocumentAnnotation().setStringValue(stringFeat, "MyExample"); cas.getDocumentAnnotation().setFeatureValue(refFeat, cas.getDocumentAnnotation()); FeaturePath featurePath = new FeaturePathImpl(); featurePath.initialize("/refFeature2"); featurePath.addFeature(stringFeat); assertEquals("MyExample", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals("/refFeature2/stringFeature", featurePath.getFeaturePath()); assertTrue(featurePath.size() == 2); assertTrue(featurePath.getFeature(1) == null); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals("MyExample", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals("MyExample", featurePath.getStringValue(cas .getDocumentAnnotation())); assertTrue(featurePath.size() == 2); assertTrue(featurePath.getFeature(1) == stringFeat); } /** * Tests all array types. * * @throws Exception */ public void testArrayTypes() throws Exception { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("featurePathTests/FeaturePathTestTypeSystem.xml")); TypeSystemDescription typeSystemDescription = UIMAFramework .getXMLParser().parseTypeSystemDescription(in); CAS cas = CasCreationUtils.createCas(typeSystemDescription, null, null); cas.setDocumentText("Sample Text"); // test stringArray feature Feature stringArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("stringArray"); StringArrayFS stringArrayFS = cas.createStringArrayFS(4); stringArrayFS.set(0, "Test0"); stringArrayFS.set(1, "Test1"); stringArrayFS.set(2, "Test2"); cas.getDocumentAnnotation().setFeatureValue(stringArrayFeat, stringArrayFS); String path = "/stringArray"; FeaturePath featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(stringArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("Test0,Test1,Test2,null", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_STRINGARRAY, featurePath .getTypClass(cas.getDocumentAnnotation())); assertEquals(stringArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test shortArray feature Feature shortArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("shortArray"); ShortArrayFS shortArrayFS = cas.createShortArrayFS(3); shortArrayFS.set(0, (short) 0); shortArrayFS.set(1, (short) 2); shortArrayFS.set(2, (short) 54); cas.getDocumentAnnotation().setFeatureValue(shortArrayFeat, shortArrayFS); path = "/shortArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(shortArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("0,2,54", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_SHORTARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(shortArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test floatArray feature Feature floatArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("floatArray"); FloatArrayFS floatArrayFS = cas.createFloatArrayFS(3); floatArrayFS.set(0, 1.4f); floatArrayFS.set(1, 0f); floatArrayFS.set(2, 3434.34f); cas.getDocumentAnnotation().setFeatureValue(floatArrayFeat, floatArrayFS); path = "/floatArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(floatArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("1.4,0.0,3434.34", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_FLOATARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(floatArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test doubleArray feature Feature doubleArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("doubleArray"); DoubleArrayFS doubleArrayFS = cas.createDoubleArrayFS(3); doubleArrayFS.set(0, 1.4); doubleArrayFS.set(1, 0); doubleArrayFS.set(2, 3434.34); cas.getDocumentAnnotation().setFeatureValue(doubleArrayFeat, doubleArrayFS); path = "/doubleArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(doubleArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("1.4,0.0,3434.34", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_DOUBLEARRAY, featurePath .getTypClass(cas.getDocumentAnnotation())); assertEquals(doubleArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test longArray feature Feature longArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("longArray"); LongArrayFS longArrayFS = cas.createLongArrayFS(3); longArrayFS.set(0, 14); longArrayFS.set(1, 0); longArrayFS.set(2, 343434); cas.getDocumentAnnotation().setFeatureValue(longArrayFeat, longArrayFS); path = "/longArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(longArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("14,0,343434", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_LONGARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(longArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test intArray feature Feature intArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("intArray"); IntArrayFS intArrayFS = cas.createIntArrayFS(3); intArrayFS.set(0, 14); intArrayFS.set(1, 0); intArrayFS.set(2, 343); cas.getDocumentAnnotation().setFeatureValue(intArrayFeat, intArrayFS); path = "/intArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(intArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("14,0,343", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_INTARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(intArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test booleanArray feature Feature booleanArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("booleanArray"); BooleanArrayFS booleanArrayFS = cas.createBooleanArrayFS(3); booleanArrayFS.set(0, true); booleanArrayFS.set(1, false); booleanArrayFS.set(2, true); cas.getDocumentAnnotation().setFeatureValue(booleanArrayFeat, booleanArrayFS); path = "/booleanArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(booleanArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("true,false,true", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_BOOLEANARRAY, featurePath .getTypClass(cas.getDocumentAnnotation())); assertEquals(booleanArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test byteArray feature Feature byteArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("byteArray"); ByteArrayFS byteArrayFS = cas.createByteArrayFS(3); byteArrayFS.set(0, (byte) 23); byteArrayFS.set(1, (byte) 47); byteArrayFS.set(2, (byte) 11); cas.getDocumentAnnotation().setFeatureValue(byteArrayFeat, byteArrayFS); path = "/byteArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(byteArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertEquals("23,47,11", featurePath.getValueAsString(cas .getDocumentAnnotation())); assertEquals(TypeClass.TYPE_CLASS_BYTEARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(byteArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); // test fsArray feature Feature fsArrayFeat = cas.getDocumentAnnotation().getType() .getFeatureByBaseName("fsArray"); ArrayFS fsArrayFS = cas.createArrayFS(2); fsArrayFS.set(0, cas.getDocumentAnnotation()); fsArrayFS.set(1, cas.getDocumentAnnotation()); fsArrayFS.toStringArray(); cas.getDocumentAnnotation().setFeatureValue(fsArrayFeat, fsArrayFS); path = "/fsArray"; featurePath = new FeaturePathImpl(); featurePath.initialize(path); featurePath.typeInit(cas.getDocumentAnnotation().getType()); assertEquals(fsArrayFS, featurePath.getFSValue(cas .getDocumentAnnotation())); assertTrue(featurePath.getValueAsString(cas.getDocumentAnnotation()) .indexOf("11") > 0); assertEquals(TypeClass.TYPE_CLASS_FSARRAY, featurePath.getTypClass(cas .getDocumentAnnotation())); assertEquals(fsArrayFeat.getRange(), featurePath.getType(cas .getDocumentAnnotation())); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/UnambiguousIteratorTest.java0000644000175000017500000001230511665471060031434 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; /** * Testclass for the JTok annotator. */ public class UnambiguousIteratorTest extends TestCase { private static final String casDataDirName = "CASTests"; private static final String xcasSampleDirName = "xcas"; private static final String sampleXcas1FileName = "sample1.xcas"; private static final String sampleXcas2FileName = "sample2.xcas"; private static final String sampleTsFileName = "sample.ts"; public void testUnambiguous() throws Exception { // The two XCASes used in this test contain the same data, but the // second one contains all annotations twice. So in that case, every // other annotation is filtered by the unambiguous iterator. File dataDir = JUnitExtension.getFile(casDataDirName); File xcasDir = new File(dataDir, xcasSampleDirName); try { File tsFile = new File(xcasDir, sampleTsFileName); Object descriptor = UIMAFramework.getXMLParser().parse(new XMLInputSource(tsFile)); // instantiate CAS to get type system. Also build style // map file if there is none. TypeSystemDescription tsDesc = (TypeSystemDescription) descriptor; CAS cas = CasCreationUtils.createCas(tsDesc, null, new FsIndexDescription[0]); SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); XCASDeserializer xcasDeserializer = new XCASDeserializer(cas.getTypeSystem()); File xcasFile = new File(xcasDir, sampleXcas1FileName); parser.parse(xcasFile, xcasDeserializer.getXCASHandler(cas)); /* * // Create an XML input source from the specifier file. XMLInputSource in = new * XMLInputSource(this.tafDataDir + "specifiers/jtok.xml"); // Parse the specifier. * ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); // * Create the Text Analysis Engine. tae = UIMAFramework.produceTAE(specifier, null, null); // * Create a new CAS. CAS cas = tae.newCAS(); // Set the document text on the CAS. * cas.setDocumentText(text); cas.setDocumentLanguage("en"); // Process the sample document. * tae.process(cas); System.out.println("Annotation index size: " + * cas.getAnnotationIndex().size()); */ LowLevelCAS llc = cas.getLowLevelCAS(); final int tokType = llc.ll_getTypeSystem().ll_getCodeForTypeName("uima.tt.TokenAnnotation"); LowLevelIndex annotIdx = llc.ll_getIndexRepository().ll_getIndex(CAS.STD_ANNOTATION_INDEX, tokType); final int annotSizeA1 = iteratorSize(annotIdx.ll_iterator()); final int annotSizeU1 = iteratorSize(annotIdx.ll_iterator(false)); assertEquals(annotSizeA1, annotSizeU1); parser = SAXParserFactory.newInstance().newSAXParser(); xcasDeserializer = new XCASDeserializer(cas.getTypeSystem()); xcasFile = new File(xcasDir, sampleXcas2FileName); parser.parse(xcasFile, xcasDeserializer.getXCASHandler(cas)); annotIdx = llc.ll_getIndexRepository().ll_getIndex(CAS.STD_ANNOTATION_INDEX, tokType); final int annotSizeA2 = iteratorSize(annotIdx.ll_iterator()); final int annotSizeU2 = iteratorSize(annotIdx.ll_iterator(false)); // System.out.println("Annotation index size: " // + cas.getAnnotationIndex().size()); // System.out.println("U1: " + annotSizeU1); // System.out.println("A1: " + annotSizeA1); // System.out.println("U2: " + annotSizeU2); // System.out.println("A2: " + annotSizeA2); assertEquals(annotSizeU1, annotSizeU2); assertTrue(annotSizeA2 > annotSizeU2); assertEquals(annotSizeA2, annotSizeU2 * 2); } catch (Exception ex) { JUnitExtension.handleException(ex); } } private static final int iteratorSize(LowLevelIterator it) { int size = 0; for (it.moveToFirst(); it.isValid(); it.moveToNext()) { ++size; } return size; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java0000644000175000017500000000757311665471060030332 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.TaeDescription; import org.apache.uima.analysis_engine.TextAnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Type; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CasResetResizeTest extends TestCase { /** * Constructor for CasPerformanceTuningSettingsTest. * * @param arg0 */ public CasResetResizeTest(String arg0) { super(arg0); } public void testInitialHeapSize() throws Exception { try { TaeDescription testDescriptor = UIMAFramework.getXMLParser().parseTaeDescription( new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/TestPrimitiveTae1.xml"))); // check default setting TextAnalysisEngine taeDefault = UIMAFramework.produceTAE(testDescriptor); CAS cas = taeDefault.newCAS(); int heapSize = ((CASImpl) cas).getHeap().getHeapSize(); int bufSize = ((CASImpl)cas).getHeap().heap.length; //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize); Assert.assertTrue(bufSize < CASImpl.DEFAULT_RESET_HEAP_SIZE); assertTrue(heapSize <= bufSize); //create enough annotations to exceed the DEFAULT_RESET_HEAP_SIZE Type annotType = cas.getTypeSystem().getType(CAS.TYPE_NAME_ANNOTATION); for (int i = 0; i < 2000000; i++) { cas.createAnnotation(annotType, i, i); } heapSize = ((CASImpl) cas).getHeap().getHeapSize(); bufSize = ((CASImpl)cas).getHeap().heap.length; //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize); assertTrue(heapSize <= bufSize); Assert.assertTrue(heapSize > CASImpl.DEFAULT_RESET_HEAP_SIZE); //reset the CAS - it should shrink cas.reset(); heapSize = ((CASImpl) cas).getHeap().getHeapSize(); bufSize = ((CASImpl)cas).getHeap().heap.length; //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize); assertTrue(heapSize <= bufSize); Assert.assertTrue(bufSize < CASImpl.DEFAULT_RESET_HEAP_SIZE); //If instead we create the annotations in smaller chunks and reset each time, //the CAS buffer size shouldn't grow for (int j = 0; j < 10; j++) { for (int i = 0; i < 200000; i++) { cas.createAnnotation(annotType, i, i); } heapSize = ((CASImpl) cas).getHeap().getHeapSize(); bufSize = ((CASImpl)cas).getHeap().heap.length; //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize); assertTrue(heapSize <= bufSize); Assert.assertTrue(bufSize < CASImpl.DEFAULT_RESET_HEAP_SIZE); cas.reset(); } } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas/impl/XCASDeserializerTest.java0000644000175000017500000004277311665471060030541 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas.impl; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.Iterator; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class XCASDeserializerTest extends TestCase { private TypeSystemDescription typeSystem; private FsIndexDescription[] indexes; /** * Constructor for XCASDeserializerTest. * * @param arg0 */ public XCASDeserializerTest(String arg0) { super(arg0); } protected void setUp() throws Exception { File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) .getFsIndexes(); } public void testNoInitialSofa() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); // create non-annotation type so as not to create the _InitialView Sofa IntArrayFS intArrayFS = cas.createIntArrayFS(5); intArrayFS.set(0, 1); intArrayFS.set(1, 2); intArrayFS.set(2, 3); intArrayFS.set(3, 4); intArrayFS.set(4, 5); cas.getIndexRepository().addFS(intArrayFS); // serialize the CAS StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XCASSerializer xcasSer = new XCASSerializer(cas.getTypeSystem()); xcasSer.serialize(cas, xmlSer.getContentHandler(), true); String xml = sw.getBuffer().toString(); // deserialize into another CAS CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); XCASDeserializer deser = new XCASDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas2); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(new StringReader(xml))); // serialize the new CAS sw = new StringWriter(); xmlSer = new XMLSerializer(sw, false); xcasSer = new XCASSerializer(cas.getTypeSystem()); xcasSer.serialize(cas2, xmlSer.getContentHandler(), true); String xml2 = sw.getBuffer().toString(); // compare assertTrue(xml2.equals(xml)); } public void testDeserializeAndReserialize() throws Exception { doTestDeserializeAndReserialize(false); doTestDeserializeAndReserialize(true); } private void doTestDeserializeAndReserialize(boolean useJCas) throws Exception { // deserialize a complex CAS CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); if (useJCas) { cas.getJCas(); } InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // check that array refs are not null Type entityType = cas.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity"); Feature classesFeat = entityType.getFeatureByBaseName("classes"); Iterator iter = cas.getIndexRepository().getIndex("testEntityIndex").iterator(); assertTrue(iter.hasNext()); while (iter.hasNext()) { FeatureStructure fs = iter.next(); StringArrayFS arrayFS = (StringArrayFS) fs.getFeatureValue(classesFeat); assertNotNull(arrayFS); for (int i = 0; i < arrayFS.size(); i++) { assertNotNull(arrayFS.get(i)); } } // reserialize StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XCASSerializer xcasSer = new XCASSerializer(cas.getTypeSystem()); xcasSer.serialize(cas, xmlSer.getContentHandler(), true); String xml = sw.getBuffer().toString(); CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); if (useJCas) { cas2.getJCas(); } // deserialize into another CAS XCASDeserializer deser2 = new XCASDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXCASHandler(cas2); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // compare assertEquals(cas.getAnnotationIndex().size(), cas2.getAnnotationIndex().size()); // CasComparer.assertEquals(cas,cas2); } public void testOutOfTypeSystem2() throws Exception { // deserialize a complex CAS into one with no TypeSystem CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), new TypePriorities_impl(), new FsIndexDescription[0]); OutOfTypeSystemData ootsd = new OutOfTypeSystemData(); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas, ootsd); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // now reserialize including OutOfTypeSystem data XCASSerializer xcasSer = new XCASSerializer(cas.getTypeSystem()); StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); xcasSer.serialize(cas, xmlSer.getContentHandler(), true, ootsd); String xml = sw.getBuffer().toString(); // System.out.println(xml); // deserialize into a CAS that accepts the full typesystem CAS cas2 = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); XCASDeserializer deser2 = new XCASDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXCASHandler(cas2); xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // check that array refs are not null Type entityType = cas2.getTypeSystem().getType("org.apache.uima.testTypeSystem.Entity"); Feature classesFeat = entityType.getFeatureByBaseName("classes"); Iterator iter = cas2.getIndexRepository().getIndex("testEntityIndex").iterator(); assertTrue(iter.hasNext()); while (iter.hasNext()) { FeatureStructure fs = iter.next(); StringArrayFS arrayFS = (StringArrayFS) fs.getFeatureValue(classesFeat); assertNotNull(arrayFS); for (int i = 0; i < arrayFS.size(); i++) { assertNotNull(arrayFS.get(i)); } } } public void testOutOfTypeSystem3() throws Exception { // deserialize an XCAS using the implicit value feature into a CAS with no TypeSystem CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), new TypePriorities_impl(), new FsIndexDescription[0]); String xcas = "" + "Test Document" + "" + "this is the value feature"; OutOfTypeSystemData ootsd = new OutOfTypeSystemData(); XMLReader xmlReader = XMLReaderFactory.createXMLReader(); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler handler = deser.getXCASHandler(cas, ootsd); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(new StringReader(xcas))); // now reserialize including OutOfTypeSystem data XCASSerializer xcasSer = new XCASSerializer(cas.getTypeSystem()); StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); xcasSer.serialize(cas, xmlSer.getContentHandler(), true, ootsd); String xml = sw.getBuffer().toString(); // System.out.println(xml); // make sure the value feature was not lost (it will be serialized as an attribute however) assertTrue(xml.indexOf("value=\"this is the value feature\"") != -1); } public void testMultipleSofas() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); // set document text for the initial view cas.setDocumentText("This is a test"); // create a new view and set its document text CAS cas2 = cas.createView("OtherSofa"); cas2.setDocumentText("This is only a test"); // create an annotation and add to index of both views AnnotationFS anAnnot = cas.createAnnotation(cas.getAnnotationType(), 0, 5); cas.getIndexRepository().addFS(anAnnot); cas2.getIndexRepository().addFS(anAnnot); FSIndex tIndex = cas.getAnnotationIndex(); FSIndex t2Index = cas2.getAnnotationIndex(); assertTrue(tIndex.size() == 2); // document annot and this one assertTrue(t2Index.size() == 2); // ditto // serialize StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XCASSerializer xcasSer = new XCASSerializer(cas.getTypeSystem()); xcasSer.serialize(cas, xmlSer.getContentHandler(), true); String xml = sw.getBuffer().toString(); // deserialize into another CAS (repeat twice to check it still works after reset) CAS newCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); for (int i = 0; i < 2; i++) { XCASDeserializer newDeser = new XCASDeserializer(newCas.getTypeSystem()); ContentHandler newDeserHandler = newDeser.getXCASHandler(newCas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(newDeserHandler); xmlReader.parse(new InputSource(new StringReader(xml))); // check sofas assertEquals("This is a test", newCas.getDocumentText()); CAS newCas2 = newCas.getView("OtherSofa"); assertEquals("This is only a test", newCas2.getDocumentText()); // check that annotation is still indexed in both views assertTrue(tIndex.size() == 2); // document annot and this one assertTrue(t2Index.size() == 2); // ditto newCas.reset(); } } public void testv1FormatXcas() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS v1cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); // get the CAS used above that is in v2.0 format InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // get a v1.x version of the same CAS serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/v1cas.xml")); deser = new XCASDeserializer(v1cas.getTypeSystem()); deserHandler = deser.getXCASHandler(v1cas); fact = SAXParserFactory.newInstance(); parser = fact.newSAXParser(); xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // compare assertEquals(cas.getAnnotationIndex().size(), v1cas.getAnnotationIndex().size()); // now a v1.x version of a multiple Sofa CAS v1cas.reset(); serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/v1MultiSofaCas.xml")); deser = new XCASDeserializer(v1cas.getTypeSystem()); deserHandler = deser.getXCASHandler(v1cas); fact = SAXParserFactory.newInstance(); parser = fact.newSAXParser(); xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); // test it assertTrue(v1cas.getDocumentText().equals("some text for the default text sofa.")); CAS engView = v1cas.getView("EnglishDocument"); assertTrue(engView.getDocumentText().equals("this beer is good")); assertTrue(engView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation CAS gerView = v1cas.getView("GermanDocument"); assertTrue(gerView.getDocumentText().equals("das bier ist gut")); assertTrue(gerView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation // reserialize StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); XCASSerializer xcasSer = new XCASSerializer(v1cas.getTypeSystem()); xcasSer.serialize(v1cas, xmlSer.getContentHandler(), true); String xml = sw.getBuffer().toString(); // deserialize into another CAS cas.reset(); XCASDeserializer deser2 = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler2 = deser2.getXCASHandler(cas); xmlReader.setContentHandler(deserHandler2); xmlReader.parse(new InputSource(new StringReader(xml))); // test it assertTrue(v1cas.getDocumentText().equals("some text for the default text sofa.")); engView = cas.getView("EnglishDocument"); assertTrue(engView.getDocumentText().equals("this beer is good")); assertTrue(engView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation gerView = cas.getView("GermanDocument"); assertTrue(gerView.getDocumentText().equals("das bier ist gut")); assertTrue(gerView.getAnnotationIndex().size() == 5); // 4 annots plus documentAnnotation } public void testStringArrayWithNullValues() throws Exception { CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); StringArrayFS strArray = cas.createStringArrayFS(3); strArray.set(1, "value"); cas.getIndexRepository().addFS(strArray); assertEquals(null, strArray.get(0)); assertEquals("value", strArray.get(1)); assertEquals(null, strArray.get(2)); //serialize to XCAS and back ByteArrayOutputStream baos = new ByteArrayOutputStream(); XCASSerializer.serialize(cas,baos); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); XCASDeserializer.deserialize(bais, cas); //check Iterator iter = cas.getIndexRepository().getAllIndexedFS(cas.getTypeSystem().getType("uima.cas.StringArray")); StringArrayFS strArrayOut = (StringArrayFS)iter.next(); assertEquals(null, strArrayOut.get(0)); assertEquals("value", strArrayOut.get(1)); assertEquals(null, strArrayOut.get(2)); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/flow/0000755000175000017500000000000011665471060023160 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/flow/impl/0000755000175000017500000000000011665471060024121 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/flow/impl/FixedFlowControllerTest.java0000644000175000017500000002111611665471060031560 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.flow.impl; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.UimaContextAdmin; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.impl.AnalysisEngineMetaData_impl; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.cas.CAS; import org.apache.uima.flow.FinalStep; import org.apache.uima.flow.Flow; import org.apache.uima.flow.FlowControllerContext; import org.apache.uima.flow.SimpleStep; import org.apache.uima.flow.Step; import org.apache.uima.resource.metadata.OperationalProperties; import org.apache.uima.resource.metadata.impl.OperationalProperties_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.util.CasCreationUtils; /** * */ public class FixedFlowControllerTest extends TestCase { private Map analysisEngineMetaDataMap; private FixedFlowController fixedFlowController; /* (non-Javadoc) * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); analysisEngineMetaDataMap = new HashMap(); AnalysisEngineMetaData delegateMd = new AnalysisEngineMetaData_impl(); delegateMd.setOperationalProperties(new OperationalProperties_impl()); analysisEngineMetaDataMap.put("key1", delegateMd); analysisEngineMetaDataMap.put("key2", delegateMd); analysisEngineMetaDataMap.put("key3", delegateMd); AnalysisEngineMetaData aggregateMd = new AnalysisEngineMetaData_impl(); FixedFlow fixedFlow = new FixedFlow_impl(); fixedFlow.setFixedFlow(new String[]{"key1", "key2", "key3"}); aggregateMd.setFlowConstraints(fixedFlow); OperationalProperties opProps = new OperationalProperties_impl(); aggregateMd.setOperationalProperties(opProps); UimaContextAdmin rootContext = UIMAFramework.newUimaContext( UIMAFramework.getLogger(), UIMAFramework.newDefaultResourceManager(), UIMAFramework.newConfigurationManager()); Map aSofaMappings = Collections.emptyMap(); FlowControllerContext fcContext = new FlowControllerContext_impl( rootContext, "_FlowController", aSofaMappings, analysisEngineMetaDataMap, aggregateMd); fixedFlowController = new FixedFlowController(); fixedFlowController.initialize(fcContext); } public void testComputeFlow() throws Exception { CAS cas1 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); CAS cas2 = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); Flow flow1 = fixedFlowController.computeFlow(cas1); Flow flow2 = fixedFlowController.computeFlow(cas2); //two steps in flow 1 Step step = flow1.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); step = flow1.next(); assertTrue(step instanceof SimpleStep); assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey()); //one step in flow 2 step = flow2.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); //third step in flow 1 step = flow1.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); //one step in flow 2 step = flow2.next(); assertTrue(step instanceof SimpleStep); assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey()); //finish flow 1 step = flow1.next(); assertTrue(step instanceof FinalStep); //finish flow 2 step = flow2.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); step = flow2.next(); assertTrue(step instanceof FinalStep); } public void testAddAnalysisEngines() throws Exception { CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); Flow flow = fixedFlowController.computeFlow(cas); //two steps in flow Step step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey()); //now add two new AEs //first update AE metadata map AnalysisEngineMetaData delegateMd = new AnalysisEngineMetaData_impl(); delegateMd.setOperationalProperties(new OperationalProperties_impl()); analysisEngineMetaDataMap.put("key4", delegateMd); analysisEngineMetaDataMap.put("key5", delegateMd); //then notify FC List newAeKeys = new ArrayList(); newAeKeys.add("key4"); newAeKeys.add("key5"); fixedFlowController.addAnalysisEngines(newAeKeys); //finish flow step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key4", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key5", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof FinalStep); //test new flow flow = fixedFlowController.computeFlow(cas); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key2", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key4", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key5", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof FinalStep); } public void testRemoveAnalysisEngines() throws Exception { CAS cas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null); Flow flow = fixedFlowController.computeFlow(cas); //one step in flow Step step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); //remove "key2" analysisEngineMetaDataMap.remove("key2"); List removedKeys = new ArrayList(); removedKeys.add("key2"); fixedFlowController.removeAnalysisEngines(removedKeys); //finish flow step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof FinalStep); //test new flow flow = fixedFlowController.computeFlow(cas); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key1", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof SimpleStep); assertEquals("key3", ((SimpleStep)step).getAnalysisEngineKey()); step = flow.next(); assertTrue(step instanceof FinalStep); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/examples/0000755000175000017500000000000011665471066024035 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/examples/cpm/0000755000175000017500000000000011665471070024607 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/examples/cpm/sofa/0000755000175000017500000000000011665471070025537 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/examples/cpm/sofa/TransAnnotator.java0000644000175000017500000001073611665471070031366 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.examples.cpm.sofa; import java.util.Arrays; import java.util.StringTokenizer; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException; import org.apache.uima.analysis_engine.annotator.Annotator_ImplBase; import org.apache.uima.analysis_engine.annotator.GenericAnnotator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.SofaID; import org.apache.uima.cas.Type; import org.apache.uima.cas.text.AnnotationFS; /** * Simple English to German translator * */ public class TransAnnotator extends Annotator_ImplBase implements GenericAnnotator { public void process(CAS aCas, ResultSpecification aResultSpec) throws AnnotatorProcessException { CAS engTcas, germTcas; // get English text Sofa and open CAS view SofaID realSofaName = getContext().mapToSofaID("EnglishDocument"); // System.out.println("TRANSANNOTATOR: real sofa name for English document " + // realSofaName.getSofaID()); engTcas = aCas.getView(aCas.getSofa(realSofaName)); // if (engTcas == null) // System.out.println(realSofaName + " sofa not found in CAS"); realSofaName = getContext().mapToSofaID("GermanDocument"); // System.out.println("TRANSANNOTATOR: real sofa name of GermanDocument " + // realSofaName.getSofaID()); // Create the output German text Sofa and open CAS view germTcas = aCas.getView(aCas.createSofa(realSofaName, "text")); // Get some necessary Type System constants Type annot = engTcas.getAnnotationType(); Type cross = engTcas.getTypeSystem().getType("sofa.test.CrossAnnotation"); Feature other = cross.getFeatureByBaseName("otherAnnotation"); // Get the English text String engText = engTcas.getDocumentText(); // Setup for translated text int engEnd = 0; int germBegin = 0; int germEnd = 0; StringBuffer translation = new StringBuffer(); // Parse the English text StringTokenizer st = new StringTokenizer(engText); while (st.hasMoreTokens()) { String thisTok = st.nextToken(); int engBegin = engText.indexOf(thisTok, engEnd); engEnd = engBegin + thisTok.length(); // Create token annotations on English text AnnotationFS engAnnot = engTcas.createAnnotation(annot, engBegin, engEnd); engTcas.getIndexRepository().addFS(engAnnot); // Simple word-by-word translation String germWord = Translate(thisTok); // Accumulate the translated text if (germBegin > 0) { translation.append(' '); germBegin += 1; } translation.append(germWord.toCharArray(), 0, germWord.length()); // Create token annotations on German text germEnd = germBegin + germWord.length(); AnnotationFS germAnnot = germTcas.createAnnotation(cross, germBegin, germEnd); germTcas.getIndexRepository().addFS(germAnnot); // add link to English text germAnnot.setFeatureValue(other, engAnnot); germBegin = germEnd; } // Finally, set the output tranlation Sofa data germTcas.setDocumentText(translation.toString()); } static char wThis[] = { 't', 'h', 'i', 's' }; static char wBeer[] = { 'b', 'e', 'e', 'r' }; static char wIs[] = { 'i', 's' }; private String Translate(String word) { String lword = word.toLowerCase(); if (Arrays.equals(wThis, lword.toCharArray())) return "das"; if (Arrays.equals(wBeer, lword.toCharArray())) return "bier"; if (Arrays.equals(wIs, lword.toCharArray())) return "ist"; return "gut"; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/0000755000175000017500000000000011665471066024352 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/0000755000175000017500000000000011665471066025313 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CollectionReaderDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CollectionReaderDescription_imp0000644000175000017500000002466111665471066033536 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.collection.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CollectionReaderDescription; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CollectionReaderDescription_implTest extends TestCase { CollectionReaderDescription_impl mTestDesc; protected void setUp() throws Exception { try { super.setUp(); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Fake", "Fake Type", "Annotation"); type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Fake"); priorityList.addType("EnumType"); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("testIndex"); index.setTypeName("Fake"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("TestFeature"); key1.setComparator(1); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Start"); key2.setComparator(0); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setTypePriority(true); index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("testIndex2"); index2.setTypeName("Fake"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl(); key1a.setFeatureName("TestFeature"); key1a.setComparator(1); index2.setKeys(new FsIndexKeyDescription[] { key1a }); // create primitive TAE description mTestDesc = new CollectionReaderDescription_impl(); mTestDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); mTestDesc.setImplementationName("org.apache.uima.examples.TestAnnotator"); ProcessingResourceMetaData md = mTestDesc.getCollectionReaderMetaData(); md.setName("Test CAS Consumer"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); md.setTypeSystem(typeSystem); md.setTypePriorities(typePriorities); md.setFsIndexes(new FsIndexDescription[] { index, index2 }); Capability cap1 = new Capability_impl(); cap1.addInputType("Fake", false); cap1.addInputFeature("TestFeature"); Capability cap2 = new Capability_impl(); cap2.addInputType("Fake", true); cap1.setLanguagesSupported(new String[] { "en", "de" }); cap1.setMimeTypesSupported(new String[] { "text/plain" }); md.setCapabilities(new Capability[] { cap1, cap2 }); ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl(); cfgParam1.setName("param1"); cfgParam1.setDescription("Test Parameter 1"); cfgParam1.setType("String"); ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl(); cfgParam2.setName("param2"); cfgParam2.setDescription("Test Parameter 2"); cfgParam2.setType("Integer"); ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl(); cfgGrp1.setNames(new String[] { "cfgGrp1" }); cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 }); ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl(); cfgParam3.setName("param3"); cfgParam3.setDescription("Test Parameter 3"); cfgParam3.setType("Float"); ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl(); cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" }); cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 }); md.getConfigurationParameterDeclarations().setConfigurationGroups( new ConfigurationGroup[] { cfgGrp1, cfgGrp2 }); NameValuePair nvp1 = new NameValuePair_impl("param1", "test"); NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42")); NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045")); NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927")); ConfigurationParameterSettings settings = md.getConfigurationParameterSettings(); settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 }); settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a }); settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b }); URISpecifier uriSpec = new URISpecifier_impl(); uriSpec.setUri("http://incubator.apache.org/uima"); uriSpec.setProtocol(Constants.PROTOCOL_SOAP); ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDependency(); dep.setKey("ResourceKey"); dep.setDescription("Test"); mTestDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep }); ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory() .createResourceManagerConfiguration(); ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDescription(); extRes.setResourceSpecifier(uriSpec); extRes.setName("Resource1"); extRes.setDescription("Test"); resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes }); ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceBinding(); binding.setKey("ResourceKey"); binding.setResourceName("Resource1"); mTestDesc.setResourceManagerConfiguration(resMgrCfg); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); mTestDesc.toXML(writer); String testDescXml = writer.getBuffer().toString(); // System.out.println(testDescXml); // parse objects from XML (no schema validation) InputStream is = new ByteArrayInputStream(testDescXml.getBytes(encoding)); CollectionReaderDescription newDesc = (CollectionReaderDescription) UIMAFramework .getXMLParser().parse(new XMLInputSource(is, null)); // compare Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSerialization() throws Exception { try { // serialize objects to byte array byte[] testDescBytes = SerializationUtils.serialize(mTestDesc); // deserialize CollectionReaderDescription newDesc = (CollectionReaderDescription) SerializationUtils .deserialize(testDescBytes); Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CasInitializerDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CasInitializerDescription_implT0000644000175000017500000002464611665471066033535 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.collection.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CasInitializerDescription; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CasInitializerDescription_implTest extends TestCase { CasInitializerDescription_impl mTestDesc; protected void setUp() throws Exception { try { super.setUp(); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Fake", "Fake Type", "Annotation"); type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Fake"); priorityList.addType("EnumType"); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("testIndex"); index.setTypeName("Fake"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("TestFeature"); key1.setComparator(1); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Start"); key2.setComparator(0); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setTypePriority(true); index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("testIndex2"); index2.setTypeName("Fake"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl(); key1a.setFeatureName("TestFeature"); key1a.setComparator(1); index2.setKeys(new FsIndexKeyDescription[] { key1a }); // create primitive TAE description mTestDesc = new CasInitializerDescription_impl(); mTestDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); mTestDesc.setImplementationName("org.apache.uima.examples.TestAnnotator"); ProcessingResourceMetaData md = mTestDesc.getCasInitializerMetaData(); md.setName("Test CAS Initializer"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); md.setTypeSystem(typeSystem); md.setTypePriorities(typePriorities); md.setFsIndexes(new FsIndexDescription[] { index, index2 }); Capability cap1 = new Capability_impl(); cap1.addInputType("Fake", false); cap1.addInputFeature("TestFeature"); Capability cap2 = new Capability_impl(); cap2.addInputType("Fake", true); cap1.setLanguagesSupported(new String[] { "en", "de" }); cap1.setMimeTypesSupported(new String[] { "text/plain" }); md.setCapabilities(new Capability[] { cap1, cap2 }); ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl(); cfgParam1.setName("param1"); cfgParam1.setDescription("Test Parameter 1"); cfgParam1.setType("String"); ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl(); cfgParam2.setName("param2"); cfgParam2.setDescription("Test Parameter 2"); cfgParam2.setType("Integer"); ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl(); cfgGrp1.setNames(new String[] { "cfgGrp1" }); cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 }); ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl(); cfgParam3.setName("param3"); cfgParam3.setDescription("Test Parameter 3"); cfgParam3.setType("Float"); ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl(); cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" }); cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 }); md.getConfigurationParameterDeclarations().setConfigurationGroups( new ConfigurationGroup[] { cfgGrp1, cfgGrp2 }); NameValuePair nvp1 = new NameValuePair_impl("param1", "test"); NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42")); NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045")); NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927")); ConfigurationParameterSettings settings = md.getConfigurationParameterSettings(); settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 }); settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a }); settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b }); URISpecifier uriSpec = new URISpecifier_impl(); uriSpec.setUri("http://www.incubator.apache.org/uima"); uriSpec.setProtocol(Constants.PROTOCOL_SOAP); ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDependency(); dep.setKey("ResourceKey"); dep.setDescription("Test"); mTestDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep }); ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory() .createResourceManagerConfiguration(); ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDescription(); extRes.setResourceSpecifier(uriSpec); extRes.setName("Resource1"); extRes.setDescription("Test"); resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes }); ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceBinding(); binding.setKey("ResourceKey"); binding.setResourceName("Resource1"); mTestDesc.setResourceManagerConfiguration(resMgrCfg); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); mTestDesc.toXML(writer); String testDescXml = writer.getBuffer().toString(); // System.out.println(testDescXml); // parse objects from XML (no schema validation) InputStream is = new ByteArrayInputStream(testDescXml.getBytes(encoding)); CasInitializerDescription newDesc = (CasInitializerDescription) UIMAFramework.getXMLParser() .parse(new XMLInputSource(is, null)); // compare Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSerialization() throws Exception { try { // serialize objects to byte array byte[] testDescBytes = SerializationUtils.serialize(mTestDesc); // deserialize CasInitializerDescription newDesc = (CasInitializerDescription) SerializationUtils .deserialize(testDescBytes); Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CasConsumerDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/collection/impl/CasConsumerDescription_implTest0000644000175000017500000002461011665471066033550 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.collection.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.impl.URISpecifier_impl; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.AllowedValue_impl; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.FsIndexKeyDescription_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class CasConsumerDescription_implTest extends TestCase { CasConsumerDescription_impl mTestDesc; protected void setUp() throws Exception { try { super.setUp(); TypeSystemDescription typeSystem = new TypeSystemDescription_impl(); TypeDescription type1 = typeSystem.addType("Fake", "Fake Type", "Annotation"); type1.addFeature("TestFeature", "For Testing Only", CAS.TYPE_NAME_STRING); TypeDescription enumType = typeSystem.addType("EnumType", "Test Enumerated Type", "uima.cas.String"); enumType.setAllowedValues(new AllowedValue[] { new AllowedValue_impl("One", "First Value"), new AllowedValue_impl("Two", "Second Value") }); TypePriorities typePriorities = new TypePriorities_impl(); TypePriorityList priorityList = typePriorities.addPriorityList(); priorityList.addType("Fake"); priorityList.addType("EnumType"); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("testIndex"); index.setTypeName("Fake"); FsIndexKeyDescription key1 = new FsIndexKeyDescription_impl(); key1.setFeatureName("TestFeature"); key1.setComparator(1); FsIndexKeyDescription key2 = new FsIndexKeyDescription_impl(); key2.setFeatureName("Start"); key2.setComparator(0); FsIndexKeyDescription key3 = new FsIndexKeyDescription_impl(); key3.setTypePriority(true); index.setKeys(new FsIndexKeyDescription[] { key1, key2, key3 }); FsIndexDescription index2 = new FsIndexDescription_impl(); index2.setLabel("testIndex2"); index2.setTypeName("Fake"); index2.setKind(FsIndexDescription.KIND_SET); FsIndexKeyDescription key1a = new FsIndexKeyDescription_impl(); key1a.setFeatureName("TestFeature"); key1a.setComparator(1); index2.setKeys(new FsIndexKeyDescription[] { key1a }); // create primitive TAE description mTestDesc = new CasConsumerDescription_impl(); mTestDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); mTestDesc.setImplementationName("org.apache.uima.examples.TestAnnotator"); ProcessingResourceMetaData md = mTestDesc.getCasConsumerMetaData(); md.setName("Test CAS Consumer"); md.setDescription("Does not do anything useful."); md.setVersion("1.0"); md.setTypeSystem(typeSystem); md.setTypePriorities(typePriorities); md.setFsIndexes(new FsIndexDescription[] { index, index2 }); Capability cap1 = new Capability_impl(); cap1.addInputType("Fake", false); cap1.addInputFeature("TestFeature"); Capability cap2 = new Capability_impl(); cap2.addInputType("Fake", true); cap1.setLanguagesSupported(new String[] { "en", "de" }); cap1.setMimeTypesSupported(new String[] { "text/plain" }); md.setCapabilities(new Capability[] { cap1, cap2 }); ConfigurationParameter cfgParam1 = new ConfigurationParameter_impl(); cfgParam1.setName("param1"); cfgParam1.setDescription("Test Parameter 1"); cfgParam1.setType("String"); ConfigurationParameter cfgParam2 = new ConfigurationParameter_impl(); cfgParam2.setName("param2"); cfgParam2.setDescription("Test Parameter 2"); cfgParam2.setType("Integer"); ConfigurationGroup cfgGrp1 = new ConfigurationGroup_impl(); cfgGrp1.setNames(new String[] { "cfgGrp1" }); cfgGrp1.setConfigurationParameters(new ConfigurationParameter[] { cfgParam1, cfgParam2 }); ConfigurationParameter cfgParam3 = new ConfigurationParameter_impl(); cfgParam3.setName("param3"); cfgParam3.setDescription("Test Parameter 3"); cfgParam3.setType("Float"); ConfigurationGroup cfgGrp2 = new ConfigurationGroup_impl(); cfgGrp2.setNames(new String[] { "cfgGrp2a", "cfgGrp2b" }); cfgGrp2.setConfigurationParameters(new ConfigurationParameter[] { cfgParam3 }); md.getConfigurationParameterDeclarations().setConfigurationGroups( new ConfigurationGroup[] { cfgGrp1, cfgGrp2 }); NameValuePair nvp1 = new NameValuePair_impl("param1", "test"); NameValuePair nvp2 = new NameValuePair_impl("param2", Integer.valueOf("42")); NameValuePair nvp3a = new NameValuePair_impl("param3", Float.valueOf("2.718281828459045")); NameValuePair nvp3b = new NameValuePair_impl("param3", Float.valueOf("3.1415927")); ConfigurationParameterSettings settings = md.getConfigurationParameterSettings(); settings.getSettingsForGroups().put("cfgGrp1", new NameValuePair[] { nvp1, nvp2 }); settings.getSettingsForGroups().put("cfgGrp2a", new NameValuePair[] { nvp3a }); settings.getSettingsForGroups().put("cfgGrp2b", new NameValuePair[] { nvp3b }); URISpecifier uriSpec = new URISpecifier_impl(); uriSpec.setUri("http://www.incubator.apache.org/uima"); uriSpec.setProtocol(Constants.PROTOCOL_SOAP); ExternalResourceDependency dep = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDependency(); dep.setKey("ResourceKey"); dep.setDescription("Test"); mTestDesc.setExternalResourceDependencies(new ExternalResourceDependency[] { dep }); ResourceManagerConfiguration resMgrCfg = UIMAFramework.getResourceSpecifierFactory() .createResourceManagerConfiguration(); ExternalResourceDescription extRes = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceDescription(); extRes.setResourceSpecifier(uriSpec); extRes.setName("Resource1"); extRes.setDescription("Test"); resMgrCfg.setExternalResources(new ExternalResourceDescription[] { extRes }); ExternalResourceBinding binding = UIMAFramework.getResourceSpecifierFactory() .createExternalResourceBinding(); binding.setKey("ResourceKey"); binding.setResourceName("Resource1"); mTestDesc.setResourceManagerConfiguration(resMgrCfg); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); mTestDesc.toXML(writer); String testDescXml = writer.getBuffer().toString(); // System.out.println(testDescXml); // parse objects from XML (no schema validation) InputStream is = new ByteArrayInputStream(testDescXml.getBytes(encoding)); CasConsumerDescription newDesc = (CasConsumerDescription) UIMAFramework.getXMLParser().parse( new XMLInputSource(is, null)); // compare Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSerialization() throws Exception { try { // serialize objects to byte array byte[] testDescBytes = SerializationUtils.serialize(mTestDesc); // deserialize CasConsumerDescription newDesc = (CasConsumerDescription) SerializationUtils .deserialize(testDescBytes); Assert.assertEquals(mTestDesc, newDesc); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/0000755000175000017500000000000011665471054023134 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/0000755000175000017500000000000011665471054024113 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/generatedx.xml0000644000175000017500000002016511665471054026767 0ustar drazzibdrazzib x.y.z.Sentence uima.tcas.Annotation x.y.z.Token uima.tcas.Annotation ttype x.y.z.TokenType tokenFloatFeat uima.cas.Float lemma uima.cas.String sentenceLength uima.cas.Integer lemmaList uima.cas.StringArray x.y.z.TokenType uima.cas.TOP x.y.z.Word x.y.z.TokenType x.y.z.Separator x.y.z.TokenType x.y.z.EndOfSentence x.y.z.TokenType org.apache.lang.LanguagePair uima.cas.TOP lang1 org.apache.lang.Group1 lang2 org.apache.lang.Group2 description uima.cas.String org.apache.lang.Group1 uima.cas.String "Chinese" "Japanese" "Korean" "English" "French" "German" "Italian" "Spanish" "Portuguese" org.apache.lang.Group2 uima.cas.String "Arabic" "Czech" "Danish" "Dutch" "Finnish" "Greek" "Hebrew" "Hungarian" "Norwegian" "Polish" "Portuguese" "Russian" "Turkish" aa.Root uima.cas.TOP arrayInt uima.cas.IntegerArray arrayRef uima.cas.FSArray arrayFloat uima.cas.FloatArray arrayString uima.cas.StringArray plainInt uima.cas.Integer plainFloat uima.cas.Float plainString uima.cas.String plainRef TokenType testMissingImport; aa.Root aa.MissingInCas uima.cas.TOP aa.MissingFeatureInCas uima.cas.TOP haveThisOne uima.cas.Integer missingThisOne uima.cas.Float changedFType uima.cas.String aa.AbstractType uima.cas.TOP abstractInt uima.cas.Integer aa.ConcreteType aa.AbstractType concreteString uima.cas.String uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/CASInitializer.java0000644000175000017500000000414411665471054027573 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.test; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; import org.apache.uima.cas.impl.CASImpl; /** * Use this as your CAS factory. */ public class CASInitializer { public static CAS initCas(AnnotatorInitializer init) throws CASException { // Create an initial CASMgr from the factory. CASMgr casMgr = CASFactory.createCAS(); // Create a writable type system. TypeSystemMgr tsa = casMgr.getTypeSystemMgr(); // assert(tsa != null); // Create a CASMgr. Ensures existence of AnnotationFS type. init.initTypeSystem(tsa); // Commit the type system. ((CASImpl) casMgr).commitTypeSystem(); // assert(tsa.isCommitted()); // Create the CAS indexes. casMgr.initCASIndexes(); // tcasMgr.initCASIndexes(); FSIndexRepositoryMgr irm = casMgr.getIndexRepositoryMgr(); init.initIndexes(irm, casMgr.getTypeSystemMgr()); // Commit the index repository. irm.commit(); // assert(cas.getIndexRepositoryMgr().isCommitted()); return casMgr.getCAS().getCurrentView(); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/CASTestSetup.java0000644000175000017500000002170711665471054027254 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.test; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; public class CASTestSetup implements AnnotatorInitializer { // selectors for generating various bad setups to force error checking public final int bad; public static final int BAD_MISSING_TYPE_IN_CAS = 1; public static final int BAD_MISSING_FEATURE_IN_CAS = 2; public static final int BAD_CHANGED_FEATURE_TYPE = 3; // Type system constants. public static final String TOKEN_TYPE = "x.y.z.Token"; public static final String SUBTOK_TYPE = "SubToken"; public static final String TOKEN_TYPE_FEAT = "ttype"; public static final String TOKEN_TYPE_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_TYPE_FEAT; public static final String TOKEN_TYPE_TYPE = "x.y.z.TokenType"; public static final String WORD_TYPE = "x.y.z.Word"; public static final String SEP_TYPE = "x.y.z.Separator"; public static final String EOS_TYPE = "x.y.z.EndOfSentence"; public static final String SENT_TYPE = "x.y.z.Sentence"; // public static final String INT_ARRAY_SUB = "IntArraySub"; public static final String INT_SUB_NAME = "x.y.z.intArrayName"; public static final String LEMMA_FEAT = "lemma"; public static final String LEMMA_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + LEMMA_FEAT; public static final String SENT_LEN_FEAT = "sentenceLength"; public static final String SENT_LEN_FEAT_Q = SENT_TYPE + TypeSystem.FEATURE_SEPARATOR + SENT_LEN_FEAT; public static final String TOKEN_FLOAT_FEAT = "tokenFloatFeat"; public static final String TOKEN_FLOAT_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + TOKEN_FLOAT_FEAT; public static final String LEMMA_LIST_FEAT = "lemmaList"; public static final String LEMMA_LIST_FEAT_Q = TOKEN_TYPE + TypeSystem.FEATURE_SEPARATOR + LEMMA_LIST_FEAT; public static final String LANG_PAIR = "org.apache.lang.LanguagePair"; public static final String LANG1 = "lang1"; public static final String LANG2 = "lang2"; public static final String DESCR_FEAT = "description"; public static final String GROUP_1 = "org.apache.lang.Group1"; public static final String GROUP_2 = "org.apache.lang.Group2"; public static final String[] GROUP_1_LANGUAGES = { "Chinese", "Japanese", "Korean", "English", "French", "German", "Italian", "Spanish", "Portuguese" }; public static final String[] GROUP_2_LANGUAGES = { "Arabic", "Czech", "Danish", "Dutch", "Finnish", "Greek", "Hebrew", "Hungarian", "Norwegian", "Polish", "Portuguese", "Russian", "Turkish" }; // Index name constants. public static final String ANNOT_SET_INDEX = "Annotation Set Index"; public static final String ANNOT_BAG_INDEX = "Annotation Bag Index"; /** * Constructor for CASTestSetup. */ public CASTestSetup() { super(); bad = 0; } public CASTestSetup(int bad) { super(); this.bad = bad; } /** * @see org.apache.uima.cas.test.AnnotatorInitializer#initTypeSystem(TypeSystemMgr) */ public void initTypeSystem(TypeSystemMgr tsm) { // Add new types and features. Type topType = tsm.getTopType(); Type annotType = tsm.getType(CAS.TYPE_NAME_ANNOTATION); Type typeArrayInt = tsm.getType(CAS.TYPE_NAME_INTEGER_ARRAY); Type typeArrayRef = tsm.getType(CAS.TYPE_NAME_FS_ARRAY); Type typeArrayFloat = tsm.getType(CAS.TYPE_NAME_FLOAT_ARRAY); Type typeArrayString = tsm.getType(CAS.TYPE_NAME_STRING_ARRAY); Type typeInteger = tsm.getType(CAS.TYPE_NAME_INTEGER); Type typeFloat = tsm.getType(CAS.TYPE_NAME_FLOAT); Type typeString = tsm.getType(CAS.TYPE_NAME_STRING); Type typeRef = tsm.getType(CAS.TYPE_NAME_TOP); // assert(annotType != null); Type sentType = tsm.addType(SENT_TYPE, annotType); Type tokenType = tsm.addType(TOKEN_TYPE, annotType); Type tokenTypeType = tsm.addType(TOKEN_TYPE_TYPE, topType); tsm.addType(WORD_TYPE, tokenTypeType); tsm.addType(SEP_TYPE, tokenTypeType); tsm.addType(EOS_TYPE, tokenTypeType); tsm.addFeature(TOKEN_TYPE_FEAT, tokenType, tokenTypeType); tsm.addFeature(TOKEN_FLOAT_FEAT, tokenType, typeFloat); // Add a type that inherits from IntArray. // tsm.addType(INT_ARRAY_SUB, tsm.getType(CAS.TYPE_NAME_INTEGER_ARRAY)); // tsm.addFeature( // INT_SUB_NAME, // tsm.getType(INT_ARRAY_SUB), // tsm.getType(CAS.TYPE_NAME_STRING)); tsm.addFeature(LEMMA_FEAT, tokenType, typeString); tsm.addFeature(SENT_LEN_FEAT, sentType, typeInteger); tsm.addFeature(LEMMA_LIST_FEAT, tokenType, typeArrayString); // add a type that inherits from Token which has no JCas model Type subTok = tsm.addType(SUBTOK_TYPE, tokenType); Type group1 = tsm.addStringSubtype(GROUP_1, GROUP_1_LANGUAGES); Type group2 = tsm.addStringSubtype(GROUP_2, GROUP_2_LANGUAGES); Type langPair = tsm.addType(LANG_PAIR, topType); tsm.addFeature(LANG1, langPair, group1); tsm.addFeature(LANG2, langPair, group2); tsm.addFeature(DESCR_FEAT, langPair, typeString); // types for testing every variant in JCas Type typeRoot = tsm.addType("aa.Root", topType); tsm.addFeature("arrayInt", typeRoot, typeArrayInt); tsm.addFeature("arrayRef", typeRoot, typeArrayRef); tsm.addFeature("arrayFloat", typeRoot, typeArrayFloat); tsm.addFeature("arrayString", typeRoot, typeArrayString); tsm.addFeature("plainInt", typeRoot, typeInteger); tsm.addFeature("plainFloat", typeRoot, typeFloat); tsm.addFeature("plainString", typeRoot, typeString); tsm.addFeature("plainRef", typeRoot, typeRef); if (bad != BAD_MISSING_TYPE_IN_CAS) tsm.addType("aa.MissingInCas", topType); Type typeMissingFeat = tsm.addType("aa.MissingFeatureInCas", topType); tsm.addFeature("haveThisOne", typeMissingFeat, typeInteger); if (bad != BAD_MISSING_FEATURE_IN_CAS) tsm.addFeature("missingThisOne", typeMissingFeat, typeFloat); tsm.addFeature("changedFType", typeMissingFeat, (bad != BAD_CHANGED_FEATURE_TYPE) ? typeString : typeFloat); Type abstractType = tsm.addType("aa.AbstractType", topType); tsm.addFeature("abstractInt", abstractType, typeInteger); Type concreteType = tsm.addType("aa.ConcreteType", abstractType); tsm.addFeature("concreteString", concreteType, typeString); /* * String subtypes cannot be inherited from. String subtypes can't have features added - they're * all added in the creation call via an array of allowed strings. */ boolean exc = false; try { tsm.addType("some.new.Name", group1); } catch (CASAdminException e) { TestCase.assertTrue(e.getError() == CASAdminException.TYPE_IS_INH_FINAL); exc = true; } TestCase.assertTrue(exc); exc = false; try { tsm.addFeature("some.new.Name", group1, typeString); } catch (CASAdminException e) { TestCase.assertTrue(e.getError() == CASAdminException.TYPE_IS_FEATURE_FINAL); exc = true; } TestCase.assertTrue(exc); } public void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts) { FSIndexComparator comp = irm.createComparator(); Type annotation = ts.getType(CAS.TYPE_NAME_ANNOTATION); comp.setType(annotation); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_BEGIN), FSIndexComparator.STANDARD_COMPARE); comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END), FSIndexComparator.REVERSE_STANDARD_COMPARE); irm.createIndex(comp, ANNOT_BAG_INDEX, FSIndex.BAG_INDEX); irm.createIndex(comp, ANNOT_SET_INDEX, FSIndex.SET_INDEX); comp = irm.createComparator(); comp.setType(ts.getType("uima.cas.TOP")); irm.createIndex(comp, "all", FSIndex.BAG_INDEX); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/JCasTest.java0000644000175000017500000007367411665471054026457 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.test; import java.util.Iterator; import junit.framework.TestCase; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASException; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.FSIndex; import org.apache.uima.cas.FSIndexRepository; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.LowLevelException; import org.apache.uima.cas.impl.LowLevelIndexRepository; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.JFSIndexRepository; import org.apache.uima.jcas.cas.EmptyFSList; import org.apache.uima.jcas.cas.EmptyFloatList; import org.apache.uima.jcas.cas.EmptyIntegerList; import org.apache.uima.jcas.cas.EmptyStringList; import org.apache.uima.jcas.cas.FSArray; import org.apache.uima.jcas.cas.FloatArray; import org.apache.uima.jcas.cas.IntegerArray; import org.apache.uima.jcas.cas.NonEmptyFSList; import org.apache.uima.jcas.cas.NonEmptyFloatList; import org.apache.uima.jcas.cas.NonEmptyIntegerList; import org.apache.uima.jcas.cas.NonEmptyStringList; import org.apache.uima.jcas.cas.StringArray; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; import org.apache.uima.jcas.tcas.Annotation_Type; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import x.y.z.EndOfSentence; import x.y.z.Sentence; import x.y.z.Token; import aa.ConcreteType; import aa.MissingFeatureInCas; import aa.Root; /** * Class comment for CASTest.java goes here. * */ public class JCasTest extends TestCase { private CAS cas; private JCas jcas; private TypeSystem ts; public EndOfSentence endOfSentenceInstance; /** * Constructor for CASTest. * * @param arg0 */ public JCasTest(String arg0) { super(arg0); } public void setUp() throws Exception { try { try { this.cas = CASInitializer.initCas(new CASTestSetup()); this.ts = this.cas.getTypeSystem(); this.jcas = cas.getJCas(); endOfSentenceInstance = new EndOfSentence(jcas); } catch (Exception e1) { checkOkMissingImport(e1); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void checkOkMissingImport(Exception e1) { if (e1 instanceof CASException) { System.out.print("setup caught CAS Exception with message: "); String m = e1.getMessage(); System.out.println(m); if (!m .equals("Error initializing JCas: Error: can't access feature information from CAS in initializing JCas type: aa.Root, feature: testMissingImport\n")) { assertTrue(false); } } else assertTrue(false); } public void checkExpectedBadCASError(Exception e1, String err) { if (e1 instanceof CASException) { CASException e = (CASException) e1; System.out.print("\nCaught CAS Exception with message: "); String m = e1.getMessage(); System.out.println(m); if (!(e.getMessageKey().equals(err))) { assertTrue(false); } } else assertTrue(false); } public void tearDown() { this.cas = null; this.ts = null; this.jcas = null; } public void testMissingFeatureInCas() throws Exception { try { // jcasCasMisMatch(CASTestSetup.BAD_MISSING_FEATURE_IN_CAS, CASException.JCAS_INIT_ERROR); CAS localCas; TypeSystem ts; JCas localJcas = null; boolean errFound = false; try { localCas = CASInitializer.initCas(new CASTestSetup(CASTestSetup.BAD_MISSING_FEATURE_IN_CAS)); ts = this.cas.getTypeSystem(); try { localJcas = localCas.getJCas(); } catch (Exception e1) { assertTrue(false); return; } } catch (Exception e) { // System.out.println("\n" + e.toString()); assertTrue(false); } // error happens when we try and ref the missing feature MissingFeatureInCas t = new MissingFeatureInCas(localJcas); try { t.setHaveThisOne(1); } catch (Exception e) { assertTrue(false); } try { t.setMissingThisOne((float) 1.0); assertTrue(false); // above should throw } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.INAPPROP_FEAT)); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testChangedFType() throws Exception { try { jcasCasMisMatch(CASTestSetup.BAD_CHANGED_FEATURE_TYPE, CASException.JCAS_INIT_ERROR); } catch (Exception e) { JUnitExtension.handleException(e); } } public void jcasCasMisMatch(int testId, String expectedErr) throws Exception { try { CAS localCas; TypeSystem ts; JCas localJcas; boolean errFound = false; try { localCas = CASInitializer.initCas(new CASTestSetup(testId)); ts = this.cas.getTypeSystem(); try { localJcas = localCas.getJCas(); } catch (Exception e1) { checkExpectedBadCASError(e1, expectedErr); errFound = true; } } catch (Exception e) { System.out.println("\n" + e.toString()); assertTrue(false); } assertTrue(errFound); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testIteratorCopy() { Annotation something = new Annotation(jcas); something.addToIndexes(); JFSIndexRepository ir = jcas.getJFSIndexRepository(); FSIterator i1 = ir.getAnnotationIndex().iterator(); FSIterator i2 = i1.copy(); FSIterator i3 = i2.copy(); assertTrue(i3 != null); } public void testGetFSIndexRepository() throws Exception { try { FSIndexRepository ir = jcas.getFSIndexRepository(); LowLevelIndexRepository ll_ir = jcas.getLowLevelIndexRepository(); assertTrue(ir != null); assertTrue(ir == cas.getIndexRepository()); assertTrue(ll_ir != null); assertTrue(ll_ir == cas.getLowLevelCAS().ll_getIndexRepository()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMisc() throws Exception { try { try { jcas.getRequiredType("uima.tcas.Annotation"); } catch (CASException e) { assertTrue(false); } try { jcas.getRequiredType("missing.type"); assertTrue(false); } catch (CASException e1) { System.out.print("This error msg expected: "); System.out.println(e1); } try { jcas.getRequiredFeature(jcas.getType(Annotation.type).casType, "begin"); } catch (CASException e2) { assertTrue(false); } try { jcas.getRequiredFeature(jcas.getType(Annotation.type).casType, "Begin"); assertTrue(false); } catch (CASException e2) { System.out.print("This error msg expected: "); System.out.println(e2); } CAS localCas = jcas.getCas(); assertTrue(localCas == this.cas); LowLevelCAS ll_cas = jcas.getLowLevelCas(); assertTrue(ll_cas == this.cas); CASImpl casImpl = jcas.getCasImpl(); assertTrue(casImpl == this.cas); TOP_Type type = jcas.getType(org.apache.uima.jcas.tcas.Annotation.type); assertTrue(type instanceof org.apache.uima.jcas.tcas.Annotation_Type); type = jcas.getType(Annotation.typeIndexID); assertTrue(type instanceof Annotation_Type); Annotation a1 = new Annotation(jcas, 4, 5); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testJCasAccessing() throws Exception { try { Root r1 = new Root(jcas); r1.setArrayFloat(new FloatArray(jcas, 2)); r1.setArrayFloat(0, (float) 3.0); r1.setArrayFloat(1, (float) 2.5); assertTrue(3.0 == r1.getArrayFloat(0)); assertTrue(2.5 == r1.getArrayFloat(1)); Root r2 = new Root(jcas); r2.setArrayRef(new FSArray(jcas, 3)); EndOfSentence eos1 = new EndOfSentence(jcas); EndOfSentence eos2 = new EndOfSentence(jcas); r2.setArrayRef(0, eos1); r2.setArrayRef(1, eos2); assertTrue(r2.getArrayRef(0).equals(eos1)); assertTrue(r2.getArrayRef(1).equals(eos2)); r2.setArrayInt(new IntegerArray(jcas, 1)); r2.setArrayInt(0, 17); assertTrue(r2.getArrayInt(0) == 17); IntegerArray ia = r2.getArrayInt(); assertTrue(ia.get(0) == 17); r2.setArrayString(new StringArray(jcas, 2)); r2.setArrayString(0, "zero"); r2.setArrayString(1, "one"); assertTrue(r2.getArrayString(0).equals("zero")); assertTrue(r2.getArrayString(1).equals("one")); // error paths // array out of bounds try { r2.getArrayString(2); } catch (LowLevelException e) { if (e.getError() != LowLevelException.ARRAY_INDEX_OUT_OF_RANGE) assertTrue(false); } try { r2.setArrayString(-1, "should fail"); } catch (LowLevelException e) { if (e.getError() != LowLevelException.ARRAY_INDEX_OUT_OF_RANGE) assertTrue(false); } // null values r2.setArrayString(0, null); r2.setArrayRef(0, null); r2.setArrayRef(null); r2.setArrayString(null); r2.setPlainRef(null); r2.setPlainString(null); assertTrue(null == r2.getPlainString()); assertTrue(null == r2.getPlainRef()); try { r2.getArrayRef(0); } catch (LowLevelException e) { if (e.getError() != LowLevelException.NULL_ARRAY_ACCESS) assertTrue(false); } assertTrue(null == r2.getArrayString()); assertTrue(null == r2.getArrayRef()); r2.addToIndexes(); r1.addToIndexes(); JFSIndexRepository jfsi = jcas.getJFSIndexRepository(); FSIndex fsi1 = jfsi.getIndex("all", Root.type); FSIterator fsit1 = fsi1.iterator(); assertTrue(fsit1.isValid()); assertTrue(r2 == fsit1.get()); fsit1.moveToNext(); assertTrue(fsit1.isValid()); assertTrue(r1 == fsit1.get()); /* * while (fsit1.isValid()) { System.out.println("Iterator getting: " + * fsit1.get().toString()); fsit1.moveToNext(); } */ // test new objects with old iterators // NOT SUPPORTED // JFSIndex oIndex = jcas.getIndex("all"); // JFSIterator oI = oIndex.iterator(); // assertTrue(oI.isValid()); // assertTrue(r2 == oI.get()); // oI.moveToNext(); // assertTrue(oI.isValid()); // assertTrue(r1 == oI.get()); } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Tests for Memory Leaks and Performance * * Core: randomly creating lots of CAS objects of all kinds with a simple computation for what * they should contain, followed by iterating over the objects and checking they contain the * proper values. Measure heap use and time. Heap use measure: System.gc(); * System.out.println("FreeMem: " + Runtime.getRuntime().freeMemory()); Creating cas objects: Use * random number to pick one of n types of objects to create For each object type, create specific * field values based on that objects' ID in ID-Hash sense. System.identityHashCode(object) * * Timing: System.currentTimeMillis() * * @throws Exception * * */ public void testRandom() throws Exception { try { // System.out.print("Making Random: "); for (int i = 0; i < 50; i++) { root1.make(); // System.out.print("m"); } JFSIndexRepository jir = jcas.getJFSIndexRepository(); FSIterator it = jir.getIndex("all", Root.type).iterator(); // System.out.print("\nTesting Random: "); while (it.isValid()) { root1.test(it.get()); // System.out.print("t"); it.moveToNext(); } } catch (Exception e) { JUnitExtension.handleException(e); } } static interface MakeAndTest { public void make(); public void test(Object o); } MakeAndTest root1 = new MakeAndTest() { public void make() { Root r1 = new Root(jcas); int k = System.identityHashCode(r1); int imax = 1 + (k % 10); r1.setArrayFloat(new FloatArray(jcas, imax)); for (int i = 0; i < imax; i++) { r1.setArrayFloat(i, (float) k / i); } int imaxFS = 1 + (k % 3); r1.setArrayRef(new FSArray(jcas, imaxFS)); for (int i = 1; i < imaxFS; i++) { r1.setArrayRef(i, endOfSentenceInstance); } r1.setPlainString("" + k); r1.addToIndexes(); } public void test(Object o1) { assertTrue(o1 instanceof Root); Root r1 = (Root) o1; int k = System.identityHashCode(r1); int imax = 1 + (k % 10); for (int i = 0; i < imax; i++) { assertTrue(r1.getArrayFloat(i) == ((float) k / i)); } int imaxFS = 1 + (k % 3); for (int i = 1; i < imaxFS; i++) { assertTrue(endOfSentenceInstance == r1.getArrayRef(i)); } assertTrue(r1.getPlainString().equals("" + k)); } }; public void test2CASs() throws Exception { try { try { CAS cas2 = CASInitializer.initCas(new CASTestSetup()); TypeSystem ts2 = cas2.getTypeSystem(); JCas jcas2 = cas2.getJCas(); assertTrue(jcas.getType(Annotation.type) != jcas2.getType(Annotation.type)); } catch (Exception e) { checkOkMissingImport(e); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAbstract() throws Exception { try { boolean caughtExc = true; try { ConcreteType concreteType = new ConcreteType(jcas); concreteType.setAbstractInt(7); concreteType.setConcreteString("sss"); assertTrue(7 == concreteType.getAbstractInt()); assertTrue("sss".equals(concreteType.getConcreteString())); jcas.getCas().createFS(jcas.getCas().getTypeSystem().getType("aa.AbstractType")); } catch (CASRuntimeException e) { caughtExc = false; // assertTrue(e.getError() == CASRuntimeException.JCAS_MAKING_ABSTRACT_INSTANCE); System.out.print("This error msg expected: "); System.out.println(e); } assertTrue(caughtExc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testNonJCasCoveredByJCas() throws Exception { try { CAS localCas = jcas.getCas(); Type subTok = localCas.getTypeSystem().getType("SubToken"); Annotation a1 = new Annotation(jcas); a1.addToIndexes(); FeatureStructure f1 = localCas.createFS(subTok); localCas.getIndexRepository().addFS(f1); JFSIndexRepository ir = jcas.getJFSIndexRepository(); FSIndex index = ir.getAnnotationIndex(); FSIterator it = index.iterator(); try { while (it.isValid()) { Object o = it.get(); assertTrue(o instanceof Annotation); it.moveToNext(); } } catch (Exception e) { System.out.println("failed: nonJCasCovered by JCas"); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testFSListNotPromoted() throws Exception { try { CAS localCas = jcas.getCas(); TypeSystem ts = localCas.getTypeSystem(); Type fsl = ts.getType("uima.cas.NonEmptyFSList"); FeatureStructure fs = localCas.createFS(fsl); assertTrue(fs instanceof NonEmptyFSList); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateFSafterReset() throws Exception { try { CAS localCas = jcas.getCas(); cas.reset(); TypeSystem ts = cas.getTypeSystem(); Type fsl = ts.getType("uima.cas.NonEmptyFSList"); cas.createFS(fsl); assertTrue(true); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testIteratorGetsJCasType() throws Exception { try { Token tok1 = new Token(jcas); tok1.addToIndexes(); FSIterator it = jcas.getJFSIndexRepository().getIndex("all", Token.type).iterator(); while (it.hasNext()) { Token token = (Token) it.next(); token.addToIndexes(); // something to do to keep Java from optimizing this away. } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetNthFSList() throws Exception { try { Token tok1 = new Token(jcas); Token tok2 = new Token(jcas); NonEmptyFSList fsList1 = new NonEmptyFSList(jcas); fsList1.setHead(tok2); fsList1.setTail(new EmptyFSList(jcas)); NonEmptyFSList fsList = new NonEmptyFSList(jcas); fsList.setHead(tok1); fsList.setTail(fsList1); EmptyFSList emptyFsList = new EmptyFSList(jcas); try { emptyFsList.getNthElement(0); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_ON_EMPTY_LIST)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { fsList.getNthElement(-1); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_NEGATIVE_INDEX)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { fsList.getNthElement(2); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_PAST_END)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } assertTrue(tok1 == fsList.getNthElement(0)); assertTrue(tok2 == fsList.getNthElement(1)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetNthIntegerList() throws Exception { try { NonEmptyIntegerList intList1 = new NonEmptyIntegerList(jcas); intList1.setHead(2); intList1.setTail(new EmptyIntegerList(jcas)); NonEmptyIntegerList intList = new NonEmptyIntegerList(jcas); intList.setHead(1); intList.setTail(intList1); EmptyIntegerList emptyFsList = new EmptyIntegerList(jcas); try { emptyFsList.getNthElement(0); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_ON_EMPTY_LIST)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { intList.getNthElement(-1); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_NEGATIVE_INDEX)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { intList.getNthElement(2); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_PAST_END)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } assertTrue(1 == intList.getNthElement(0)); assertTrue(2 == intList.getNthElement(1)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetNthFloatList() throws Exception { try { NonEmptyFloatList floatList1 = new NonEmptyFloatList(jcas); floatList1.setHead((float) 2.0); floatList1.setTail(new EmptyFloatList(jcas)); NonEmptyFloatList floatList = new NonEmptyFloatList(jcas); floatList.setHead((float) 1.0); floatList.setTail(floatList1); EmptyFloatList emptyFsList = new EmptyFloatList(jcas); try { emptyFsList.getNthElement(0); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_ON_EMPTY_LIST)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { floatList.getNthElement(-1); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_NEGATIVE_INDEX)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { floatList.getNthElement(2); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_PAST_END)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } assertTrue(1.0 == floatList.getNthElement(0)); assertTrue(2.0 == floatList.getNthElement(1)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetNthStringList() throws Exception { try { NonEmptyStringList stringList1 = new NonEmptyStringList(jcas); stringList1.setHead("2"); stringList1.setTail(new EmptyStringList(jcas)); NonEmptyStringList stringList = new NonEmptyStringList(jcas); stringList.setHead("1"); stringList.setTail(stringList1); EmptyStringList emptyFsList = new EmptyStringList(jcas); try { emptyFsList.getNthElement(0); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_ON_EMPTY_LIST)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { stringList.getNthElement(-1); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_NEGATIVE_INDEX)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } try { stringList.getNthElement(2); assertTrue(false); // error if we get here } catch (CASRuntimeException e) { assertTrue(e.getMessageKey().equals(CASRuntimeException.JCAS_GET_NTH_PAST_END)); System.out.print("Expected Error: "); System.out.println(e.getMessage()); } assertTrue("1".equals(stringList.getNthElement(0))); assertTrue("2".equals(stringList.getNthElement(1))); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testUndefinedType() throws Exception { //create jcas with no type system JCas jcas = CasCreationUtils.createCas(new TypeSystemDescription_impl(), null, null).getJCas(); jcas.setDocumentText("This is a test."); try { //this should throw an exception jcas.getType(Sentence.type); fail(); } catch(CASRuntimeException e) { } //check that this does not leave JCAS in an inconsistent state //(a check for bug UIMA-738) Iterator iter = jcas.getAnnotationIndex().iterator(); assertTrue(iter.hasNext()); Annotation annot = iter.next(); assertEquals("This is a test.", annot.getCoveredText()); } /* * skip this - takes too long private static final int largeN = 10000; public void testPerf() * throws Exception { try { long tFs = 0, tJCas = 0, td1 = 0, td2 = 0, tllFs = 0, td3 = 0; long * tFsIndex = 0, tJCasIndex = 0, tllFsIndex = 0, td4=0, td5=0, td6=0; long [] timeResults = new * long [12]; for (int i = 0; i < 20; i++) { timeResults = innertimingperf(); } for (int i = 0; i < * 10; i++) { timeResults = innertimingperf(); System.out.println(timeResults[0] + " " + * timeResults[1] + " " + timeResults[2] + " " + timeResults[6] + " " + timeResults[7] + " " + * timeResults[8]); tFs += timeResults[0]; tJCas += timeResults[1]; tllFs += timeResults[2]; td1 += * timeResults[3]; td2 += timeResults[4]; td3 += timeResults[5]; tFsIndex += timeResults[6]; * //System.out.print ("tFsIndex incr = " + timeResults[6]) ; tJCasIndex += timeResults[7]; * //System.out.println(", tJCasIndex incr = " + timeResults[7]) ; tllFsIndex += timeResults[8]; * td4 += timeResults[9]; td5 += timeResults[10]; td6 += timeResults[11]; } * System.out.println("Timing Test, no indexing, av createFS took: " + tFs/10 + " dummy " + td1); * System.out.println("Timing Test, no indexing, av JCas cr took: " + tJCas/10 + " dummy " + td2); * System.out.println("Timing Test, no indexing, av llCrFs took: " + tllFs/10 + " dummy " + td3); * System.out.println("Timing Test, indexing, av createFS took: " + tFsIndex/10 + " dummy " + * td4); System.out.println("Timing Test, indexing, av JCas cr took: " + tJCasIndex/10 + " dummy " + * td5); System.out.println("Timing Test, indexing, av llCrFs took: " + tllFsIndex/10 + " dummy " + * td6); * * assertTrue ((tFs / 2) > tJCas); // JCas time should be over 2x faster than non-JCas } catch * (Exception e) {JUnitExtension.handleException(e); } } * * private static final boolean DO_CHECKS = true; public long[] innertimingperf() { * * long [] times = new long [12]; CAS cas = jcas.getCas(); FSIndexRepository ir = * cas.getIndexRepository(); TypeSystem ts = cas.getTypeSystem(); Type tokenType = * ts.getType(CASTestSetup.TOKEN_TYPE); // make a lot of FS, without adding to indexes // save in * array final FeatureStructure [] results = new FeatureStructure [largeN]; jcas.reset(); * System.gc(); long startTime = System.currentTimeMillis(); * * for (int i = 0; i < results.length; i++) { results[i] = cas.createFS(tokenType); } times[0] = * System.currentTimeMillis() - startTime; int j = 0; for (int i = 0; i < results.length; i++) { * if (results[i].equals(results[0])) j ++; } times[4] = j; // this code an attempt to fool JIT * into keeping the results * * jcas.reset(); System.gc(); startTime = System.currentTimeMillis(); for (int i = 0; i < * results.length; i++) { results[i] = new Token(jcas); } times[1] = System.currentTimeMillis() - * startTime; j = 0; for (int i = 0; i < results.length; i++) { if (results[i].equals(results[0])) * j ++; } times[3] = j; // this code an attempt to fool JIT into keeping the results // run with * low-level jcas.reset(); System.gc(); final int [] iresults = new int[largeN]; int tokenTypeCode = * ((TypeImpl)tokenType).getCode(); LowLevelCAS llCas = (LowLevelCAS)cas; LowLevelIndexRepository * llir = llCas.ll_getIndexRepository(); startTime = System.currentTimeMillis(); * * for (int i = 0; i < iresults.length; i++) { iresults[i] = llCas.ll_createFS(tokenTypeCode); } * times[2] = System.currentTimeMillis() - startTime; j = 0; for (int i = 0; i < iresults.length; * i++) { if (iresults[i] == iresults[0]) j ++; } times[5] = j; // this code an attempt to fool * JIT into keeping the results * * //***************** // with indexing //***************** jcas.reset(); System.gc(); startTime = * System.currentTimeMillis(); * * for (int i = 0; i < results.length; i++) { results[i] = cas.createFS(tokenType); * ir.addFS(results[i]); } times[6] = System.currentTimeMillis() - startTime; j = 0; for (int i = * 0; i < results.length; i++) { if (results[i].equals(results[0])) j ++; } times[10] = j; // this * code an attempt to fool JIT into keeping the results * * jcas.reset(); System.gc(); startTime = System.currentTimeMillis(); * * for (int i = 0; i < results.length; i++) { results[i] = new Token(jcas); * ((Token)results[i]).addToIndexes(); } times[7] = System.currentTimeMillis() - startTime; j = 0; * for (int i = 0; i < results.length; i++) { if (results[i].equals(results[0])) j ++; } times[9] = * j; // this code an attempt to fool JIT into keeping the results // run with low-level * jcas.reset(); System.gc(); * * startTime = System.currentTimeMillis(); * * for (int i = 0; i < iresults.length; i++) { iresults[i] = llCas.ll_createFS(tokenTypeCode); * llir.ll_addFS(iresults[i], !DO_CHECKS); } times[8] = System.currentTimeMillis() - startTime; j = * 0; for (int i = 0; i < iresults.length; i++) { if (iresults[i] == iresults[0]) j ++; } * times[11] = j; // this code an attempt to fool JIT into keeping the results return times; } */ /* * public void testCreateFS() { // Can create FS of type "Top" * assertTrue(this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_TOP)) != null); boolean caughtExc = * false; // Can't create int FS. try { this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_INTEGER)); } * catch (CASRuntimeException e) { caughtExc = true; assertTrue(e.getError() == * CASRuntimeException.NON_CREATABLE_TYPE); } assertTrue(caughtExc); caughtExc = false; // Can't * create array with CAS.createFS(). try { * this.cas.createFS(this.ts.getType(CAS.TYPE_NAME_FS_ARRAY)); } catch (CASRuntimeException e) { * caughtExc = true; assertTrue(e.getError() == CASRuntimeException.NON_CREATABLE_TYPE); } * assertTrue(caughtExc); caughtExc = false; // Can't create array subtype with CAS.createFS(). // * try { // this.cas.createFS(this.ts.getType(CASTestSetup.INT_ARRAY_SUB)); // } catch * (CASRuntimeException e) { // caughtExc = true; // assertTrue(e.getError() == * CASRuntimeException.NON_CREATABLE_TYPE); // } // assertTrue(caughtExc); } * * public void testCreateArrayFS() { // Has its own test class. } * * public void testCreateIntArrayFS() { // Has its own test class. } * * public void testCreateStringArrayFS() { // Has its own test class. } // public void * testCreateFilteredIterator() { // } // // public void testCommitFS() { // } // // public void * testGetConstraintFactory() { // } // // public void testCreateFeaturePath() { // } // // public * void testGetIndexRepository() { // } // // public void testFs2listIterator() { // } // * */ public static void main(String[] args) { junit.textui.TestRunner.run(JCasTest.class); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/jcas/test/AnnotatorInitializer.java0000644000175000017500000000243111665471054031127 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.jcas.test; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.FSIndexRepositoryMgr; import org.apache.uima.cas.admin.TypeSystemMgr; /** * Implement this interface to create types, features and indexes. Use in conjunction with * CASInitializer. */ public interface AnnotatorInitializer { void initTypeSystem(TypeSystemMgr tsm); void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts); } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/0000755000175000017500000000000011665471066024033 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/0000755000175000017500000000000011665471066025010 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/AnalysisEnginePoolTest.java0000644000175000017500000002331011665471066032255 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.internal.util; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.Constants; import org.apache.uima.UIMAException; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.analysis_engine.impl.ResultSpecification_impl; import org.apache.uima.analysis_engine.impl.TestAnnotator; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.impl.Capability_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.test.junit_extension.JUnitExtension; public class AnalysisEnginePoolTest extends TestCase { private TypeSystem mLastTypeSystem; /** * Constructor for MultithreadableAnalysisEngine_implTest. * * @param arg0 */ public AnalysisEnginePoolTest(String arg0) throws java.io.FileNotFoundException { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); mSimpleDesc = new AnalysisEngineDescription_impl(); mSimpleDesc.setFrameworkImplementation(Constants.JAVA_FRAMEWORK_NAME); mSimpleDesc.setPrimitive(true); mSimpleDesc.getMetaData().setName("Test Primitive TAE"); mSimpleDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); mSimpleDesc.getMetaData().setName("Simple Test"); Capability cap = new Capability_impl(); cap.addOutputType("NamedEntity", true); cap.addOutputType("DocumentStructure", true); Capability[] caps = new Capability[] {cap}; mSimpleDesc.getAnalysisEngineMetaData().setCapabilities(caps); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetAnalysisEngineMetaData() throws Exception { AnalysisEnginePool pool = null; try { // create pool pool = new AnalysisEnginePool("taePool", 3, mSimpleDesc); AnalysisEngine tae = pool.getAnalysisEngine(); AnalysisEngineMetaData md = tae.getAnalysisEngineMetaData(); Assert.assertNotNull(md); Assert.assertEquals("Simple Test", md.getName()); } catch (Exception e) { JUnitExtension.handleException(e); } finally { if (pool != null) pool.destroy(); } } public void testProcess() throws Exception { try { // test simple primitive MultithreadableTextAnalysisEngine // (using TestAnnotator class) AnalysisEnginePool pool = new AnalysisEnginePool("taePool", 3, mSimpleDesc); _testProcess(pool, 0); // test simple aggregate MultithreadableTextAnalysisEngine // (again using TestAnnotator class) AnalysisEngineDescription aggDesc = new AnalysisEngineDescription_impl(); aggDesc.setPrimitive(false); aggDesc.getMetaData().setName("Test Aggregate TAE"); aggDesc.getDelegateAnalysisEngineSpecifiersWithImports().put("Test", mSimpleDesc); FixedFlow_impl flow = new FixedFlow_impl(); flow.setFixedFlow(new String[] { "Test" }); aggDesc.getAnalysisEngineMetaData().setFlowConstraints(flow); pool = new AnalysisEnginePool("taePool", 3, aggDesc); _testProcess(pool, 0); // multiple threads! final int NUM_THREADS = 4; ProcessThread[] threads = new ProcessThread[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { threads[i] = new ProcessThread(pool, i); threads[i].start(); } // wait for threads to finish and check if they got exceptions for (int i = 0; i < NUM_THREADS; i++) { threads[i].join(); Throwable failure = threads[i].getFailure(); if (failure != null) { if (failure instanceof Exception) { throw (Exception)failure; } else { fail(failure.getMessage()); } } } //Check TestAnnotator fields only at the very end of processing, //we can't test from the threads themsleves since the state of //these fields is nondeterministic during the multithreaded processing. assertEquals("testing...", TestAnnotator.getLastDocument()); ResultSpecification resultSpec = new ResultSpecification_impl(TestAnnotator.getLastResultSpec().getTypeSystem()); resultSpec.addResultType("NamedEntity", true); assertEquals(resultSpec, TestAnnotator.getLastResultSpec()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testReconfigure() throws Exception { try { // create simple primitive TextAnalysisEngine descriptor (using TestAnnotator class) AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc.getMetaData().setName("Test Primitive TAE"); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("StringParam"); p1.setDescription("parameter with String data type"); p1.setType(ConfigurationParameter.TYPE_STRING); primitiveDesc.getMetaData().getConfigurationParameterDeclarations() .setConfigurationParameters(new ConfigurationParameter[] { p1 }); primitiveDesc.getMetaData().getConfigurationParameterSettings().setParameterSettings( new NameValuePair[] { new NameValuePair_impl("StringParam", "Test1") }); // create pool AnalysisEnginePool pool = new AnalysisEnginePool("taePool", 3, primitiveDesc); AnalysisEngine tae = pool.getAnalysisEngine(); try { // check value of string param (TestAnnotator saves it in a static field) assertEquals("Test1", TestAnnotator.stringParamValue); // reconfigure tae.setConfigParameterValue("StringParam", "Test2"); tae.reconfigure(); //test again assertEquals("Test2", TestAnnotator.stringParamValue); // check pool metadata pool.getMetaData().setUUID(tae.getMetaData().getUUID()); Assert.assertEquals(tae.getMetaData(), pool.getMetaData()); } finally { pool.releaseAnalysisEngine(tae); } } catch (Exception e) { JUnitExtension.handleException(e); } } /** * Auxilliary method used by testProcess() * * @param aTaeDesc * description of TextAnalysisEngine to test */ protected void _testProcess(AnalysisEnginePool aPool, int i) throws UIMAException { AnalysisEngine tae = aPool.getAnalysisEngine(0); try { // Test each form of the process method. When TestAnnotator executes, it // stores in static fields the document text and the ResultSpecification. // We use thse to make sure the information propogates correctly to the annotator. // process(CAS) CAS tcas = tae.newCAS(); mLastTypeSystem = tcas.getTypeSystem(); tcas.setDocumentText("new test"); tae.process(tcas); tcas.reset(); // process(CAS,ResultSpecification) ResultSpecification resultSpec = new ResultSpecification_impl(tcas.getTypeSystem()); resultSpec.addResultType("NamedEntity", true); tcas.setDocumentText("testing..."); tae.process(tcas, resultSpec); tcas.reset(); } finally { aPool.releaseAnalysisEngine(tae); } } class ProcessThread extends Thread { ProcessThread(AnalysisEnginePool aPool, int aId) { mPool = aPool; mId = aId; } public void run() { try { // System.out.println("thread started"); _testProcess(mPool, mId); // System.out.println("thread finished"); } catch (Throwable t) { t.printStackTrace(); //can't cause unit test to fail by throwing exception from thread. //record the failure and the main thread will check for it later. mFailure = t; } } public synchronized Throwable getFailure() { return mFailure; } int mId; AnalysisEnginePool mPool; boolean mIsAggregate; Throwable mFailure = null; } private AnalysisEngineDescription mSimpleDesc; } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/XmlUtilsTest.java0000644000175000017500000000465011665471066030301 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.internal.util; import junit.framework.TestCase; /** * Test XML utilities. */ public class XmlUtilsTest extends TestCase { /** */ public XmlUtilsTest(String arg0) { super(arg0); } public void testXMLChars() { // Create a string with chars from all the valid ranges. char[] chars = new char[] { 0x9, 0xA, 0xD, 0x20, 0x25, 0xD7FF, 0xE000, 0xEFFF, 0xFFFD, 0xD800, 0xDC00, 0xDBFF, 0xDFFF }; String s = new String(chars); assertTrue(XMLUtils.checkForNonXmlCharacters(s) < 0); // The follownig utf 16 code units are not valid XML chars, or can not stand by themselves // (i.e., they're surrogates). chars = new char[] { 0x0, 0xDFFF, 0xD800, 0xDC00, 0xFFFF }; for (int i = 0; i < chars.length; i++) { assertTrue(XMLUtils.checkForNonXmlCharacters(new String(new char[] { chars[i] })) == 0); } //The following characters are valid in XML 1.1 but not 1.0 chars = new char[] {0x1, 0xB}; for (int i = 0; i < chars.length; i++) { assertTrue(XMLUtils.checkForNonXmlCharacters(new String(new char[] { chars[i] })) == 0); assertTrue(XMLUtils.checkForNonXmlCharacters(new String(new char[] { chars[i] }), true) < 0); } //Check high surrogate followed by low surrogate (legal combination) assertTrue(XMLUtils.checkForNonXmlCharacters(new String(new char [] { 0xD800, 0xDC00})) < 0); // Check low surrogate followed by high surrogate (illegal combination). assertTrue(XMLUtils.checkForNonXmlCharacters(new String(new char [] { 0xDC00, 0xD800})) == 0); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/UIMAClassLoaderTest.java0000644000175000017500000001156111665471066031367 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.internal.util; import java.io.File; import java.net.URL; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.ResourceManager; import org.apache.uima.test.junit_extension.JUnitExtension; /* * UIMA ClassLoader test * */ public class UIMAClassLoaderTest extends TestCase { private String testClassPath; /** * Constructor for UIMAClassLoaderTest * * @param arg0 */ public UIMAClassLoaderTest(String arg0) { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { this.testClassPath = JUnitExtension.getFile("ClassLoaderTest/classLoadingTest.jar").getAbsolutePath(); } public void testSimpleRsrcMgrCLassLoaderCreation() throws Exception { ResourceManager rsrcMgr = UIMAFramework.newDefaultResourceManager(); Assert.assertNull(rsrcMgr.getExtensionClassLoader()); rsrcMgr.setExtensionClassPath("../this/is/a/simple/test.jar", false); Assert.assertNotNull(rsrcMgr.getExtensionClassLoader()); } public void testAdvancedRsrcMgrCLassLoaderCreation() throws Exception { ResourceManager rsrcMgr = UIMAFramework.newDefaultResourceManager(); Assert.assertNull(rsrcMgr.getExtensionClassLoader()); rsrcMgr.setExtensionClassPath("../this/is/a/simple/test.jar", true); Assert.assertNotNull(rsrcMgr.getExtensionClassLoader()); } public void testSimpleClassloadingSampleString() throws Exception { UIMAClassLoader cl = new UIMAClassLoader(this.testClassPath, this.getClass().getClassLoader()); Class testClass = null; testClass = cl.loadClass("org.apache.uima.internal.util.ClassloadingTestClass"); Assert.assertNotNull(testClass); Assert.assertEquals(cl, testClass.getClassLoader()); testClass = cl.loadClass("org.apache.uima.flow.impl.AnalysisSequenceCapabilityNode"); Assert.assertNotNull(testClass); Assert.assertEquals(this.getClass().getClassLoader(),testClass.getClassLoader()); } public void testSimpleClassloadingSampleURL() throws Exception { URL[] urlClasspath = new URL[] { new File(this.testClassPath).toURL() }; UIMAClassLoader cl = new UIMAClassLoader(urlClasspath, this.getClass().getClassLoader()); Class testClass = null; testClass = cl.loadClass("org.apache.uima.internal.util.ClassloadingTestClass"); Assert.assertNotNull(testClass); Assert.assertEquals(cl, testClass.getClassLoader()); testClass = cl.loadClass("org.apache.uima.flow.impl.AnalysisSequenceCapabilityNode"); Assert.assertNotNull(testClass); Assert.assertEquals(this.getClass().getClassLoader(),testClass.getClassLoader()); } public void testAdvancedClassloadingSampleString() throws Exception { UIMAClassLoader cl = new UIMAClassLoader(this.testClassPath, this.getClass().getClassLoader()); Class testClass = null; testClass = cl.loadClass("org.apache.uima.internal.util.ClassloadingTestClass"); Assert.assertNotNull(testClass); Assert.assertEquals(cl, testClass.getClassLoader()); testClass = cl.loadClass("org.apache.uima.flow.impl.AnalysisSequenceCapabilityNode"); Assert.assertNotNull(testClass); Assert.assertEquals(this.getClass().getClassLoader(), testClass.getClassLoader()); } public void testAdvancedClassloadingSampleURL() throws Exception { URL[] urlClasspath = new URL[] { new File(this.testClassPath).toURL() }; UIMAClassLoader cl = new UIMAClassLoader(urlClasspath, this.getClass().getClassLoader()); Class testClass = null; testClass = cl.loadClass("org.apache.uima.internal.util.ClassloadingTestClass"); Assert.assertNotNull(testClass); Assert.assertEquals(cl, testClass.getClassLoader()); testClass = cl.loadClass("org.apache.uima.flow.impl.AnalysisSequenceCapabilityNode"); Assert.assertNotNull(testClass); Assert.assertEquals(this.getClass().getClassLoader(), testClass.getClassLoader()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/ClassloadingTestClass.java0000644000175000017500000000203211665471066032101 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.internal.util; /* * Test class for UIMA ClassLoader test * */ public class ClassloadingTestClass { private int value; public ClassloadingTestClass() { value = 10; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/internal/util/ResourcePoolTest.java0000644000175000017500000001704311665471066031141 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.internal.util; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.resource.Resource; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.Level; /** * Tests the ResourcePool_impl class. * */ public class ResourcePoolTest extends TestCase { /** * Constructor for ResourcePool_implTest. * * @param arg0 */ public ResourcePoolTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); // create resource specifier and a pool containing 3 instances mDesc = new AnalysisEngineDescription_impl(); mDesc.setPrimitive(true); mDesc.setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); mDesc.getMetaData().setName("Test TAE"); mDesc.getMetaData().setDescription("This is a test."); pool1 = new ResourcePool(3, mDesc, AnalysisEngine.class); } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Resource_impl getResource() */ public void testGetResource() throws Exception { try { Assert.assertEquals(3, pool1.getFreeInstances().size()); // get two resources Resource foo = pool1.getResource(); Assert.assertNotNull(foo); Assert.assertEquals(2, pool1.getFreeInstances().size()); Resource bar = pool1.getResource(); Assert.assertNotNull(bar); Assert.assertTrue(!foo.equals(bar)); Assert.assertEquals(1, pool1.getFreeInstances().size()); // get two more resources (should exhaust pool) Resource a = pool1.getResource(); Assert.assertNotNull(a); Assert.assertEquals(0, pool1.getFreeInstances().size()); Resource b = pool1.getResource(); Assert.assertNull(b); Assert.assertEquals(0, pool1.getFreeInstances().size()); } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Resource_impl getResource(long) */ public void testGetResourceJ() throws Exception { try { // ask for resources with timeout of 2 seconds. should respond quickly // until resources are exhausted, then it will pause 2 seconds before // returning null long startTime = System.currentTimeMillis(); Resource foo = pool1.getResource(2000); Assert.assertNotNull(foo); Assert.assertTrue(System.currentTimeMillis() - startTime < 1000); startTime = System.currentTimeMillis(); Resource bar = pool1.getResource(2000); Assert.assertNotNull(bar); Assert.assertTrue(!foo.equals(bar)); Assert.assertTrue(System.currentTimeMillis() - startTime < 1000); startTime = System.currentTimeMillis(); Resource a = pool1.getResource(2000); Assert.assertNotNull(a); Assert.assertTrue(System.currentTimeMillis() - startTime < 1000); startTime = System.currentTimeMillis(); Resource b = pool1.getResource(2000); Assert.assertNull(b); Assert.assertTrue(System.currentTimeMillis() - startTime >= 2000); // Start a thread that will release "foo" in 1 second. Demonstrate that // getResource() will not acquire a resource but getResource(2000) will. Thread releaserThread = new ReleaserThread(foo); releaserThread.start(); b = pool1.getResource(); Assert.assertNull(b); b = pool1.getResource(2000); Assert.assertNotNull(b); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testReleaseResource() throws Exception { try { // acquire all the resources Assert.assertEquals(3, pool1.getFreeInstances().size()); Resource foo = pool1.getResource(); Resource bar = pool1.getResource(); Resource blah = pool1.getResource(); Assert.assertEquals(0, pool1.getFreeInstances().size()); // release one pool1.releaseResource(foo); Assert.assertEquals(1, pool1.getFreeInstances().size()); // try to release "foo" again - should not change the free instances count // this will log a warning - first we log that this is expected UIMAFramework.getLogger().log(Level.WARNING, "Unit test is expecting to log ResourcePool warning."); pool1.releaseResource(foo); Assert.assertEquals(1, pool1.getFreeInstances().size()); // show that we can then check out a new one Resource test = pool1.getResource(); Assert.assertNotNull(test); Assert.assertEquals(0, pool1.getFreeInstances().size()); // release the others pool1.releaseResource(test); pool1.releaseResource(bar); pool1.releaseResource(blah); Assert.assertEquals(3, pool1.getFreeInstances().size()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testDestroy() throws Exception { try { // do some stuff Resource foo = pool1.getResource(); Resource bar = pool1.getResource(); Resource a = pool1.getResource(); pool1.releaseResource(foo); Resource b = pool1.getResource(); pool1.releaseResource(b); // now some stuff should be recorded in the pool Assert.assertTrue(!pool1.getFreeInstances().isEmpty()); // destroy the pool pool1.destroy(); // check that everything is gone Assert.assertTrue(pool1.getFreeInstances().isEmpty()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetMetaData() throws Exception { try { ResourceMetaData descMetaData = mDesc.getMetaData(); ResourceMetaData poolMetaData = pool1.getMetaData(); // only UUID should be different descMetaData.setUUID(poolMetaData.getUUID()); Assert.assertEquals(descMetaData, poolMetaData); } catch (Exception e) { JUnitExtension.handleException(e); } } private AnalysisEngineDescription mDesc; private ResourcePool pool1; class ReleaserThread extends Thread { private Resource r; ReleaserThread(Resource r) { this.r = r; } public void run() { try { synchronized (this) { wait(1000); } pool1.releaseResource(r); } catch (Exception e) { Assert.fail(e.getMessage()); } } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas_data/0000755000175000017500000000000011665471052023751 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/0000755000175000017500000000000011665471052024712 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasDataToXCasTest.java0000644000175000017500000001076211665471052031005 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas_data.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.cas_data.CasData; import org.apache.uima.cas_data.FeatureStructure; import org.apache.uima.test.junit_extension.JUnitExtension; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class CasDataToXCasTest extends TestCase { /** * Constructor for CasDataToXCasTest. * * @param arg0 */ public CasDataToXCasTest(String arg0) { super(arg0); } /* * Test for void generateXCas(CasData) */ public void testGenerateXCasCasData() throws Exception { try { CasData casData = new CasDataImpl(); FeatureStructure testFS = new FeatureStructureImpl(); testFS.setType("Test"); testFS.setId("foo"); testFS.setIndexed(new int[] { 1 }); testFS.setFeatureValue("myFeature", new PrimitiveValueImpl("myValue")); testFS.setFeatureValue("value", new PrimitiveValueImpl("this should show up in XML content")); casData.addFeatureStructure(testFS); CasDataToXCas generator = new CasDataToXCas(); TestContentHandler testContentHandler = new TestContentHandler("Test"); generator.setContentHandler(testContentHandler); generator.generateXCas(casData); Assert.assertTrue(testContentHandler.foundTestElement); // also try colon and dash conversions casData = new CasDataImpl(); testFS = new FeatureStructureImpl(); testFS.setType("Test_colon_Foo_dash_Bar_colon_What_dash_a_dash_mess"); testFS.setId("foo"); testFS.setIndexed(new int[] { 1 }); testFS.setFeatureValue("myFeature", new PrimitiveValueImpl("myValue")); testFS.setFeatureValue("value", new PrimitiveValueImpl("this should show up in XML content")); casData.addFeatureStructure(testFS); testContentHandler = new TestContentHandler("Test:Foo-Bar:What-a-mess"); generator.setContentHandler(testContentHandler); generator.generateXCas(casData); Assert.assertTrue(testContentHandler.foundTestElement); } catch (Exception e) { JUnitExtension.handleException(e); } } public class TestContentHandler extends DefaultHandler { String inElement; StringBuffer buf; boolean foundTestElement = false; String testElementName; public TestContentHandler(String aTestElementName) { testElementName = aTestElementName; } /* * (non-Javadoc) * * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, * java.lang.String, org.xml.sax.Attributes) */ public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { this.inElement = arg1; this.buf = new StringBuffer(); if (this.testElementName.equals(arg1)) { foundTestElement = true; Assert.assertEquals("myValue", arg3.getValue("myFeature")); } } /* * (non-Javadoc) * * @see org.xml.sax.ContentHandler#characters(char[], int, int) */ public void characters(char[] arg0, int arg1, int arg2) throws SAXException { buf.append(arg0, arg1, arg2); } /* * (non-Javadoc) * * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, * java.lang.String) */ public void endElement(String arg0, String arg1, String arg2) throws SAXException { if (this.testElementName.equals(arg1)) { Assert.assertEquals("this should show up in XML content", buf.toString()); } } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/XCasToCasDataSaxHandlerTest.java0000644000175000017500000002350611665471052032757 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas_data.impl; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; import java.util.Iterator; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.CASRuntimeException; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.impl.XCASSerializer; import org.apache.uima.cas_data.CasData; import org.apache.uima.cas_data.FeatureStructure; import org.apache.uima.cas_data.FeatureValue; import org.apache.uima.cas_data.PrimitiveValue; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.Level; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; /** * Tests XCasToCasDataSaxHandler. Also Tests CasDataToXCas. * */ public class XCasToCasDataSaxHandlerTest extends TestCase { /** * Constructor for XCasToCasDataSaxHandlerTest. * * @param arg0 */ public XCasToCasDataSaxHandlerTest(String arg0) { super(arg0); } public void testParse() throws Exception { try { CasData casData = new CasDataImpl(); XCasToCasDataSaxHandler handler = new XCasToCasDataSaxHandler(casData); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(handler); xmlReader.parse(new InputSource(getClass().getResourceAsStream("xcastest.xml"))); // System.out.println(casData); Iterator fsIter = casData.getFeatureStructures(); boolean foundCrawlUrl = false; while (fsIter.hasNext()) { FeatureStructure fs = fsIter.next(); if ("Crawl_colon_URL".equals(fs.getType())) { // System.out.println("[" + fs.getFeatureValue("value") + "]"); Assert .assertEquals( "http://www.nolimitmedia.com/index.php?act=group&gro=1&gron=Flash&PHPSESSID=5dcc31fb425c4a204b70d9eab92531a5", fs.getFeatureValue("value").toString()); foundCrawlUrl = true; } } assertTrue(foundCrawlUrl); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testConversions() throws Exception { try { // complex CAS obtained by deserialization File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); TypeSystemDescription typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); CAS cas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), new FsIndexDescription[0]); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer deser = new XCASDeserializer(cas.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(serCasStream)); serCasStream.close(); _testConversions(cas); // a CAS with multiple Sofas InputStream translatorAeStream = new FileInputStream(JUnitExtension .getFile("CpeSofaTest/TransAnnotator.xml")); AnalysisEngineDescription translatorAeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(translatorAeStream, null)); AnalysisEngine transAnnotator = UIMAFramework.produceAnalysisEngine(translatorAeDesc); CAS cas2 = transAnnotator.newCAS(); CAS englishView = cas2.createView("EnglishDocument"); englishView.setSofaDataString("this beer is good", "text/plain"); transAnnotator.process(cas2); _testConversions(cas2); } catch (Exception e) { JUnitExtension.handleException(e); } } private void _testConversions(CAS aCAS) throws IOException, ParserConfigurationException, SAXException, ResourceInitializationException, CASRuntimeException { // generate XCAS events and pipe them to XCasToCasDataSaxHandler CasData casData = new CasDataImpl(); XCasToCasDataSaxHandler handler = new XCasToCasDataSaxHandler(casData); XCASSerializer xcasSer = new XCASSerializer(aCAS.getTypeSystem()); xcasSer.serialize(aCAS, handler); Assert.assertNotNull(casData); assertValidCasData(casData, aCAS.getTypeSystem()); // System.out.println(casData); // now generate XCAS from the CasData CasDataToXCas generator = new CasDataToXCas(); StringWriter sw = new StringWriter(); XMLSerializer xmlSer = new XMLSerializer(sw, false); generator.setContentHandler(xmlSer.getContentHandler()); generator.generateXCas(casData); String xml = sw.getBuffer().toString(); //workaround for XML serializatioj problem on Sun Java 1.4 if (!builtInXmlSerializationSupportsCRs()) { xml = xml.replaceAll(" ", " "); } UIMAFramework.getLogger(XCasToCasDataSaxHandlerTest.class).log(Level.FINE, xml); // deserialize back into CAS for comparison // CASMgr tcasMgr = CASFactory.createCAS(aCAS.getTypeSystem()); // tcasMgr.initCASIndexes(); // tcasMgr.getIndexRepositoryMgr().commit(); CAS cas2 = CasCreationUtils.createCas(null, aCAS.getTypeSystem(), null); XCASDeserializer deser = new XCASDeserializer(cas2.getTypeSystem()); ContentHandler deserHandler = deser.getXCASHandler(cas2); SAXParserFactory fact = SAXParserFactory.newInstance(); SAXParser parser = fact.newSAXParser(); XMLReader xmlReader = parser.getXMLReader(); xmlReader.setContentHandler(deserHandler); xmlReader.parse(new InputSource(new StringReader(xml))); // CASes should be identical CasComparer.assertEquals(aCAS, cas2); } /** * @param casData * @param system */ private void assertValidCasData(CasData casData, TypeSystem typeSystem) { Type annotType = typeSystem.getType(CAS.TYPE_NAME_ANNOTATION); Type arrayType = typeSystem.getType(CAS.TYPE_NAME_ARRAY_BASE); Iterator fsIter = casData.getFeatureStructures(); while (fsIter.hasNext()) { org.apache.uima.cas_data.FeatureStructure fs = (org.apache.uima.cas_data.FeatureStructure) fsIter .next(); String typeName = fs.getType(); // don't do tests on the "fake" document text FS if (XCASSerializer.DEFAULT_DOC_TYPE_NAME.equals(typeName)) continue; Type type = typeSystem.getType(typeName); Assert.assertNotNull(type); if (typeSystem.subsumes(annotType, type)) { // annotation type - check for presence of begin/end FeatureValue beginVal = fs.getFeatureValue("begin"); Assert.assertTrue(beginVal instanceof PrimitiveValue); Assert.assertTrue(((PrimitiveValue) beginVal).toInt() >= 0); FeatureValue endVal = fs.getFeatureValue("end"); Assert.assertTrue(endVal instanceof PrimitiveValue); Assert.assertTrue(((PrimitiveValue) endVal).toInt() >= 0); } } } /** * Checks the Java vendor and version and returns true if running a version * of Java whose built-in XSLT support can properly serialize carriage return * characters, and false if not. It seems to be the case that Sun JVMs prior * to 1.5 do not properly serialize carriage return characters. We have to * modify our test case to account for this. * @return true if XML serialization of CRs behave properly in the current JRE */ private boolean builtInXmlSerializationSupportsCRs() { String javaVendor = System.getProperty("java.vendor"); if( javaVendor.startsWith("Sun") ) { String javaVersion = System.getProperty("java.version"); if( javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") ) return false; } return true; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/cas_data/impl/CasComparer.java0000644000175000017500000001422211665471052027755 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.cas_data.impl; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.Assert; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.FloatArrayFS; import org.apache.uima.cas.IntArrayFS; import org.apache.uima.cas.SofaFS; import org.apache.uima.cas.StringArrayFS; import org.apache.uima.cas.Type; import org.apache.uima.cas.text.AnnotationFS; /** * A non-perfect CAS equality checker for JUnit. * */ public class CasComparer { public static void assertEquals(CAS c1, CAS c2) { FSIterator sofaIter = c1.getSofaIterator(); int c1Sofas = 0; while (sofaIter.hasNext()) { SofaFS sofa = (SofaFS) sofaIter.next(); CAS tcas1 = c1.getView(sofa); CAS tcas2 = c2.getView(tcas1.getViewName()); assertEqualViews(tcas1, tcas2); c1Sofas++; } sofaIter = c2.getSofaIterator(); int c2Sofas = 0; while (sofaIter.hasNext()) { c2Sofas++; sofaIter.moveToNext(); } Assert.assertTrue(c1Sofas == c2Sofas); } public static void assertEqualViews(CAS c1, CAS c2) { Map visited = new HashMap(); FSIterator it1 = c1.getAnnotationIndex().iterator(); FSIterator it2 = c2.getAnnotationIndex().iterator(); while (it1.isValid()) { Assert.assertTrue(it2.isValid()); FeatureStructure fs1 = it1.get(); FeatureStructure fs2 = it2.get(); assertEquals(fs1, fs2, visited); it1.moveToNext(); it2.moveToNext(); } } public static void assertEquals(FeatureStructure fs1, FeatureStructure fs2) { assertEquals(fs1, fs2, new HashMap()); } public static void assertEquals(FeatureStructure fs1, FeatureStructure fs2, Map visited) { if (fs1 == null) { Assert.assertNull(fs2); return; } else { Assert.assertNotNull(fs2); } if (visited.containsKey(fs1)) { return; } visited.put(fs1, fs1); // System.out.println("Comparing " + fs1.getType().getName()); Assert.assertEquals(fs1.getType().getName(), fs2.getType().getName()); List features1 = fs1.getType().getFeatures(); List features2 = fs2.getType().getFeatures(); for (int i = 0; i < features1.size(); i++) { Feature feat1 = features1.get(i); Feature feat2 = features2.get(i); // System.out.println("Comparing " + feat1.getName()); Type rangeType1 = feat1.getRange(); Type rangeType2 = feat2.getRange(); Assert.assertEquals(rangeType1.getName(), rangeType2.getName()); // System.out.println("Range type " + rangeType1); String rangeTypeName = rangeType1.getName(); if (fs1.getCAS().getTypeSystem().subsumes( fs1.getCAS().getTypeSystem().getType(CAS.TYPE_NAME_STRING), rangeType1)) { Assert.assertEquals(fs1.getStringValue(feat1), fs2.getStringValue(feat2)); } else if (CAS.TYPE_NAME_INTEGER.equals(rangeTypeName)) { Assert.assertEquals(fs1.getIntValue(feat1), fs2.getIntValue(feat2)); } else if (CAS.TYPE_NAME_FLOAT.equals(rangeTypeName)) { Assert.assertEquals(fs1.getFloatValue(feat1), fs2.getFloatValue(feat2), 0); } else if (CAS.TYPE_NAME_STRING_ARRAY.equals(rangeTypeName)) { StringArrayFS arrayFS1 = (StringArrayFS) fs1.getFeatureValue(feat1); StringArrayFS arrayFS2 = (StringArrayFS) fs2.getFeatureValue(feat2); Assert.assertEquals(arrayFS1.size(), arrayFS2.size()); for (int j = 0; j < arrayFS1.size(); j++) { Assert.assertEquals(arrayFS1.get(j), arrayFS2.get(j)); } } else if (CAS.TYPE_NAME_INTEGER_ARRAY.equals(rangeTypeName)) { IntArrayFS arrayFS1 = (IntArrayFS) fs1.getFeatureValue(feat1); IntArrayFS arrayFS2 = (IntArrayFS) fs2.getFeatureValue(feat2); Assert.assertEquals(arrayFS1.size(), arrayFS2.size()); for (int j = 0; j < arrayFS1.size(); j++) { Assert.assertEquals(arrayFS1.get(j), arrayFS2.get(j)); } } else if (CAS.TYPE_NAME_FLOAT_ARRAY.equals(rangeTypeName)) { FloatArrayFS arrayFS1 = (FloatArrayFS) fs1.getFeatureValue(feat1); FloatArrayFS arrayFS2 = (FloatArrayFS) fs2.getFeatureValue(feat2); Assert.assertEquals(arrayFS1.size(), arrayFS2.size()); for (int j = 0; j < arrayFS1.size(); j++) { Assert.assertEquals(arrayFS1.get(j), arrayFS2.get(j), 0); } } else if (CAS.TYPE_NAME_FS_ARRAY.equals(rangeTypeName)) { ArrayFS arrayFS1 = (ArrayFS) fs1.getFeatureValue(feat1); ArrayFS arrayFS2 = (ArrayFS) fs2.getFeatureValue(feat2); Assert.assertEquals(arrayFS1.size(), arrayFS2.size()); for (int j = 0; j < arrayFS1.size(); j++) { assertEquals(arrayFS1.get(j), arrayFS2.get(j), visited); } } else // single feature value { FeatureStructure fsVal1 = fs1.getFeatureValue(feat1); FeatureStructure fsVal2 = fs2.getFeatureValue(feat2); assertEquals(fsVal1, fsVal2, visited); } } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/0000755000175000017500000000000011665471060023140 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/0000755000175000017500000000000011665471060024115 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/PearEncodingTest.java0000644000175000017500000000655311665471060030167 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.pear.util; import java.io.File; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Pear encoding tests * */ public class PearEncodingTest extends TestCase { public void testUTF8NoSignature() throws Exception { // get XML file File xmlFile = JUnitExtension.getFile("pearTests/encodingTests/UTF8_no_signature.xml"); // get encoding String encoding = XMLUtil.detectXmlFileEncoding(xmlFile); // normalize encoding encoding = encoding.toUpperCase(); Assert.assertTrue(encoding.equals("UTF-8")); } public void testUTF8WithSignature() throws Exception { // cancel this test for Sun's Java 1.3.x or 1.4.x - it does not support BOM String javaVendor = System.getProperty("java.vendor"); if( javaVendor.startsWith("Sun") ) { String javaVersion = System.getProperty("java.version"); if( javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") ) return; } // get XML file File xmlFile = JUnitExtension.getFile("pearTests/encodingTests/UTF8_with_signature.xml"); // get encoding String encoding = XMLUtil.detectXmlFileEncoding(xmlFile); // normalize encoding encoding = encoding.toUpperCase(); Assert.assertTrue(encoding.equals("UTF-8")); } public void testUTF16NoSignature() throws Exception { //NOTE: this test fails when using SUN JVM 1.4.2_12 // get XML file File xmlFile = JUnitExtension.getFile("pearTests/encodingTests/UTF16_no_signature.xml"); // get encoding String encoding = XMLUtil.detectXmlFileEncoding(xmlFile); // normalize encoding encoding = encoding.toUpperCase(); Assert.assertTrue(encoding.equals("UTF-16LE")); } public void testUTF16WithSignature() throws Exception { // cancel this test for Sun's Java 1.3.x or 1.4.x - it does not support BOM String javaVendor = System.getProperty("java.vendor"); if( javaVendor.startsWith("Sun") ) { String javaVersion = System.getProperty("java.version"); if( javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") ) return; } // get XML file File xmlFile = JUnitExtension.getFile("pearTests/encodingTests/UTF16_with_signature.xml"); // get encoding String encoding = XMLUtil.detectXmlFileEncoding(xmlFile); // normalize encoding encoding = encoding.toUpperCase(); Assert.assertTrue(encoding.equals("UTF-16")); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/PearInstallerTest.java0000644000175000017500000001031311665471060030363 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.pear.util; import java.io.File; import java.io.FileNotFoundException; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.cas.CAS; import org.apache.uima.pear.tools.PackageBrowser; import org.apache.uima.pear.tools.PackageInstaller; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * The PearInstallerTest tests the PEAR installation and checks some * parameters of the installed PEAR file * */ public class PearInstallerTest extends TestCase { // Temporary working directory, used to install the pear package private File tempInstallDir = null; /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // create temporary working directory File tempFile = File.createTempFile("pear_installer_test_", "tmp"); if (tempFile.delete()) { File tempDir = tempFile; if (tempDir.mkdirs()) this.tempInstallDir = tempDir; } } /** * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { if (this.tempInstallDir != null) { FileUtil.deleteDirectory(this.tempInstallDir); } } /** * @throws Exception */ public void testPearInstall() throws Exception { // check temporary working directory if (this.tempInstallDir == null) throw new FileNotFoundException("temp directory not found"); // check sample PEAR files //get pear file to install File pearFile = JUnitExtension.getFile("pearTests/DateTime.pear"); Assert.assertNotNull(pearFile); // Install PEAR package PackageBrowser instPear = PackageInstaller.installPackage( this.tempInstallDir, pearFile, true); //check pear PackageBrowser object Assert.assertNotNull(instPear); //check PEAR component ID String componentID = instPear.getInstallationDescriptor().getMainComponentId(); Assert.assertEquals("uima.example.DateTimeAnnotator", componentID); //check PEAR datapath setting //pear file contains (uima.datapath = $main_root/my/test/data/path) File datapath = new File(this.tempInstallDir, "uima.example.DateTimeAnnotator/my/test/data/path"); File pearDatapath = new File(instPear.getComponentDataPath()); Assert.assertEquals(datapath, pearDatapath); // Create resouce manager and set PEAR package classpath ResourceManager rsrcMgr = UIMAFramework.newDefaultResourceManager(); // Create analysis engine from the installed PEAR package XMLInputSource in = new XMLInputSource(instPear.getComponentPearDescPath()); ResourceSpecifier specifier = UIMAFramework.getXMLParser() .parseResourceSpecifier(in); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine( specifier, rsrcMgr, null); Assert.assertNotNull(ae); // Create a CAS with a sample document text and process the CAS CAS cas = ae.newCAS(); cas.setDocumentText("Sample text to process with a date 05/29/07 and a time 9:45 AM"); cas.setDocumentLanguage("en"); ae.process(cas); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/ComponentCategoryTest.java0000644000175000017500000000775511665471060031276 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.pear.util; import java.io.File; import java.io.FileNotFoundException; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.test.junit_extension.JUnitExtension; /** * The ComponentCategoryTest class provides JUnit test cases for the * org.apache.uima.pear.util.UIMAUtil.identifyUimaComponentCategory() method. The test cases are * based on the sample XML descriptors located in the 'pearTests/componentCategoryTests' folder. * */ public class ComponentCategoryTest extends TestCase { // relative location of test descriptors private static String TEST_FOLDER = "pearTests/componentCategoryTests"; // test descriptor file names private static String AE_DESC_NAME = "ae.xml"; private static String CC_DESC_NAME = "cc.xml"; private static String CI_DESC_NAME = "ci.xml"; private static String CR_DESC_NAME = "cr.xml"; private static String TS_DESC_NAME = "ts.xml"; // NOTE: the testcase to identify a CPE descriptor has meen moved to the CPE project /** * Runs test case for Analysis Engine descriptor. */ public void testAeDescriptor() throws Exception { File aeDescFile = JUnitExtension.getFile(TEST_FOLDER + "/" + AE_DESC_NAME); if (!aeDescFile.isFile()) throw new FileNotFoundException("AE descriptor not found"); Assert.assertTrue(UIMAUtil.ANALYSIS_ENGINE_CTG.equals(UIMAUtil .identifyUimaComponentCategory(aeDescFile))); } /** * Runs test case for CAS Consumer descriptor. */ public void testCcDescriptor() throws Exception { File ccDescFile = JUnitExtension.getFile(TEST_FOLDER + "/" + CC_DESC_NAME); if (!ccDescFile.isFile()) throw new FileNotFoundException("CC descriptor not found"); Assert.assertTrue(UIMAUtil.CAS_CONSUMER_CTG.equals(UIMAUtil .identifyUimaComponentCategory(ccDescFile))); } /** * Runs test case for CAS Initializer descriptor. */ public void testCiDescriptor() throws Exception { File ciDescFile = JUnitExtension.getFile(TEST_FOLDER + "/" + CI_DESC_NAME); if (!ciDescFile.isFile()) throw new FileNotFoundException("CI descriptor not found"); Assert.assertTrue(UIMAUtil.CAS_INITIALIZER_CTG.equals(UIMAUtil .identifyUimaComponentCategory(ciDescFile))); } /** * Runs test case for Collection Reader descriptor. */ public void testCrDescriptor() throws Exception { File crDescFile = JUnitExtension.getFile(TEST_FOLDER + "/" + CR_DESC_NAME); if (!crDescFile.isFile()) throw new FileNotFoundException("CR descriptor not found"); Assert.assertTrue(UIMAUtil.COLLECTION_READER_CTG.equals(UIMAUtil .identifyUimaComponentCategory(crDescFile))); } /** * Runs test case for Type System descriptor. */ public void testTsDescriptor() throws Exception { File tsDescFile = JUnitExtension.getFile(TEST_FOLDER + "/" + TS_DESC_NAME); if (!tsDescFile.isFile()) throw new FileNotFoundException("TS descriptor not found"); Assert.assertTrue(UIMAUtil.TYPE_SYSTEM_CTG.equals(UIMAUtil .identifyUimaComponentCategory(tsDescFile))); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/TestPearInstallationVerification.java0000644000175000017500000001034211665471060033434 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.pear.util; import java.io.File; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.pear.tools.InstallationTester; import org.apache.uima.pear.tools.PackageBrowser; import org.apache.uima.pear.tools.PackageInstaller; import org.apache.uima.pear.tools.InstallationController.TestStatus; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Test the pear installation verification * */ public class TestPearInstallationVerification extends TestCase { // Temporary working directory, used to install the pear package private File tempInstallDir = null; /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // create temporary working directory File tempFile = File.createTempFile("pear_verification_test_", "tmp"); if (tempFile.delete()) { File tempDir = tempFile; if (tempDir.mkdirs()) this.tempInstallDir = tempDir; } } /** * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { if (this.tempInstallDir != null) { FileUtil.deleteDirectory(this.tempInstallDir); } } public void testAePearVerification() throws Exception { //get pear file to install File pearFile = JUnitExtension.getFile("pearTests/analysisEngine.pear"); Assert.assertNotNull("analysisEngine.pear file not found", pearFile); // Install PEAR package without verification PackageBrowser instPear = PackageInstaller.installPackage( this.tempInstallDir, pearFile, false); //check package browser Assert.assertNotNull("PackageBrowser is null", instPear); InstallationTester installTester = new InstallationTester(instPear); TestStatus status = installTester.doTest(); Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL); } public void testCcPearVerification() throws Exception { //get pear file to install File pearFile = JUnitExtension.getFile("pearTests/casConsumer.pear"); Assert.assertNotNull("casConsumer.pear file not found", pearFile); // Install PEAR package without verification PackageBrowser instPear = PackageInstaller.installPackage( this.tempInstallDir, pearFile, false); //check package browser Assert.assertNotNull("PackageBrowser is null", instPear); InstallationTester installTester = new InstallationTester(instPear); TestStatus status = installTester.doTest(); Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL); } public void testTsPearVerification() throws Exception { //get pear file to install File pearFile = JUnitExtension.getFile("pearTests/typeSystem.pear"); Assert.assertNotNull("typeSystem.pear file not found", pearFile); // Install PEAR package without verification PackageBrowser instPear = PackageInstaller.installPackage( this.tempInstallDir, pearFile, false); //check package browser Assert.assertNotNull("PackageBrowser is null", instPear); InstallationTester installTester = new InstallationTester(instPear); TestStatus status = installTester.doTest(); Assert.assertEquals(status.getRetCode(), TestStatus.TEST_SUCCESSFUL); } //TODO: create testcases for ci, cr, cpe pear packages } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/pear/util/PearRuntimeTest.java0000644000175000017500000002062011665471060030053 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.pear.util; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.SofaMapping; import org.apache.uima.cas.CAS; import org.apache.uima.pear.tools.PackageBrowser; import org.apache.uima.pear.tools.PackageInstaller; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.test.junit_extension.JUnitExtension; /** * The PEAR runtime tests installs two pears files that both use JCas classes * in their processing. */ public class PearRuntimeTest extends TestCase { // Temporary working directory, used to install the pear package private File tempInstallDir = null; /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { // create temporary working directory File tempFile = File.createTempFile("pear_runtime_test_", "tmp"); if (tempFile.delete()) { File tempDir = tempFile; if (tempDir.mkdirs()) this.tempInstallDir = tempDir; } } /** * @see junit.framework.TestCase#tearDown() */ protected void tearDown() throws Exception { if (this.tempInstallDir != null) { FileUtil.deleteDirectory(this.tempInstallDir); } } public void testPearSofaMapping() throws Exception { AnalysisEngineDescription desc = createAeDescriptionFromPears(new String[]{"pearTests/pearSofaMap.pear"}); Capability[] capabilities = new Capability[]{UIMAFramework.getResourceSpecifierFactory().createCapability()}; capabilities[0].setInputSofas(new String[] {"_InitialView"}); capabilities[0].setOutputSofas(new String[] {"GermanDocument"}); desc.getAnalysisEngineMetaData().setCapabilities(capabilities); SofaMapping[] sofaMappings = new SofaMapping[] {UIMAFramework.getResourceSpecifierFactory().createSofaMapping(), UIMAFramework.getResourceSpecifierFactory().createSofaMapping()}; // ProjectForPear_pear // EnglishDocument // _InitialView sofaMappings[0].setComponentKey("Pear0"); sofaMappings[1].setComponentKey("Pear0"); sofaMappings[0].setComponentSofaName("EnglishDocument"); sofaMappings[1].setComponentSofaName("GermanDocument"); sofaMappings[0].setAggregateSofaName("_InitialView"); sofaMappings[1].setAggregateSofaName("GermanDocument"); desc.setSofaMappings(sofaMappings); CAS cas = runDesc(desc); } /** * @throws Exception */ public void testPearRuntime() throws Exception { CAS cas = this.runPearRuntimeTestcase(new String[]{"pearTests/DateTime.pear", "pearTests/RoomNumber.pear"}); //check if 3 annotations are available in the CAS index // The 3 annotations are the doc annotation, plus 2 room numbers // The date-time annotators are skipped because the default result spec is "en" // and is missing the "x-unspecified" Assert.assertEquals(cas.getAnnotationIndex().size(), 3); // FSIterator i = cas.getAnnotationIndex().iterator(); // while (i.hasNext()) { // System.out.println(i.next()); // } } /** * @throws Exception */ public void testPearRuntimeDocAnnot() throws Exception { CAS cas = this.runPearRuntimeTestcase(new String[]{"pearTests/analysisEngine.pear", "pearTests/analysisEngine2.pear"}); //check if 3 annotations are available in the CAS index Assert.assertEquals(cas.getAnnotationIndex().size(), 3); } private Import [] installPears(String [] pears) throws IOException { List result = new ArrayList(); for (String s : pears) { result.add(installPear(s)); } return result.toArray(new Import[result.size()]); } private Import installPear(String pear) throws IOException { // check temporary working directory if (this.tempInstallDir == null) throw new FileNotFoundException("temp directory not found"); // check sample PEAR files // get pear files to install File pearFile = JUnitExtension.getFile(pear); Assert.assertNotNull(pearFile); // Install PEAR packages PackageBrowser instPear = PackageInstaller .installPackage(this.tempInstallDir, pearFile, true); // check pear PackageBrowser object Assert.assertNotNull(instPear); // import pear specifiers Import impPear = UIMAFramework.getResourceSpecifierFactory().createImport(); File import1 = new File(instPear.getComponentPearDescPath()); impPear.setLocation(import1.toURI().getPath()); return impPear; } private AnalysisEngineDescription createAeDescriptionFromPears(String[] pears) throws Exception { Import[] impPears = installPears(pears); // create aggregate analysis engine descriptor AnalysisEngineDescription desc = UIMAFramework.getResourceSpecifierFactory() .createAnalysisEngineDescription(); desc.setPrimitive(false); // add delegates as imports Map delegates = desc.getDelegateAnalysisEngineSpecifiersWithImports(); String [] keys = new String[impPears.length]; for (int i = 0; i < impPears.length; i++) { keys[i] = "Pear" + i; delegates.put(keys[i], impPears[i]); } // add sequence - fixed flow FixedFlow fixedFlow = UIMAFramework.getResourceSpecifierFactory().createFixedFlow(); fixedFlow.setFixedFlow(keys); // add analysis engine meta data AnalysisEngineMetaData md = desc.getAnalysisEngineMetaData(); md.setName("PEAR aggregate"); md.setDescription("combines one or more PEARs"); md.setVersion("1.0"); md.setFlowConstraints(fixedFlow); // serialize descriptor // String outputDir = JUnitExtension.getFile("pearTests/DateTime.pear").getParent(); File // outputFile = new File(outputDir, "PearAggregate.xml"); OutputStream outStream = new // BufferedOutputStream(new FileOutputStream(outputFile)); Writer writer = new // OutputStreamWriter(outStream, OutputFormat.Defaults.Encoding); XMLSerializer xmlSerializer = // new XMLSerializer(); xmlSerializer.setWriter(writer); // desc.toXML(xmlSerializer.getContentHandler(), true); writer.close(); return desc; } private CAS runDesc(AnalysisEngineDescription desc) throws Exception { // Create analysis engine from aggregate ae description AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(desc, null, null); Assert.assertNotNull(ae); // Create a CAS with a sample document text and process the CAS CAS cas = ae.newCAS(); cas.setDocumentText("Sample text to process with a date 05/29/07 and a time 9:45 AM and a Room number GN-K35 or two GN-K37"); cas.setDocumentLanguage("en"); ae.process(cas); return cas; } /** * @throws Exception */ private CAS runPearRuntimeTestcase(String[] pears) throws Exception { AnalysisEngineDescription desc = createAeDescriptionFromPears(pears); return runDesc(desc); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/0000755000175000017500000000000011665471062024042 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/0000755000175000017500000000000011665471062025502 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/0000755000175000017500000000000011665471062026443 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/ResourceService_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/ResourceService_implTest.0000644000175000017500000000611411665471062033437 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.service.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Tests the ResourceService_impl class. * */ public class ResourceService_implTest extends TestCase { /** * Constructor for ResourceService_implTest. * * @param arg0 */ public ResourceService_implTest(String arg0) throws java.io.FileNotFoundException { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); // create resource specifier and a pool containing 2 instances AnalysisEngineDescription primitiveDesc = new AnalysisEngineDescription_impl(); primitiveDesc.setPrimitive(true); primitiveDesc .setAnnotatorImplementationName("org.apache.uima.analysis_engine.impl.TestAnnotator"); primitiveDesc.getMetaData().setName("Test Annotator"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("StringParam"); p1.setDescription("parameter with String data type"); p1.setType(ConfigurationParameter.TYPE_STRING); primitiveDesc.getMetaData().getConfigurationParameterDeclarations() .setConfigurationParameters(new ConfigurationParameter[] { p1 }); // create a ResourceService_impl service = new ResourceService_impl(); service.initialize(primitiveDesc, null); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetMetaData() throws Exception { try { ResourceMetaData md = service.getMetaData(); Assert.assertNotNull(md); Assert.assertEquals("Test Annotator", md.getName()); Assert.assertNotNull(md.getUUID()); } catch (Exception e) { JUnitExtension.handleException(e); } } private ResourceService_impl service; } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/ResourceServiceAdapter_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/ResourceServiceAdapter_im0000644000175000017500000000607111665471062033470 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.service.impl; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Tests the ResourceServiceAdapter_impl class. * */ public class ResourceServiceAdapter_implTest extends TestCase { /** * Constructor for ResourceServiceAdapter_implTest. * * @param arg0 */ public ResourceServiceAdapter_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); mServiceStub = new TestResourceServiceStub(); mAdapter = new ResourceServiceAdapter() { public boolean initialize(ResourceSpecifier p1, Map p2) { return false; } }; mAdapter.setStub(mServiceStub); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetMetaData() throws Exception { try { ResourceMetaData md = new ResourceMetaData_impl(); md.setName("Test"); md.setDescription("This is a test"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("IntegerArrayParam"); p1.setDescription("multi-valued parameter with Integer data type"); p1.setType(ConfigurationParameter.TYPE_INTEGER); p1.setMultiValued(true); md.getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[] { p1 }); mServiceStub.getMetaDataReturnValue = md; ResourceMetaData result = mAdapter.getMetaData(); Assert.assertEquals("callGetMetaData", mServiceStub.lastMethodName); Assert.assertEquals(md, result); } catch (Exception e) { JUnitExtension.handleException(e); } } private TestResourceServiceStub mServiceStub; private ResourceServiceAdapter mAdapter; } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/TestResourceServiceStub.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/service/impl/TestResourceServiceStub.j0000644000175000017500000000374511665471062033435 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.service.impl; import org.apache.uima.resource.ResourceServiceException; import org.apache.uima.resource.ResourceServiceStub; import org.apache.uima.resource.metadata.ResourceMetaData; /** * A mock ResourceService implementation used for testing communications. Return values of all * methods are specified by public fields. Info on last method called is also specified by public * fields. * */ public class TestResourceServiceStub implements ResourceServiceStub { /** Name of last method called */ public String lastMethodName; /** Args to last method call */ public Object[] lastMethodArgs; /** Return value of getMetaData */ public ResourceMetaData getMetaDataReturnValue; /** * @see org.apache.uima.resource.service.ResourceService#getMetaData() */ public ResourceMetaData callGetMetaData() throws ResourceServiceException { lastMethodName = "callGetMetaData"; lastMethodArgs = new Object[] {}; return getMetaDataReturnValue; } /** * @see org.apache.uima.resource.service.impl.ResourceServiceStub#destroy() */ public void destroy() { //do nothing } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/0000755000175000017500000000000011665471062025622 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/0000755000175000017500000000000011665471062026563 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypePriorities_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypePriorities_implTest.0000644000175000017500000001355411665471062033450 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; public class TypePriorities_implTest extends TestCase { /** * Constructor for TypeSystemDescription_implTest. * * @param arg0 */ public TypePriorities_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); UIMAFramework.getXMLParser().enableSchemaValidation(true); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } public void testBuildFromXmlElement() throws Exception { try { // simple type priorties (backwards compatibility check) File descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/SimpleTypePriorities.xml"); TypePriorities pri = UIMAFramework.getXMLParser().parseTypePriorities( new XMLInputSource(descriptor)); assertEquals(null, pri.getName()); assertEquals(null, pri.getDescription()); assertEquals(null, pri.getVendor()); assertEquals(null, pri.getVersion()); assertEquals(0, pri.getImports().length); assertEquals(2, pri.getPriorityLists().length); // try one with imports descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/TestTypePriorities.xml"); pri = UIMAFramework.getXMLParser().parseTypePriorities(new XMLInputSource(descriptor)); assertEquals("TestTypePriorities", pri.getName()); assertEquals("This is a test.", pri.getDescription()); assertEquals("The Apache Software Foundation", pri.getVendor()); assertEquals("0.1", pri.getVersion()); Import[] imports = pri.getImports(); assertEquals(2, imports.length); assertEquals("TypePrioritiesImportedByLocation.xml", imports[0].getLocation()); assertNull(imports[0].getName()); assertNull(imports[1].getLocation()); assertEquals("TypePrioritiesImportedFromDataPath", imports[1].getName()); TypePriorityList[] priLists = pri.getPriorityLists(); assertEquals(1, priLists.length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveImports() throws Exception { try { File descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/TestTypePriorities.xml"); TypePriorities pri = UIMAFramework.getXMLParser().parseTypePriorities( new XMLInputSource(descriptor)); TypePriorityList[] priLists = pri.getPriorityLists(); assertEquals(1, priLists.length); // resolving imports without setting data path should fail InvalidXMLException ex = null; try { pri.resolveImports(); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); assertEquals(1, pri.getPriorityLists().length); // should be no side effects when exception is // thrown // set data path correctly and it should work ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(JUnitExtension.getFile("TypePrioritiesImplTest/dataPathDir") .getAbsolutePath()); pri.resolveImports(resMgr); priLists = pri.getPriorityLists(); assertEquals(3, priLists.length); // test that circular imports don't crash descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/Circular1.xml"); pri = UIMAFramework.getXMLParser().parseTypePriorities(new XMLInputSource(descriptor)); pri.resolveImports(); assertEquals(2, pri.getPriorityLists().length); // calling resolveImports when there are none should do nothing descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/SimpleTypePriorities.xml"); pri = UIMAFramework.getXMLParser().parseTypePriorities(new XMLInputSource(descriptor)); assertEquals(2, pri.getPriorityLists().length); pri.resolveImports(); assertEquals(2, pri.getPriorityLists().length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testClone() throws Exception { try { File descriptor = JUnitExtension.getFile("TypePrioritiesImplTest/TestTypePriorities.xml"); TypePriorities pri = UIMAFramework.getXMLParser().parseTypePriorities( new XMLInputSource(descriptor)); TypePriorities clone = (TypePriorities) pri.clone(); assertEquals(clone, pri); assertFalse(clone.getPriorityLists()[0] == pri.getPriorityLists()[0]); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TestFruitBagObject.java0000644000175000017500000000401111665471062033114 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.util.HashSet; import java.util.Set; import org.apache.uima.util.NameClassPair; /** * A simple concrete MetaDataObject implementation for use in testing the MetaDataObject_impl class. */ public class TestFruitBagObject extends MetaDataObject_impl { static final private XmlizationInfo XMLIZATION_INFO = new XmlizationInfo("fruitBag", new PropertyXmlInfo[] { new PropertyXmlInfo("fruits") }); private String mName; private TestFruitObject[] mFruits; public TestFruitBagObject() { //do nothing } public TestFruitObject[] getFruits() { return mFruits; } public void setFruits(TestFruitObject[] aFruits) { mFruits = aFruits; } /** * For testing purposes - a hardcoded attribute set. Should be compared with the results of * {@link #listAttributes()}. */ static public Set getAttributeSet() { Set result = new HashSet(); result.add(new NameClassPair("fruits", TestFruitObject[].class.getName())); return result; } protected XmlizationInfo getXmlizationInfo() { return XMLIZATION_INFO; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/ConfigurationParameterDeclarations_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/ConfigurationParameterDe0000644000175000017500000000425211665471062033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.FileInputStream; import java.io.InputStream; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.test.junit_extension.JUnitExtension; import org.w3c.dom.Document; public class ConfigurationParameterDeclarations_implTest extends TestCase { /** * Constructor for ConfigurationParameterDeclarations_implTest. * * @param arg0 */ public ConfigurationParameterDeclarations_implTest(String arg0) { super(arg0); } public void testBuildFromXmlElement() throws Exception { // parse XML DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); InputStream str = new FileInputStream(JUnitExtension .getFile("org/apache/uima/resource/metadata/impl/ConfigParamEmptyGroup.xml")); Document doc = docBuilder.parse(str); ConfigurationParameterDeclarations_impl obj = new ConfigurationParameterDeclarations_impl(); obj.buildFromXMLElement(doc.getDocumentElement(), UIMAFramework.getXMLParser()); Assert.assertEquals(1, obj.getConfigurationGroups().length); } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TypeSystemDescription_im0000644000175000017500000002016511665471062033531 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.File; import java.net.URL; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; public class TypeSystemDescription_implTest extends TestCase { /** * Constructor for TypeSystemDescription_implTest. * * @param arg0 */ public TypeSystemDescription_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); UIMAFramework.getXMLParser().enableSchemaValidation(true); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } public void testBuildFromXmlElement() throws Exception { try { File descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml"); TypeSystemDescription ts = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(descriptor)); assertEquals("TestTypeSystem", ts.getName()); assertEquals("This is a test.", ts.getDescription()); assertEquals("The Apache Software Foundation", ts.getVendor()); assertEquals("0.1", ts.getVersion()); Import[] imports = ts.getImports(); assertEquals(3, imports.length); assertEquals("org.apache.uima.resource.metadata.impl.TypeSystemImportedByName", imports[0] .getName()); assertNull(imports[0].getLocation()); assertNull(imports[1].getName()); assertEquals("TypeSystemImportedByLocation.xml", imports[1].getLocation()); TypeDescription[] types = ts.getTypes(); assertEquals(6, types.length); TypeDescription paragraphType = types[4]; assertEquals("Paragraph", paragraphType.getName()); assertEquals("A paragraph.", paragraphType.getDescription()); assertEquals("DocumentStructure", paragraphType.getSupertypeName()); FeatureDescription[] features = paragraphType.getFeatures(); assertEquals(2, features.length); assertEquals("sentences", features[0].getName()); assertEquals("Direct references to sentences in this paragraph", features[0].getDescription()); assertEquals("uima.cas.FSArray", features[0].getRangeTypeName()); assertEquals("Sentence", features[0].getElementType()); assertFalse(features[0].getMultipleReferencesAllowed().booleanValue()); // ts.toXML(System.out); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveImports() throws Exception { try { File descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/TestTypeSystem.xml"); TypeSystemDescription ts = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(descriptor)); TypeDescription[] types = ts.getTypes(); assertEquals(6, types.length); // resolving imports without setting data path should fail InvalidXMLException ex = null; try { ts.resolveImports(); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); assertEquals(6, ts.getTypes().length); // should be no side effects when exception is thrown // set data path correctly and it should work ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir") .getAbsolutePath()); ts.resolveImports(resMgr); types = ts.getTypes(); assertEquals(13, types.length); // test that circular imports don't crash descriptor = JUnitExtension.getFile("TypeSystemDescriptionImplTest/Circular1.xml"); ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(new XMLInputSource(descriptor)); ts.resolveImports(); assertEquals(2, ts.getTypes().length); // calling resolveImports when there are none should do nothing descriptor = JUnitExtension .getFile("TypeSystemDescriptionImplTest/TypeSystemImportedByLocation.xml"); ts = UIMAFramework.getXMLParser().parseTypeSystemDescription(new XMLInputSource(descriptor)); assertEquals(2, ts.getTypes().length); ts.resolveImports(); assertEquals(2, ts.getTypes().length); // test import from programatically created TypeSystemDescription TypeSystemDescription typeSystemDescription = UIMAFramework.getResourceSpecifierFactory() .createTypeSystemDescription(); Import[] imports = new Import[1]; imports[0] = new Import_impl(); URL url = JUnitExtension.getFile("TypeSystemDescriptionImplTest").toURL(); ((Import_impl) imports[0]).setSourceUrl(url); imports[0].setLocation("TypeSystemImportedByLocation.xml"); typeSystemDescription.setImports(imports); TypeSystemDescription typeSystemWithResolvedImports = (TypeSystemDescription) typeSystemDescription .clone(); typeSystemWithResolvedImports.resolveImports(resMgr); assertTrue(typeSystemWithResolvedImports.getTypes().length > 0); //test that importing the same descriptor twice (using the same ResourceManager) caches //the result of the first import and does not create new objects TypeSystemDescription typeSystemDescription2 = UIMAFramework.getResourceSpecifierFactory() .createTypeSystemDescription(); Import[] imports2 = new Import[1]; imports2[0] = new Import_impl(); ((Import_impl) imports2[0]).setSourceUrl(url); imports2[0].setLocation("TypeSystemImportedByLocation.xml"); typeSystemDescription2.setImports(imports2); TypeSystemDescription typeSystemWithResolvedImports2 = (TypeSystemDescription) typeSystemDescription2 .clone(); typeSystemWithResolvedImports2.resolveImports(resMgr); for (int i = 0 ; i < typeSystemWithResolvedImports.getTypes().length; i++) { assertTrue(typeSystemWithResolvedImports.getTypes()[i] == typeSystemWithResolvedImports2.getTypes()[i]); } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testInvalidTypeSystem() throws Exception { File file = JUnitExtension.getFile("TypeSystemDescriptionImplTest/InvalidTypeSystem1.xml"); TypeSystemDescription tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(file)); try { CasCreationUtils.createCas(tsDesc, null, null); // the above line should throw an exception fail(); } catch (ResourceInitializationException e) { assertNotNull(e.getMessage()); assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfiguration_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/ResourceManagerConfigura0000644000175000017500000001400111665471062033422 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ResourceManagerConfiguration_implTest extends TestCase { /** * Constructor for TypeSystemDescription_implTest. * * @param arg0 */ public ResourceManagerConfiguration_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); UIMAFramework.getXMLParser().enableSchemaValidation(true); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } public void testBuildFromXmlElement() throws Exception { try { File descriptor = JUnitExtension .getFile("ResourceManagerConfigurationImplTest/TestResourceManagerConfiguration.xml"); ResourceManagerConfiguration rmc = UIMAFramework.getXMLParser() .parseResourceManagerConfiguration(new XMLInputSource(descriptor)); ExternalResourceDescription[] resources = rmc.getExternalResources(); ExternalResourceBinding[] bindings = rmc.getExternalResourceBindings(); assertEquals(4, resources.length); assertEquals(4, bindings.length); assertEquals("Test Resource Manager Configuration", rmc.getName()); assertEquals("This is a test. This is only a test.", rmc.getDescription()); assertEquals("0.1", rmc.getVersion()); assertEquals("The Apache Software Foundation", rmc.getVendor()); descriptor = JUnitExtension .getFile("ResourceManagerConfigurationImplTest/ResourceManagerConfigurationWithImports.xml"); rmc = UIMAFramework.getXMLParser().parseResourceManagerConfiguration( new XMLInputSource(descriptor)); Import[] imports = rmc.getImports(); resources = rmc.getExternalResources(); bindings = rmc.getExternalResourceBindings(); assertEquals(1, imports.length); assertEquals(0, resources.length); assertEquals(1, bindings.length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveImports() throws Exception { try { File descriptor = JUnitExtension .getFile("ResourceManagerConfigurationImplTest/TaeImportingResourceManagerConfiguration.xml"); AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(descriptor)); ResourceManagerConfiguration rmc = aeDesc.getResourceManagerConfiguration(); assertEquals(0, rmc.getExternalResources().length); assertEquals(0, rmc.getExternalResourceBindings().length); rmc.resolveImports(); assertEquals(4, rmc.getExternalResources().length); assertEquals(4, rmc.getExternalResourceBindings().length); // test old single-import style descriptor = JUnitExtension .getFile("ResourceManagerConfigurationImplTest/TaeImportingResourceManagerConfiguration.xml"); aeDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descriptor)); rmc = aeDesc.getResourceManagerConfiguration(); assertEquals(0, rmc.getExternalResources().length); assertEquals(0, rmc.getExternalResourceBindings().length); rmc.resolveImports(); assertEquals(4, rmc.getExternalResources().length); assertEquals(4, rmc.getExternalResourceBindings().length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testClone() throws Exception { try { File descriptor = JUnitExtension .getFile("ResourceManagerConfigurationImplTest/TaeImportingResourceManagerConfiguration.xml"); AnalysisEngineDescription aeDesc = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(descriptor)); ResourceManagerConfiguration rmc = aeDesc.getResourceManagerConfiguration(); ResourceManagerConfiguration rmcClone = (ResourceManagerConfiguration) rmc.clone(); assertEquals(0, rmcClone.getExternalResources().length); assertEquals(0, rmcClone.getExternalResourceBindings().length); assertEquals(1, rmcClone.getImports().length); rmc.resolveImports(); assertEquals(4, rmc.getExternalResources().length); assertEquals(4, rmc.getExternalResourceBindings().length); assertEquals(0, rmc.getImports().length); assertEquals(0, rmcClone.getExternalResources().length); assertEquals(0, rmcClone.getExternalResourceBindings().length); assertEquals(1, rmcClone.getImports().length); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/FsIndexCollection_implTe0000644000175000017500000001073411665471062033401 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.Import; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; public class FsIndexCollection_implTest extends TestCase { /** * Constructor for TypeSystemDescription_implTest. * * @param arg0 */ public FsIndexCollection_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); UIMAFramework.getXMLParser().enableSchemaValidation(true); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } public void testBuildFromXmlElement() throws Exception { try { File descriptor = JUnitExtension .getFile("FsIndexCollectionImplTest/TestFsIndexCollection.xml"); FsIndexCollection indexColl = UIMAFramework.getXMLParser().parseFsIndexCollection( new XMLInputSource(descriptor)); assertEquals("TestFsIndexCollection", indexColl.getName()); assertEquals("This is a test.", indexColl.getDescription()); assertEquals("The Apache Software Foundation", indexColl.getVendor()); assertEquals("0.1", indexColl.getVersion()); Import[] imports = indexColl.getImports(); assertEquals(2, imports.length); assertEquals("FsIndexCollectionImportedFromDataPath", imports[0].getName()); assertNull(imports[0].getLocation()); assertNull(imports[1].getName()); assertEquals("FsIndexCollectionImportedByLocation.xml", imports[1].getLocation()); FsIndexDescription[] indexes = indexColl.getFsIndexes(); assertEquals(2, indexes.length); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveImports() throws Exception { try { File descriptor = JUnitExtension .getFile("FsIndexCollectionImplTest/TestFsIndexCollection.xml"); FsIndexCollection ic = UIMAFramework.getXMLParser().parseFsIndexCollection( new XMLInputSource(descriptor)); FsIndexDescription[] indexes = ic.getFsIndexes(); assertEquals(2, indexes.length); // resolving imports without setting data path should fail InvalidXMLException ex = null; try { ic.resolveImports(); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); assertEquals(2, ic.getFsIndexes().length); // should be no side effects when exception is // thrown // set data path correctly and it should work ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(JUnitExtension.getFile("FsIndexCollectionImplTest/dataPathDir") .getAbsolutePath()); ic.resolveImports(resMgr); indexes = ic.getFsIndexes(); assertEquals(4, indexes.length); // test that circular imports don't crash descriptor = JUnitExtension.getFile("FsIndexCollectionImplTest/Circular1.xml"); ic = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(descriptor)); ic.resolveImports(); assertEquals(2, ic.getFsIndexes().length); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/Import_implTest.java0000644000175000017500000001475511665471062032575 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.ByteArrayInputStream; import java.io.File; import java.net.URL; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.resource.ResourceManager; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.w3c.dom.Document; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; public class Import_implTest extends TestCase { /** * Constructor for Import_implTest. * * @param arg0 */ public Import_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } public void testBuildFromXmlElement() throws Exception { try { DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); // name import String importXml = ""; Document importDoc = docBuilder.parse(new ByteArrayInputStream(importXml.getBytes(encoding))); Import_impl importObj = new Import_impl(); importObj.buildFromXMLElement(importDoc.getDocumentElement(), null); assertEquals("this.is.a.test", importObj.getName()); assertNull(importObj.getLocation()); // location import importXml = ""; importDoc = docBuilder.parse(new ByteArrayInputStream(importXml.getBytes(encoding))); importObj = new Import_impl(); importObj.buildFromXMLElement(importDoc.getDocumentElement(), null); assertEquals("foo/bar/MyFile.xml", importObj.getLocation()); assertNull(importObj.getName()); // invalid - both location and name importXml = ""; importDoc = docBuilder.parse(new ByteArrayInputStream(importXml.getBytes(encoding))); importObj = new Import_impl(); InvalidXMLException ex = null; try { importObj.buildFromXMLElement(importDoc.getDocumentElement(), null); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); // invalid - empty import importXml = ""; importDoc = docBuilder.parse(new ByteArrayInputStream(importXml.getBytes(encoding))); importObj = new Import_impl(); ex = null; try { importObj.buildFromXMLElement(importDoc.getDocumentElement(), null); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); assertNotNull(ex.getMessage()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testFindAbsoluteUrl() throws Exception { try { // location import Import_impl importObj = new Import_impl(); importObj.setLocation("foo/bar/MyFile.xml"); URL absUrl = importObj.findAbsoluteUrl(UIMAFramework.newDefaultResourceManager()); URL expectedUrl = new File(System.getProperty("user.dir"), "foo/bar/MyFile.xml").getAbsoluteFile().toURL(); assertEquals(expectedUrl, absUrl); // name import importObj = new Import_impl(); importObj.setName("TypeSystemDescriptionImplTest.TestTypeSystem"); String workingDir = JUnitExtension.getFile("TypeSystemDescriptionImplTest").getParentFile() .getAbsolutePath(); ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(workingDir); absUrl = importObj.findAbsoluteUrl(resMgr); expectedUrl = new File(workingDir, "TypeSystemDescriptionImplTest/TestTypeSystem.xml") .toURL(); assertEquals(expectedUrl, absUrl); // name not found importObj = new Import_impl(); importObj.setName("this.should.not.be.found.at.least.i.hope.not"); InvalidXMLException ex = null; try { importObj.findAbsoluteUrl(UIMAFramework.newDefaultResourceManager()); } catch (InvalidXMLException e) { ex = e; } assertNotNull(ex); assertNotNull(ex.getMessage()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testNestedImports() throws Exception { try { File baseDescriptorFile = JUnitExtension .getFile("ImportImplTest/subdir/subdir2/AggregateTaeForNestedImportTest.xml"); File importedFile = JUnitExtension .getFile("ImportImplTest/subdir/PrimitiveTaeForNestedImportTest.xml"); AnalysisEngineDescription_impl agg = (AnalysisEngineDescription_impl) UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(baseDescriptorFile)); assertEquals(baseDescriptorFile.toURL(), agg.getSourceUrl()); AnalysisEngineDescription_impl prim = (AnalysisEngineDescription_impl) agg.getDelegateAnalysisEngineSpecifiers() .get("Annotator1"); assertEquals(importedFile.toURL(), prim.getSourceUrl()); prim.getAnalysisEngineMetaData().getTypeSystem().resolveImports(); assertEquals(1, prim.getAnalysisEngineMetaData().getTypeSystem().getTypes().length); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/MetaDataObject_implTest.0000644000175000017500000003012411665471062033254 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.io.ByteArrayInputStream; import java.io.StringWriter; import java.io.Writer; import java.util.HashSet; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.internal.util.SerializationUtils; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.NameClassPair; import org.apache.uima.util.XMLParser; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Tests the MetaDataObject_impl class. * */ public class MetaDataObject_implTest extends TestCase { /** * Constructor for MetaDataObject_implTest. * * @param arg0 */ public MetaDataObject_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); // create an object that can represent a fruit unknownFruit = new TestFruitObject(); // create two identical apples and an orange apple1 = new TestFruitObject(); apple1.setAttributeValue("name", "Apple"); apple1.setAttributeValue("color", "red"); apple1.setAttributeValue("avgWeightLbs", Float.valueOf(0.3F)); apple1.setAttributeValue("avgCostCents", Integer.valueOf(40)); apple1.setAttributeValue("citrus", Boolean.valueOf(false)); apple1.setAttributeValue("commonUses", new String[] { "baking", "snack" }); apple2 = new TestFruitObject(); apple2.setAttributeValue("name", "Apple"); apple2.setAttributeValue("color", "red"); apple2.setAttributeValue("avgWeightLbs", Float.valueOf(0.3F)); apple2.setAttributeValue("avgCostCents", Integer.valueOf(40)); apple2.setAttributeValue("citrus", Boolean.valueOf(false)); apple2.setAttributeValue("commonUses", new String[] { "baking", "snack" }); orange = new TestFruitObject(); orange.setAttributeValue("name", "Orange"); orange.setAttributeValue("color", "orange"); orange.setAttributeValue("avgWeightLbs", Float.valueOf(0.2F)); orange.setAttributeValue("avgCostCents", Integer.valueOf(50)); orange.setAttributeValue("citrus", Boolean.valueOf(true)); orange.setAttributeValue("commonUses", new String[] { "snack", "juice" }); // create a fruit bag containing these three objects fruitBag = new TestFruitBagObject(); TestFruitObject[] fruitArray = { apple1, apple2, orange }; fruitBag.setAttributeValue("fruits", fruitArray); } /** * Tests the {@link MetaDataObject#listAttributes()} method. */ public void testListAttributes() throws Exception { try { HashSet apple1Attrs = new HashSet(apple1.listAttributes()); HashSet orangeAttrs = new HashSet(orange.listAttributes()); HashSet bagAttrs = new HashSet(fruitBag.listAttributes()); Assert.assertEquals(TestFruitObject.getAttributeSet(), apple1Attrs); Assert.assertEquals(TestFruitObject.getAttributeSet(), orangeAttrs); Assert.assertEquals(TestFruitBagObject.getAttributeSet(), bagAttrs); } catch (RuntimeException e) { JUnitExtension.handleException(e); } } /** * Tests the {@link MetaDataObject#equals(Object)} method. */ public void testEquals() throws Exception { try { Assert.assertEquals(unknownFruit, unknownFruit); Assert.assertEquals(apple1, apple2); Assert.assertEquals(apple2, apple1); Assert.assertTrue(!unknownFruit.equals(apple1)); Assert.assertTrue(!apple1.equals(orange)); Assert.assertTrue(!apple1.equals(null)); Assert.assertEquals(apple1, apple1.clone()); Assert.assertEquals(fruitBag, fruitBag.clone()); Assert.assertTrue(!apple1.equals(orange.clone())); // test with maps ConfigurationParameterSettings cps1 = UIMAFramework.getResourceSpecifierFactory().createConfigurationParameterSettings(); cps1.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")}); cps1.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")}); ConfigurationParameterSettings cps2 = UIMAFramework.getResourceSpecifierFactory().createConfigurationParameterSettings(); cps2.getSettingsForGroups().put("k1", new NameValuePair[] {new NameValuePair_impl("s1", "o1")}); cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "o2")}); Assert.assertEquals(cps1, cps2); Assert.assertEquals(cps1, cps2.clone()); cps2.getSettingsForGroups().put("k2", new NameValuePair[] {new NameValuePair_impl("s2", "ox2")}); Assert.assertFalse(cps1.equals(cps2)); } catch (RuntimeException e) { JUnitExtension.handleException(e); } } /** * Tests the {@link MetaDataObject#toString()} method. */ public void testToString() throws Exception { try { String apple1Str = apple1.toString(); String apple2Str = apple2.toString(); String orangeStr = orange.toString(); Assert.assertEquals(apple1Str, apple2Str); Assert.assertTrue(!apple1Str.equals(orangeStr)); } catch (RuntimeException e) { JUnitExtension.handleException(e); } } /** * Tests the {@link MetaDataObject#toXML(Writer)} and * {@link MetaDataObject#buildFromXMLElement(Element,XMLParser)} methods. These also sufficiently * excercise the {@link MetaDataObject#getAttributeValue(String)} and * {@link MetaDataObject#setAttributeValue(String,Object)} methods. */ public void bestXMLization() throws Exception { try { // write objects to XML StringWriter writer = new StringWriter(); apple1.toXML(writer); String apple1xml = writer.getBuffer().toString(); // System.out.println(apple1xml); writer = new StringWriter(); apple2.toXML(writer); String apple2xml = writer.getBuffer().toString(); writer = new StringWriter(); orange.toXML(writer); String orangeXml = writer.getBuffer().toString(); writer = new StringWriter(); fruitBag.toXML(writer); String fruitBagXml = writer.getBuffer().toString(); // identical objects should have identical XML Assert.assertEquals(apple1xml, apple2xml); // parse the XML DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); Document apple1xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple1xml.getBytes())); Document apple2xmlDoc = docBuilder.parse(new ByteArrayInputStream(apple2xml.getBytes())); Document orangeXmlDoc = docBuilder.parse(new ByteArrayInputStream(orangeXml.getBytes())); Document fruitBagXmlDoc = docBuilder.parse(new ByteArrayInputStream(fruitBagXml.getBytes())); // construct new objects from the XML XMLParser xmlp = UIMAFramework.getXMLParser(); MetaDataObject_impl newApple1 = (MetaDataObject_impl) unknownFruit.clone(); newApple1.buildFromXMLElement(apple1xmlDoc.getDocumentElement(), xmlp); MetaDataObject_impl newApple2 = (MetaDataObject_impl) unknownFruit.clone(); newApple2.buildFromXMLElement(apple2xmlDoc.getDocumentElement(), xmlp); MetaDataObject_impl newOrange = (MetaDataObject_impl) unknownFruit.clone(); newOrange.buildFromXMLElement(orangeXmlDoc.getDocumentElement(), xmlp); xmlp.addMapping("fruit", TestFruitObject.class.getName()); MetaDataObject_impl newFruitBag = new TestFruitBagObject(); newFruitBag.buildFromXMLElement(fruitBagXmlDoc.getDocumentElement(), xmlp); // new objects should be equal to the originals Assert.assertEquals(apple1, newApple1); Assert.assertEquals(apple2, newApple2); Assert.assertEquals(orange, newOrange); Assert.assertTrue(fruitBag.equals(newFruitBag)); // test special cases // single-property object where propety name is ommitted from XML String xmlStr = "bananayellow" + "raspberryred"; Document xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes())); TestFruitBagObject bag = new TestFruitBagObject(); bag.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp); TestFruitObject[] fruits = bag.getFruits(); Assert.assertEquals(2, fruits.length); Assert.assertEquals("banana", fruits[0].getName()); Assert.assertEquals("raspberry", fruits[1].getName()); // property name ommitted but can be inferred from type of value xmlStr = "bananayellow"; xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes())); TestFruitObject banana = new TestFruitObject(); banana.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp); Assert.assertEquals("yellow", banana.getColor()); Assert.assertEquals("banana", banana.getName()); // env var reference xmlStr = "raspberrytest.raspberry.color"; System.setProperty("test.raspberry.color", "red"); xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlStr.getBytes())); TestFruitObject raspberry = new TestFruitObject(); raspberry.buildFromXMLElement(xmlDoc.getDocumentElement(), xmlp); Assert.assertEquals("red", raspberry.getColor()); Assert.assertEquals("raspberry", raspberry.getName()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void bestSerialization() throws Exception { try { byte[] apple1Bytes = SerializationUtils.serialize(apple1); TestFruitObject apple1a = (TestFruitObject) SerializationUtils.deserialize(apple1Bytes); Assert.assertEquals(apple1, apple1a); byte[] apple2Bytes = SerializationUtils.serialize(apple2); TestFruitObject apple2a = (TestFruitObject) SerializationUtils.deserialize(apple2Bytes); Assert.assertEquals(apple2, apple2a); byte[] orangeBytes = SerializationUtils.serialize(orange); TestFruitObject orange2 = (TestFruitObject) SerializationUtils.deserialize(orangeBytes); Assert.assertEquals(orange, orange2); // make sure XMLization still works StringWriter sw = new StringWriter(); orange.toXML(sw); String orange1xml = sw.getBuffer().toString(); sw.getBuffer().setLength(0); orange2.toXML(sw); String orange2xml = sw.getBuffer().toString(); assertEquals(orange1xml, orange2xml); } catch (Exception e) { JUnitExtension.handleException(e); } } private TestFruitObject unknownFruit; private TestFruitObject apple1; private TestFruitObject apple2; private TestFruitObject orange; private TestFruitBagObject fruitBag; } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/metadata/impl/TestFruitObject.java0000644000175000017500000000664711665471062032523 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.metadata.impl; import java.util.HashSet; import java.util.Set; import org.apache.uima.util.NameClassPair; /** * A simple concrete MetaDataObject implementation for use in testing the MetaDataObject_impl class. */ public class TestFruitObject extends MetaDataObject_impl { private static final long serialVersionUID = 1L; public TestFruitObject() { //do nothing } public String getName() { return mName; } public void setName(String aName) { mName = aName; } public String getColor() { return mColor; } public void setColor(String aColor) { mColor = aColor; } public float getAvgWeightLbs() { return mAvgWeightLbs; } public void setAvgWeightLbs(float aAvgWeightLbs) { mAvgWeightLbs = aAvgWeightLbs; } public int getAvgCostCents() { return mAvgCostCents; } public void setAvgCostCents(int aAvgCostCents) { mAvgCostCents = aAvgCostCents; } public boolean isCitrus() { return mCitrus; } public void setCitrus(boolean aCitrus) { mCitrus = aCitrus; } public String[] getCommonUses() { return mCommonUses; } public void setCommonUses(String[] aCommonUses) { mCommonUses = aCommonUses; } protected XmlizationInfo getXmlizationInfo() { return XMLIZATION_INFO; } static final private XmlizationInfo XMLIZATION_INFO = new XmlizationInfo("fruit", new PropertyXmlInfo[] { new PropertyXmlInfo("name"), new PropertyXmlInfo("color"), new PropertyXmlInfo("avgWeightLbs"), new PropertyXmlInfo("avgCostCents"), new PropertyXmlInfo("citrus"), new PropertyXmlInfo("commonUses"), }); /** * For testing purposes - a hardcoded attribute set. Should be compared with the results of * {@link #listAttributes()}. */ static public Set getAttributeSet() { HashSet result = new HashSet(); result.add(new NameClassPair("name", String.class.getName())); result.add(new NameClassPair("color", String.class.getName())); result.add(new NameClassPair("avgWeightLbs", Float.class.getName())); result.add(new NameClassPair("avgCostCents", Integer.class.getName())); result.add(new NameClassPair("citrus", Boolean.class.getName())); result.add(new NameClassPair("commonUses", String[].class.getName())); return result; } private String mName; private String mColor; private float mAvgWeightLbs; private int mAvgCostCents; private boolean mCitrus; private String[] mCommonUses; } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/TestCasConsumer.java0000644000175000017500000000233311665471062027770 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CasConsumer_ImplBase; public class TestCasConsumer extends CasConsumer_ImplBase { /** * @see org.apache.uima.collection.base_cpm.CasObjectProcessor#processCas(org.apache.uima.cas.CAS) */ public void processCas(CAS aCAS) throws ResourceProcessException { // empty method } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/0000755000175000017500000000000011665471062025003 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/TestResourceInterface.java0000644000175000017500000000165511665471062032125 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; public interface TestResourceInterface { String readString(); } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/PearSpecifier_implTest.java0000644000175000017500000001025311665471062032251 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.ByteArrayInputStream; import java.io.StringWriter; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.Parameter; import org.apache.uima.resource.PearSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; /** * PearSpecifier creation and Xmlization test */ public class PearSpecifier_implTest extends TestCase { /** * pearSpecifier creation test * * @throws Exception */ public void testProducePearResource() throws Exception { PearSpecifier specifier = UIMAFramework.getResourceSpecifierFactory().createPearSpecifier(); specifier.setPearPath("/home/user/uimaApp/installedPears/testpear"); Parameter[] parameters = new Parameter[2]; parameters[0] = UIMAFramework.getResourceSpecifierFactory().createParameter(); parameters[0].setName("param1"); parameters[0].setValue("val1"); parameters[1] = UIMAFramework.getResourceSpecifierFactory().createParameter(); parameters[1].setName("param2"); parameters[1].setValue("val2"); specifier.setParameters(parameters); //compare created specifier with available test specifier XMLInputSource in = new XMLInputSource( JUnitExtension.getFile("XmlParserTest/TestPearSpecifier.xml")); PearSpecifier pearSpec = UIMAFramework.getXMLParser().parsePearSpecifier(in); Assert.assertEquals(pearSpec.getPearPath(), specifier.getPearPath()); Assert.assertEquals(pearSpec.getParameters()[0].getValue(), specifier.getParameters()[0].getValue()); Assert.assertEquals(pearSpec.getParameters()[1].getValue(), specifier.getParameters()[1].getValue()); //compare created specifier with a manually create pear specifier PearSpecifier manPearSpec = new PearSpecifier_impl(); manPearSpec.setPearPath("/home/user/uimaApp/installedPears/testpear"); manPearSpec.setParameters(new Parameter[] { new Parameter_impl("param1", "val1"), new Parameter_impl("param2", "val2") }); Assert.assertEquals(manPearSpec.getPearPath(), specifier.getPearPath()); Assert.assertEquals(manPearSpec.getParameters()[0].getValue(), specifier.getParameters()[0].getValue()); Assert.assertEquals(manPearSpec.getParameters()[1].getValue(), specifier.getParameters()[1].getValue()); } /** * pearSpecifier xmlization test * * @throws Exception */ public void testXmlization() throws Exception { try { PearSpecifier pearSpec = new PearSpecifier_impl(); pearSpec.setPearPath("/home/user/uimaApp/installedPears/testpear"); pearSpec.setParameters(new Parameter[] { new Parameter_impl("param1", "val1"), new Parameter_impl("param2", "val2") }); StringWriter sw = new StringWriter(); pearSpec.toXML(sw); PearSpecifier pearSpec2 = (PearSpecifier) UIMAFramework.getXMLParser().parse( new XMLInputSource(new ByteArrayInputStream(sw.getBuffer().toString().getBytes(encoding)), null)); assertEquals(pearSpec, pearSpec2); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ResourceManager_implTest.java0000644000175000017500000002703411665471062032617 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URL; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.resource.DataResource; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.FileLanguageResourceSpecifier; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.impl.ExternalResourceBinding_impl; import org.apache.uima.resource.metadata.impl.ResourceManagerConfiguration_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ResourceManager_implTest extends TestCase { private final File TEST_DATA_FILE = JUnitExtension .getFile("ResourceTest/ResourceManager_implTest_tempDataFile.dat"); private final String TEST_DATAPATH_WITH_SPACES = JUnitExtension.getFile( "ResourceTest/spaces in dir name").toString(); private final String TEST_FILE_IN_DATAPATH = "file:Test.dat"; private final String TEST_STRING = "This is a test. This is only a test."; // contents of test // data file private final String TEST_CONTEXT_NAME = "/testContext1/testContext2/"; private ResourceManager_impl mManager; /** * Constructor for ResourceManager_implTest. * * @param arg0 */ public ResourceManager_implTest(String arg0) throws IOException { super(arg0); } /** * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); mManager = new ResourceManager_impl(); mManager.setDataPath(TEST_DATAPATH_WITH_SPACES); // initialize sample resources ResourceManagerConfiguration cfg = new ResourceManagerConfiguration_impl(); // simple data resource FileResourceSpecifier_impl spec = new FileResourceSpecifier_impl(); spec.setFileUrl(TEST_DATA_FILE.toURL().toString()); ExternalResourceDescription desc = new ExternalResourceDescription_impl(); desc.setName("myData"); desc.setResourceSpecifier(spec); // data resource with custom interface and implementation class ExternalResourceDescription desc2 = new ExternalResourceDescription_impl(); desc2.setName("myCustomObject"); desc2.setResourceSpecifier(spec); desc2.setImplementationName(TestResourceInterface_impl.class.getName()); // parameterized (language-based) resource FileLanguageResourceSpecifier langSpec = new FileLanguageResourceSpecifier_impl(); File baseDir = JUnitExtension.getFile("ResourceTest"); langSpec.setFileUrlPrefix(new File(baseDir, "FileLanguageResource_implTest_data_").toURL() .toString()); langSpec.setFileUrlSuffix(".dat"); ExternalResourceDescription desc3 = new ExternalResourceDescription_impl(); desc3.setName("myLanguageResource"); desc3.setResourceSpecifier(langSpec); // parameterized resource with custom impl class ExternalResourceDescription desc4 = new ExternalResourceDescription_impl(); desc4.setName("myLanguageResourceObject"); desc4.setResourceSpecifier(langSpec); desc4.setImplementationName(TestResourceInterface_impl.class.getName()); // resource path with space in it (tests proper URL encoding of spaces) FileResourceSpecifier_impl spec2 = new FileResourceSpecifier_impl(); spec2.setFileUrl(TEST_FILE_IN_DATAPATH); ExternalResourceDescription desc5 = new ExternalResourceDescription_impl(); desc5.setName("myResourceWithSpaceInPath"); desc5.setResourceSpecifier(spec2); // resource path as filename instead of URL ExternalResourceDescription desc6 = new ExternalResourceDescription_impl(); FileResourceSpecifier_impl fileSpec = new FileResourceSpecifier_impl(); fileSpec.setFileUrl(TEST_DATA_FILE.getAbsolutePath()); desc6.setResourceSpecifier(fileSpec); desc6.setName("myResourceWithFilePathNotUrl"); cfg.setExternalResources(new ExternalResourceDescription[] { desc, desc2, desc3, desc4, desc5, desc6 }); // define bindings ExternalResourceBinding binding1 = new ExternalResourceBinding_impl(); binding1.setKey("myDataKey"); binding1.setResourceName("myData"); ExternalResourceBinding binding2 = new ExternalResourceBinding_impl(); binding2.setKey("myCustomObjectKey"); binding2.setResourceName("myCustomObject"); ExternalResourceBinding binding3 = new ExternalResourceBinding_impl(); binding3.setKey("myLanguageResourceKey"); binding3.setResourceName("myLanguageResource"); ExternalResourceBinding binding4 = new ExternalResourceBinding_impl(); binding4.setKey("myLanguageResourceObjectKey"); binding4.setResourceName("myLanguageResourceObject"); ExternalResourceBinding binding5 = new ExternalResourceBinding_impl(); binding5.setKey("myResourceWithSpaceInPathKey"); binding5.setResourceName("myResourceWithSpaceInPath"); ExternalResourceBinding binding6 = new ExternalResourceBinding_impl(); binding6.setKey("myResourceWithFilePathNotUrl"); binding6.setResourceName("myResourceWithFilePathNotUrl"); cfg.setExternalResourceBindings(new ExternalResourceBinding[] { binding1, binding2, binding3, binding4, binding5, binding6 }); mManager.initializeExternalResources(cfg, TEST_CONTEXT_NAME, null); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSetDataPath() throws Exception { try { String path = "c:\\this\\path\\is;for\\windows"; mManager.setDataPath(path); Assert.assertEquals(path, mManager.getDataPath()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResource() throws Exception { try { // test retrieval DataResource r1 = (DataResource) mManager.getResource(TEST_CONTEXT_NAME + "myDataKey"); Assert.assertEquals(TEST_DATA_FILE.toURL(), r1.getUrl()); TestResourceInterface r2 = (TestResourceInterface) mManager.getResource(TEST_CONTEXT_NAME + "myCustomObjectKey"); Assert.assertEquals(TEST_STRING, r2.readString()); DataResource en_r = (DataResource) mManager.getResource(TEST_CONTEXT_NAME + "myLanguageResourceKey", new String[] { "en" }); Assert.assertTrue(en_r.getUrl().toString().endsWith( "FileLanguageResource_implTest_data_en.dat")); DataResource de_r = (DataResource) mManager.getResource(TEST_CONTEXT_NAME + "myLanguageResourceKey", new String[] { "de" }); Assert.assertTrue(de_r.getUrl().toString().endsWith( "FileLanguageResource_implTest_data_de.dat")); // this should get the exact same DataResource object as for the "en" param DataResource enus_r = (DataResource) mManager.getResource(TEST_CONTEXT_NAME + "myLanguageResourceKey", new String[] { "en-US" }); Assert.assertTrue(en_r == enus_r); TestResourceInterface en_obj = (TestResourceInterface) mManager.getResource(TEST_CONTEXT_NAME + "myLanguageResourceObjectKey", new String[] { "en" }); Assert.assertEquals("English", en_obj.readString()); // test spaces in datapath DataResource r3 = (DataResource) mManager.getResource(TEST_CONTEXT_NAME + "myResourceWithSpaceInPathKey"); URL expectedBaseUrl = new File(TEST_DATAPATH_WITH_SPACES).toURL(); URL expectedUrl = new URL(expectedBaseUrl, TEST_FILE_IN_DATAPATH); Assert.assertEquals(expectedUrl, r3.getUrl()); URI expectedBaseUri = new File(TEST_DATAPATH_WITH_SPACES).toURI(); URI expectedUri = expectedBaseUri.resolve("Test.dat"); Assert.assertEquals(expectedUri, r3.getUri()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveAndValidateDependencies() throws Exception { try { // dependencies 1-4 are for the resource bindings created in setUp() ExternalResourceDependency dep1 = new ExternalResourceDependency_impl(); dep1.setKey("myDataKey"); ExternalResourceDependency dep2 = new ExternalResourceDependency_impl(); dep2.setKey("myLanguageResourceKey"); ExternalResourceDependency dep3 = new ExternalResourceDependency_impl(); dep3.setKey("myCustomObjectKey"); dep3.setInterfaceName(TestResourceInterface.class.getName()); ExternalResourceDependency dep4 = new ExternalResourceDependency_impl(); dep4.setKey("myLanguageResourceObjectKey"); dep4.setInterfaceName(TestResourceInterface.class.getName()); // dependency 5 is an unbound but optional resource ExternalResourceDependency dep5 = new ExternalResourceDependency_impl(); dep5.setKey("nonExsitentResource"); dep5.setOptional(true); // dependency 6 is resolvable in the classpath ExternalResourceDependency dep6 = new ExternalResourceDependency_impl(); dep6.setKey("org/apache/uima/resource/impl/ResourceInClasspath.txt"); mManager.resolveAndValidateResourceDependencies(new ExternalResourceDependency[] { dep1, dep2, dep3, dep4, dep5, dep6 }, TEST_CONTEXT_NAME); // at this point we should be able to look up dep6 Object r = mManager.getResource(TEST_CONTEXT_NAME + dep6.getKey()); assertTrue(r instanceof DataResource); assertTrue(((DataResource) r).getUrl().toString().endsWith(dep6.getKey())); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testOverrides() throws Exception { try { final String TEST_DATAPATH = JUnitExtension.getFile("AnnotatorContextTest").getPath(); File descFile = JUnitExtension.getFile("ResourceManagerImplTest/ResourceTestAggregate.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(TEST_DATAPATH); UIMAFramework.produceAnalysisEngine(desc, resMgr, null); URL url = resMgr.getResourceURL("/Annotator1/TestFileResource"); assertTrue(url.toString().endsWith("testDataFile2.dat")); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ConfigurableDataResourceSpecifier_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ConfigurableDataResourceSpecifier0000644000175000017500000000677011665471062033474 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.ByteArrayInputStream; import java.io.StringWriter; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.impl.ConfigurationParameterDeclarations_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameterSettings_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.NameValuePair_impl; import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * */ public class ConfigurableDataResourceSpecifier_implTest extends TestCase { public void testXmlization() throws Exception { try { // create a ConfigurableDataResourceSpecifier ConfigurableDataResourceSpecifier_impl cspec = new ConfigurableDataResourceSpecifier_impl(); cspec.setUrl("jdbc:db2:MyDatabase"); ResourceMetaData md = new ResourceMetaData_impl(); cspec.setMetaData(md); md.setName("foo"); ConfigurationParameterDeclarations decls = new ConfigurationParameterDeclarations_impl(); ConfigurationParameter param = new ConfigurationParameter_impl(); param.setName("param"); param.setType("String"); decls.addConfigurationParameter(param); md.setConfigurationParameterDeclarations(decls); ConfigurationParameterSettings settings = new ConfigurationParameterSettings_impl(); NameValuePair nvp = new NameValuePair_impl(); nvp.setName("param"); nvp.setValue("bar"); settings.setParameterSettings(new NameValuePair[] { nvp }); md.setConfigurationParameterSettings(settings); // wrtie to XML StringWriter sw = new StringWriter(); cspec.toXML(sw); String xmlStr = sw.getBuffer().toString(); // parse back ByteArrayInputStream inStream = new ByteArrayInputStream(xmlStr.getBytes("UTF-8")); XMLInputSource in = new XMLInputSource(inStream, null); ConfigurableDataResourceSpecifier_impl parsedSpec = (ConfigurableDataResourceSpecifier_impl) UIMAFramework .getXMLParser().parse(in); assertEquals(cspec, parsedSpec); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/CasManager_implTest.java0000644000175000017500000000332511665471062031533 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.resource.CasManager; /** * */ public class CasManager_implTest extends TestCase { public void testEnableReset() throws Exception { CasManager mgr = UIMAFramework.newDefaultResourceManager().getCasManager(); mgr.defineCasPool("test", 1, null); CAS cas = mgr.getCas("test"); ((CASImpl)cas).enableReset(false); // try { // cas.release(); // fail(); // } // catch (CASAdminException e) { // //expected // } cas.release(); // should work, release unlocks things. cas = mgr.getCas("test"); ((CASImpl)cas).enableReset(true); cas.release(); } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ResourceCreationSpecifier_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ResourceCreationSpecifier_implTes0000644000175000017500000000323111665471062033530 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.File; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; /** * */ public class ResourceCreationSpecifier_implTest extends TestCase { public void testDoFullValidation() throws Exception { try { File descFile = JUnitExtension.getFile("UimaContextTest/CasConsumerForUimaContextTest.xml"); ResourceCreationSpecifier resCreaSpec = (ResourceCreationSpecifier) UIMAFramework .getXMLParser().parseResourceSpecifier(new XMLInputSource(descFile)); resCreaSpec.doFullValidation(); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/TestResourceInterface_impl.java0000644000175000017500000000603111665471062033137 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Map; import org.apache.uima.resource.DataResource; import org.apache.uima.resource.ResourceConfigurationException; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.Resource_ImplBase; import org.apache.uima.resource.SharedResourceObject; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.ResourceMetaData; public class TestResourceInterface_impl extends Resource_ImplBase implements SharedResourceObject, TestResourceInterface { private String mString; /** * @see org.apache.uima.resource.SharedResourceObject#load(DataResource) */ public void load(DataResource aData) throws ResourceInitializationException { try { // try to get an input stream and read from the file InputStream inStr = aData.getInputStream(); BufferedReader bufRdr = new BufferedReader(new InputStreamReader(inStr, "utf-8")); mString = bufRdr.readLine(); inStr.close(); } catch (IOException e) { throw new ResourceInitializationException(e); } } /** * @see org.apache.uima.resource.impl.TestResourceInterface#readString() */ public String readString() { return mString; } /** * @see org.apache.uima.resource.Resource#destroy() */ public void destroy() { //do nothing } /** * @see org.apache.uima.resource.Resource#getMetaData() */ public ResourceMetaData getMetaData() { return null; } /** * @see org.apache.uima.resource.Resource#initialize(ResourceSpecifier, Map) */ public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams) throws ResourceInitializationException { return true; } /** * @see org.apache.uima.resource.Resource#setConfigurationParameters(NameValuePair[]) */ public void setConfigurationParameters(NameValuePair[] aSettings) throws ResourceConfigurationException { //do nothing } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/FileLanguageResource_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/FileLanguageResource_implTest.jav0000644000175000017500000000623511665471062033427 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.File; import java.io.IOException; import java.util.Collections; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.resource.DataResource; import org.apache.uima.resource.FileLanguageResourceSpecifier; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Tests the FileLanguageResource_impl class. * */ public class FileLanguageResource_implTest extends TestCase { /** * Constructor for FileLanguageResource_implTest. * * @param arg0 */ public FileLanguageResource_implTest(String arg0) throws IOException { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { try { super.setUp(); FileLanguageResourceSpecifier spec = new FileLanguageResourceSpecifier_impl(); File baseDir = JUnitExtension.getFile("ResourceTest"); spec.setFileUrlPrefix(new File(baseDir, "FileLanguageResource_implTest_data_").toURL().toString()); spec.setFileUrlSuffix(".dat"); mResource = new FileLanguageResource_impl(); mResource.initialize(spec, Collections.EMPTY_MAP); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetDataResource() throws Exception { try { DataResource enResource = mResource.getDataResource(new String[] { "en" }); DataResource deResource = mResource.getDataResource(new String[] { "de" }); DataResource enusResource = mResource.getDataResource(new String[] { "en-US" }); Assert.assertNotNull(enResource); Assert.assertNotNull(deResource); Assert.assertNotNull(enusResource); Assert.assertFalse(enResource.equals(deResource)); Assert.assertTrue(enResource.equals(enusResource)); Assert.assertEquals(enResource.hashCode(), enusResource.hashCode()); ResourceInitializationException ex = null; try { DataResource zhResource = mResource.getDataResource(new String[] { "zh" }); } catch (ResourceInitializationException e) { ex = e; } Assert.assertNotNull(ex); } catch (Exception e) { JUnitExtension.handleException(e); } } FileLanguageResource_impl mResource; } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/URISpecifier_implTest.java0000644000175000017500000000420011665471062032014 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import static org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_implTest.encoding; import java.io.ByteArrayInputStream; import java.io.StringWriter; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.Parameter; import org.apache.uima.resource.URISpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class URISpecifier_implTest extends TestCase { URISpecifier_impl uriSpec; protected void setUp() throws Exception { uriSpec = new URISpecifier_impl(); uriSpec.setProtocol("Vinci"); uriSpec.setUri("foo.bar"); uriSpec.setParameters(new Parameter[] { new Parameter_impl("VNS_HOST", "myhost"), new Parameter_impl("VNS_PORT", "42") }); } public void testXmlization() throws Exception { try { StringWriter sw = new StringWriter(); uriSpec.toXML(sw); URISpecifier uriSpec2 = (URISpecifier) UIMAFramework.getXMLParser().parse( new XMLInputSource(new ByteArrayInputStream(sw.getBuffer().toString().getBytes(encoding)), null)); assertEquals(uriSpec, uriSpec2); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ConfigurableDataResource_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/ConfigurableDataResource_implTest0000644000175000017500000000620411665471062033513 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.net.URI; import java.util.Collections; import junit.framework.TestCase; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.impl.ConfigurationParameterDeclarations_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Tests the DataResource_impl class. * */ public class ConfigurableDataResource_implTest extends TestCase { /** * Constructor for DataResource_implTest. * * @param arg0 */ public ConfigurableDataResource_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } public void testInitialize() throws Exception { try { // create a ConfigurableDataResourceSpecifier ConfigurableDataResourceSpecifier_impl cspec = new ConfigurableDataResourceSpecifier_impl(); cspec.setUrl("jdbc:db2:MyDatabase"); ResourceMetaData md = new ResourceMetaData_impl(); cspec.setMetaData(md); md.setName("foo"); ConfigurationParameterDeclarations decls = new ConfigurationParameterDeclarations_impl(); ConfigurationParameter param = new ConfigurationParameter_impl(); param.setName("param"); param.setType("String"); decls.addConfigurationParameter(param); md.setConfigurationParameterDeclarations(decls); // initialize a DataResource ConfigurableDataResource_impl cdr = new ConfigurableDataResource_impl(); cdr.initialize(cspec, Collections.EMPTY_MAP); assertEquals(new URI("jdbc:db2:MyDatabase"), cdr.getUri()); assertEquals("foo", cdr.getMetaData().getName()); ConfigurationParameter param0 = cdr.getMetaData().getConfigurationParameterDeclarations() .getConfigurationParameters()[0]; assertEquals("param", param0.getName()); assertEquals("String", param0.getType()); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/DataResource_implTest.java0000644000175000017500000001002611665471062032107 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.BufferedReader; import java.io.File; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Collections; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.test.junit_extension.JUnitExtension; /** * Tests the DataResource_impl class. * */ public class DataResource_implTest extends TestCase { /** * Constructor for DataResource_implTest. * * @param arg0 */ public DataResource_implTest(String arg0) { super(arg0); } /** * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } public void testInitialize() throws Exception { try { // create a FileResourceSpecifier FileResourceSpecifier_impl spec = new FileResourceSpecifier_impl(); File tempDataFile = JUnitExtension .getFile("ResourceTest/DataResource_implTest_tempDataFile.dat"); String fileUrl = tempDataFile.toURL().toString(); String localCacheFile = "c:\\temp\\cache"; spec.setFileUrl(fileUrl); spec.setLocalCache(localCacheFile); // initialize a DataResource DataResource_impl dr = new DataResource_impl(); dr.initialize(spec, Collections.EMPTY_MAP); // test Assert.assertEquals(new URL(fileUrl), dr.getUrl()); Assert.assertEquals(new File(localCacheFile), dr.getLocalCache()); // test failure for nonexistent data ResourceInitializationException ex = null; try { FileResourceSpecifier_impl invalidSpec = new FileResourceSpecifier_impl(); invalidSpec.setFileUrl("file:/this/file/does/not/exist"); DataResource_impl dr2 = new DataResource_impl(); dr2.initialize(invalidSpec, Collections.EMPTY_MAP); } catch (ResourceInitializationException e) { ex = e; } Assert.assertNotNull(ex); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetInputStream() throws Exception { try { // write a File (APL: changed to use preexisting file - 6/28/04) File tempDataFile = JUnitExtension .getFile("ResourceTest/DataResource_implTest_tempDataFile.dat"); // FileWriter writer = new FileWriter(tempDataFile); String testString = "This is a test. This is only a test."; // writer.write(testString); // writer.close(); // initialize a DataResource for this file FileResourceSpecifier_impl spec = new FileResourceSpecifier_impl(); spec.setFileUrl(tempDataFile.toURL().toString()); DataResource_impl dr = new DataResource_impl(); dr.initialize(spec, Collections.EMPTY_MAP); // try to get an input stream and read from the file InputStream inStr = dr.getInputStream(); BufferedReader bufRdr = new BufferedReader(new InputStreamReader(inStr, "utf-8")); String result = bufRdr.readLine(); inStr.close(); Assert.assertEquals(testString, result); } catch (Exception e) { JUnitExtension.handleException(e); } } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/RelativePathResolver_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/impl/RelativePathResolver_implTest.jav0000644000175000017500000000547111665471062033507 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource.impl; import java.io.File; import java.net.URL; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.test.junit_extension.JUnitExtension; public class RelativePathResolver_implTest extends TestCase { /** * Constructor for RelativePathResolver_implTest. * * @param arg0 */ public RelativePathResolver_implTest(String arg0) { super(arg0); } public void testSetDataPath() throws Exception { try { RelativePathResolver_impl resolver = new RelativePathResolver_impl(); // specify path by file names String path = "/this/is/a/test" + System.getProperty("path.separator") + "/another/test"; resolver.setDataPath(path); Assert.assertEquals(path, resolver.getDataPath()); URL[] urls = resolver.getBaseUrls(); Assert.assertEquals(2, urls.length); Assert.assertEquals(new File("/this/is/a/test").toURL(), urls[0]); Assert.assertEquals(new File("/another/test").toURL(), urls[1]); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testResolveRelativePath() throws Exception { try { RelativePathResolver_impl resolver = new RelativePathResolver_impl(); // file should not be found URL absUrl = resolver.resolveRelativePath(new URL("file:test/relativePathTest.dat")); Assert.assertNull(absUrl); // specify path String path = JUnitExtension.getFile("ResourceTest/subdir").getAbsolutePath(); resolver.setDataPath(path); // now file should be found absUrl = resolver.resolveRelativePath(new URL("file:test/relativePathTest.dat")); Assert.assertNotNull(absUrl); // try resolving an absolute path even with no data path resolver.setDataPath(""); URL newUrl = resolver.resolveRelativePath(absUrl); assertEquals(absUrl, newUrl); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/resource/ConfigurableResource_implTest.java0000644000175000017500000003114311665471062032700 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.resource; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.resource.impl.ResourceCreationSpecifier_impl; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.PropertyXmlInfo; import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl; import org.apache.uima.resource.metadata.impl.XmlizationInfo; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class ConfigurableResource_implTest extends TestCase { /** * Constructor for ConfigurableResource_implTest. * * @param arg0 */ public ConfigurableResource_implTest(String arg0) { super(arg0); } public void testReconfigure() throws Exception { try { // set up some resource metadata and create a resource ResourceCreationSpecifier specifier = new MyTestSpecifier(); ResourceMetaData md = specifier.getMetaData(); md.setName("TestResource"); md.setDescription("Resource used for Testing the Resource_impl base class"); ConfigurationParameter p1 = new ConfigurationParameter_impl(); p1.setName("StringParam"); p1.setDescription("parameter with String data type"); p1.setType(ConfigurationParameter.TYPE_STRING); ConfigurationParameter p2 = new ConfigurationParameter_impl(); p2.setName("IntegerParam"); p2.setDescription("parameter with Integer data type"); p2.setType(ConfigurationParameter.TYPE_INTEGER); ConfigurationParameter p3 = new ConfigurationParameter_impl(); p3.setName("BooleanParam"); p3.setDescription("parameter with Boolean data type"); p3.setType(ConfigurationParameter.TYPE_BOOLEAN); ConfigurationParameter p4 = new ConfigurationParameter_impl(); p4.setName("FloatParam"); p4.setDescription("parameter with Float data type"); p4.setType(ConfigurationParameter.TYPE_FLOAT); ConfigurationParameter p5 = new ConfigurationParameter_impl(); p5.setName("StringArrayParam"); p5.setDescription("mutli-valued parameter with String data type"); p5.setType(ConfigurationParameter.TYPE_STRING); p5.setMultiValued(true); ConfigurationParameter p6 = new ConfigurationParameter_impl(); p6.setName("IntegerArrayParam"); p6.setDescription("multi-valued parameter with Integer data type"); p6.setType(ConfigurationParameter.TYPE_INTEGER); p6.setMultiValued(true); ConfigurationParameter p7 = new ConfigurationParameter_impl(); p7.setName("BooleanArrayParam"); p7.setDescription("multi-valued parameter with Boolean data type"); p7.setType(ConfigurationParameter.TYPE_BOOLEAN); p7.setMultiValued(true); ConfigurationParameter p8 = new ConfigurationParameter_impl(); p8.setName("FloatArrayParam"); p8.setDescription("multi-valued parameter with Float data type"); p8.setType(ConfigurationParameter.TYPE_FLOAT); p8.setMultiValued(true); md.getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[] { p1, p2, p3, p4, p5, p6, p7, p8 }); ConfigurableResource testResource1 = new MyTestResource(); testResource1.initialize(specifier, null); // valid settings String[] paramNames = { "StringParam", "BooleanParam", "IntegerParam", "FloatParam", "StringArrayParam", "BooleanArrayParam", "IntegerArrayParam", "FloatArrayParam" }; String theStr = "hello world"; Boolean theBool = Boolean.valueOf(false); Integer theInt = Integer.valueOf(42); Float theFloat = Float.valueOf(2.718281828459045F); String[] theStrArr = { "the", "quick", "brown", "fox" }; Boolean[] theBoolArr = { Boolean.valueOf(false), Boolean.valueOf(true) }; Integer[] theIntArr = { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }; Float[] theFloatArr = { Float.valueOf(3.0F), Float.valueOf(3.1F), Float.valueOf(3.14F) }; Object[] values = new Object[] { theStr, theBool, theInt, theFloat, theStrArr, theBoolArr, theIntArr, theFloatArr }; for (int i = 0; i < paramNames.length; i++) { testResource1.setConfigParameterValue(paramNames[i], values[i]); } testResource1.reconfigure(); // check for (int i = 0; i < paramNames.length; i++) { Object val = testResource1.getConfigParameterValue(paramNames[i]); Assert.assertEquals(val, values[i]); } // invalid settings // wrong type Exception ex = null; testResource1.setConfigParameterValue("StringParam", Integer.valueOf(13)); try { testResource1.reconfigure(); } catch (ResourceConfigurationException e) { ex = e; } Assert.assertNotNull(ex); ex = null; testResource1.setConfigParameterValue("IntegerArrayParam", new Object[] { "A", "B", "C" }); try { testResource1.reconfigure(); } catch (ResourceConfigurationException e) { ex = e; } Assert.assertNotNull(ex); // inappropriate array ex = null; testResource1.setConfigParameterValue("FloatParam", new Float[] { Float.valueOf(0.1F), Float.valueOf(0.2F), Float.valueOf(0.3F) }); try { testResource1.reconfigure(); } catch (ResourceConfigurationException e) { ex = e; } Assert.assertNotNull(ex); // array required ex = null; testResource1.setConfigParameterValue("BooleanArrayParam", Boolean.valueOf(true)); try { testResource1.reconfigure(); } catch (ResourceConfigurationException e) { ex = e; } Assert.assertNotNull(ex); // required parameter set to null ex = null; testResource1.setConfigParameterValue("StringParam", null); try { testResource1.reconfigure(); } catch (ResourceConfigurationException e) { ex = e; } Assert.assertNotNull(ex); // Now try a resource that defines configuration groups // (instantiate metadata from XML TAE descriptor because it's convenient) XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("ConfigurableResourceImplTest/AnnotatorWithConfigurationGroups.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); ResourceMetaData metadata = desc.getMetaData(); MyTestSpecifier spec = new MyTestSpecifier(); spec.setMetaData(metadata); ConfigurableResource testResource2 = new MyTestResource(); testResource2.initialize(spec, null); // valid settings String[] groupNames = new String[] { "en", "en-US", "de", "zh" }; String[][] grpParamNames = new String[][] { new String[] { "StringParam", "StringArrayParam", "IntegerParam", "IntegerArrayParam" }, new String[] { "StringParam", "StringArrayParam", "IntegerParam", "IntegerArrayParam" }, new String[] { "StringParam", "StringArrayParam", "IntegerParam", "IntegerArrayParam" }, new String[] { "StringParam", "StringArrayParam", "FloatParam", "FloatArrayParam" } }; Object[][] grpValues = new Object[][] { new Object[] { "test", new String[] { "foo", "bar" }, Integer.valueOf(1024), new Integer[] { Integer.valueOf(1), Integer.valueOf(3), Integer.valueOf(5) } }, new Object[] { "blah", new String[] { "abc", "def" }, Integer.valueOf(32768), new Integer[] { Integer.valueOf(-1), Integer.valueOf(-3), Integer.valueOf(-5) } }, new Object[] { "?", new String[] { "+", "-" }, Integer.valueOf(112376), new Integer[] { Integer.valueOf(-1), Integer.valueOf(0), Integer.valueOf(1) } }, new Object[] { "different", new String[] { "test", "ing" }, Float.valueOf(49.95F), new Float[] { Float.valueOf(3.14F), Float.valueOf(2.71F), Float.valueOf(1.4F) } } }; for (int i = 0; i < groupNames.length; i++) { String[] paramsInGrp = grpParamNames[i]; for (int j = 0; j < paramsInGrp.length; j++) { testResource2.setConfigParameterValue(groupNames[i], paramsInGrp[j], grpValues[i][j]); } } testResource2.reconfigure(); for (int i = 0; i < groupNames.length; i++) { String[] paramsInGrp = grpParamNames[i]; for (int j = 0; j < paramsInGrp.length; j++) { Object val = testResource2.getConfigParameterValue(groupNames[i], paramsInGrp[j]); Assert.assertEquals(val, grpValues[i][j]); } } } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Object getConfigParameterValue(String) */ public void testGetConfigParameterValueString() throws Exception { try { XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("ConfigurableResourceImplTest/AnnotatorWithConfigurationGroups.xml")); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( in); AnalysisEngine test = UIMAFramework.produceAnalysisEngine(desc); // test default fallback String str3 = (String) test.getConfigParameterValue("StringParam"); Assert.assertEquals("en", str3); // The below was commented out because it has a dependency on the jedii_cpe_impl module // //XMLInputSource in = new // XMLInputSource("CasConsumerWithDefaultFallbackConfiguration.xml"); // XMLInputSource in = new XMLInputSource("GroupCasConsumer.xml"); // CasConsumerDescription desc = UIMAFramework.getXMLParser().parseCasConsumerDescription(in); // //ConfigurableResource testResource1 = new TestResource(); // CasConsumer test = UIMAFramework.produceCasConsumer(desc); // // testResource1.initialize(desc, null); // // //test default fallback // String str3 = (String)test.getConfigParameterValue("FeatureIndex"); // Assert.assertEquals("test",str3); // // String[] strArr2 = (String[])testResource1.getConfigParameterValue("StringArrayParam"); // Assert.assertEquals(4,strArr2.length); // Assert.assertEquals("t",strArr2[0]); // Assert.assertEquals("e",strArr2[1]); // Assert.assertEquals("s",strArr2[2]); // Assert.assertEquals("t",strArr2[3]); } catch (Exception e) { JUnitExtension.handleException(e); } } } /** * A simple concrete Resource class used for testing. */ class MyTestResource extends ConfigurableResource_ImplBase { public boolean initialize(ResourceSpecifier aSpecifier, Map aParams) throws ResourceInitializationException { return super.initialize(aSpecifier, aParams); // if (aSpecifier instanceof ResourceCreationSpecifier) // { // setMetaData(((ResourceCreationSpecifier)aSpecifier).getMetaData()); // return true; // } // // return false; } public void destroy() { //do nothing } } class MyTestSpecifier extends ResourceCreationSpecifier_impl { public MyTestSpecifier() { setMetaData(new ResourceMetaData_impl()); } protected XmlizationInfo getXmlizationInfo() { return XMLIZATION_INFO; } static final private XmlizationInfo XMLIZATION_INFO = new XmlizationInfo("testSpecifier", new PropertyXmlInfo[] { new PropertyXmlInfo("metaData", null, false), }); } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/ae/0000755000175000017500000000000011665471054022601 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/ae/noop/0000755000175000017500000000000011665471054023554 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/ae/noop/NoOpAnnotator.java0000644000175000017500000001214011665471054027156 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.ae.noop; import java.io.FileNotFoundException; import org.apache.uima.UIMAFramework; import org.apache.uima.UimaContext; import org.apache.uima.analysis_component.CasAnnotator_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.cas.CAS; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.util.Level; import org.apache.uima.util.Logger; public class NoOpAnnotator extends CasAnnotator_ImplBase { private long counter = 0; private long countDown = 0; int errorFrequency = 0; int processDelay = 0; int finalCount = 0; int cpcDelay = 0; public void initialize(UimaContext aContext) throws ResourceInitializationException { super.initialize(aContext); if (getContext().getConfigParameterValue("FailDuringInitialization") != null) { throw new ResourceInitializationException(new FileNotFoundException("Simulated Exception")); } if (getContext().getConfigParameterValue("ErrorFrequency") != null) { errorFrequency = ((Integer) getContext().getConfigParameterValue("ErrorFrequency")) .intValue(); countDown = errorFrequency; } if (getContext().getConfigParameterValue("CpCDelay") != null) { cpcDelay = ((Integer) getContext().getConfigParameterValue("CpCDelay")).intValue(); System.out.println("NoOpAnnotator.initialize() Initializing With CpC Delay of " + cpcDelay + " millis"); } if (getContext().getConfigParameterValue("ProcessDelay") != null) { processDelay = ((Integer) getContext().getConfigParameterValue("ProcessDelay")).intValue(); System.out.println("NoOpAnnotator.initialize() Initializing With Process Delay of " + processDelay + " millis"); } if (getContext().getConfigParameterValue("FinalCount") != null) { finalCount = ((Integer) getContext().getConfigParameterValue("FinalCount")).intValue(); } // write log messages Logger logger = getContext().getLogger(); logger.log(Level.CONFIG, "NAnnotator initialized"); } public void typeSystemInit(TypeSystem aTypeSystem) throws AnalysisEngineProcessException { } public void collectionProcessComplete() throws AnalysisEngineProcessException { System.out .println("NoOpAnnotator.collectionProcessComplete() Called -------------------------------------"); if (cpcDelay > 0) { try { System.out.println("NoOpAnnotator.collectionProcessComplete() Delaying CpC Reply For " + cpcDelay + " millis"); synchronized (this) { this.wait(cpcDelay); } } catch (InterruptedException e) { } } if (finalCount > 0 && finalCount != counter) { String msg = "NoOpAnnotator expected " + finalCount + " CASes but was given " + counter; System.out.println(msg); throw new AnalysisEngineProcessException(new Exception(msg)); } counter = 0; } public void process(CAS aCAS) throws AnalysisEngineProcessException { ++counter; try { if (processDelay == 0) { if (UIMAFramework.getLogger().isLoggable(Level.FINE)) System.out.println("NoOpAnnotator.process() called for the " + counter + "th time. Hashcode:" + hashCode()); } else { // if ( UIMAFramework.getLogger().isLoggable(Level.FINE)) System.out.println("NoOpAnnotator.process() called for the " + counter + "th time, delaying Response For:" + processDelay + " millis"); synchronized (this) { try { wait(processDelay); } catch (InterruptedException e) { } } } // If creating exceptions, reduce interval between them each time. if (errorFrequency > 0) { if (--countDown == 0) { System.out.println("Generating OutOfBoundsException on " + counter + "th call."); if (errorFrequency > 1) { --errorFrequency; } countDown = errorFrequency; throw new IndexOutOfBoundsException(); } } } catch (Exception e) { throw new AnalysisEngineProcessException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/ae/multiplier/0000755000175000017500000000000011665471054024767 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/ae/multiplier/SimpleCasGenerator.java0000644000175000017500000001263111665471054031364 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.ae.multiplier; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ import java.io.File; import java.io.FileInputStream; import java.net.URL; import org.apache.uima.UIMAFramework; import org.apache.uima.UimaContext; import org.apache.uima.analysis_component.CasMultiplier_ImplBase; import org.apache.uima.analysis_engine.AnalysisEngineProcessException; import org.apache.uima.analysis_engine.ResultSpecification; import org.apache.uima.cas.AbstractCas; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.util.Level; /** * An example CasMultiplier, which generates the specified number of output CASes. */ public class SimpleCasGenerator extends CasMultiplier_ImplBase { private int mCount; private int nToGen; private String text; long docCount = 0; public static String lastDocument; public static ResultSpecification lastResultSpec; public static synchronized String getLastDocument() { return lastDocument; } public static synchronized ResultSpecification getLastResultSpec() { return lastResultSpec; } /* * (non-Javadoc) * * @seeorg.apache.uima.analysis_component.AnalysisComponent_ImplBase#initialize(org.apache.uima. * UimaContext) */ public void initialize(UimaContext aContext) throws ResourceInitializationException { super.initialize(aContext); lastDocument = null; lastResultSpec = null; this.nToGen = ((Integer) aContext.getConfigParameterValue("NumberToGenerate")).intValue(); FileInputStream fis = null; try { String filename = ((String) aContext.getConfigParameterValue("InputFile")).trim(); File file = null; try { URL url = this.getClass().getClassLoader().getResource(filename); // System.out.println("************ File::::" + url.getPath()); // open input stream to file file = new File(url.getPath()); } catch (Exception e) { file = new File(filename); } fis = new FileInputStream(file); byte[] contents = new byte[(int) file.length()]; fis.read(contents); text = new String(contents); } catch (Exception e) { throw new ResourceInitializationException(e); } finally { if (fis != null) { try { fis.close(); } catch (Exception e) { } } } } /* * (non-Javadoc) * * @see JCasMultiplier_ImplBase#process(JCas) */ public void process(CAS aCas) throws AnalysisEngineProcessException { // set static fields to contain document text, result spec, // and value of StringParam configuration parameter. lastDocument = aCas.getDocumentText(); lastResultSpec = getResultSpecification(); this.mCount = 0; this.docCount = 0; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#hasNext() */ public boolean hasNext() throws AnalysisEngineProcessException { return this.mCount < this.nToGen; } /* * (non-Javadoc) * * @see org.apache.uima.analysis_component.AnalysisComponent#next() */ public AbstractCas next() throws AnalysisEngineProcessException { CAS cas = getEmptyCAS(); /* * int junk = this.gen.nextInt(); if ((junk & 1) != 0) { cas.setDocumentText(this.mDoc1); } else * { cas.setDocumentText(this.mDoc2); } */ if (docCount == 0 && UIMAFramework.getLogger().isLoggable(Level.FINE)) { System.out.println("Initializing CAS with a Document of Size:" + text.length()); } docCount++; if (UIMAFramework.getLogger().isLoggable(Level.FINE)) System.out.println("CasMult creating document#" + docCount); cas.setDocumentText(this.text); this.mCount++; return cas; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/0000755000175000017500000000000011665471054023155 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/AnalysisEngineFactory_implTest.java0000644000175000017500000000375411665471054032153 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.util.Collections; import junit.framework.TestCase; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.resource.ResourceInitializationException; /** * */ public class AnalysisEngineFactory_implTest extends TestCase { private AnalysisEngineFactory_impl aeFactory; protected void setUp() throws Exception { aeFactory = new AnalysisEngineFactory_impl(); } public void testInvalidFrameworkImplementation() { AnalysisEngineDescription desc = new AnalysisEngineDescription_impl(); desc.setFrameworkImplementation("foo"); try { aeFactory.produceResource(AnalysisEngine.class, desc, Collections.EMPTY_MAP); fail(); } catch (ResourceInitializationException e) { assertNotNull(e.getMessage()); assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); assertEquals(e.getMessageKey(), ResourceInitializationException.UNSUPPORTED_FRAMEWORK_IMPLEMENTATION); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/SomeCustomResource.java0000644000175000017500000000363311665471054027633 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.util.HashMap; import java.util.Map; import junit.framework.Assert; import org.apache.uima.resource.CustomResourceSpecifier; import org.apache.uima.resource.Parameter; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.Resource_ImplBase; /** * */ public class SomeCustomResource extends Resource_ImplBase { public Map paramMap = new HashMap(); /* (non-Javadoc) * @see org.apache.uima.resource.Resource_ImplBase#initialize(org.apache.uima.resource.ResourceSpecifier, java.util.Map) */ public boolean initialize(ResourceSpecifier aSpecifier, Map aAdditionalParams) throws ResourceInitializationException { Assert.assertTrue(aSpecifier instanceof CustomResourceSpecifier); Parameter[] params = ((CustomResourceSpecifier)aSpecifier).getParameters(); for (int i = 0; i < params.length; i++) { paramMap.put(params[i].getName(), params[i].getValue()); } return true; } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/CollectionReaderFactory_implTest.java0000644000175000017500000000375711665471054032463 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.util.Collections; import junit.framework.TestCase; import org.apache.uima.collection.CollectionReader; import org.apache.uima.collection.CollectionReaderDescription; import org.apache.uima.collection.impl.CollectionReaderDescription_impl; import org.apache.uima.resource.ResourceInitializationException; /** * */ public class CollectionReaderFactory_implTest extends TestCase { private CollectionReaderFactory_impl ccFactory; protected void setUp() throws Exception { ccFactory = new CollectionReaderFactory_impl(); } public void testInvalidFrameworkImplementation() { CollectionReaderDescription desc = new CollectionReaderDescription_impl(); desc.setFrameworkImplementation("foo"); try { ccFactory.produceResource(CollectionReader.class, desc, Collections.EMPTY_MAP); fail(); } catch (ResourceInitializationException e) { assertNotNull(e.getMessage()); assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); assertEquals(e.getMessageKey(), ResourceInitializationException.UNSUPPORTED_FRAMEWORK_IMPLEMENTATION); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/UimaContext_implTest.java0000644000175000017500000010203111665471054030136 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.UimaContext; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CasConsumer; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.resource.DataResource; import org.apache.uima.resource.ResourceAccessException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.impl.ResourceCreationSpecifier_impl; import org.apache.uima.resource.impl.TestResourceInterface; import org.apache.uima.resource.metadata.impl.PropertyXmlInfo; import org.apache.uima.resource.metadata.impl.ResourceMetaData_impl; import org.apache.uima.resource.metadata.impl.XmlizationInfo; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.XMLInputSource; public class UimaContext_implTest extends TestCase { protected final String TEST_DATAPATH = JUnitExtension.getFile("AnnotatorContextTest").getPath() + System.getProperty("path.separator") + JUnitExtension.getFile("ResourceTest"); protected final String TEST_EXTENSION_CLASSPATH = JUnitExtension.getFile( "ResourceTest/spaces in dir name").getPath(); private UimaContext mContext; private UimaContext mContext2; private UimaContext mContext3; private UimaContext mContext4; private UimaContext mContext5; /** * Constructor for UimaContext_implTest. * * @param arg0 */ public UimaContext_implTest(String arg0) { super(arg0); } /* * (non-Javadoc) * * @see junit.framework.TestCase#setUp() */ protected void setUp() throws Exception { try { // configure ResourceManager to allow test components to locate their resources ResourceManager rm = UIMAFramework.newDefaultResourceManager(); rm.setDataPath(TEST_DATAPATH); rm.setExtensionClassPath(TEST_EXTENSION_CLASSPATH, true); // create a UimaContext with Config Params and Resources UIMAFramework.getXMLParser().enableSchemaValidation(true); CasConsumerDescription ccDesc = UIMAFramework.getXMLParser().parseCasConsumerDescription( new XMLInputSource(JUnitExtension .getFile("UimaContextTest/CasConsumerForUimaContextTest.xml"))); CasConsumer cc = UIMAFramework.produceCasConsumer(ccDesc, rm, null); mContext = cc.getUimaContext(); // create a UimaContext with Config Params in Groups but no resources XMLInputSource in = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithConfigurationGroups.xml")); AnalysisEngineDescription taeDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(taeDesc, rm, null); mContext2 = ae.getUimaContext(); // create a UimaContext with Groups and Groupless Parameters XMLInputSource in2 = new XMLInputSource(JUnitExtension .getFile("AnnotatorContextTest/AnnotatorWithGroupsAndNonGroupParams.xml")); AnalysisEngineDescription taeDesc2 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in2); AnalysisEngine ae2 = UIMAFramework.produceAnalysisEngine(taeDesc2, rm, null); mContext3 = ae2.getUimaContext(); // create a UimaContext with duplicate configuration groups XMLInputSource in3 = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/AnnotatorWithDuplicateConfigurationGroups.xml")); AnalysisEngineDescription taeDesc3 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in3); AnalysisEngine ae3 = UIMAFramework.produceAnalysisEngine(taeDesc3, rm, null); mContext4 = ae3.getUimaContext(); super.setUp(); // create a UimaContext for a CAS Multiplier XMLInputSource in4 = new XMLInputSource(JUnitExtension .getFile("TextAnalysisEngineImplTest/NewlineSegmenter.xml")); AnalysisEngineDescription taeDesc4 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(in4); AnalysisEngine ae4 = UIMAFramework.produceAnalysisEngine(taeDesc4); mContext5 = ae4.getUimaContext(); super.setUp(); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetConfigParameterValueString() throws Exception { try { String str = (String) mContext.getConfigParameterValue("StringParam"); Assert.assertEquals("myString", str); String[] strArr = (String[]) mContext.getConfigParameterValue("StringArrayParam"); Assert.assertEquals(Arrays.asList(new String[] { "one", "two" }), Arrays.asList(strArr)); Integer integer = (Integer) mContext.getConfigParameterValue("IntegerParam"); Assert.assertEquals(Integer.valueOf(42), integer); Integer[] intArr = (Integer[]) mContext.getConfigParameterValue("IntegerArrayParam"); Assert.assertEquals(Arrays.asList(new Integer[] { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }), Arrays.asList(intArr)); Float flt = (Float) mContext.getConfigParameterValue("FloatParam"); Assert.assertEquals(Float.valueOf(3.14F), flt); // default fallback String str2 = (String) mContext2.getConfigParameterValue("StringParam"); Assert.assertEquals("en", str2); // get groupless param String str3 = (String) mContext3.getConfigParameterValue("GrouplessParam1"); Assert.assertEquals("foo", str3); // default fallback in presence of groupless params (of different names) String str4 = (String) mContext3.getConfigParameterValue("StringParam"); Assert.assertEquals("en", str4); } catch (Exception e) { JUnitExtension.handleException(e); } } /* * Test for Object getConfigParameterValue(String, String) */ public void testGetConfigParameterValueStringString() throws Exception { try { // en-US group String str = (String) mContext2.getConfigParameterValue("en-US", "StringParam"); Assert.assertEquals("en", str); // language fallback String[] strArr = (String[]) mContext2.getConfigParameterValue("en-US", "StringArrayParam"); Assert.assertEquals(5, strArr.length); Assert.assertEquals("e", strArr[0]); Assert.assertEquals("n", strArr[1]); Assert.assertEquals("-", strArr[2]); Assert.assertEquals("U", strArr[3]); Assert.assertEquals("S", strArr[4]); Integer intVal = (Integer) mContext2.getConfigParameterValue("en-US", "IntegerParam"); Assert.assertEquals(1776, intVal.intValue()); Integer[] intArr = (Integer[]) mContext2 .getConfigParameterValue("en-US", "IntegerArrayParam"); Assert.assertEquals(3, intArr.length); // language fallback Assert.assertEquals(1, intArr[0].intValue()); Assert.assertEquals(2, intArr[1].intValue()); Assert.assertEquals(3, intArr[2].intValue()); Float floatVal = (Float) mContext2.getConfigParameterValue("en-US", "FloatParam"); Assert.assertEquals(null, floatVal); // de group String str2 = (String) mContext2.getConfigParameterValue("de", "StringParam"); Assert.assertEquals("de", str2); String[] strArr2 = (String[]) mContext2.getConfigParameterValue("de", "StringArrayParam"); Assert.assertEquals(2, strArr2.length); Assert.assertEquals("d", strArr2[0]); Assert.assertEquals("e", strArr2[1]); Integer intVal2 = (Integer) mContext2.getConfigParameterValue("de", "IntegerParam"); Assert.assertEquals(42, intVal2.intValue()); // default fallback Integer[] intArr2 = (Integer[]) mContext2.getConfigParameterValue("de", "IntegerArrayParam"); Assert.assertEquals(3, intArr2.length); Assert.assertEquals(4, intArr2[0].intValue()); Assert.assertEquals(5, intArr2[1].intValue()); Assert.assertEquals(6, intArr2[2].intValue()); Float floatVal2 = (Float) mContext2.getConfigParameterValue("de", "FloatParam"); Assert.assertEquals(null, floatVal2); // zh group String str3 = (String) mContext2.getConfigParameterValue("zh", "StringParam"); Assert.assertEquals("zh", str3); String[] strArr3 = (String[]) mContext2.getConfigParameterValue("zh", "StringArrayParam"); Assert.assertEquals(2, strArr3.length); Assert.assertEquals("z", strArr3[0]); Assert.assertEquals("h", strArr3[1]); Integer intVal3 = (Integer) mContext2.getConfigParameterValue("zh", "IntegerParam"); Assert.assertEquals(42, intVal3.intValue()); // default fallback Integer[] intArr3 = (Integer[]) mContext2.getConfigParameterValue("zh", "IntegerArrayParam"); Assert.assertEquals(3, intArr3.length); // default fallback Assert.assertEquals(1, intArr3[0].intValue()); Assert.assertEquals(2, intArr3[1].intValue()); Assert.assertEquals(3, intArr3[2].intValue()); Float floatVal3 = (Float) mContext2.getConfigParameterValue("zh", "FloatParam"); Assert.assertEquals(3.14, floatVal3.floatValue(), 0.0001); // testing duplicate groups assertEquals("common-a", mContext4.getConfigParameterValue("a", "CommonParam")); assertEquals("ab-a", mContext4.getConfigParameterValue("a", "ABParam")); assertNull(mContext4.getConfigParameterValue("a", "BCParam")); assertEquals("common-b", mContext4.getConfigParameterValue("b", "CommonParam")); assertEquals("ab-b", mContext4.getConfigParameterValue("b", "ABParam")); assertEquals("bc-b", mContext4.getConfigParameterValue("b", "BCParam")); assertEquals("common-c", mContext4.getConfigParameterValue("c", "CommonParam")); assertEquals("bc-c", mContext4.getConfigParameterValue("c", "BCParam")); assertNull(mContext4.getConfigParameterValue("c", "ABParam")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetConfigurationGroupNames() { String[] names = mContext2.getConfigurationGroupNames(); Assert.assertEquals(5, names.length); ArrayList l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("en")); Assert.assertTrue(l.contains("en-US")); Assert.assertTrue(l.contains("de")); Assert.assertTrue(l.contains("zh")); Assert.assertTrue(l.contains("x-unspecified")); // try on something with both groups and groupless parameters names = mContext3.getConfigurationGroupNames(); Assert.assertEquals(5, names.length); l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("en")); Assert.assertTrue(l.contains("en-US")); Assert.assertTrue(l.contains("de")); Assert.assertTrue(l.contains("zh")); Assert.assertTrue(l.contains("x-unspecified")); // try on something that has no groups names = mContext.getConfigurationGroupNames(); Assert.assertEquals(0, names.length); } public void testGetConfigParameterNames() { String[] names = mContext.getConfigParameterNames(); Assert.assertEquals(6, names.length); Assert.assertEquals("StringParam", names[0]); Assert.assertEquals("StringArrayParam", names[1]); Assert.assertEquals("IntegerParam", names[2]); Assert.assertEquals("IntegerArrayParam", names[3]); Assert.assertEquals("FloatParam", names[4]); Assert.assertEquals("FloatArrayParam", names[5]); // try on something that has groups names = mContext2.getConfigParameterNames(); Assert.assertEquals(0, names.length); // try on something with both groups and groupless parameters names = mContext3.getConfigParameterNames(); Assert.assertEquals(2, names.length); Assert.assertEquals("GrouplessParam1", names[0]); Assert.assertEquals("GrouplessParam2", names[1]); } public void testGetConfigParameterNamesString() { String[] names = mContext2.getConfigParameterNames("en"); Assert.assertEquals(4, names.length); ArrayList l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("StringParam")); Assert.assertTrue(l.contains("StringArrayParam")); Assert.assertTrue(l.contains("IntegerParam")); Assert.assertTrue(l.contains("IntegerArrayParam")); // try on nonexistent group names = mContext2.getConfigParameterNames("foo"); Assert.assertEquals(0, names.length); // try on something that has no groups names = mContext.getConfigParameterNames("en"); Assert.assertEquals(0, names.length); // try on something with both groups and groupless params names = mContext3.getConfigParameterNames("en"); Assert.assertEquals(4, names.length); l = new ArrayList(Arrays.asList(names)); Assert.assertTrue(l.contains("StringParam")); Assert.assertTrue(l.contains("StringArrayParam")); Assert.assertTrue(l.contains("IntegerParam")); Assert.assertTrue(l.contains("IntegerArrayParam")); } public void testGetResourceObjectString() throws Exception { try { // custom object Object r = mContext.getResourceObject("TestResourceObject"); Assert.assertNotNull(r); Assert.assertTrue(r instanceof TestResourceInterface); // standard data resource Object r2 = mContext.getResourceObject("TestFileResource"); Assert.assertNotNull(r2); Assert.assertTrue(r2 instanceof DataResource); // parameterized resources (should fail) ResourceAccessException ex = null; try { mContext.getResourceObject("TestFileLanguageResource"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceObject("TestLanguageResourceObject"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) Object r3 = mContext.getResourceObject("Unknown"); Assert.assertNull(r3); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURLString() throws Exception { try { // standard data resource (should succeed) URL url = mContext.getResourceURL("TestFileResource"); Assert.assertNotNull(url); // custom resource object (should return null) URL url2 = mContext.getResourceURL("TestResourceObject"); Assert.assertNull(url2); // parameterized resources (should fail) ResourceAccessException ex = null; try { mContext.getResourceURL("TestFileLanguageResource"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURL("TestLanguageResourceObject"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URL url3 = mContext.getResourceURL("Unknown"); Assert.assertNull(url3); // passthrough to class loader URL url5 = mContext.getResourceURL("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(url5); // passthrough to data path URL url6 = mContext.getResourceURL("testDataFile.dat"); Assert.assertNotNull(url6); // for directory URL url7 = mContext.getResourceURL("subdir"); Assert.assertNotNull(url7); // spaces as part of extension classpath (spaces should be URL-encoded) URL url8 = mContext.getResourceURL("OtherFileResource"); assertNotNull(url8); assertTrue(url8.getPath().indexOf("%20") > -1); assertTrue(url8.getPath().indexOf(" ") == -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURIString() throws Exception { try { // standard data resource (should succeed) URI uri = mContext.getResourceURI("TestFileResource"); Assert.assertNotNull(uri); // custom resource object (should return null) URI uri2 = mContext.getResourceURI("TestResourceObject"); Assert.assertNull(uri2); // parameterized resources (should fail) ResourceAccessException ex = null; try { mContext.getResourceURI("TestFileLanguageResource"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURI("TestLanguageResourceObject"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URI uri3 = mContext.getResourceURI("Unknown"); Assert.assertNull(uri3); // passthrough to class loader URI uri5 = mContext.getResourceURI("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(uri5); // passthrough to data path URI uri6 = mContext.getResourceURI("testDataFile.dat"); Assert.assertNotNull(uri6); // for directory URI uri7 = mContext.getResourceURI("subdir"); Assert.assertNotNull(uri7); // spaces as part of extension classpath (spaces should be decoded, unlike with URL) URI uri8 = mContext.getResourceURI("OtherFileResource"); assertNotNull(uri8); assertTrue(uri8.getPath().indexOf("%20") == -1); assertTrue(uri8.getPath().indexOf(" ") > -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceFilePathString() throws Exception { try { // standard data resource (should succeed) String path = mContext.getResourceFilePath("TestFileResource"); Assert.assertNotNull(path); // custom resource object (should return null) String path2 = mContext.getResourceFilePath("TestResourceObject"); Assert.assertNull(path2); // parameterized resources (should fail) ResourceAccessException ex = null; try { mContext.getResourceFilePath("TestFileLanguageResource"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceFilePath("TestLanguageResourceObject"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) String path3 = mContext.getResourceFilePath("Unknown"); Assert.assertNull(path3); // passthrough to class loader String path5 = mContext .getResourceFilePath("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(path5); // passthrough to data path String path6 = mContext.getResourceFilePath("testDataFile.dat"); Assert.assertNotNull(path6); // for directory String path7 = mContext.getResourceFilePath("subdir"); Assert.assertNotNull(path7); // spaces as part of extension classpath (spaces should be decoded, unlike with URL) String path8 = mContext.getResourceFilePath("OtherFileResource"); assertNotNull(path8); assertTrue(path8.indexOf("%20") == -1); assertTrue(path8.indexOf(" ") > -1); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceAsStreamString() throws Exception { try { // standard data resource (should succeed) InputStream strm = mContext.getResourceAsStream("TestFileResource"); Assert.assertNotNull(strm); // custom resource object (should return null) InputStream strm2 = mContext.getResourceAsStream("TestResourceObject"); Assert.assertNull(strm2); // parameterized resources (should fail) ResourceAccessException ex = null; try { mContext.getResourceAsStream("TestFileLanguageResource"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceAsStream("TestLanguageResourceObject"); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) InputStream strm3 = mContext.getResourceAsStream("Unknown"); Assert.assertNull(strm3); // passthrough to class loader InputStream strm4 = mContext .getResourceAsStream("org/apache/uima/analysis_engine/impl/testDataFile3.dat"); Assert.assertNotNull(strm4); // passthrough to data path InputStream strm5 = mContext.getResourceAsStream("testDataFile.dat"); Assert.assertNotNull(strm5); // for directory InputStream strm6 = mContext.getResourceAsStream("subdir"); Assert.assertNotNull(strm6); // spaces as part of extension classpath InputStream strm7 = mContext.getResourceAsStream("OtherFileResource"); assertNotNull(strm7); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceObjectStringStringArray() throws Exception { try { // standard data resource Object r = mContext.getResourceObject("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(r); Assert.assertTrue(r instanceof DataResource); Object r2 = mContext.getResourceObject("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(r2); Assert.assertTrue(r2 instanceof DataResource); Assert.assertFalse(r2.equals(r)); // custom object Object r3 = mContext.getResourceObject("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNotNull(r3); Assert.assertTrue(r3 instanceof TestResourceInterface); Object r4 = mContext.getResourceObject("TestLanguageResourceObject", new String[] { "de" }); Assert.assertNotNull(r4); Assert.assertTrue(r4 instanceof TestResourceInterface); Assert.assertFalse(r4.equals(r3)); // parameter values for which no resource exists (should fail) ResourceAccessException ex = null; try { mContext.getResourceObject("TestFileLanguageResource", new String[] { "zh" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceObject("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mContext.getResourceObject("TestFileResource", new String[] { "en" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceObject("TestResourceObject", new String[] { "de" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) Object r5 = mContext.getResourceObject("Unknown", new String[] { "en" }); Assert.assertNull(r5); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceAsStreamStringStringArray() throws Exception { try { // standard data resource InputStream strm = mContext.getResourceAsStream("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(strm); InputStream strm2 = mContext.getResourceAsStream("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(strm2); Assert.assertFalse(strm2.equals(strm)); // custom object (should return null) InputStream strm3 = mContext.getResourceAsStream("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(strm3); // parameter values for which no resource exists (should fail) ResourceAccessException ex = null; try { mContext.getResourceAsStream("TestFileLanguageResource", new String[] { "zh" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceAsStream("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mContext.getResourceAsStream("TestFileResource", new String[] { "en" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceAsStream("TestResourceObject", new String[] { "de" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) InputStream strm4 = mContext.getResourceAsStream("Unknown", new String[] { "en" }); Assert.assertNull(strm4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURLStringStringArray() throws Exception { try { // standard data resource URL url = mContext.getResourceURL("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(url); URL url2 = mContext.getResourceURL("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(url2); Assert.assertFalse(url2.toString().equals(url.toString())); // custom object (should return null) URL url3 = mContext.getResourceURL("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(url3); // parameter values for which no resource exists (should fail) ResourceAccessException ex = null; try { mContext.getResourceURL("TestFileLanguageResource", new String[] { "zh" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURL("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mContext.getResourceURL("TestFileResource", new String[] { "en" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURL("TestResourceObject", new String[] { "de" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URL url4 = mContext.getResourceURL("Unknown", new String[] { "en" }); Assert.assertNull(url4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceURIStringStringArray() throws Exception { try { // standard data resource URI uri = mContext.getResourceURI("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(uri); URI uri2 = mContext.getResourceURI("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(uri2); Assert.assertFalse(uri2.equals(uri)); // custom object (should return null) URI uri3 = mContext.getResourceURI("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(uri3); // parameter values for which no resource exists (should fail) ResourceAccessException ex = null; try { mContext.getResourceURI("TestFileLanguageResource", new String[] { "zh" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURI("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mContext.getResourceURI("TestFileResource", new String[] { "en" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceURI("TestResourceObject", new String[] { "de" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) URI uri4 = mContext.getResourceURI("Unknown", new String[] { "en" }); Assert.assertNull(uri4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetResourceFilePathStringStringArray() throws Exception { try { // standard data resource String path = mContext.getResourceFilePath("TestFileLanguageResource", new String[] { "en" }); Assert.assertNotNull(path); String path2 = mContext .getResourceFilePath("TestFileLanguageResource", new String[] { "de" }); Assert.assertNotNull(path2); Assert.assertFalse(path2.equals(path)); // custom object (should return null) String path3 = mContext.getResourceFilePath("TestLanguageResourceObject", new String[] { "en" }); Assert.assertNull(path3); // parameter values for which no resource exists (should fail) ResourceAccessException ex = null; try { mContext.getResourceFilePath("TestFileLanguageResource", new String[] { "zh" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceFilePath("TestFileLanguageResource", new String[] { "en", "p2" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // non-parameterized resources (should fail) ex = null; try { mContext.getResourceFilePath("TestFileResource", new String[] { "en" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); ex = null; try { mContext.getResourceFilePath("TestResourceObject", new String[] { "de" }); } catch (ResourceAccessException e) { ex = e; } Assert.assertNotNull(ex); // nonexistent resource (should return null) String path4 = mContext.getResourceFilePath("Unknown", new String[] { "en" }); Assert.assertNull(path4); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetDataPath() throws Exception { try { Assert.assertEquals(TEST_DATAPATH, mContext.getDataPath()); Assert.assertEquals(TEST_DATAPATH, mContext2.getDataPath()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testGetEmptyCas() throws Exception { try { CAS emptyCas = (CAS)mContext5.getEmptyCas(CAS.class); //should be allowed to release this CAS emptyCas.release(); //and then get it again emptyCas = (CAS)mContext5.getEmptyCas(CAS.class); emptyCas.release(); } catch (Exception e) { JUnitExtension.handleException(e); } } } class MyTestSpecifier extends ResourceCreationSpecifier_impl { public MyTestSpecifier() { setMetaData(new ResourceMetaData_impl()); } protected XmlizationInfo getXmlizationInfo() { return XMLIZATION_INFO; } static final private XmlizationInfo XMLIZATION_INFO = new XmlizationInfo("testSpecifier", new PropertyXmlInfo[] { new PropertyXmlInfo("metaData", null, false), }); } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/CasConsumerFactory_implTest.java0000644000175000017500000000370211665471054031455 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.util.Collections; import junit.framework.TestCase; import org.apache.uima.collection.CasConsumer; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.collection.impl.CasConsumerDescription_impl; import org.apache.uima.resource.ResourceInitializationException; /** * */ public class CasConsumerFactory_implTest extends TestCase { private CasConsumerFactory_impl ccFactory; protected void setUp() throws Exception { ccFactory = new CasConsumerFactory_impl(); } public void testInvalidFrameworkImplementation() { CasConsumerDescription desc = new CasConsumerDescription_impl(); desc.setFrameworkImplementation("foo"); try { ccFactory.produceResource(CasConsumer.class, desc, Collections.EMPTY_MAP); fail(); } catch (ResourceInitializationException e) { assertNotNull(e.getMessage()); assertFalse(e.getMessage().startsWith("EXCEPTION MESSAGE LOCALIZATION FAILED")); assertEquals(e.getMessageKey(), ResourceInitializationException.UNSUPPORTED_FRAMEWORK_IMPLEMENTATION); } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/CustomResourceSpecifierFactory_implTest.javauimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/impl/CustomResourceSpecifierFactory_implTest.ja0000644000175000017500000000522611665471054033523 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.impl; import java.util.Collections; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.CustomResourceSpecifier; import org.apache.uima.resource.Parameter; import org.apache.uima.resource.Resource; /** * */ public class CustomResourceSpecifierFactory_implTest extends TestCase { private CustomResourceFactory_impl crFactory; protected void setUp() throws Exception { crFactory = new CustomResourceFactory_impl(); } public void testProduceResource() throws Exception { CustomResourceSpecifier specifier = UIMAFramework.getResourceSpecifierFactory().createCustomResourceSpecifier(); specifier.setResourceClassName("org.apache.uima.impl.SomeCustomResource"); Parameter[] parameters = new Parameter[2]; parameters[0] = UIMAFramework.getResourceSpecifierFactory().createParameter(); parameters[0].setName("param1"); parameters[0].setValue("val1"); parameters[1] = UIMAFramework.getResourceSpecifierFactory().createParameter(); parameters[1].setName("param2"); parameters[1].setValue("val2"); specifier.setParameters(parameters); Resource res = crFactory.produceResource(Resource.class, specifier, Collections.EMPTY_MAP); assertTrue(res instanceof SomeCustomResource); assertEquals("val1", ((SomeCustomResource)res).paramMap.get("param1")); assertEquals("val2", ((SomeCustomResource)res).paramMap.get("param2")); //also UIMAFramework.produceResource should do the same thing res = UIMAFramework.produceResource(specifier, Collections.EMPTY_MAP); assertTrue(res instanceof SomeCustomResource); assertEquals("val1", ((SomeCustomResource)res).paramMap.get("param1")); assertEquals("val2", ((SomeCustomResource)res).paramMap.get("param2")); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/0000755000175000017500000000000011665471066023174 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/TestCollectionReader.java0000644000175000017500000000353411665471066030122 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.IOException; import org.apache.uima.cas.CAS; import org.apache.uima.collection.CollectionException; import org.apache.uima.collection.CollectionReader_ImplBase; public class TestCollectionReader extends CollectionReader_ImplBase { /** * @see org.apache.uima.collection.CollectionReader#getNext(org.apache.uima.cas.CAS) */ public void getNext(CAS aCAS) throws IOException, CollectionException { // empty method } /** * @see org.apache.uima.collection.base_cpm.BaseCollectionReader#hasNext() */ public boolean hasNext() throws IOException, CollectionException { // empty method return false; } /** * @see org.apache.uima.collection.base_cpm.BaseCollectionReader#getProgress() */ public Progress[] getProgress() { // empty method return null; } /** * @see org.apache.uima.collection.base_cpm.BaseCollectionReader#close() */ public void close() throws IOException { // empty method } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/CasCreationUtilsTest.java0000644000175000017500000007366011665471066030127 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FSIterator; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.admin.CASFactory; import org.apache.uima.cas.admin.CASMgr; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.resource.metadata.impl.FsIndexCollection_impl; import org.apache.uima.resource.metadata.impl.FsIndexDescription_impl; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypePriorityList_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; public class CasCreationUtilsTest extends TestCase { /** * Constructor for CasCreationUtilsTest. * * @param arg0 */ public CasCreationUtilsTest(String arg0) { super(arg0); } public void testMergeTypeSystems() throws Exception { try { TypeSystemDescription ts1desc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(JUnitExtension.getFile("CasCreationUtilsTest/TypeSystem1.xml"))); Assert.assertEquals(1, ts1desc.getType("Type1").getFeatures().length); Assert.assertEquals(1, ts1desc.getType("Type2").getFeatures().length); Assert.assertEquals(1, ts1desc.getType("Type3").getFeatures().length); TypeSystemDescription ts2desc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(JUnitExtension.getFile("CasCreationUtilsTest/TypeSystem2.xml"))); Assert.assertEquals(1, ts2desc.getType("Type1").getFeatures().length); Assert.assertEquals(1, ts2desc.getType("Type2").getFeatures().length); ArrayList tsList = new ArrayList(); tsList.add(ts1desc); tsList.add(ts2desc); Map typesWithMergedFeatures = new HashMap(); TypeSystemDescription merged = CasCreationUtils.mergeTypeSystems(tsList, UIMAFramework .newDefaultResourceManager(), typesWithMergedFeatures); Assert.assertEquals(2, merged.getType("Type1").getFeatures().length); Assert.assertEquals(2, merged.getType("Type2").getFeatures().length); Assert.assertEquals(1, merged.getType("Type3").getFeatures().length); assertEquals(2, typesWithMergedFeatures.size()); assertTrue(typesWithMergedFeatures.containsKey("Type1")); assertTrue(typesWithMergedFeatures.containsKey("Type2")); // make sure one-arg version doesn't fail CasCreationUtils.mergeTypeSystems(tsList); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeTypeSystemElementType() throws Exception { try { TypeSystemDescription ts1desc = UIMAFramework.getXMLParser() .parseTypeSystemDescription( new XMLInputSource(JUnitExtension .getFile("CasCreationUtilsTest/TypeSystemMergeBase.xml"))); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongElementType1.xml", ResourceInitializationException.INCOMPATIBLE_ELEMENT_RANGE_TYPES); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongElementType2.xml", ResourceInitializationException.INCOMPATIBLE_ELEMENT_RANGE_TYPES); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongMultiRef1.xml", ResourceInitializationException.INCOMPATIBLE_MULTI_REFS); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongMultiRef2.xml", ResourceInitializationException.INCOMPATIBLE_MULTI_REFS); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongMultiRef3.xml", ResourceInitializationException.INCOMPATIBLE_MULTI_REFS); checkMergeTypeSystem(ts1desc, "TypeSystemMergeOkMultiRef.xml", null); checkMergeTypeSystem(ts1desc, "TypeSystemMergeNoElementType.xml", null); checkMergeTypeSystem(ts1desc, "typeSystemMergeTopElementType.xml", null); checkMergeTypeSystem(ts1desc, "TypeSystemMergeWrongElementTypeWithNone.xml", ResourceInitializationException.INCOMPATIBLE_ELEMENT_RANGE_TYPES); } catch (Exception e) { JUnitExtension.handleException(e); } } private void checkMergeTypeSystem(TypeSystemDescription ts1desc, String typeFile, String msgKey) throws Exception { try { TypeSystemDescription ts2desc = UIMAFramework .getXMLParser() .parseTypeSystemDescription( new XMLInputSource( JUnitExtension .getFile("CasCreationUtilsTest/" + typeFile))); List tsList = new ArrayList(); tsList.add(ts1desc); tsList.add(ts2desc); boolean rightExceptionThrown = (null != msgKey) ? false : true; try { CasCreationUtils.mergeTypeSystems( tsList, UIMAFramework.newDefaultResourceManager(), new HashMap()); } catch (ResourceInitializationException rie) { rightExceptionThrown = (null != msgKey) && rie.hasMessageKey(msgKey); } assertTrue(rightExceptionThrown); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeTypeSystemsWithDifferentSupertypes() throws Exception { try { TypeSystemDescription ts1desc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(JUnitExtension.getFile("CasCreationUtilsTest/SupertypeMergeTest1.xml"))); assertEquals("uima.tcas.Annotation", ts1desc.getType("uima.test.Sub").getSupertypeName()); TypeSystemDescription ts2desc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(JUnitExtension.getFile("CasCreationUtilsTest/SupertypeMergeTest2.xml"))); assertEquals("uima.test.Super", ts2desc.getType("uima.test.Sub").getSupertypeName()); List tsList = new ArrayList(); tsList.add(ts1desc); tsList.add(ts2desc); TypeSystemDescription merged = CasCreationUtils.mergeTypeSystems(tsList, UIMAFramework .newDefaultResourceManager()); assertEquals("uima.test.Super", merged.getType("uima.test.Sub").getSupertypeName()); // try merging in the other order - bug UIMA-826 was an order dependency in the behavior of // this kind of merging tsList = new ArrayList(); tsList.add(ts2desc); tsList.add(ts1desc); merged = CasCreationUtils.mergeTypeSystems(tsList, UIMAFramework .newDefaultResourceManager()); assertEquals("uima.test.Super", merged.getType("uima.test.Sub").getSupertypeName()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testAggregateWithImports() throws Exception { try { String pathSep = System.getProperty("path.separator"); ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); resMgr.setDataPath(JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir") .getAbsolutePath() + pathSep + JUnitExtension.getFile("TypePrioritiesImplTest/dataPathDir").getAbsolutePath() + pathSep + JUnitExtension.getFile("FsIndexCollectionImplTest/dataPathDir").getAbsolutePath()); File taeDescriptorWithImport = JUnitExtension .getFile("CasCreationUtilsTest/AggregateTaeWithImports.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(taeDescriptorWithImport)); ArrayList mdList = new ArrayList(); mdList.add(desc); CAS tcas = CasCreationUtils.createCas(mdList, UIMAFramework .getDefaultPerformanceTuningProperties(), resMgr); // check that imports were resolved correctly assertNotNull(tcas.getTypeSystem().getType("DocumentStructure")); assertNotNull(tcas.getTypeSystem().getType("NamedEntity")); assertNotNull(tcas.getTypeSystem().getType("TestType3")); assertNotNull(tcas.getTypeSystem().getType("Sentence")); assertNotNull(tcas.getIndexRepository().getIndex("TestIndex")); assertNotNull(tcas.getIndexRepository().getIndex("ReverseAnnotationIndex")); assertNotNull(tcas.getIndexRepository().getIndex("DocumentStructureIndex")); // Check elementType and multipleReferencesAllowed for array feature Feature arrayFeat = tcas.getTypeSystem().getFeatureByFullName("Paragraph:sentences"); assertNotNull(arrayFeat); assertFalse(arrayFeat.isMultipleReferencesAllowed()); Type sentenceArrayType = arrayFeat.getRange(); assertNotNull(sentenceArrayType); assertTrue(sentenceArrayType.isArray()); assertEquals(tcas.getTypeSystem().getType("Sentence"), sentenceArrayType.getComponentType()); Feature arrayFeat2 = tcas.getTypeSystem().getFeatureByFullName( "Paragraph:testMultiRefAllowedFeature"); assertNotNull(arrayFeat2); assertTrue(arrayFeat2.isMultipleReferencesAllowed()); // test imports aren't resolved more than once Object spec1 = desc.getDelegateAnalysisEngineSpecifiers().get("Annotator1"); assertNotNull(spec1); Object spec2 = desc.getDelegateAnalysisEngineSpecifiers().get("Annotator1"); assertTrue(spec1 == spec2); // test removal desc.getDelegateAnalysisEngineSpecifiersWithImports().remove("Annotator1"); assertTrue(desc.getDelegateAnalysisEngineSpecifiers().isEmpty()); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeDelegateAnalysisEngineTypeSystems() throws Exception { try { File descFile = JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); Map mergedTypes = new HashMap(); TypeSystemDescription typeSys = CasCreationUtils.mergeDelegateAnalysisEngineTypeSystems(desc, UIMAFramework.newDefaultResourceManager(), mergedTypes); // test results of merge Assert.assertEquals(8, typeSys.getTypes().length); TypeDescription type0 = typeSys.getType("NamedEntity"); Assert.assertNotNull(type0); Assert.assertEquals("uima.tcas.Annotation", type0.getSupertypeName()); Assert.assertEquals(1, type0.getFeatures().length); TypeDescription type1 = typeSys.getType("Person"); Assert.assertNotNull(type1); Assert.assertEquals("NamedEntity", type1.getSupertypeName()); Assert.assertEquals(1, type1.getFeatures().length); TypeDescription type2 = typeSys.getType("Place"); Assert.assertNotNull(type2); Assert.assertEquals("NamedEntity", type2.getSupertypeName()); Assert.assertEquals(3, type2.getFeatures().length); TypeDescription type3 = typeSys.getType("Org"); Assert.assertNotNull(type3); Assert.assertEquals("uima.tcas.Annotation", type3.getSupertypeName()); Assert.assertEquals(0, type3.getFeatures().length); TypeDescription type4 = typeSys.getType("DocumentStructure"); Assert.assertNotNull(type4); Assert.assertEquals("uima.tcas.Annotation", type4.getSupertypeName()); Assert.assertEquals(0, type4.getFeatures().length); TypeDescription type5 = typeSys.getType("Paragraph"); Assert.assertNotNull(type5); Assert.assertEquals("DocumentStructure", type5.getSupertypeName()); Assert.assertEquals(0, type5.getFeatures().length); TypeDescription type6 = typeSys.getType("Sentence"); Assert.assertNotNull(type6); Assert.assertEquals("DocumentStructure", type6.getSupertypeName()); Assert.assertEquals(0, type6.getFeatures().length); TypeDescription type7 = typeSys.getType("test.flowController.Test"); Assert.assertNotNull(type7); Assert.assertEquals("uima.tcas.Annotation", type7.getSupertypeName()); Assert.assertEquals(1, type7.getFeatures().length); // Place has merged features, Person has different supertype assertEquals(2, mergedTypes.size()); assertTrue(mergedTypes.containsKey("Place")); assertTrue(mergedTypes.containsKey("Person")); // make sure one-arg version doesn't fail CasCreationUtils.mergeDelegateAnalysisEngineTypeSystems(desc); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeDelegateAnalysisEngineTypePriorities() throws Exception { try { File descFile = JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); TypePriorities pri = CasCreationUtils.mergeDelegateAnalysisEngineTypePriorities(desc); // test results of merge Assert.assertNotNull(pri); TypePriorityList[] priLists = pri.getPriorityLists(); Assert.assertEquals(3, priLists.length); String[] list0 = priLists[0].getTypes(); String[] list1 = priLists[1].getTypes(); String[] list2 = priLists[2].getTypes(); // order of the three lists is not defined Assert.assertTrue((list0.length == 2 && list1.length == 2 && list2.length == 3) || (list0.length == 2 && list1.length == 3 && list2.length == 2) || (list0.length == 3 && list1.length == 2 && list2.length == 2)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeDelegateAnalysisEngineFsIndexCollections() throws Exception { try { File descFile = JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); FsIndexCollection indexColl = CasCreationUtils .mergeDelegateAnalysisEngineFsIndexCollections(desc); // test results of merge FsIndexDescription[] indexes = indexColl.getFsIndexes(); Assert.assertEquals(3, indexes.length); // order of indexes is not defined String label0 = indexes[0].getLabel(); String label1 = indexes[1].getLabel(); String label2 = indexes[2].getLabel(); Assert.assertTrue(label0.equals("DocStructIndex") || label1.equals("DocStructIndex") || label2.equals("DocStructIndex")); Assert.assertTrue(label0.equals("PlaceIndex") || label1.equals("PlaceIndex") || label2.equals("PlaceIndex")); Assert.assertTrue(label0.equals("FlowControllerTestIndex") || label1.equals("FlowControllerTestIndex") || label2.equals("FlowControllerTestIndex")); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testSetupTypeSystem() throws Exception { try { // test that duplicate feature names on supertype and subtype works // regardless of the order in which the types appear in the TypeSystemDescription TypeSystemDescription tsd1 = new TypeSystemDescription_impl(); TypeDescription supertype = tsd1.addType("test.Super", "", "uima.cas.TOP"); supertype.addFeature("testfeat", "", "uima.cas.Integer"); TypeDescription subtype = tsd1.addType("test.Sub", "", "test.Super"); subtype.addFeature("testfeat", "", "uima.cas.Integer"); CASMgr casMgr = CASFactory.createCAS(); CasCreationUtils.setupTypeSystem(casMgr, tsd1); assertNotNull(casMgr.getTypeSystemMgr().getType("test.Super") .getFeatureByBaseName("testfeat")); TypeSystemDescription tsd2 = new TypeSystemDescription_impl(); tsd2.setTypes(new TypeDescription[] { subtype, supertype }); casMgr = CASFactory.createCAS(); CasCreationUtils.setupTypeSystem(casMgr, tsd2); assertNotNull(casMgr.getTypeSystemMgr().getType("test.Super") .getFeatureByBaseName("testfeat")); } catch (ResourceInitializationException e) { JUnitExtension.handleException(e); } } public void testCreateCasCollectionPropertiesResourceManager() throws Exception { try { // parse an AE descriptor File taeDescriptorWithImport = JUnitExtension .getFile("CasCreationUtilsTest/TaeWithImports.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(taeDescriptorWithImport)); // create Resource Manager & set data path - necessary to resolve imports ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); String pathSep = System.getProperty("path.separator"); resMgr.setDataPath(JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir") .getAbsolutePath() + pathSep + JUnitExtension.getFile("TypePrioritiesImplTest/dataPathDir").getAbsolutePath() + pathSep + JUnitExtension.getFile("FsIndexCollectionImplTest/dataPathDir").getAbsolutePath()); // call method ArrayList descList = new ArrayList(); descList.add(desc); CAS cas = CasCreationUtils.createCas(descList, UIMAFramework .getDefaultPerformanceTuningProperties(), resMgr); // check that imports were resolved correctly assertNotNull(cas.getTypeSystem().getType("DocumentStructure")); assertNotNull(cas.getTypeSystem().getType("NamedEntity")); assertNotNull(cas.getTypeSystem().getType("TestType3")); assertNotNull(cas.getIndexRepository().getIndex("TestIndex")); assertNotNull(cas.getIndexRepository().getIndex("ReverseAnnotationIndex")); assertNotNull(cas.getIndexRepository().getIndex("DocumentStructureIndex")); // check of type priority AnnotationFS fs1 = cas.createAnnotation(cas.getTypeSystem().getType("Paragraph"), 0, 1); AnnotationFS fs2 = cas.createAnnotation(cas.getTypeSystem().getType("Sentence"), 0, 1); assertTrue(cas.getAnnotationIndex().compare(fs1, fs2) < 0); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateCasCollection() throws Exception { try { // create two Type System description objects TypeSystemDescription tsd1 = new TypeSystemDescription_impl(); TypeDescription supertype = tsd1.addType("test.Super", "", "uima.tcas.Annotation"); supertype.addFeature("testfeat", "", "uima.cas.Integer"); TypeDescription subtype = tsd1.addType("test.Sub", "", "test.Super"); subtype.addFeature("testfeat", "", "uima.cas.Integer"); TypeSystemDescription tsd2 = new TypeSystemDescription_impl(); TypeDescription fooType = tsd1.addType("test.Foo", "", "uima.cas.TOP"); fooType.addFeature("bar", "", "uima.cas.String"); // create index and priorities descriptions FsIndexCollection indexes = new FsIndexCollection_impl(); FsIndexDescription index = new FsIndexDescription_impl(); index.setLabel("MyIndex"); index.setTypeName("test.Foo"); index.setKind(FsIndexDescription.KIND_BAG); indexes.addFsIndex(index); TypePriorities priorities = new TypePriorities_impl(); TypePriorityList priList = new TypePriorityList_impl(); priList.addType("test.Foo"); priList.addType("test.Sub"); priList.addType("test.Super"); priorities.addPriorityList(priList); // create a CAS containing all these definitions ArrayList descList = new ArrayList(); descList.add(tsd1); descList.add(tsd2); descList.add(indexes); descList.add(priorities); CAS cas = CasCreationUtils.createCas(descList); // check that type system has been installed TypeSystem ts = cas.getTypeSystem(); Type supertypeHandle = ts.getType(supertype.getName()); assertNotNull(supertypeHandle); assertNotNull(supertypeHandle.getFeatureByBaseName("testfeat")); Type subtypeHandle = ts.getType(subtype.getName()); assertNotNull(subtypeHandle); assertNotNull(subtypeHandle.getFeatureByBaseName("testfeat")); Type fooTypeHandle = ts.getType(fooType.getName()); assertNotNull(fooTypeHandle); assertNotNull(fooTypeHandle.getFeatureByBaseName("bar")); // check that index exists assertNotNull(cas.getIndexRepository().getIndex("MyIndex")); // test that priorities work cas.createFS(supertypeHandle); cas.createFS(subtypeHandle); FSIterator iter = cas.getAnnotationIndex().iterator(); while (iter.isValid()) { if (iter.get().getType() == subtypeHandle) // expected break; if (iter.get().getType() == supertypeHandle) // unexpected fail(); iter.moveToNext(); } // test that passing an invalid object causes an error descList.add(new ConfigurationParameter_impl()); try { CasCreationUtils.createCas(descList); fail(); } catch (ResourceInitializationException e) { // expected } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testCreateCasTypeSystemDescription() throws Exception { try { //parse type system description TypeSystemDescription tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(JUnitExtension.getFile("CasCreationUtilsTest/SupertypeMergeTestMaster.xml"))); // call method CAS cas = CasCreationUtils.createCas(tsDesc, null, null); //check that imports were resolved and supertype merged properly Type subType = cas.getTypeSystem().getType("uima.test.Sub"); assertNotNull(subType); Type superType = cas.getTypeSystem().getType("uima.test.Super"); assertNotNull(superType); assertTrue(cas.getTypeSystem().subsumes(superType,subType)); } catch (Exception e) { JUnitExtension.handleException(e); } } public void testMergeDelegateAnalysisEngineMetaData() throws Exception { try { File descFile = JUnitExtension .getFile("TextAnalysisEngineImplTest/AggregateTaeForMergeTest.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(descFile)); Map mergedTypes = new HashMap(); ProcessingResourceMetaData mergedMetaData = CasCreationUtils .mergeDelegateAnalysisEngineMetaData(desc, UIMAFramework.newDefaultResourceManager(), mergedTypes, null); TypeSystemDescription typeSys = mergedMetaData.getTypeSystem(); TypePriorities pri = mergedMetaData.getTypePriorities(); FsIndexCollection indexColl = mergedMetaData.getFsIndexCollection(); // test results of merge // Type System Assert.assertEquals(8, typeSys.getTypes().length); TypeDescription type0 = typeSys.getType("NamedEntity"); Assert.assertNotNull(type0); Assert.assertEquals("uima.tcas.Annotation", type0.getSupertypeName()); Assert.assertEquals(1, type0.getFeatures().length); TypeDescription type1 = typeSys.getType("Person"); Assert.assertNotNull(type1); Assert.assertEquals("NamedEntity", type1.getSupertypeName()); Assert.assertEquals(1, type1.getFeatures().length); TypeDescription type2 = typeSys.getType("Place"); Assert.assertNotNull(type2); Assert.assertEquals("NamedEntity", type2.getSupertypeName()); Assert.assertEquals(3, type2.getFeatures().length); TypeDescription type3 = typeSys.getType("Org"); Assert.assertNotNull(type3); Assert.assertEquals("uima.tcas.Annotation", type3.getSupertypeName()); Assert.assertEquals(0, type3.getFeatures().length); TypeDescription type4 = typeSys.getType("DocumentStructure"); Assert.assertNotNull(type4); Assert.assertEquals("uima.tcas.Annotation", type4.getSupertypeName()); Assert.assertEquals(0, type4.getFeatures().length); TypeDescription type5 = typeSys.getType("Paragraph"); Assert.assertNotNull(type5); Assert.assertEquals("DocumentStructure", type5.getSupertypeName()); Assert.assertEquals(0, type5.getFeatures().length); TypeDescription type6 = typeSys.getType("Sentence"); Assert.assertNotNull(type6); Assert.assertEquals("DocumentStructure", type6.getSupertypeName()); Assert.assertEquals(0, type6.getFeatures().length); TypeDescription type7 = typeSys.getType("test.flowController.Test"); Assert.assertNotNull(type7); Assert.assertEquals("uima.tcas.Annotation", type7.getSupertypeName()); Assert.assertEquals(1, type7.getFeatures().length); // Place has merged features, Person has different supertype assertEquals(2, mergedTypes.size()); assertTrue(mergedTypes.containsKey("Place")); assertTrue(mergedTypes.containsKey("Person")); // Type Priorities Assert.assertNotNull(pri); TypePriorityList[] priLists = pri.getPriorityLists(); Assert.assertEquals(3, priLists.length); String[] list0 = priLists[0].getTypes(); String[] list1 = priLists[1].getTypes(); String[] list2 = priLists[2].getTypes(); // order of the three lists is not defined Assert.assertTrue((list0.length == 2 && list1.length == 2 && list2.length == 3) || (list0.length == 2 && list1.length == 3 && list2.length == 2) || (list0.length == 3 && list1.length == 2 && list2.length == 2)); // Indexes FsIndexDescription[] indexes = indexColl.getFsIndexes(); Assert.assertEquals(3, indexes.length); // order of indexes is not defined String label0 = indexes[0].getLabel(); String label1 = indexes[1].getLabel(); String label2 = indexes[2].getLabel(); Assert.assertTrue(label0.equals("DocStructIndex") || label1.equals("DocStructIndex") || label2.equals("DocStructIndex")); Assert.assertTrue(label0.equals("PlaceIndex") || label1.equals("PlaceIndex") || label2.equals("PlaceIndex")); Assert.assertTrue(label0.equals("FlowControllerTestIndex") || label1.equals("FlowControllerTestIndex") || label2.equals("FlowControllerTestIndex")); // Now test case where aggregate contains a remote, and we want to do the // merge of the non-remote delegates and report the failure. (This example // also happens to use import-by-name so we need to set the data path.) ResourceManager resMgr = UIMAFramework.newDefaultResourceManager(); String pathSep = System.getProperty("path.separator"); resMgr.setDataPath(JUnitExtension.getFile("TypeSystemDescriptionImplTest/dataPathDir") .getAbsolutePath() + pathSep + JUnitExtension.getFile("TypePrioritiesImplTest/dataPathDir").getAbsolutePath() + pathSep + JUnitExtension.getFile("FsIndexCollectionImplTest/dataPathDir").getAbsolutePath()); File descFile2 = JUnitExtension .getFile("CasCreationUtilsTest/AggregateTaeWithSoapDelegate.xml"); AnalysisEngineDescription desc2 = UIMAFramework.getXMLParser() .parseAnalysisEngineDescription(new XMLInputSource(descFile2)); Map mergedTypes2 = new HashMap(); Map failedRemotes = new HashMap(); ProcessingResourceMetaData mergedMetaData2 = CasCreationUtils .mergeDelegateAnalysisEngineMetaData(desc2, resMgr, mergedTypes2, failedRemotes); assertTrue(failedRemotes.containsKey("/RemoteDelegate")); ((Exception)failedRemotes.get("/RemoteDelegate")).printStackTrace(); assertTrue(mergedMetaData2.getTypeSystem().getTypes().length > 0); } catch (Exception e) { JUnitExtension.handleException(e); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/CasCopierTest.java0000644000175000017500000002343311665471066026554 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Iterator; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.ArrayFS; import org.apache.uima.cas.CAS; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.LowLevelCAS; import org.apache.uima.cas.impl.XCASDeserializer; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas_data.impl.CasComparer; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.TypePriorities_impl; import org.apache.uima.resource.metadata.impl.TypeSystemDescription_impl; import org.apache.uima.test.junit_extension.JUnitExtension; /** * */ public class CasCopierTest extends TestCase { private TypeSystemDescription typeSystem; private FsIndexDescription[] indexes; protected void setUp() throws Exception { File typeSystemFile1 = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile1)); indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) .getFsIndexes(); } public void testCopyCas() throws Exception { // create a source CAS by deserializing from XCAS CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension .getFile("ExampleCas/multiSofaCas.xml")); XCASDeserializer.deserialize(serCasStream, srcCas); serCasStream.close(); // create a destination CAS CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); // do the copy CasCopier.copyCas(srcCas, destCas, true); // XCASSerializer.serialize(destCas, System.out); // verify copy CasComparer.assertEquals(srcCas, destCas); // try with type systems are not identical (dest. a superset of src.) TypeSystemDescription additionalTypes = new TypeSystemDescription_impl(); TypeDescription fooType = additionalTypes.addType("test.Foo", "Test Type", "uima.tcas.Annotation"); fooType.addFeature("bar", "Test Feature", "uima.cas.String"); ArrayList destTypeSystems = new ArrayList(); destTypeSystems.add(additionalTypes); destTypeSystems.add(typeSystem); CAS destCas2 = CasCreationUtils.createCas(destTypeSystems); CasCopier.copyCas(srcCas, destCas2, true); CasComparer.assertEquals(srcCas, destCas); // try with base CAS rather than initial view CAS srcCasBase = ((CASImpl) srcCas).getBaseCAS(); destCas.reset(); CAS destCasBase = ((CASImpl) destCas).getBaseCAS(); CasCopier.copyCas(srcCasBase, destCasBase, true); CasComparer.assertEquals(srcCasBase, destCasBase); } public void testCopyCasWithDifferentTypeSystemObject() throws Exception { // create a source CAS by deserializing from XCAS CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension .getFile("ExampleCas/multiSofaCas.xml")); XCASDeserializer.deserialize(serCasStream, srcCas); serCasStream.close(); // create a destination CAS (do not share the same type system object) File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); File indexesFile = JUnitExtension.getFile("ExampleCas/testIndexes.xml"); TypeSystemDescription newTsDesc = typeSystem = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); FsIndexDescription[] newFsIndexes = indexes = UIMAFramework.getXMLParser().parseFsIndexCollection(new XMLInputSource(indexesFile)) .getFsIndexes(); CAS destCas = CasCreationUtils.createCas(newTsDesc, new TypePriorities_impl(), newFsIndexes); // do the copy CasCopier.copyCas(srcCas, destCas, true); // XCASSerializer.serialize(destCas, System.out); // verify copy CasComparer.assertEquals(srcCas, destCas); // try with type systems are not identical (dest. a superset of src.) TypeSystemDescription additionalTypes = new TypeSystemDescription_impl(); TypeDescription fooType = additionalTypes.addType("test.Foo", "Test Type", "uima.tcas.Annotation"); fooType.addFeature("bar", "Test Feature", "uima.cas.String"); ArrayList destTypeSystems = new ArrayList(); destTypeSystems.add(additionalTypes); destTypeSystems.add(typeSystem); CAS destCas2 = CasCreationUtils.createCas(destTypeSystems); CasCopier.copyCas(srcCas, destCas2, true); CasComparer.assertEquals(srcCas, destCas); // try with base CAS rather than initial view CAS srcCasBase = ((CASImpl) srcCas).getBaseCAS(); destCas.reset(); CAS destCasBase = ((CASImpl) destCas).getBaseCAS(); CasCopier.copyCas(srcCasBase, destCasBase, true); CasComparer.assertEquals(srcCasBase, destCasBase); } public void testCopyCasView() throws Exception { // create a source CAS by deserializing from XCAS CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer.deserialize(serCasStream, srcCas); serCasStream.close(); // create a destination CAS CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); // do the copy CasCopier copier = new CasCopier(srcCas, destCas); copier.copyCasView(srcCas, true); // verify copy CasComparer.assertEquals(srcCas, destCas); } public void testCopyFs() throws Exception { // create a source CAS by deserializing from XCAS CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); InputStream serCasStream = new FileInputStream(JUnitExtension.getFile("ExampleCas/cas.xml")); XCASDeserializer.deserialize(serCasStream, srcCas); serCasStream.close(); // create a destination CAS and the CasCopier instance CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CasCopier copier = new CasCopier(srcCas, destCas); // set sofa data in destination CAS (this is not copied automtically) destCas.setDocumentText(srcCas.getDocumentText()); // copy an Annotation Iterator annotIter = srcCas.getAnnotationIndex().iterator(); FeatureStructure annot = (FeatureStructure) annotIter.next(); FeatureStructure copy = copier.copyFs(annot); // verify copy CasComparer.assertEquals(annot, copy); // copy a Relation (which will have references) Iterator relationIter = srcCas.getIndexRepository().getIndex("testRelationIndex").iterator(); FeatureStructure relFS = (FeatureStructure) relationIter.next(); FeatureStructure relCopy = copier.copyFs(relFS); // verify copy CasComparer.assertEquals(relFS, relCopy); // test null array element ArrayFS arrFS = srcCas.createArrayFS(3); arrFS.set(0, annot); arrFS.set(1, null); arrFS.set(2, relFS); FeatureStructure copyArrFS = copier.copyFs(arrFS); CasComparer.assertEquals(arrFS, copyArrFS); } public void testAnnotationWithNullSofaRef() throws Exception { CAS srcCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); CAS srcCasView = srcCas.createView("TestView"); srcCasView.setDocumentText("This is a test"); CAS destCas = CasCreationUtils.createCas(typeSystem, new TypePriorities_impl(), indexes); LowLevelCAS lowLevelSrcCasView = srcCasView.getLowLevelCAS(); int typeCode = lowLevelSrcCasView.ll_getTypeSystem().ll_getCodeForType( srcCas.getAnnotationType()); int destFsAddr = lowLevelSrcCasView.ll_createFS(typeCode); AnnotationFS fs = (AnnotationFS) lowLevelSrcCasView.ll_getFSForRef(destFsAddr); fs.setIntValue(srcCas.getBeginFeature(), 0); fs.setIntValue(srcCas.getEndFeature(), 4); assertEquals("This", fs.getCoveredText()); srcCasView.addFsToIndexes(fs); CasCopier.copyCas(srcCas, destCas, true); CAS destCasView = destCas.getView("TestView"); Iterator annotIter = destCasView.getAnnotationIndex().iterator(); annotIter.next(); // document annotation AnnotationFS copiedFs = annotIter.next(); assertEquals("This", copiedFs.getCoveredText()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/XMLSerializerTest.java0000644000175000017500000000426111665471066027374 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.ByteArrayOutputStream; import javax.xml.transform.OutputKeys; import junit.framework.TestCase; import org.xml.sax.ContentHandler; import org.xml.sax.helpers.AttributesImpl; public class XMLSerializerTest extends TestCase { public void testXml10() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMLSerializer sax2xml = new XMLSerializer(baos, false); ContentHandler ch = sax2xml.getContentHandler(); ch.startDocument(); ch.startElement("","foo","foo", new AttributesImpl()); ch.endElement("", "foo", "foo"); ch.endDocument(); String xmlStr = new String(baos.toByteArray(), "UTF-8"); assertEquals("", xmlStr); } public void testXml11() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); XMLSerializer sax2xml = new XMLSerializer(baos, false); sax2xml.setOutputProperty(OutputKeys.VERSION, "1.1"); ContentHandler ch = sax2xml.getContentHandler(); ch.startDocument(); ch.startElement("","foo","foo", new AttributesImpl()); ch.endElement("", "foo", "foo"); ch.endDocument(); String xmlStr = new String(baos.toByteArray(), "UTF-8"); assertEquals("", xmlStr); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/LevelTest.java0000644000175000017500000003722311665471066025755 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import junit.framework.Assert; import junit.framework.TestCase; /** * class Level provides the message level constants for logging and tracing * */ public class LevelTest extends TestCase { public LevelTest(String arg0) { super(arg0); } public void testLevelOff() throws Exception { Level level = Level.OFF; // check if level is on Assert.assertFalse(level.isOn()); // check if level is equal to "OFF" Assert.assertTrue(level.equals(Level.OFF)); // check if level is not equal to "FINE" Assert.assertFalse(level.equals(Level.FINE)); // check if level text is "OFF" Assert.assertEquals(level.toString(), "OFF"); // check if level value is Integer.MAX_VALUE Assert.assertEquals(level.toInteger(), Integer.MAX_VALUE); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertFalse(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertFalse(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertFalse(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertFalse(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertFalse(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelALL() throws Exception { Level level = Level.ALL; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "ALL" Assert.assertTrue(level.equals(Level.ALL)); // check if level is not equal to "CONFIG" Assert.assertFalse(level.equals(Level.CONFIG)); // check if level text is "ALL" Assert.assertEquals(level.toString(), "ALL"); // check if level value is Integer.MIN_VALUE Assert.assertEquals(level.toInteger(), Integer.MIN_VALUE); // check if level is greater or equal to ALL Assert.assertTrue(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertTrue(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertTrue(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertTrue(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertTrue(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelFINEST() throws Exception { Level level = Level.FINEST; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "FINEST" Assert.assertTrue(level.equals(Level.FINEST)); // check if level is not equal to "WARNING" Assert.assertFalse(level.equals(Level.WARNING)); // check if level text is "FINEST" Assert.assertEquals(level.toString(), "FINEST"); // check if level value is 10000 Assert.assertEquals(level.toInteger(), 10000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertTrue(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertTrue(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertTrue(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertTrue(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelFINER() throws Exception { Level level = Level.FINER; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "FINER" Assert.assertTrue(level.equals(Level.FINER)); // check if level is not equal to "WARNING" Assert.assertFalse(level.equals(Level.WARNING)); // check if level text is "FINER" Assert.assertEquals(level.toString(), "FINER"); // check if level value is 20000 Assert.assertEquals(level.toInteger(), 20000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertTrue(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertTrue(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertTrue(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelFINE() throws Exception { Level level = Level.FINE; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "FINE" Assert.assertTrue(level.equals(Level.FINE)); // check if level is not equal to "WARNING" Assert.assertFalse(level.equals(Level.WARNING)); // check if level text is "FINE" Assert.assertEquals(level.toString(), "FINE"); // check if level value is 30000 Assert.assertEquals(level.toInteger(), 30000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertTrue(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertTrue(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelCONFIG() throws Exception { Level level = Level.CONFIG; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "CONFIG" Assert.assertTrue(level.equals(Level.CONFIG)); // check if level is not equal to "WARNING" Assert.assertFalse(level.equals(Level.WARNING)); // check if level text is "CONFIG" Assert.assertEquals(level.toString(), "CONFIG"); // check if level value is 40000 Assert.assertEquals(level.toInteger(), 40000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertFalse(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertTrue(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelINFO() throws Exception { Level level = Level.INFO; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "INFO" Assert.assertTrue(level.equals(Level.INFO)); // check if level is not equal to "WARNING" Assert.assertFalse(level.equals(Level.WARNING)); // check if level text is "INFO" Assert.assertEquals(level.toString(), "INFO"); // check if level value is 50000 Assert.assertEquals(level.toInteger(), 50000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertFalse(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertFalse(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertTrue(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelWARNING() throws Exception { Level level = Level.WARNING; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "WARNING" Assert.assertTrue(level.equals(Level.WARNING)); // check if level is not equal to "OFF" Assert.assertFalse(level.equals(Level.OFF)); // check if level text is "WARNING" Assert.assertEquals(level.toString(), "WARNING"); // check if level value is 60000 Assert.assertEquals(level.toInteger(), 60000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertFalse(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertFalse(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertFalse(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertTrue(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testLevelSEVERE() throws Exception { Level level = Level.SEVERE; // check if level is on Assert.assertTrue(level.isOn()); // check if level is equal to "SEVERE" Assert.assertTrue(level.equals(Level.SEVERE)); // check if level is not equal to "OFF" Assert.assertFalse(level.equals(Level.OFF)); // check if level text is "SEVERE" Assert.assertEquals(level.toString(), "SEVERE"); // check if level value is 70000 Assert.assertEquals(level.toInteger(), 70000); // check if level is greater or equal to ALL Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level is greater or equal to FINEST Assert.assertFalse(level.isGreaterOrEqual(Level.FINEST)); // check if level is greater or equal to FINER Assert.assertFalse(level.isGreaterOrEqual(Level.FINER)); // check if level is greater or equal to FINE Assert.assertFalse(level.isGreaterOrEqual(Level.FINE)); // check if level is greater or equal to CONFIG Assert.assertFalse(level.isGreaterOrEqual(Level.CONFIG)); // check if level is greater or equal to INFO Assert.assertFalse(level.isGreaterOrEqual(Level.INFO)); // check if level is greater or equal to WARNING Assert.assertFalse(level.isGreaterOrEqual(Level.WARNING)); // check if level is greater or equal to SEVERE Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check if level is greater or equal to OFF Assert.assertTrue(level.isGreaterOrEqual(Level.OFF)); } public void testEquals() throws Exception { Level level = Level.SEVERE; Integer myInt = Integer.valueOf(70000); // check if level is equal to "SEVERE" Assert.assertTrue(level.equals(Level.SEVERE)); // check with another class than Level Assert.assertFalse(level.equals(myInt)); // check with null value Assert.assertFalse(level.equals(null)); } public void testisGreaterOrEqual() throws Exception { Level level = Level.INFO; // check if level "ALL" is greater or equal to "INFO" Assert.assertFalse(level.isGreaterOrEqual(Level.ALL)); // check if level "SEVERE" is greater or equal to "INFO" Assert.assertTrue(level.isGreaterOrEqual(Level.SEVERE)); // check with null value Assert.assertFalse(level.isGreaterOrEqual(null)); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/TypeSystemUtilTest.java0000644000175000017500000000452411665471066027670 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.File; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.test.junit_extension.JUnitExtension; import junit.framework.TestCase; public class TypeSystemUtilTest extends TestCase { public void testTypeSystem2TypeSystemDescription() throws Exception { //create a CAS with example type system File typeSystemFile = JUnitExtension.getFile("ExampleCas/testTypeSystem.xml"); TypeSystemDescription tsDesc = UIMAFramework.getXMLParser().parseTypeSystemDescription( new XMLInputSource(typeSystemFile)); //add an example type to test FSArrays with and without elementTypes TypeDescription type = tsDesc.addType("example.TestType", "", "uima.tcas.Annotation"); type.addFeature("testFeat", "", "uima.cas.FSArray","uima.tcas.Annotation", null); TypeDescription type2 = tsDesc.addType("example.TestType2", "", "uima.tcas.Annotation"); type2.addFeature("testFeat", "", "uima.cas.FSArray"); CAS cas = CasCreationUtils.createCas(tsDesc, null, null); //convert that CAS's type system back to a TypeSystemDescription TypeSystemDescription tsDesc2 = TypeSystemUtil.typeSystem2TypeSystemDescription(cas.getTypeSystem()); tsDesc2.toXML(System.out); //test that this is valid by creating a new CAS CasCreationUtils.createCas(tsDesc2, null, null); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/0000755000175000017500000000000011665471066024135 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/Logger_implTest.java0000644000175000017500000001245411665471066030106 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.util.Level; /** * UIMA Logging interface implementation test without using an logging toolkit * */ public class Logger_implTest extends TestCase { public Logger_implTest(String arg0) { super(arg0); } public void testLogWrapperCreation() throws Exception { org.apache.uima.util.Logger rootLogger = Logger_impl.getInstance(); org.apache.uima.util.Logger rootLogger1 = Logger_impl.getInstance(); org.apache.uima.util.Logger classLogger = Logger_impl.getInstance(this.getClass()); org.apache.uima.util.Logger classLogger1 = Logger_impl.getInstance(this.getClass()); rootLogger.setLevel(Level.INFO); // check default configuration Assert.assertNotNull(rootLogger); Assert.assertNotNull(classLogger); Assert.assertTrue(rootLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.INFO)); // check getInstance() calls Assert.assertNotSame(classLogger, rootLogger); Assert.assertEquals(rootLogger, rootLogger1); Assert.assertNotSame(classLogger, classLogger1); } public void testMessageLeveling() throws Exception { // create logger org.apache.uima.util.Logger rootLogger = Logger_impl.getInstance(); org.apache.uima.util.Logger classLogger = Logger_impl.getInstance(this.getClass()); rootLogger.setLevel(Level.INFO); // check message leveling root logger Assert.assertFalse(rootLogger.isLoggable(Level.ALL)); Assert.assertFalse(rootLogger.isLoggable(Level.FINEST)); Assert.assertFalse(rootLogger.isLoggable(Level.FINER)); Assert.assertFalse(rootLogger.isLoggable(Level.FINE)); Assert.assertFalse(rootLogger.isLoggable(Level.CONFIG)); Assert.assertTrue(rootLogger.isLoggable(Level.INFO)); Assert.assertTrue(rootLogger.isLoggable(Level.WARNING)); Assert.assertTrue(rootLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(rootLogger.isLoggable(Level.OFF)); // check message leveling class logger Assert.assertFalse(rootLogger.isLoggable(Level.ALL)); Assert.assertFalse(rootLogger.isLoggable(Level.FINEST)); Assert.assertFalse(rootLogger.isLoggable(Level.FINER)); Assert.assertFalse(rootLogger.isLoggable(Level.FINE)); Assert.assertFalse(rootLogger.isLoggable(Level.CONFIG)); Assert.assertTrue(rootLogger.isLoggable(Level.INFO)); Assert.assertTrue(rootLogger.isLoggable(Level.WARNING)); Assert.assertTrue(rootLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(rootLogger.isLoggable(Level.OFF)); // reset class logger level to OFF classLogger.setLevel(Level.OFF); Assert.assertFalse(classLogger.isLoggable(Level.ALL)); Assert.assertFalse(classLogger.isLoggable(Level.FINEST)); Assert.assertFalse(classLogger.isLoggable(Level.FINER)); Assert.assertFalse(classLogger.isLoggable(Level.FINE)); Assert.assertFalse(classLogger.isLoggable(Level.CONFIG)); Assert.assertFalse(classLogger.isLoggable(Level.INFO)); Assert.assertFalse(classLogger.isLoggable(Level.WARNING)); Assert.assertFalse(classLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(classLogger.isLoggable(Level.OFF)); // reset class logger level to ALL classLogger.setLevel(Level.ALL); Assert.assertTrue(classLogger.isLoggable(Level.ALL)); Assert.assertTrue(classLogger.isLoggable(Level.FINEST)); Assert.assertTrue(classLogger.isLoggable(Level.FINER)); Assert.assertTrue(classLogger.isLoggable(Level.FINE)); Assert.assertTrue(classLogger.isLoggable(Level.CONFIG)); Assert.assertTrue(classLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.WARNING)); Assert.assertTrue(classLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(classLogger.isLoggable(Level.OFF)); // reset class logger level to WARNING classLogger.setLevel(Level.WARNING); Assert.assertFalse(classLogger.isLoggable(Level.ALL)); Assert.assertFalse(classLogger.isLoggable(Level.FINEST)); Assert.assertFalse(classLogger.isLoggable(Level.FINER)); Assert.assertFalse(classLogger.isLoggable(Level.FINE)); Assert.assertFalse(classLogger.isLoggable(Level.CONFIG)); Assert.assertFalse(classLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.WARNING)); Assert.assertTrue(classLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(classLogger.isLoggable(Level.OFF)); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/LoggingTest.java0000644000175000017500000001011511665471066027224 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.Level; import org.apache.uima.util.Logger; /** * Logger implementation test * */ public class LoggingTest extends TestCase { /** * Constructor for SequencerTest * * @param arg0 */ public LoggingTest(String arg0) { super(arg0); } public void testDefaultLoggerCreation() throws Exception { try { // get default logger Logger logger = UIMAFramework.getLogger(); Assert.assertNotNull(logger); // create another logger Logger logger1 = UIMAFramework.getLogger(); // both loggers must reference the same instance Assert.assertEquals(logger, logger1); // test base logging functions logger.log(Level.SEVERE, "Log test messege with Level SEVERE"); } catch (Exception ex) { JUnitExtension.handleException(ex); } } public void testClassLoggerCreation() throws Exception { try { // get class logger Logger logger = UIMAFramework.getLogger(this.getClass()); Assert.assertNotNull(logger); // create another class logger Logger logger1 = UIMAFramework.getLogger(this.getClass()); // create default logger Logger defaultLogger = UIMAFramework.getLogger(); // both loggers must reference the same instance Assert.assertEquals(logger, logger1); // should not be the same Assert.assertNotSame(defaultLogger, logger1); // test base logging functions logger.log(Level.SEVERE, "Log test messege with Level SEVERE"); } catch (Exception ex) { JUnitExtension.handleException(ex); } } public void testSetLevel() throws Exception { try { // get class logger Logger logger = UIMAFramework.getLogger(this.getClass()); Logger uimaLogger = UIMAFramework.getLogger(); // should affect everything in // org.apache.uima.* // set level to WARNING uimaLogger.setLevel(Level.WARNING); Assert.assertTrue(uimaLogger.isLoggable(Level.WARNING)); Assert.assertTrue(uimaLogger.isLoggable(Level.SEVERE)); Assert.assertFalse(uimaLogger.isLoggable(Level.INFO)); Assert.assertTrue(logger.isLoggable(Level.WARNING)); Assert.assertTrue(logger.isLoggable(Level.SEVERE)); Assert.assertFalse(logger.isLoggable(Level.INFO)); // set level to FINE uimaLogger.setLevel(Level.FINE); Assert.assertTrue(uimaLogger.isLoggable(Level.WARNING)); Assert.assertTrue(uimaLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(uimaLogger.isLoggable(Level.INFO)); Assert.assertFalse(uimaLogger.isLoggable(Level.FINER)); Assert.assertFalse(uimaLogger.isLoggable(Level.ALL)); Assert.assertTrue(logger.isLoggable(Level.WARNING)); Assert.assertTrue(logger.isLoggable(Level.SEVERE)); Assert.assertTrue(logger.isLoggable(Level.INFO)); Assert.assertFalse(logger.isLoggable(Level.FINER)); Assert.assertFalse(logger.isLoggable(Level.ALL)); } catch (Exception ex) { JUnitExtension.handleException(ex); } } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/JSR47Logger_implTest.java0000644000175000017500000003065411665471066030642 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import java.util.HashMap; import java.util.logging.Logger; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.util.Level; /** * UIMA Logging Test * */ public class JSR47Logger_implTest extends TestCase { private static HashMap logLevels = new HashMap(9); static { logLevels.put("OFF", Level.OFF); logLevels.put("SEVERE", Level.SEVERE); logLevels.put("WARNING", Level.WARNING); logLevels.put("INFO", Level.INFO); logLevels.put("CONFIG", Level.CONFIG); logLevels.put("FINE", Level.FINE); logLevels.put("FINER", Level.FINER); logLevels.put("FINEST", Level.FINEST); logLevels.put("ALL", Level.ALL); } public JSR47Logger_implTest(String arg0) { super(arg0); } public void testLogWrapperCreation() throws Exception { org.apache.uima.util.Logger uimaLogger = JSR47Logger_impl.getInstance(); org.apache.uima.util.Logger classLogger = JSR47Logger_impl.getInstance(this.getClass()); // check base configuration Assert.assertNotNull(uimaLogger); Assert.assertNotNull(classLogger); Assert.assertTrue(uimaLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.INFO)); } public void testIsLoggable() throws Exception { // create logger org.apache.uima.util.Logger uimaLogger = JSR47Logger_impl.getInstance(); org.apache.uima.util.Logger classLogger = JSR47Logger_impl.getInstance(this.getClass()); //get uimaLogger log level, get parent logger of "org.apache.uima" until we have the //JSR47 root logger that defines the default log level Logger jsrLogger = java.util.logging.Logger.getLogger("org.apache.uima"); while(jsrLogger.getLevel() == null) { jsrLogger = jsrLogger.getParent(); } Level defaultLogLevel = logLevels.get(jsrLogger.getLevel().toString()); // check message logging for root logger based on default log level Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.ALL), uimaLogger .isLoggable(Level.ALL)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINEST), uimaLogger .isLoggable(Level.FINEST)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINER), uimaLogger .isLoggable(Level.FINER)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINE), uimaLogger .isLoggable(Level.FINE)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.CONFIG), uimaLogger .isLoggable(Level.CONFIG)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.INFO), uimaLogger .isLoggable(Level.INFO)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.WARNING), uimaLogger .isLoggable(Level.WARNING)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.SEVERE), uimaLogger .isLoggable(Level.SEVERE)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.OFF), uimaLogger .isLoggable(Level.OFF)); // check message logging for class logger based on default log level Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.ALL), classLogger .isLoggable(Level.ALL)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINEST), classLogger .isLoggable(Level.FINEST)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINER), classLogger .isLoggable(Level.FINER)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINE), classLogger .isLoggable(Level.FINE)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.CONFIG), classLogger .isLoggable(Level.CONFIG)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.INFO), classLogger .isLoggable(Level.INFO)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.WARNING), classLogger .isLoggable(Level.WARNING)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.SEVERE), classLogger .isLoggable(Level.SEVERE)); Assert.assertEquals(defaultLogLevel.isGreaterOrEqual(Level.OFF), classLogger .isLoggable(Level.OFF)); // reset class logger level to OFF // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.OFF); classLogger.setLevel(Level.OFF); Assert.assertFalse(classLogger.isLoggable(Level.ALL)); Assert.assertFalse(classLogger.isLoggable(Level.FINEST)); Assert.assertFalse(classLogger.isLoggable(Level.FINER)); Assert.assertFalse(classLogger.isLoggable(Level.FINE)); Assert.assertFalse(classLogger.isLoggable(Level.CONFIG)); Assert.assertFalse(classLogger.isLoggable(Level.INFO)); Assert.assertFalse(classLogger.isLoggable(Level.WARNING)); Assert.assertFalse(classLogger.isLoggable(Level.SEVERE)); Assert.assertFalse(classLogger.isLoggable(Level.OFF)); // reset class logger level to ALL // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.ALL); classLogger.setLevel(Level.ALL); Assert.assertTrue(classLogger.isLoggable(Level.ALL)); Assert.assertTrue(classLogger.isLoggable(Level.FINEST)); Assert.assertTrue(classLogger.isLoggable(Level.FINER)); Assert.assertTrue(classLogger.isLoggable(Level.FINE)); Assert.assertTrue(classLogger.isLoggable(Level.CONFIG)); Assert.assertTrue(classLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.WARNING)); Assert.assertTrue(classLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(classLogger.isLoggable(Level.OFF)); // reset class logger level to WARNING // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.WARNING); classLogger.setLevel(Level.WARNING); Assert.assertFalse(classLogger.isLoggable(Level.ALL)); Assert.assertFalse(classLogger.isLoggable(Level.FINEST)); Assert.assertFalse(classLogger.isLoggable(Level.FINER)); Assert.assertFalse(classLogger.isLoggable(Level.FINE)); Assert.assertFalse(classLogger.isLoggable(Level.CONFIG)); Assert.assertFalse(classLogger.isLoggable(Level.INFO)); Assert.assertTrue(classLogger.isLoggable(Level.WARNING)); Assert.assertTrue(classLogger.isLoggable(Level.SEVERE)); Assert.assertTrue(classLogger.isLoggable(Level.OFF)); // reset log level to default log level classLogger.setLevel(defaultLogLevel); } public void testMessageLogMethods() throws Exception { // create Logger org.apache.uima.util.Logger logger = JSR47Logger_impl.getInstance(); // reset log level to INFO logger.setLevel(Level.INFO); // File file = File.createTempFile("LoggingTest","log"); // file.deleteOnExit(); // change output temporary file // logger.setOutputStream(new PrintStream(new FileOutputStream(file))); // log test with method log(Level,String) logger.log(Level.INFO, "My first test message"); logger.log(Level.INFO, ""); logger.log(Level.INFO, null); // log test with method log(Level,String,Object) Object obj = null; logger.log(Level.INFO, "My {0} test message", "second"); logger.log(Level.INFO, "My {0} test message", new Object()); logger.log(Level.INFO, "My {0} test message", ""); logger.log(Level.INFO, "My {0} test message", obj); logger.log(Level.INFO, "", ""); logger.log(Level.INFO, null, ""); // log test with method log(Level,String,Object[]) logger.log(Level.INFO, "My {0} test message", new Object[] { "third" }); logger.log(Level.INFO, "My {0} test message", new Object[] {}); logger.log(Level.INFO, "", new Object[] { "" }); logger.log(Level.INFO, "", new Object[] { null }); logger.log(Level.INFO, "My {0} test message", new Object[] { "" }); logger.log(Level.INFO, "My {0} test message", new Object[] { null }); logger.log(Level.INFO, null, ""); // log test with method log(Level,String,Throwable) Throwable thrown = new Throwable(); logger.log(Level.INFO, "My fourth test message", thrown); logger.log(Level.INFO, "", thrown); logger.log(Level.INFO, null, thrown); thrown = null; logger.log(Level.INFO, "My fourth test message", thrown); // test deprecated log method logger.log("My fifth test message"); logger.log(""); logger.log(null); // test deprecated logException method Exception ex = new Exception("My sixth test message"); logger.logException(ex); logger.logException(null); } public void testMessageKeyLogMethods() throws Exception { // create Logger org.apache.uima.util.Logger logger = JSR47Logger_impl.getInstance(); // reset log level to INFO logger.setLevel(Level.INFO); // File file = File.createTempFile("LoggingTest","log"); // file.deleteOnExit(); // change output temporary file // logger.setOutputStream(new PrintStream(new FileOutputStream(file))); // test deprecated log(String, String, Object[]) String msgKey = "UIMA_logger_test"; String bundle = "org.apache.uima.util.impl.logger_test_messages"; logger.log(bundle, msgKey, new Object[] { "message key test" }); logger.log(bundle, null, new Object[] { "message key test" }); logger.log(bundle, msgKey, new Object[] { "" }); logger.log(bundle, msgKey, new Object[] { null }); // test method logrb(Level, String, String, String, String) logger.logrb(Level.INFO, null, null, bundle, msgKey); logger.logrb(Level.INFO, null, null, bundle, null); logger.logrb(Level.INFO, null, null, null, msgKey); logger.logrb(Level.INFO, null, null, null, null); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey); logger.logrb(Level.INFO, "testClass", "testMethod", null, null); // test method logrb(Level, String, String, String, String, Object) Object obj = null; logger.logrb(Level.INFO, null, null, bundle, msgKey, new Object()); logger.logrb(Level.INFO, null, null, bundle, msgKey, "message key test"); logger.logrb(Level.INFO, null, null, bundle, null, "message key test"); logger.logrb(Level.INFO, null, null, null, msgKey, ""); logger.logrb(Level.INFO, null, null, null, null, ""); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, obj); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, obj); // test method logrb(Level, String, String, String, String, Object[]) Object[] objects = null; logger.logrb(Level.INFO, null, null, bundle, msgKey, new Object[] {}); logger.logrb(Level.INFO, null, null, bundle, null, new Object[] { "message key test" }); logger.logrb(Level.INFO, null, null, null, msgKey, new Object[] { "" }); logger.logrb(Level.INFO, null, null, null, null, new Object[] { "" }); logger.logrb(Level.INFO, null, null, null, null, new Object[] { null }); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, objects); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, objects); // test method logrb(Level, String, String, String, String, thrown) Throwable thrown = new Throwable(); logger.logrb(Level.INFO, null, null, bundle, msgKey, thrown); logger.logrb(Level.INFO, null, null, bundle, null, thrown); logger.logrb(Level.INFO, null, null, null, msgKey, thrown); logger.logrb(Level.INFO, null, null, null, null, thrown); thrown = null; logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, thrown); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, thrown); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/TestLog4jLogger_impl.java0000644000175000017500000003273611665471066031013 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import java.util.HashMap; import junit.framework.TestCase; import org.apache.log4j.BasicConfigurator; import org.apache.log4j.Logger; import org.apache.uima.UIMAFramework; import org.apache.uima.util.Level; /** * UIMA Logging Test */ public class TestLog4jLogger_impl extends TestCase { public void setUp() throws Exception { BasicConfigurator.configure(); } public void tearDown() throws Exception { BasicConfigurator.resetConfiguration(); } private static HashMap logLevels = new HashMap( 9); static { logLevels.put("OFF", Level.OFF); logLevels.put("ERROR", Level.SEVERE); logLevels.put("WARN", Level.WARNING); logLevels.put("INFO", Level.INFO); logLevels.put("INFO", Level.CONFIG); logLevels.put("DEBUG", Level.FINE); logLevels.put("ALL", Level.FINER); logLevels.put("ALL", Level.FINEST); logLevels.put("ALL", Level.ALL); } public void testLogWrapperCreation() throws Exception { org.apache.uima.util.Logger uimaLogger = Log4jLogger_impl.getInstance(); org.apache.uima.util.Logger classLogger = Log4jLogger_impl .getInstance(this.getClass()); // check base configuration assertNotNull(uimaLogger); assertNotNull(classLogger); assertTrue(uimaLogger.isLoggable(Level.INFO)); assertTrue(classLogger.isLoggable(Level.INFO)); classLogger.log("ola"); classLogger.log(Level.INFO, "OLA in info"); uimaLogger.log(Level.INFO, "UIMA OLA in info"); } public void testIsLoggable() throws Exception { // create logger org.apache.uima.util.Logger uimaLogger = Log4jLogger_impl.getInstance(); org.apache.uima.util.Logger classLogger = Log4jLogger_impl .getInstance(this.getClass()); assertNotNull(uimaLogger); assertNotNull(classLogger); Logger log4jLogger = org.apache.log4j.Logger.getLogger("org.apache.uima"); while (log4jLogger.getLevel() == null) { log4jLogger = Logger.getRootLogger(); } String key = log4jLogger.getLevel().toString(); Level defaultLogLevel = (Level) logLevels.get(key); assertNotNull(defaultLogLevel); // check message logging for root logger based on default log level assertEquals(defaultLogLevel.isGreaterOrEqual(Level.ALL), uimaLogger .isLoggable(Level.ALL)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINEST), uimaLogger .isLoggable(Level.FINEST)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINER), uimaLogger .isLoggable(Level.FINER)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINE), uimaLogger .isLoggable(Level.FINE)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.CONFIG), uimaLogger .isLoggable(Level.CONFIG)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.INFO), uimaLogger .isLoggable(Level.INFO)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.WARNING), uimaLogger .isLoggable(Level.WARNING)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.SEVERE), uimaLogger .isLoggable(Level.SEVERE)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.OFF), uimaLogger .isLoggable(Level.OFF)); // check message logging for class logger based on default log level assertEquals(defaultLogLevel.isGreaterOrEqual(Level.ALL), classLogger .isLoggable(Level.ALL)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINEST), classLogger .isLoggable(Level.FINEST)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINER), classLogger .isLoggable(Level.FINER)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.FINE), classLogger .isLoggable(Level.FINE)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.CONFIG), classLogger .isLoggable(Level.CONFIG)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.INFO), classLogger .isLoggable(Level.INFO)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.WARNING), classLogger .isLoggable(Level.WARNING)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.SEVERE), classLogger .isLoggable(Level.SEVERE)); assertEquals(defaultLogLevel.isGreaterOrEqual(Level.OFF), classLogger .isLoggable(Level.OFF)); // reset class logger level to OFF // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.OFF); classLogger.setLevel(Level.OFF); assertFalse(classLogger.isLoggable(Level.ALL)); assertFalse(classLogger.isLoggable(Level.FINEST)); assertFalse(classLogger.isLoggable(Level.FINER)); assertFalse(classLogger.isLoggable(Level.FINE)); assertFalse(classLogger.isLoggable(Level.CONFIG)); assertFalse(classLogger.isLoggable(Level.INFO)); assertFalse(classLogger.isLoggable(Level.WARNING)); assertFalse(classLogger.isLoggable(Level.SEVERE)); assertTrue(classLogger.isLoggable(Level.OFF)); // reset class logger level to ALL // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.ALL); classLogger.setLevel(Level.ALL); assertTrue(classLogger.isLoggable(Level.ALL)); assertTrue(classLogger.isLoggable(Level.FINEST)); assertTrue(classLogger.isLoggable(Level.FINER)); assertTrue(classLogger.isLoggable(Level.FINE)); assertTrue(classLogger.isLoggable(Level.CONFIG)); assertTrue(classLogger.isLoggable(Level.INFO)); assertTrue(classLogger.isLoggable(Level.WARNING)); assertTrue(classLogger.isLoggable(Level.SEVERE)); assertTrue(classLogger.isLoggable(Level.OFF)); // reset class logger level to WARNING // Logger.getLogger(this.getClass().getName()).setLevel(java.util.logging.Level.WARNING); classLogger.setLevel(Level.WARNING); assertFalse(classLogger.isLoggable(Level.ALL)); assertFalse(classLogger.isLoggable(Level.FINEST)); assertFalse(classLogger.isLoggable(Level.FINER)); assertFalse(classLogger.isLoggable(Level.FINE)); assertFalse(classLogger.isLoggable(Level.CONFIG)); assertFalse(classLogger.isLoggable(Level.INFO)); assertTrue(classLogger.isLoggable(Level.WARNING)); assertTrue(classLogger.isLoggable(Level.SEVERE)); assertTrue(classLogger.isLoggable(Level.OFF)); // reset log level to default log level classLogger.setLevel(defaultLogLevel); } public void testMessageLogMethods() throws Exception { // create Logger org.apache.uima.util.Logger logger = Log4jLogger_impl.getInstance(); // reset log level to INFO logger.setLevel(Level.INFO); // File file = File.createTempFile("LoggingTest","log"); // file.deleteOnExit(); // change output temporary file // logger.setOutputStream(new PrintStream(new FileOutputStream(file))); // log test with method log(Level,String) logger.log(Level.INFO, "My first test message"); logger.log(Level.INFO, ""); logger.log(Level.INFO, null); // log test with method log(Level,String,Object) Object obj = null; logger.log(Level.INFO, "My {0} test message", "second"); logger.log(Level.INFO, "My {0} test message", new Object()); logger.log(Level.INFO, "My {0} test message", ""); logger.log(Level.INFO, "My {0} test message", obj); logger.log(Level.INFO, "", ""); logger.log(Level.INFO, null, ""); // log test with method log(Level,String,Object[]) logger.log(Level.INFO, "My {0} test message", new Object[] { "third" }); logger.log(Level.INFO, "My {0} test message", new Object[] {}); logger.log(Level.INFO, "", new Object[] { "" }); logger.log(Level.INFO, "", new Object[] { null }); logger.log(Level.INFO, "My {0} test message", new Object[] { "" }); logger.log(Level.INFO, "My {0} test message", new Object[] { null }); logger.log(Level.INFO, null, ""); // log test with method log(Level,String,Throwable) Throwable thrown = new Throwable(); logger.log(Level.INFO, "My fourth test message", thrown); logger.log(Level.INFO, "", thrown); logger.log(Level.INFO, null, thrown); thrown = null; logger.log(Level.INFO, "My fourth test message", thrown); // test deprecated log method logger.log("My fifth test message"); logger.log(""); logger.log(null); // test deprecated logException method Exception ex = new Exception("My sixth test message"); logger.logException(ex); logger.logException(null); } public void testMessageKeyLogMethods() throws Exception { // create Logger org.apache.uima.util.Logger logger = Log4jLogger_impl.getInstance(); // reset log level to INFO logger.setLevel(Level.INFO); // File file = File.createTempFile("LoggingTest","log"); // file.deleteOnExit(); // change output temporary file // logger.setOutputStream(new PrintStream(new FileOutputStream(file))); // test deprecated log(String, String, Object[]) String msgKey = "UIMA_logger_test"; String bundle = "org.apache.uima.util.impl.logger_test_messages"; logger.log(bundle, msgKey, new Object[] { "message key test" }); logger.log(bundle, null, new Object[] { "message key test" }); logger.log(bundle, msgKey, new Object[] { "" }); logger.log(bundle, msgKey, new Object[] { null }); // test method logrb(Level, String, String, String, String) logger.logrb(Level.INFO, null, null, bundle, msgKey); logger.logrb(Level.INFO, null, null, bundle, null); logger.logrb(Level.INFO, null, null, null, msgKey); logger.logrb(Level.INFO, null, null, null, null); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey); logger.logrb(Level.INFO, "testClass", "testMethod", null, null); // test method logrb(Level, String, String, String, String, Object) Object obj = null; logger.logrb(Level.INFO, null, null, bundle, msgKey, new Object()); logger.logrb(Level.INFO, null, null, bundle, msgKey, "message key test"); logger.logrb(Level.INFO, null, null, bundle, null, "message key test"); logger.logrb(Level.INFO, null, null, null, msgKey, ""); logger.logrb(Level.INFO, null, null, null, null, ""); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, obj); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, obj); // test method logrb(Level, String, String, String, String, Object[]) Object[] objects = null; logger.logrb(Level.INFO, null, null, bundle, msgKey, new Object[] {}); logger.logrb(Level.INFO, null, null, bundle, null, new Object[] { "message key test" }); logger.logrb(Level.INFO, null, null, null, msgKey, new Object[] { "" }); logger.logrb(Level.INFO, null, null, null, null, new Object[] { "" }); logger.logrb(Level.INFO, null, null, null, null, new Object[] { null }); logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, objects); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, objects); // test method logrb(Level, String, String, String, String, thrown) Throwable thrown = new Throwable(); logger.logrb(Level.INFO, null, null, bundle, msgKey, thrown); logger.logrb(Level.INFO, null, null, bundle, null, thrown); logger.logrb(Level.INFO, null, null, null, msgKey, thrown); logger.logrb(Level.INFO, null, null, null, null, thrown); thrown = null; logger.logrb(Level.INFO, "testClass", "testMethod", bundle, msgKey, thrown); logger.logrb(Level.INFO, "testClass", "testMethod", null, null, thrown); } public void testLoggerFromUIMAFramework() { org.apache.uima.util.Logger logger = UIMAFramework.getLogger(this .getClass()); logger.setLevel(Level.INFO); // File file = File.createTempFile("LoggingTest","log"); // file.deleteOnExit(); // change output temporary file // logger.setOutputStream(new PrintStream(new FileOutputStream(file))); // log test with method log(Level,String) logger.log(Level.INFO, "------------------------------------------------------------"); logger.log(Level.INFO, "My first test message"); logger.log(Level.INFO, ""); logger.log(Level.INFO, null); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/ProcessTrace_implTest.java0000644000175000017500000002230511665471066031260 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import java.util.List; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.util.ProcessTrace; import org.apache.uima.util.ProcessTraceEvent; public class ProcessTrace_implTest extends TestCase { /** * Constructor for ProcessTrace_implTest. * * @param arg0 */ public ProcessTrace_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } public void testStartAndEndEvent() { ProcessTrace pt = new ProcessTrace_impl(); // should be nothing on event list Assert.assertTrue(pt.getEvents().isEmpty()); // start two events pt.startEvent("c1", "t1", "testing"); pt.startEvent("c1", "t2", "testing"); // should be nothing on event list until both are closed Assert.assertTrue(pt.getEvents().isEmpty()); pt.endEvent("c1", "t2", "success"); Assert.assertTrue(pt.getEvents().isEmpty()); pt.endEvent("c1", "t1", "success"); Assert.assertEquals(1, pt.getEvents().size()); // start two more events pt.startEvent("c2", "t1", "testing"); pt.startEvent("c2", "t2", "testing"); // close one and start another pt.endEvent("c2", "t2", "testing"); Assert.assertEquals(1, pt.getEvents().size()); pt.startEvent("c2", "t3", "testing"); pt.endEvent("c2", "t3", "testing"); Assert.assertEquals(1, pt.getEvents().size()); // start another event and then end the original event pt.startEvent("c2", "t4", "testing"); pt.endEvent("c2", "t1", "success"); Assert.assertEquals(2, pt.getEvents().size()); // verify contents of the ProcessTrace List evts = pt.getEvents(); ProcessTraceEvent evt0 = (ProcessTraceEvent) evts.get(0); Assert.assertEquals("c1", evt0.getComponentName()); Assert.assertEquals("t1", evt0.getType()); Assert.assertEquals("testing", evt0.getDescription()); Assert.assertEquals("success", evt0.getResultMessage()); List subEvts = evt0.getSubEvents(); ProcessTraceEvent subEvt0 = (ProcessTraceEvent) subEvts.get(0); Assert.assertEquals("c1", subEvt0.getComponentName()); Assert.assertEquals("t2", subEvt0.getType()); Assert.assertEquals("testing", subEvt0.getDescription()); Assert.assertEquals("success", subEvt0.getResultMessage()); Assert.assertTrue(subEvt0.getSubEvents().isEmpty()); ProcessTraceEvent evt1 = (ProcessTraceEvent) evts.get(1); Assert.assertEquals("c2", evt1.getComponentName()); Assert.assertEquals("t1", evt1.getType()); Assert.assertEquals("testing", evt1.getDescription()); Assert.assertEquals("success", evt1.getResultMessage()); Assert.assertEquals(3, evt1.getSubEvents().size()); } public void testAddEvent() { ProcessTrace_impl pt = new ProcessTrace_impl(); // should be nothing on event list Assert.assertTrue(pt.getEvents().isEmpty()); // add event pt.addEvent("c1", "t1", "testing", 0, "success"); // should be one thing on list Assert.assertEquals(1, pt.getEvents().size()); // start an event pt.startEvent("c2", "t1", "testing"); // add event pt.addEvent("c2", "t2", "testing", 0, "success"); // should still be one thing on list Assert.assertEquals(1, pt.getEvents().size()); // end event that we started pt.endEvent("c2", "t1", "success"); // should be 2 events on list Assert.assertEquals(2, pt.getEvents().size()); // 2nd event should have a sub-event ProcessTraceEvent evt = (ProcessTraceEvent) pt.getEvents().get(1); Assert.assertEquals(1, evt.getSubEvents().size()); } /* * Test for List getEventsByComponentName(String, boolean) */ public void testGetEventsByComponentName() { ProcessTrace pt = new ProcessTrace_impl(); // create some events pt.startEvent("c1", "t1", "testing"); pt.startEvent("c1", "t2", "testing"); pt.endEvent("c1", "t2", "success"); pt.endEvent("c1", "t1", "success"); pt.startEvent("c2", "t1", "testing"); pt.startEvent("c2", "t2", "testing"); pt.endEvent("c2", "t2", "testing"); pt.startEvent("c2", "t3", "testing"); pt.endEvent("c2", "t3", "testing"); pt.startEvent("c2", "t4", "testing"); pt.endEvent("c2", "t1", "success"); // get top-level events for component c1 List c1evts = pt.getEventsByComponentName("c1", false); Assert.assertEquals(1, c1evts.size()); ProcessTraceEvent evt = (ProcessTraceEvent) c1evts.get(0); Assert.assertEquals(evt.getType(), "t1"); // get all events for component c1 c1evts = pt.getEventsByComponentName("c1", true); Assert.assertEquals(2, c1evts.size()); evt = (ProcessTraceEvent) c1evts.get(1); Assert.assertEquals(evt.getType(), "t2"); // get top-level events for component c2 List c2evts = pt.getEventsByComponentName("c2", false); Assert.assertEquals(1, c2evts.size()); evt = (ProcessTraceEvent) c2evts.get(0); Assert.assertEquals(evt.getType(), "t1"); // get all events for component c2 c2evts = pt.getEventsByComponentName("c2", true); Assert.assertEquals(4, c2evts.size()); evt = (ProcessTraceEvent) c2evts.get(3); Assert.assertEquals(evt.getType(), "t4"); } /* * Test for List getEventsByType(String, boolean) */ public void testGetEventsByType() { ProcessTrace pt = new ProcessTrace_impl(); // create some events pt.startEvent("c1", "t1", "testing"); pt.startEvent("c1", "t2", "testing"); pt.endEvent("c1", "t2", "success"); pt.endEvent("c1", "t1", "success"); pt.startEvent("c2", "t1", "testing"); pt.startEvent("c2", "t2", "testing"); pt.endEvent("c2", "t2", "testing"); pt.startEvent("c3", "t1", "testing"); pt.endEvent("c3", "t1", "testing"); pt.startEvent("c2", "t3", "testing"); pt.endEvent("c2", "t1", "success"); // get top-level events of type t1 List t1evts = pt.getEventsByType("t1", false); Assert.assertEquals(2, t1evts.size()); ProcessTraceEvent evt = (ProcessTraceEvent) t1evts.get(0); Assert.assertEquals(evt.getComponentName(), "c1"); evt = (ProcessTraceEvent) t1evts.get(1); Assert.assertEquals(evt.getComponentName(), "c2"); // get all events for type t1 t1evts = pt.getEventsByType("t1", true); Assert.assertEquals(3, t1evts.size()); evt = (ProcessTraceEvent) t1evts.get(2); Assert.assertEquals(evt.getComponentName(), "c3"); } /* * Test for ProcessTraceEvent getEvent(String, String) */ public void testGetEvent() { ProcessTrace_impl pt = new ProcessTrace_impl(); // create some events pt.startEvent("c1", "t1", "testing"); pt.startEvent("c1", "t2", "testing"); pt.endEvent("c1", "t2", "success"); pt.endEvent("c1", "t1", "success"); pt.startEvent("c2", "t1", "testing"); pt.startEvent("c2", "t2", "testing"); pt.endEvent("c2", "t2", "testing"); pt.startEvent("c3", "t1", "testing"); pt.endEvent("c3", "t1", "testing"); pt.startEvent("c2", "t3", "testing"); pt.endEvent("c2", "t1", "success"); ProcessTraceEvent evt = pt.getEvent("c2", "t2"); Assert.assertEquals("c2", evt.getComponentName()); Assert.assertEquals("t2", evt.getType()); evt = pt.getEvent("c3", "t2"); Assert.assertNull(evt); } public void testAggregate() { // create two ProcessTrace objects ProcessTrace_impl pt1 = new ProcessTrace_impl(); pt1.addEvent("c1", "t1", "testing", 1000, "success"); pt1.startEvent("c2", "t1", "testing"); pt1.addEvent("c2", "t2", "testing", 500, "success"); pt1.endEvent("c2", "t1", "success"); ProcessTrace_impl pt2 = new ProcessTrace_impl(); pt2.startEvent("c2", "t1", "testing"); pt2.addEvent("c2", "t2", "testing", 500, "success"); pt2.endEvent("c2", "t1", "success"); pt2.addEvent("c1", "t1", "testing", 250, "success"); pt1.aggregate(pt2); ProcessTraceEvent c1evt = (ProcessTraceEvent) pt1.getEvents().get(0); ProcessTraceEvent c2evt = (ProcessTraceEvent) pt1.getEvents().get(1); ProcessTraceEvent c2subEvt = (ProcessTraceEvent) c2evt.getSubEvents().get(0); Assert.assertEquals(1250, c1evt.getDuration()); Assert.assertEquals(1000, c2subEvt.getDuration()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/impl/XMLParser_implTest.java0000644000175000017500000002001311665471066030472 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util.impl; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.resource.CustomResourceSpecifier; import org.apache.uima.resource.Parameter; import org.apache.uima.resource.PearSpecifier; import org.apache.uima.resource.URISpecifier; import org.apache.uima.test.junit_extension.JUnitExtension; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; import org.xml.sax.XMLReader; public class XMLParser_implTest extends TestCase { private XMLParser mXmlParser; /** * Constructor for XMLParser_implTest. * * @param arg0 */ public XMLParser_implTest(String arg0) { super(arg0); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); mXmlParser = UIMAFramework.getXMLParser(); // Enable schema validation. Note that this will enable schema validation // for tests that run after this too, but that's not so bad since we'd like // to test the schema. This is currently the first test in CoreTests, so // schema validation will be enabled for the whole suite. mXmlParser.enableSchemaValidation(true); } public void testParse() throws Exception { try { // JTalentAndStringMatch.xml contains imports, // JTalentAndStringMatch_Expanded.xml has had them manually expanded File withImports = JUnitExtension.getFile("XmlParserTest/JTalentAndStringMatch.xml"); File manuallyExpanded = JUnitExtension .getFile("XmlParserTest/JTalentAndStringMatch_Expanded.xml"); // After parsing both files and calling resolveImports, // we should then be able to parse both files and get identical results. AnalysisEngineDescription desc1 = (AnalysisEngineDescription) mXmlParser .parse(new XMLInputSource(withImports)); AnalysisEngineDescription desc2 = (AnalysisEngineDescription) mXmlParser .parse(new XMLInputSource(manuallyExpanded)); Assert.assertNotNull(desc1); Assert.assertNotNull(desc2); Assert.assertEquals(desc1.getDelegateAnalysisEngineSpecifiers(), desc2 .getDelegateAnalysisEngineSpecifiers()); } catch (Exception e) { JUnitExtension.handleException(e); } finally { mXmlParser = null; } } public void testParseXMLInputSourceParseOptions() throws Exception { try { // test for env var refs File envVarRefTest = JUnitExtension.getFile("XmlParserTest/EnvVarRefTest.xml"); System.setProperty("uima.test.var1", "foo"); System.setProperty("uima.test.var2", "bar"); AnalysisEngineDescription taeDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription( new XMLInputSource(envVarRefTest), new XMLParser.ParsingOptions(true, true)); Assert.assertEquals("foo-bar", taeDesc.getMetaData().getName()); // parse with env var ref expansion disabled taeDesc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(new XMLInputSource(envVarRefTest), new XMLParser.ParsingOptions(false)); Assert.assertEquals( "uima.test.var1-uima.test.var2", taeDesc.getMetaData().getName()); } catch (Exception e) { JUnitExtension.handleException(e); } finally { mXmlParser = null; } } public void testParseResourceSpecifier() throws Exception { try { //can't run this test under Sun Java 1.4 with no Xerces installed, as //it doesn't support schema validation. The following is a test for that. SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); XMLReader reader = parser.getXMLReader(); try { reader.setProperty("http://apache.org/xml/properties/schema/external-schemaLocation", "test"); } catch(Exception e) { System.err.println("Skipping XMLParser_implTest.testParseResourceSpecifier() because installed XML parser doesn't support schema validation."); return; } //test schema validation File invalid = JUnitExtension.getFile("XmlParserTest/NotConformingToSchema.xml"); try { mXmlParser.parseResourceSpecifier(new XMLInputSource(invalid)); fail(); } catch (InvalidXMLException e) { //do nothing } } catch (Exception e) { JUnitExtension.handleException(e); } } public void testParseFlowControllerDescription() throws Exception { XMLInputSource in = new XMLInputSource( JUnitExtension.getFile("TextAnalysisEngineImplTest/FlowControllerForErrorTest.xml")); FlowControllerDescription desc = mXmlParser.parseFlowControllerDescription(in); assertEquals("Flow Controller for Error Test", desc.getMetaData().getName()); } public void testParseURISpecifier() throws Exception { XMLInputSource in = new XMLInputSource( JUnitExtension.getFile("XmlParserTest/TestUriSpecifier.xml")); URISpecifier uriSpec = mXmlParser.parseURISpecifier(in); assertEquals("AnalysisEngine", uriSpec.getResourceType()); assertEquals("Vinci", uriSpec.getProtocol()); assertEquals(60000, uriSpec.getTimeout().intValue()); Parameter[] params = uriSpec.getParameters(); assertEquals(2, params.length); assertEquals("VNS_HOST", params[0].getName()); assertEquals("some.internet.ip.name-or-address", params[0].getValue()); assertEquals("VNS_PORT", params[1].getName()); assertEquals("9000", params[1].getValue()); } public void testParseCustomResourceSpecifier() throws Exception { XMLInputSource in = new XMLInputSource( JUnitExtension.getFile("XmlParserTest/TestCustomResourceSpecifier.xml")); CustomResourceSpecifier uriSpec = mXmlParser.parseCustomResourceSpecifier(in); assertEquals("foo.bar.MyResource", uriSpec.getResourceClassName()); Parameter[] params = uriSpec.getParameters(); assertEquals(2, params.length); assertEquals("param1", params[0].getName()); assertEquals("val1", params[0].getValue()); assertEquals("param2", params[1].getName()); assertEquals("val2", params[1].getValue()); } public void testParsePearSpecifier() throws Exception { XMLInputSource in = new XMLInputSource( JUnitExtension.getFile("XmlParserTest/TestPearSpecifier.xml")); PearSpecifier pearSpec = this.mXmlParser.parsePearSpecifier(in); assertEquals("/home/user/uimaApp/installedPears/testpear", pearSpec.getPearPath()); Parameter[] params = pearSpec.getParameters(); assertEquals(2, params.length); assertEquals("param1", params[0].getName()); assertEquals("val1", params[0].getValue()); assertEquals("param2", params[1].getName()); assertEquals("val2", params[1].getValue()); } } uimaj-2.4.0/uimaj-core/src/test/java/org/apache/uima/util/FileUtilsTest.java0000644000175000017500000000520211665471066026576 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.util; import java.io.File; import java.io.IOException; import junit.framework.TestCase; /** * */ public class FileUtilsTest extends TestCase { public void testFindRelativePath() throws Exception { File target = new File("/this/is/a/file.txt"); File base = new File("/this/is/a/test"); assertEquals("../file.txt", FileUtils.findRelativePath(target, base)); base = new File("c:/foo/bar/baz/dir/"); target = new File("c:/foo/d1/d2/d3/blah.xml"); assertEquals("../../../d1/d2/d3/blah.xml", FileUtils.findRelativePath(target, base)); if (File.separatorChar == '\\') { base = new File("c:\\foo\\bar\\baz\\dir\\"); target = new File("c:\\foo\\d1\\d2\\d3\\blah.xml"); assertEquals("../../../d1/d2/d3/blah.xml", FileUtils.findRelativePath(target, base)); } } public void testReadWriteTempFile() throws IOException { final String tmpDirPath = System.getProperty("java.io.tmpdir"); assertNotNull("java.io.tmpdir system property not available", tmpDirPath); File tmpDir = FileUtils.createTempDir(new File(tmpDirPath), "fileUtilsTest"); File tmpFile1 = FileUtils.createTempFile("test", null, tmpDir); File tmpFile2 = FileUtils.createTempFile("test", null, tmpDir); final String text = "This is some text to test file writing. Add an Umlaut for encoding tests:" + "\n Greetings from T\u00FCbingen!\n"; final String utf8 = "UTF-8"; // UIMA-2050 Does not work on all platform encodings // Solution: Do not do it! // FileUtils.saveString2File(text, tmpFile1); // assertEquals(text, FileUtils.file2String(tmpFile1)); FileUtils.saveString2File(text, tmpFile2, utf8); assertEquals(text, FileUtils.file2String(tmpFile2, utf8)); FileUtils.deleteRecursive(tmpDir); } } uimaj-2.4.0/uimaj-core/src/test/java/x/0000755000175000017500000000000011665471070017516 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/x/y/0000755000175000017500000000000011665471070017766 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/x/y/z/0000755000175000017500000000000011665471070020237 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Word_Type.java0000644000175000017500000000453011665471070023020 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; /* comment 4 of 14 */ public class Word_Type extends TokenType_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Word(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Word(addr, instanceOf_Type); } }; public final static int typeIndexID = Word.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.Word"); // * initialize variables to correspond with Cas Type and Features public Word_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } protected Word_Type() { // block default new operator throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/TokenType_Type.java0000644000175000017500000000464011665471070024031 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /* comment 3 of 14 */ public class TokenType_Type extends TOP_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new TokenType(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new TokenType(addr, instanceOf_Type); } }; public final static int typeIndexID = TokenType.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.TokenType"); // * initialize variables to correspond with Cas Type and Features public TokenType_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } protected TokenType_Type() { // block default new operator throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Token_Type.java0000644000175000017500000001735311665471070023174 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.Feature; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.FeatureImpl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation_Type; /* comment 2 of 14 */ public class Token_Type extends Annotation_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Token(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Token(addr, instanceOf_Type); } }; public final static int typeIndexID = Token.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.Token"); final Feature casFeat_ttype; final int casFeatCode_ttype; public int getTtype(int addr) { if (featOkTst && casFeat_ttype == null) this.jcas.throwFeatMissing("ttype", "x.y.z.Token"); return ll_cas.ll_getRefValue(addr, casFeatCode_ttype); } public void setTtype(int addr, int v) { if (featOkTst && casFeat_ttype == null) this.jcas.throwFeatMissing("ttype", "x.y.z.Token"); ll_cas.ll_setRefValue(addr, casFeatCode_ttype, v); } final Feature casFeat_tokenFloatFeat; final int casFeatCode_tokenFloatFeat; public float getTokenFloatFeat(int addr) { if (featOkTst && casFeat_tokenFloatFeat == null) this.jcas.throwFeatMissing("tokenFloatFeat", "x.y.z.Token"); return ll_cas.ll_getFloatValue(addr, casFeatCode_tokenFloatFeat); } public void setTokenFloatFeat(int addr, float v) { if (featOkTst && casFeat_tokenFloatFeat == null) this.jcas.throwFeatMissing("tokenFloatFeat", "x.y.z.Token"); ll_cas.ll_setFloatValue(addr, casFeatCode_tokenFloatFeat, v); } final Feature casFeat_lemma; final int casFeatCode_lemma; public String getLemma(int addr) { if (featOkTst && casFeat_lemma == null) this.jcas.throwFeatMissing("lemma", "x.y.z.Token"); return ll_cas.ll_getStringValue(addr, casFeatCode_lemma); } public void setLemma(int addr, String v) { if (featOkTst && casFeat_lemma == null) this.jcas.throwFeatMissing("lemma", "x.y.z.Token"); ll_cas.ll_setStringValue(addr, casFeatCode_lemma, v); } final Feature casFeat_sentenceLength; final int casFeatCode_sentenceLength; public int getSentenceLength(int addr) { if (featOkTst && casFeat_sentenceLength == null) this.jcas.throwFeatMissing("sentenceLength", "x.y.z.Token"); return ll_cas.ll_getIntValue(addr, casFeatCode_sentenceLength); } public void setSentenceLength(int addr, int v) { if (featOkTst && casFeat_sentenceLength == null) this.jcas.throwFeatMissing("sentenceLength", "x.y.z.Token"); ll_cas.ll_setIntValue(addr, casFeatCode_sentenceLength, v); } final Feature casFeat_lemmaList; final int casFeatCode_lemmaList; public int getLemmaList(int addr) { if (featOkTst && casFeat_lemmaList == null) this.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); return ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList); } public String getLemmaList(int addr, int i) { if (featOkTst && casFeat_lemmaList == null) this.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); if (lowLevelTypeChecks) return ll_cas.ll_getStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i); return ll_cas.ll_getStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i); } public void setLemmaList(int addr, int v) { if (featOkTst && casFeat_lemmaList == null) this.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); ll_cas.ll_setRefValue(addr, casFeatCode_lemmaList, v); } public void setLemmaList(int addr, int i, String v) { if (featOkTst && casFeat_lemmaList == null) this.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); if (lowLevelTypeChecks) ll_cas.ll_setStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i, v, true); jcas.checkArrayBounds(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i); ll_cas.ll_setStringArrayValue(ll_cas.ll_getRefValue(addr, casFeatCode_lemmaList), i, v); } // * initialize variables to correspond with Cas Type and Features public Token_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); casFeat_ttype = jcas.getRequiredFeatureDE(casType, "ttype", "x.y.z.TokenType", featOkTst); casFeatCode_ttype = (null == casFeat_ttype) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_ttype).getCode(); casFeat_tokenFloatFeat = jcas.getRequiredFeatureDE(casType, "tokenFloatFeat", "uima.cas.Float", featOkTst); casFeatCode_tokenFloatFeat = (null == casFeat_tokenFloatFeat) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_tokenFloatFeat).getCode(); casFeat_lemma = jcas.getRequiredFeatureDE(casType, "lemma", "uima.cas.String", featOkTst); casFeatCode_lemma = (null == casFeat_lemma) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_lemma).getCode(); casFeat_sentenceLength = jcas.getRequiredFeatureDE(casType, "sentenceLength", "uima.cas.Integer", featOkTst); casFeatCode_sentenceLength = (null == casFeat_sentenceLength) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_sentenceLength).getCode(); casFeat_lemmaList = jcas.getRequiredFeatureDE(casType, "lemmaList", "uima.cas.StringArray", featOkTst); casFeatCode_lemmaList = (null == casFeat_lemmaList) ? JCas.INVALID_FEATURE_CODE : ((FeatureImpl) casFeat_lemmaList).getCode(); } protected Token_Type() { // block default new operator casFeat_ttype = null; casFeatCode_ttype = JCas.INVALID_FEATURE_CODE; casFeat_tokenFloatFeat = null; casFeatCode_tokenFloatFeat = JCas.INVALID_FEATURE_CODE; casFeat_lemma = null; casFeatCode_lemma = JCas.INVALID_FEATURE_CODE; casFeat_sentenceLength = null; casFeatCode_sentenceLength = JCas.INVALID_FEATURE_CODE; casFeat_lemmaList = null; casFeatCode_lemmaList = JCas.INVALID_FEATURE_CODE; throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/EndOfSentence_Type.java0000644000175000017500000000462711665471070024574 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; /* comment 6 of 14 */ public class EndOfSentence_Type extends TokenType_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new EndOfSentence(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new EndOfSentence(addr, instanceOf_Type); } }; public final static int typeIndexID = EndOfSentence.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.EndOfSentence"); // * initialize variables to correspond with Cas Type and Features public EndOfSentence_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } protected EndOfSentence_Type() { // block default new operator throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/TokenType.java0000644000175000017500000000323511665471070023027 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.cas.TOP_Type; /* comment 3 of 14 */ public class TokenType extends TOP { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(TokenType.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected TokenType() { } /** Internal - Constructor used by generator */ public TokenType(int addr, TOP_Type type) { super(addr, type); } public TokenType(JCas jcas) { super(jcas); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Separator_Type.java0000644000175000017500000000457311665471070024054 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; /* comment 5 of 14 */ public class Separator_Type extends TokenType_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Separator(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Separator(addr, instanceOf_Type); } }; public final static int typeIndexID = Separator.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.Separator"); // * initialize variables to correspond with Cas Type and Features public Separator_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } protected Separator_Type() { // block default new operator throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Separator.java0000644000175000017500000000317511665471070023050 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /* comment 5 of 14 */ public class Separator extends TokenType { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(Separator.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected Separator() { } /** Internal - Constructor used by generator */ public Separator(int addr, TOP_Type type) { super(addr, type); } public Separator(JCas jcas) { super(jcas); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Sentence.java0000644000175000017500000000345711665471070022657 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /* comment 1 of 14 */ public class Sentence extends Annotation { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(Sentence.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected Sentence() { } /** Internal - Constructor used by generator */ public Sentence(int addr, TOP_Type type) { super(addr, type); } public Sentence(JCas jcas) { super(jcas); } public Sentence(JCas jcas, int begin, int end) { super(jcas); setBegin(begin); setEnd(end); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Sentence_Type.java0000644000175000017500000000465011665471070023654 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.cas.FeatureStructure; import org.apache.uima.cas.Type; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.cas.impl.FSGenerator; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.tcas.Annotation_Type; /* comment 1 of 14 */ public class Sentence_Type extends Annotation_Type { protected FSGenerator getFSGenerator() { return fsGenerator; } private final FSGenerator fsGenerator = new FSGenerator() { public FeatureStructure createFS(int addr, CASImpl cas) { if (instanceOf_Type.useExistingInstance) { // Return eq fs instance if already created FeatureStructure fs = instanceOf_Type.jcas.getJfsFromCaddr(addr); if (null == fs) { fs = new Sentence(addr, instanceOf_Type); instanceOf_Type.jcas.putJfsFromCaddr(addr, fs); return fs; } return fs; } else return new Sentence(addr, instanceOf_Type); } }; public final static int typeIndexID = Sentence.typeIndexID; public final static boolean featOkTst = org.apache.uima.jcas.JCasRegistry.getFeatOkTst("x.y.z.Sentence"); // * initialize variables to correspond with Cas Type and Features public Sentence_Type(JCas jcas, Type casType) { super(jcas, casType); casImpl.getFSClassRegistry().addGeneratorForType((TypeImpl) this.casType, getFSGenerator()); } protected Sentence_Type() { // block default new operator throw new RuntimeException("Internal Error-this constructor should never be called."); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Token.java0000644000175000017500000001513111665471070022163 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.StringArray; import org.apache.uima.jcas.cas.TOP_Type; import org.apache.uima.jcas.tcas.Annotation; /* comment 2 of 14 */ public class Token extends Annotation { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(Token.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected Token() { } /** Internal - Constructor used by generator */ public Token(int addr, TOP_Type type) { super(addr, type); } public Token(JCas jcas) { super(jcas); } public Token(JCas jcas, int begin, int end) { super(jcas); setBegin(begin); setEnd(end); readObject(); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } // *------------------* // * Feature: ttype /** getter for ttype * */ public TokenType getTtype() { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_ttype == null) this.jcasType.jcas.throwFeatMissing("ttype", "x.y.z.Token"); return (TokenType) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_ttype))); } /** setter for ttype * */ public void setTtype(TokenType v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_ttype == null) this.jcasType.jcas.throwFeatMissing("ttype", "x.y.z.Token"); jcasType.ll_cas.ll_setRefValue(addr, ((Token_Type) jcasType).casFeatCode_ttype, jcasType.ll_cas .ll_getFSRef(v)); } // *------------------* // * Feature: tokenFloatFeat /** getter for tokenFloatFeat * */ public float getTokenFloatFeat() { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_tokenFloatFeat == null) this.jcasType.jcas.throwFeatMissing("tokenFloatFeat", "x.y.z.Token"); return jcasType.ll_cas.ll_getFloatValue(addr, ((Token_Type) jcasType).casFeatCode_tokenFloatFeat); } /** setter for tokenFloatFeat * */ public void setTokenFloatFeat(float v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_tokenFloatFeat == null) this.jcasType.jcas.throwFeatMissing("tokenFloatFeat", "x.y.z.Token"); jcasType.ll_cas.ll_setFloatValue(addr, ((Token_Type) jcasType).casFeatCode_tokenFloatFeat, v); } // *------------------* // * Feature: lemma /** getter for lemma * */ public String getLemma() { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemma == null) this.jcasType.jcas.throwFeatMissing("lemma", "x.y.z.Token"); return jcasType.ll_cas.ll_getStringValue(addr, ((Token_Type) jcasType).casFeatCode_lemma); } /** setter for lemma * */ public void setLemma(String v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemma == null) this.jcasType.jcas.throwFeatMissing("lemma", "x.y.z.Token"); jcasType.ll_cas.ll_setStringValue(addr, ((Token_Type) jcasType).casFeatCode_lemma, v); } // *------------------* // * Feature: sentenceLength /** getter for sentenceLength * */ public int getSentenceLength() { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_sentenceLength == null) this.jcasType.jcas.throwFeatMissing("sentenceLength", "x.y.z.Token"); return jcasType.ll_cas.ll_getIntValue(addr, ((Token_Type) jcasType).casFeatCode_sentenceLength); } /** setter for sentenceLength * */ public void setSentenceLength(int v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_sentenceLength == null) this.jcasType.jcas.throwFeatMissing("sentenceLength", "x.y.z.Token"); jcasType.ll_cas.ll_setIntValue(addr, ((Token_Type) jcasType).casFeatCode_sentenceLength, v); } // *------------------* // * Feature: lemmaList /** getter for lemmaList * */ public StringArray getLemmaList() { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemmaList == null) this.jcasType.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); return (StringArray) (jcasType.ll_cas.ll_getFSForRef(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList))); } /** indexed getter for lemmaList * */ public String getLemmaList(int i) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemmaList == null) this.jcasType.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList), i); return jcasType.ll_cas.ll_getStringArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList), i); } /** setter for lemmaList * */ public void setLemmaList(StringArray v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemmaList == null) this.jcasType.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); jcasType.ll_cas.ll_setRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList, jcasType.ll_cas.ll_getFSRef(v)); } /** indexed setter for lemmaList * */ public void setLemmaList(int i, String v) { if (Token_Type.featOkTst && ((Token_Type) jcasType).casFeat_lemmaList == null) this.jcasType.jcas.throwFeatMissing("lemmaList", "x.y.z.Token"); jcasType.jcas.checkArrayBounds(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList), i); jcasType.ll_cas.ll_setStringArrayValue(jcasType.ll_cas.ll_getRefValue(addr, ((Token_Type) jcasType).casFeatCode_lemmaList), i, v); } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/EndOfSentence.java0000644000175000017500000000322111665471070023560 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /* comment 6 of 14 */ public class EndOfSentence extends TokenType { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(EndOfSentence.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected EndOfSentence() { } /** Internal - Constructor used by generator */ public EndOfSentence(int addr, TOP_Type type) { super(addr, type); } public EndOfSentence(JCas jcas) { super(jcas); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-core/src/test/java/x/y/z/Word.java0000644000175000017500000000314411665471070022017 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package x.y.z; import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.TOP_Type; /* comment 4 of 14 */ public class Word extends TokenType { public final static int typeIndexID = org.apache.uima.jcas.JCasRegistry.register(Word.class); public final static int type = typeIndexID; public int getTypeIndexID() { return typeIndexID; } // Never called. Disable default constructor protected Word() { } /** Internal - Constructor used by generator */ public Word(int addr, TOP_Type type) { super(addr, type); } public Word(JCas jcas) { super(jcas); } /** * Write your own initialization here * * @generated modifiable */ private void readObject() { } } uimaj-2.4.0/uimaj-ep-configurator/0000755000175000017500000000000011665472116016736 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/META-INF/0000755000175000017500000000000011665472130020072 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/META-INF/MANIFEST.MF0000644000175000017500000000655711665472130021541 0ustar drazzibdrazzibManifest-Version: 1.0 Implementation-Vendor: The Apache Software Foundation Bundle-RequiredExecutionEnvironment: J2SE-1.5 Built-By: schor Bundle-Activator: org.eclipse.core.internal.compatibility.PluginActiva tor Ignore-Package: org.eclipse.ui.dialogs,org.eclipse.ui.texteditor,org.e clipse.ui.actions,org.eclipse.jface.text.source,org.eclipse.ui,org.ec lipse.jface.text,org.eclipse.core.runtime,org.eclipse.ui.part Bundle-Version: 2.4.0 Eclipse-AutoStart: true Build-Jdk: 1.6.0 Implementation-Url: http://uima.apache.org Tool: Bnd-1.15.0 Created-By: Apache Maven Bundle Plugin Plugin-Class: org.apache.uima.taeconfigurator.TAEConfiguratorPlugin Import-Package: org.apache.uima,org.apache.uima.analysis_engine,org.ap ache.uima.analysis_engine.impl,org.apache.uima.analysis_engine.metada ta,org.apache.uima.analysis_engine.metadata.impl,org.apache.uima.cas, org.apache.uima.cas.admin,org.apache.uima.cas.impl,org.apache.uima.co llection,org.apache.uima.flow,org.apache.uima.impl,org.apache.uima.in ternal.util,org.apache.uima.jcas.jcasgenp,org.apache.uima.resource,or g.apache.uima.resource.impl,org.apache.uima.resource.metadata,org.apa che.uima.resource.metadata.impl,org.apache.uima.tools.jcasgen,org.apa che.uima.util,org.eclipse.core.internal.compatibility,org.eclipse.cor e.resources,org.eclipse.jdt.core,org.eclipse.jdt.core.search,org.ecli pse.jdt.launching,org.eclipse.jdt.ui,org.eclipse.jface.action,org.ecl ipse.jface.dialogs,org.eclipse.jface.fieldassist,org.eclipse.jface.op eration,org.eclipse.jface.preference,org.eclipse.jface.resource,org.e clipse.jface.text.presentation,org.eclipse.jface.text.rules,org.eclip se.jface.util,org.eclipse.jface.viewers,org.eclipse.jface.wizard,org. eclipse.swt.custom,org.eclipse.swt.events,org.eclipse.swt.graphics,or g.eclipse.swt.layout,org.eclipse.swt.widgets,org.eclipse.ui.editors.t ext,org.eclipse.ui.fieldassist,org.eclipse.ui.forms,org.eclipse.ui.fo rms.editor,org.eclipse.ui.forms.widgets,org.eclipse.ui.ide,org.eclips e.ui.plugin,org.osgi.framework;version="[1.3,2)",org.xml.sax Bundle-DocURL: http://www.apache.org/ Project-Title: Apache UIMA Implementation-Vendor-Id: org.apache.uima Implementation-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-SymbolicName: org.apache.uima.desceditor;singleton:=true Require-Bundle: org.eclipse.jface.text,org.eclipse.text,org.eclipse.ui .editors,org.eclipse.ui.workbench.texteditor,org.eclipse.ui.ide,org.e clipse.ui,org.eclipse.core.runtime Build-Date: 111130_1918 Export-Package: org.apache.uima.taeconfigurator,org.apache.uima.taecon figurator.editors,org.apache.uima.taeconfigurator.editors.point,org.a pache.uima.taeconfigurator.editors.ui,org.apache.uima.taeconfigurator .editors.ui.dialogs,org.apache.uima.taeconfigurator.editors.xml,org.a pache.uima.taeconfigurator.files,org.apache.uima.taeconfigurator.mode l,org.apache.uima.taeconfigurator.wizards Bundle-Description: A frame-based editor for most of the UIMA XML descriptors Bundle-Vendor: The Apache Software Foundation Bnd-LastModified: 1322698934371 Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt Bundle-Name: Apache UIMA Eclipse: uimaj-ep-configurator: Descriptor Ed itor Eclipse-ExtensibleAPI: true Implementation-Title: Apache UIMA Eclipse: uimaj-ep-configurator: Desc riptor Editor Implementation-Version: 2.4.0 Bundle-ManifestVersion: 2 uimaj-2.4.0/uimaj-ep-configurator/pom.xml0000644000175000017500000003761011665471546020270 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-ep-configurator 2.4.0 jar Apache UIMA Eclipse: ${project.artifactId}: Descriptor Editor A frame-based editor for most of the UIMA XML descriptors ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-configurator scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-configurator http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-ep-configurator ${project.artifactId} ${ibmNoticeText} org.apache.uima uimaj-core ${project.parent.version} compile org.apache.uima uimaj-tools ${project.parent.version} compile org.apache.uima uimaj-ep-jcasgen ${project.parent.version} provided org.eclipse.core org.eclipse.core.runtime.compatibility 3.1.100 provided org.eclipse.jdt org.eclipse.jdt.ui 3.2.0 provided org.eclipse.swt org.eclipse.swt.win32.win32.x86 3.2.0 provided org.eclipse.core org.eclipse.core.runtime 3.2.0 provided org.eclipse.equinox org.eclipse.equinox.registry 3.2.1 provided org.eclipse.core org.eclipse.core.jobs 3.2.0 provided org.eclipse.core org.eclipse.core.contenttype 3.2.0 provided org.eclipse.equinox org.eclipse.equinox.preferences 3.2.1 provided org.eclipse.core org.eclipse.core.runtime.compatibility.auth 3.2.0 provided org.eclipse.osgi org.eclipse.osgi 3.2.1 provided org.eclipse.core org.eclipse.core.filesystem 1.0.0 provided org.eclipse.equinox org.eclipse.equinox.common 3.2.0 provided org.eclipse.core org.eclipse.core.resources 3.2.1 provided org.eclipse.ant org.eclipse.ant.core 3.1.100 provided org.eclipse.core org.eclipse.core.expressions 3.2.1 provided org.eclipse.core org.eclipse.core.variables 3.1.100 provided org.apache.uima.desceditor_${parsedVersion.osgiVersion} org.apache.felix maven-bundle-plugin META-INF <_nouses>true org.apache.uima.taeconfigurator, org.apache.uima.taeconfigurator.editors, org.apache.uima.taeconfigurator.editors.point, org.apache.uima.taeconfigurator.editors.ui, org.apache.uima.taeconfigurator.editors.ui.dialogs, org.apache.uima.taeconfigurator.editors.xml, org.apache.uima.taeconfigurator.files, org.apache.uima.taeconfigurator.model, org.apache.uima.taeconfigurator.wizards org.eclipse.core.internal.compatibility.PluginActivator org.apache.uima.desceditor;singleton:=true J2SE-1.5 org.eclipse.jface.text, org.eclipse.text, org.eclipse.ui.editors, org.eclipse.ui.workbench.texteditor, org.eclipse.ui.ide, org.eclipse.ui, org.eclipse.core.runtime !org.eclipse.jface.text, !org.eclipse.jface.text.source, !org.eclipse.ui.texteditor, !org.eclipse.ui, !org.eclipse.ui.actions, !org.eclipse.ui.dialogs, !org.eclipse.ui.part, !org.eclipse.core.runtime, *, org.apache.uima.jcas.jcasgenp, org.eclipse.jdt.ui true org.apache.uima.taeconfigurator.TAEConfiguratorPlugin true uimaj-2.4.0/uimaj-ep-configurator/plugin.xml0000644000175000017500000001441411665471222020757 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-ep-configurator/marker-file-identifying-eclipse-plugin0000644000175000017500000000000011665471222026267 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/icons/0000755000175000017500000000000011665471222020046 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/icons/parameter.gif0000644000175000017500000000104711665471222022517 0ustar drazzibdrazzibGIF89a0'b1(d1(c1(bZR/'b0(c0(bIέƽֽPkhtqՔkilj.-w98s98kRQJI{KJ|SRRQcbbakjSR|01((b11k99t99s99kQQII{JJ|JJ{RR01k7!H,H =  8 107G;;.6A":*< D2!2$5B3 2#+ +%,,ʄ@''(((C& >)?/09E4C4F- ;uimaj-2.4.0/uimaj-ep-configurator/icons/group.gif0000644000175000017500000000157311665471222021677 0ustar drazzibdrazzibGIF89a??_???_?߿_,`H`&,`P`!&4 BJXq@#"1$đ#Hr@,OҤK(' x%D mbG6DHdžPJ;uimaj-2.4.0/uimaj-ep-configurator/icons/big_t_s.gif0000644000175000017500000000340211665471222022142 0ustar drazzibdrazzibGIF89a@@)(*ts젟XWfؿ98s&%L:9t:9s88s99t88r99sݴϬ忿||??@!#V89s$*_p~|)..ܠʄ "+0 ƚ$/½3\yx8@1PB &`(0@7B8ٙ] ԈR:f,"p$ T xaPJ@gx# =qTX%~tiy4Z ,5I׋ʶ`09@tGTSFXGrr@iEq%\)hwf=(U0 &&uA)_P~T"wey'A wI2̵)ATw޾l*Y?%[P.!@ƃ@VЬQy.  "0)qZca `uSJˆ `*xDq[5ȧ*L0u8%x}{ Bh(aD e[SHaTh:^eܡDmz5b ! (i15E@4b2+JF"$P #kPJS> tQK(7 %E p!8h! `}7(H@;uimaj-2.4.0/uimaj-ep-configurator/icons/big_ae.gif0000644000175000017500000000175611665471222021754 0ustar drazzibdrazzibGIF89a@@=>>?켹ݽ켺98s:9t:9s88s99t88r99s89sƄŽ223!9,@@pH,Ȥrl:ШtJZجvz'Q P֢ƒN^h24)|}T$501.\   C$%30&e !C'6,\w121-[%8140+Z$7u '/u8tL Tئg2OOm8 ;5' u "@4kJ/z"bB#H#(DWF5h` .@ (X@0HT/ *h$pZ,CII b؊ m0 ҬV2C/(m&@U 4!eRZpng6`jh.ڥhy $cB @&|WX W! #p PMP}PPPICV#}P#"V!A;uimaj-2.4.0/uimaj-ep-configurator/icons/common.gif0000644000175000017500000000024111665471222022022 0ustar drazzibdrazzibGIF89a??_???_?߿_! ,N0Ted}$UށIA|0 T4('A=WVB@UWn;uimaj-2.4.0/uimaj-ep-configurator/icons/editor.gif0000644000175000017500000000055611665471222022031 0ustar drazzibdrazzibGIF89aeff彺98s:9t:9sFE88s99t99sEFEEFFEEFF89sEF1̙!(,@pH!"0H 3 4t (Drr"Pl$qQ@$"%VCfi%pC|&Je J} E E  JhhJQBA;uimaj-2.4.0/uimaj-ep-configurator/icons/gelb.gif0000644000175000017500000000034211665471222021445 0ustar drazzibdrazzibGIF89a?___?߿?߿????___!,_$4x tL%6 TpxA!pXQa`Xa"+Ș&$Ȇ ذѣ;uimaj-2.4.0/uimaj-ep-configurator/icons/th_vertical.gif0000644000175000017500000000054011665471222023040 0ustar drazzibdrazzibGIF89aщg}t7`η|}k^둆!!,}pH, ;Ȥ29,b3,& d˅p" fHD!gC CCRC ] C  CgiC ~CCBA;uimaj-2.4.0/uimaj-ep-configurator/icons/form_banner.gif0000644000175000017500000001274011665471222023031 0ustar drazzibdrazzibGIF89aX,XH*\ȰÇ#JHŋ3j,(GrIɓ(ǨSe)0cV9͛ir':C茣XtӧBJI Gj=b7`;vŊ?h#Dv[K^%ԥ  %o_(pzBÈ )^\ !L˘-̹Ϡ;ϑ4ҧMsZ`i֥;m5RhN[5ѷatհw׶;wrI쭚sܹr܅N][ws] $eO\󛞝!GvkvGzG6ZH$@Ia!J`J,db 2T+DENV=逆P8uRm)S>y6QGcLQOA!N9GyEOBл4EI%u=!lNyЁL#LvQeVkMU`55_P'gZ{us} j dbY1468` (,m d !@ p 1p(̘ItЁ6tMPL`+JP$` 'C"17TI@"09` v;H $ IX" Ɛ.b?VЂ)ݨE4JB?(!~0cL`-H@$&'8"IIJ< xIXV؁('<*@v `ɀ (e.E*& 8K0Lf2J(F!Qd En(8Yo~N4zt>Y|„gO: <> } E(A~4BPΠͧ?юbH/PuEАԟ( hCA:ӄ>>H'Ou&(hN1*ҙ49EZQTHO Tj!Ti:T3ѤZ3I聓%kOLyJSH $ů~]`!>P"}AU ̪Ydl lf?"EphG+ZA*Cj@i׌6In~B/ȭn[DַO8pNvӝ^L2%@"'AICTDH0Yr`MIAJkZ^K|>/E.X]7. 7*NF;ѐ'MJ[Ҙδ7N{Ҧ]骅RYB, k`qJPyk:]FrW|Q2Y&X`%0|nɦ(BPD-rF@#Zz1 < mC08 ӘcXw8 . 8'pS<w7q<'yA~+7C\58wj,B'5AG?z>0L"8@B4fXZLpҖ Vڲ`̬e-Ӛ/m&m1@EmΞs'NȻ0Ox'hm1V\x"&O76-7{GOқOWֻwˡ۞ bt"!A sO!an`A2Y@}M~mk]k_{\4.^JmߗhxxWyo'BtQt H$  (SAȀ؁X8R&xx +Ȃ8*39h؃-$K#C؂6/(.I(FG!h"4D QdBQjPfHiȧ$Zupr( >C+a7mLZKfcv6f%^0wxaw`Hg@} xx?P &gxCy(y 'GnGX{YZ3n3ʨl،n(J8؋HȌǨ{`[Y8Y3(XƸȋ˜8x؋ȏ8Y[Ax؍Jblp ɖlPeͦ A#}o@}E00em}2I6 JJ?y~P5&W |wP nwť& pXyxx^rRy8hsjlٖnpr9tYvyxz|ٗ~p=\Y-{8m^0f;[B5Ip`@wIwv`5W7xPx ? 0y`7Ygi')mYZ)י٩ye9ɝhAعe䩞ɜ[֝i9[YY i͉ٞvi I%]MLM.Jp _3:Zrff%;9]Of@N[|Qw (N\N?oiIeicv%X`_jhtJvlzrڦ*_rݶKpvʦZoʦm`ڦimv*xj}z%g`ʨ*:zJj pʫuZڦڪjrLsomY<ʈeƙtM]@BJyatfNhgXSd\5a*cejgEMЈ]"nM˰+nKqMT { ;[k ;  ! ۲۰+K0{ʲ!ڄM4 +#JA n7HMO{1{2[0V;O;#{>OCxq ]5`RdFZHy| |xcҔPY&6 O0%\` z5_a# poD;[{ۻ+y儤Լ!?PYPpn:Ůť g &Noй`OaJ;򋺭o~S{ۤI:< ,˿{l l ܤ䊿\ !\*>[#`oS3ǽ pg=<ȥ\^  `JK1[PpeWY^ algabl]blVlm _i

@gg,<Н Ih::6<|h>]ѻ<57= }xL-*&/-ъ5}9M*g@BݕЯ8éȜ\լPV}լ Y5ܛ^=b=f]fh=k m`]pr={~=d| EoyЎ=aԑ-ԘЭЖRդ\\]ԩ]̫=ЭEmԮ]ړر-۴ڹm̩ ۽MMƜ=čŭm۱ܾ-=ٔԛ-԰#=mڧ=]}])ٰ t٠>U@ ">$^&~(٠ ..ըkV4/~8:<>@B>DU]SmTMڛ]PR>T^V~XZ\^;uimaj-2.4.0/uimaj-ep-configurator/icons/one_arrow.gif0000644000175000017500000000044311665471222022531 0ustar drazzibdrazzibGIF89adadaebcadbѤУΥФ10cbacb00c.0b/0c/1c01d/0b01b.0a! ,@@pH,ȤYCq< "Q 縘L(%{L|6 cU}}}A;uimaj-2.4.0/uimaj-ep-configurator/schema/0000755000175000017500000000000011665471206020175 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/schema/editorContribution.exsd0000644000175000017500000002121611665471206024752 0ustar drazzibdrazzib <p>This extension point is used to add a new editing capability to the UIMA CDE for an additional kind of UIMA XML descriptor (Resource Specifer). Developers can extend the editor to edit a new kind of Resource Specifier by using this extension point to extend the CDE's editing capability. </p> <p>The extension must implement two interfaces: <ol><li><code>org.apache.uima.taeconfigurator.editors.point.IUimaEditorExtension</code> and</li> <li><code>org.apache.uima.taeconfigurator.editors.point.IUimaMultiPageEditor</code>.</li> </ol></p> <p>When the CDE is instantiated, it will load the information in the XML spec for all contributors to the extension point. When an attempt is made to edit a top-most element which the CDE doesn't know how to handle, this XML info is scanned to see if some contributor can handle this. All this is done without loading any classes. If it finds one, it loads the class and calls the <code>init</code> method of the <code>IUimaEditorExtension</code> interface; this allows all extensions to do whatever initialization they may need to do. For instance, the extension could register a factory class for the new descriptor's type (see below) with UIMA's general ResourceSpecifier support. </p> <p>If the parser can't parse the descriptor, this same scan code is used to see if some editor can possibly contribute a parser for the particular top-level element. If so, the <code>init</code> method is called, as above, in the hopes that the editor will cause some additional parser to get "registered", and then the parsing is retried. </p> <p> The <code>IUimaMultiPageEditor</code> interface is used by CDE to redirect the editing functions to the external editor. </p> <p>Note: To add a new kind of Resource Specifier to UIMA, you can register a new factory class for the new descriptor's type (by using the <code>addMapping(String, String)</code> method of the <code>org.apache.uima.ResourceSpecifierFactory</code> factory class) </p> a fully qualified identifier of the target extension point an optional identifier of the extension instance an optional name of the extension instance a translatable name that will be used in the UI for this editor a unique name that will be used to identify this editor the name of a class that implements <code>org.apache.uima.taeconfigurator.editors.point.IUimaEditorExtension</code> and <code>org.apache.uima.taeconfigurator.editors.point.IUimaMultiPageEditor</code>. The attributes One or more handlesElement elements name the kinds of XML top-level elements that a particular editor will edit. The CDE scans these to determine which editor to load. The name of the top-level element; cannot be one of the elements the CDE already edits An interface that represents the result of parsing this element 2.2.1 The following is an example of an external editor extension definition: <p> <pre> <extension point="org.apache.uima.desceditor.externalEditor"> <editor class="org.apache.uima.dde.internal.DeploymentDescriptorEditor" id="org.apache.uima.dde" name="Deployment Descriptor Editor"> <handlesElement class="org.apache.uima.aae.deployment.AEService" elementName="analysisEngineDeploymentDescription" internalParseClass="org.apache.uima.aae.deployment.impl.AEDeploymentDescription_Impl"/> </editor> </extension> </pre> </p> The contributed class must implement <code>org.apache.uima.taeconfigurator.editors.point.IUimaEditorExtension</code> and <code>org.apache.uima.taeconfigurator.editors.point.IUimaMultiPageEditor</code> Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/uimaj-ep-configurator/src/0000755000175000017500000000000011665471206017524 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/0000755000175000017500000000000011665471220020444 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/0000755000175000017500000000000011665471220022456 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/0000755000175000017500000000000011665471220023245 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/apache/0000755000175000017500000000000011665471220024466 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/apache/uima/0000755000175000017500000000000011665471220025421 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/0000755000175000017500000000000011665471220030615 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/messages.propertiesuimaj-2.4.0/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/messages.proper0000644000175000017500000001437211665471220033664 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** AbstractSection.0= AbstractSectionParm.16=Integer AbstractSectionParm.common= AbstractSectionParm.delegateKeyName=Delegate Key Name: AbstractSectionParm.headerCommon= AbstractSectionParm.headerGroupNames=GROUP Names: AbstractSectionParm.headerNotInAnyGroup= AbstractSectionParm.notInAnyGroup= AbstractSectionParm.overrides=Overrides: FlowSection.ComponentEngineFlowDescription=Choose a flow type and describe the execution order of your engines.\nThe table shows the delegates using their key names. FlowSection.ComponentEngineFlowTitle=Component Engine Flow FlowSection.downTip=Click here to move the selected engine one position lower in the flow list. FlowSection.FlowKind=Flow Kind: FlowSection.FlowKindTip=Pick the kind of flow sequencing to use FlowSection.notUsed=Not Used FlowSection.onlyForAggregates=This section is only applicable for Aggregate descriptors. FlowSection.upTip=Click here to move the selected engine one position higher in the flow list. LimitedResourceSelectionDialog.ResourceSelectionDialog=Resource Selection Dialog MultiPageEditor.aggregateTab=Aggregate MultiPageEditor.capabilityTab=Capabilities MultiPageEditor.causedBy=\r\nCaused by: MultiPageEditor.EditExisting=Edit existing MultiPageEditor.errorInDesc=The descriptor has one or more errors. Please fix in the source editor. MultiPageEditor.errorInDescTitle=Error in Descriptor MultiPageEditor.failedAeValidation=Error in AE Descriptor MultiPageEditor.failedAeValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.failedCollRdrValidation=Error in Collection Reader Descriptor MultiPageEditor.failedCollRdrValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.failedCollRdreValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.failedCasInitValidation=Error in Cas Initializer Descriptor MultiPageEditor.failedCasInitValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.failedCasConsValidation=Error in Cas Consumer Descriptor MultiPageEditor.failedCasConsValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.failedCasConsAeValidationMsg=The Descriptor is invalid for the following reason: MultiPageEditor.indexDefProblem=There is a problem in the index definition.\r\n MultiPageEditor.indexDefProblemTitle=Index Definition Problem MultiPageEditor.indexesTab=Indexes MultiPageEditor.invalidInputClass=Invalid Input: Must be IFileEditorInput MultiPageEditor.invalidTypeSpec=Your edited XML is valid but results in an invalid TCAS.\n MultiPageEditor.invalidTypeSpecTitle=Invalid Type Specification MultiPageEditor.invalidXML=Your edited XML is invalid.\n MultiPageEditor.invalidXMLTitle=Invalid XML MultiPageEditor.IOError=I/O Error reading file ''{0}'' MultiPageEditor.jcasGenErr=An error has occured running JCasGen: {0}. You may have to generate the java source for your type files by hand. MultiPageEditor.JCasGenErr=Error from within JCasGen: MultiPageEditor.JCasGenErrorTitle=JCasGen Error MultiPageEditor.noSrcDir=No Source Directory MultiPageEditor.noSrcNoJCas=No source directories have been defined. JCasGen will not be run\! MultiPageEditor.overviewTab=Overview MultiPageEditor.parameterTab=Parameters MultiPageEditor.resourcesTab=Resources MultiPageEditor.revertToLastValid=Revert to last valid MultiPageEditor.settingsTab=Parameter Settings MultiPageEditor.sourceTab=Source MultiPageEditor.typeTab=Type System MultiPageEditor.0=Analysis Engine MultiPageEditor.1=Type System MultiPageEditor.2=Index MultiPageEditor.3=Type Priorities MultiPageEditor.4=Resource Manager Configuration MultiPageEditor.5=Collection Reader MultiPageEditor.6=CAS Initializier MultiPageEditor.7=CAS Consumer MultiPageEditor.8=invalid state MultiPageEditor.9=\ descriptor MultiPageEditor.10=\n MultiPageEditor.11=\n MultiPageEditor.12=org.apache.uima.taeconfigurator.messages MultiPageEditor.13=MultiPageEditor.descriptorKindChanged MultiPageEditor.14=Exception should not happen MultiPageEditor.15=Exception should not happen MultiPageEditor.16=encoding=" MultiPageEditor.17=UTF-8 MultiPageEditor.18=" MultiPageEditor.19=Error MultiPageEditor.20=Error MultiPageEditor.21=invalid state MultiPageEditor.22=Unexpected Exception MultiPageEditor.23=Unexpected Exception MultiPageEditor.24=invalid Null Argument MultiPageEditor.25=Error Writing JCasGen Java files MultiPageEditor.26=I/O error while writing the generated JCas files.\n MultiPageEditor.unrecognizedDescType=Unrecognized descriptor type for file ''{0}''. MultiPageEditor.XMLerrorInDescriptor=The descriptor has one or more XML errors, and can''t be parsed. Please fix in the source editor. MultiPageEditor.XMLerrorInDescriptorTitle=XML Error in Descriptor MultiPageEditorContributor.autoGenJCas=Auto generate JCAS source java files when changing types MultiPageEditorContributor.showFullNames=Display fully qualified type names MultiResourceSelectionDialog.BrowseFileSys=Browse the file system... MultiResourceSelectionDialog.Or=OR MultiResourceSelectionDialog.starDotXml=*.xml MultiResourceSelectionDialogWithFlowOption.addSelectedAEsToEndOfFlow=Add selected AEs to end of flow ResourceSelectionDialog.message=Resource Selection ResourceSelectionDialog.title=Resource Selection uimaj-2.4.0/uimaj-ep-configurator/src/main/java/0000755000175000017500000000000011665471206021371 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/0000755000175000017500000000000011665471206022160 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/0000755000175000017500000000000011665471206023401 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/0000755000175000017500000000000011665471206024334 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/0000755000175000017500000000000011665471220027524 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/0000755000175000017500000000000011665471220031175 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditorContributor.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEdi0000644000175000017500000002613711665471220033442 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors; import org.eclipse.core.runtime.Preferences; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.ide.IDEActionFactory; import org.eclipse.ui.part.MultiPageEditorActionBarContributor; import org.eclipse.ui.part.MultiPageEditorPart; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.ITextEditorActionConstants; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.PreferencePage; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.xml.XMLEditor; // import org.eclipse.jdt.launching.IVMRunner; // import org.apache.uima.jcas.jcasgen.Prefs; /** * Manages the installation/deinstallation of global actions for multi-page editors. Responsible for * the redirection of global actions to the active editor. Multi-page contributor replaces the * contributors for the individual editors in the multi-page editor. */ public class MultiPageEditorContributor extends MultiPageEditorActionBarContributor { private IEditorPart activeEditorPart; Action autoJCasAction; Action qualifiedTypesAction; Action runJCasGenAction; /** * Creates a multi-page contributor. */ public MultiPageEditorContributor() { super(); createActions(); } /** * Returns the action registed with the given text editor. * * @return IAction or null if editor is null. */ protected IAction getAction(MultiPageEditorPart editor, String actionID) { ITextEditor txtEditor = ((MultiPageEditor) editor).getSourcePageEditor(); return (txtEditor == null ? null : txtEditor.getAction(actionID)); } protected IAction getAction1(ITextEditor editor, String actionID) { return (editor == null ? null : editor.getAction(actionID)); } /* * (non-JavaDoc) Method declared in AbstractMultiPageEditorActionBarContributor. */ public void setActiveEditor(IEditorPart part) { if (activeEditorPart == part) return; if (null == part) return; activeEditorPart = part; IActionBars actionBars = getActionBars(); if (actionBars != null) { MultiPageEditorPart editor = (MultiPageEditorPart) part; actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), getAction(editor, ITextEditorActionConstants.DELETE)); actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), getAction(editor, ITextEditorActionConstants.UNDO)); actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), getAction(editor, ITextEditorActionConstants.REDO)); actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), getAction(editor, ITextEditorActionConstants.CUT)); actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), getAction(editor, ITextEditorActionConstants.COPY)); actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), getAction(editor, ITextEditorActionConstants.PASTE)); actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), getAction(editor, ITextEditorActionConstants.SELECT_ALL)); actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), getAction(editor, ITextEditorActionConstants.FIND)); actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction(editor, IDEActionFactory.BOOKMARK.getId())); actionBars.updateActionBars(); } } /* * (non-Javadoc) * * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor#setActivePage(org.eclipse.ui.IEditorPart) */ public void setActivePage(IEditorPart part) { IActionBars actionBars = getActionBars(); if (actionBars != null) { ITextEditor textEditor = (part instanceof XMLEditor) ? (ITextEditor) part : null; actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), getAction1(textEditor, ITextEditorActionConstants.DELETE)); actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), getAction1(textEditor, ITextEditorActionConstants.UNDO)); actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), getAction1(textEditor, ITextEditorActionConstants.REDO)); actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), getAction1(textEditor, ITextEditorActionConstants.CUT)); actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), getAction1(textEditor, ITextEditorActionConstants.COPY)); actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), getAction1(textEditor, ITextEditorActionConstants.PASTE)); actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), getAction1(textEditor, ITextEditorActionConstants.SELECT_ALL)); actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), getAction1(textEditor, ITextEditorActionConstants.FIND)); actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction1(textEditor, IDEActionFactory.BOOKMARK.getId())); actionBars.updateActionBars(); } } private void createActions() { autoJCasAction = new Action() { // The run action is simply to toggle the setting in the prefs page, and // to update the checked status to correspond to that public void run() { TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault(); Preferences prefs = plugin.getPluginPreferences(); boolean bAutoJCasGen = !prefs.getBoolean(PreferencePage.P_JCAS); //$NON-NLS-1$ autoJCasAction.setChecked(bAutoJCasGen); prefs.setValue(PreferencePage.P_JCAS, bAutoJCasGen); //$NON-NLS-1$ } }; runJCasGenAction = new Action() { public void run() { ((MultiPageEditor) activeEditorPart).doJCasGenChkSrc(null); // don't know how to get // progress monitor } }; qualifiedTypesAction = new Action() { public void run() { TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault(); Preferences prefs = plugin.getPluginPreferences(); boolean bFullyQualifiedTypeNames = !prefs .getBoolean(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES); //$NON-NLS-1$ qualifiedTypesAction.setChecked(bFullyQualifiedTypeNames); prefs.setValue(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES, bFullyQualifiedTypeNames); //$NON-NLS-1$ // mark all pages as stale for all editors, since this is a global setting IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages(); for (int i = 0; i < pages.length; i++) { IWorkbenchPart[] editors = pages[i].getEditors(); for (int j = 0; j < editors.length; j++) { if (editors[j] != null && editors[j] instanceof MultiPageEditor) { ((MultiPageEditor) editors[j]).markAllPagesStale(); } } } } }; autoJCasAction.setText(Messages.getString("MultiPageEditorContributor.autoGenJCas")); //$NON-NLS-1$ autoJCasAction.setChecked(getAutoJCasGen()); //$NON-NLS-1$ qualifiedTypesAction.setText(Messages.getString("MultiPageEditorContributor.showFullNames")); //$NON-NLS-1$ qualifiedTypesAction.setChecked(getUseQualifiedTypes()); //$NON-NLS-1$ runJCasGenAction.setText("Run JCasGen"); } public void contributeToMenu(IMenuManager manager) { IMenuManager menu = new MenuManager("&UIMA"); //$NON-NLS-1$ manager.prependToGroup(IWorkbenchActionConstants.MB_ADDITIONS, menu); menu.add(runJCasGenAction); IMenuManager settingsMenu = new MenuManager("Settings"); //$NON-NLS-1$ menu.add(settingsMenu); settingsMenu.add(autoJCasAction); settingsMenu.add(qualifiedTypesAction); } public static boolean getAutoJCasGen() { return getUimaPrefBoolean(PreferencePage.P_JCAS, false); // Jira UIMA-1177 } public static boolean getUseQualifiedTypes() { return getUimaPrefBoolean(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES, true); } public static int getXMLindent() { return getUimaPrefInt(PreferencePage.P_XML_TAB_SPACES, 2); } public static String getCDEVnsHost() { return getUimaPrefString(PreferencePage.P_VNS_HOST, "localhost"); } public static String getCDEVnsPort() { return getUimaPrefString(PreferencePage.P_VNS_PORT, "9000"); } public static void setVnsHost(String v) { System.setProperty("VNS_HOST", v); } public static void setVnsPort(String v) { System.setProperty("VNS_PORT", v); } public static void setVnsHost() { setVnsHost(getCDEVnsHost()); } public static void setVnsPort() { setVnsPort(getCDEVnsPort()); } private static String getUimaPrefString(String key, String defaultValue) { TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault(); Preferences prefs = plugin.getPluginPreferences(); boolean isDefault = prefs.isDefault(key); if (isDefault) prefs.setDefault(key, defaultValue); return prefs.getString(key); } private static boolean getUimaPrefBoolean(String key, boolean defaultValue) { TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault(); Preferences prefs = plugin.getPluginPreferences(); boolean isDefault = prefs.isDefault(key); if (isDefault) prefs.setDefault(key, defaultValue); return prefs.getBoolean(key); } private static int getUimaPrefInt(String key, int defaultValue) { TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault(); Preferences prefs = plugin.getPluginPreferences(); boolean isDefault = prefs.isDefault(key); if (isDefault) prefs.setDefault(key, defaultValue); return prefs.getInt(key); } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/Form2Panel.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/Form2Panel.j0000644000175000017500000000234111665471220033315 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors; import org.eclipse.swt.widgets.Composite; /** * 3 element return value for 2 panel forms */ public class Form2Panel { public Composite form; public Composite left; public Composite right; public Form2Panel(Composite form, Composite left, Composite right) { this.form = form; this.left = left; this.right = right; } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/point/0000755000175000017500000000000011665471212032327 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/point/IUimaEditorExtension.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/point/IUimaE0000644000175000017500000000507711665471212033374 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.point; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.util.XMLizable; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.PartInitException; /** * The interface implemented by an external editor * */ public interface IUimaEditorExtension { /** * The first method called by the CDE after the implementation class of this * interface is instantiated. * * @return void */ public void init (); /** * When a new type of descriptor is encountered and cannot edit, CDE will * called this method to test if the external editor can edit this new type of descriptor. * * @param cde An instance of CDE * @param xmlizable New type of descriptor to be edited * @return boolean Return true if the external editor can edit the specified type of descriptor */ public boolean canEdit (MultiPageEditor cde, XMLizable xmlizable); /** * Called by CDE to activate the external editor for editing the new type of descriptor. * * * @param site * The site for which this part is being created; must not be * null. * @param editorInput * The input on which this editor should be created; must not be * null. * @param cde An instance of CDE * @param xmlizable New type of descriptor to be edited * @throws PartInitException * If the initialization of the part fails * @return void */ public void activateEditor(IEditorSite site, IEditorInput editorInput, MultiPageEditor cde, XMLizable xmlizable) throws PartInitException; } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/point/IUimaMultiPageEditor.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/point/IUimaM0000644000175000017500000000252311665471212033375 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.point; import org.eclipse.core.runtime.IProgressMonitor; /** * This interface is used to redirect the editing functions from CDE * to the external editor for a new type of Resource Specifier * */ public interface IUimaMultiPageEditor { public void addPagesForCurrentEditor(); public void pageChangeForCurrentEditor(int newPageIndex); public void doSaveForCurrentEditor(IProgressMonitor monitor); public void doSaveAsForCurrentEditor(); } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/0000755000175000017500000000000011665471220031612 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexSect0000644000175000017500000004144311665471220033431 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.util.ArrayList; import java.util.List; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddIndexDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddIndexKeyDialog; import org.apache.uima.taeconfigurator.wizards.FsIndexCollectionNewWizard; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableTree; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.ui.forms.IManagedForm; public class IndexSection extends AbstractSection { public static final String ANNOTATION_INDEX_BUILT_IN = "Annotation Index (Built-in)"; public final static int INDEX_NAME_COL = 0; public final static int INDEX_TYPE_COL = 1; public final static int ASC_DES_COL = 1; public final static int INDEX_KIND_COL = 2; public TableTree tt; // accessed by inner class private Button addIndexButton; private Button addKeyButton; private Button editButton; private Button removeButton; private Button upButton; private Button downButton; FsIndexDescription m_builtInIndexDescription = null; private Button exportButton; private IndexImportSection indexImportSection; public IndexSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Indexes", "The following indexes are defined on the type system for this engine."); } public void initialize(IManagedForm form) { super.initialize(form); // set up Composite to hold widgets in the section Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); tt = newTableTree(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION); final Table table = tt.getTable(); table.setHeaderVisible(true); newTableColumn(table).setText("Name"); newTableColumn(table).setText("Type"); newTableColumn(table).setText("Kind"); final Composite buttonContainer = newButtonContainer(sectionClient); addIndexButton = newPushButton(buttonContainer, "Add Index", "Click here to add a new index."); addKeyButton = newPushButton(buttonContainer, "Add Key", "Click here to add a new key for the selected index."); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP); downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP); exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP); // in addition to normal keyup and mouse up: table.addListener(SWT.MouseHover, this); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { if (null == indexImportSection) indexImportSection = editor.getIndexesPage().getIndexImportSection(); super.refresh(); tt.removeAll(); // add built-in annotation index updateIndexSpec(new TableTreeItem(tt, SWT.NONE), getBuiltInIndexDescription()); FsIndexDescription[] fsIndexes = getAnalysisEngineMetaData().getFsIndexes(); if (fsIndexes != null) { for (int i = 0; i < fsIndexes.length; i++) { updateIndexSpec(new TableTreeItem(tt, SWT.NONE), fsIndexes[i]); } } packTable(tt.getTable()); enable(); } private void updateIndexSpec(TableTreeItem item, FsIndexDescription ndx) { item.setText(INDEX_NAME_COL, ndx.getLabel()); item.setText(INDEX_TYPE_COL, formatName(ndx.getTypeName())); item.setText(INDEX_KIND_COL, handleDefaultIndexKind(ndx.getKind())); item.setData(ndx); removeChildren(item); FsIndexKeyDescription[] keys = ndx.getKeys(); if (null != keys) for (int i = 0; i < keys.length; i++) { updateKeySpec(new TableTreeItem(item, SWT.NONE), keys[i]); } } private void updateKeySpec(TableTreeItem item, FsIndexKeyDescription key) { String name = key.getFeatureName(); item.setText(INDEX_NAME_COL, null == name ? "TYPE PRIORITY" : name); item.setText(ASC_DES_COL, key.getComparator() == FSIndexComparator.STANDARD_COMPARE ? "Standard" : "Reverse"); item.setData(key); } public FsIndexKeyDescription createFsIndexKeyDescription() { return UIMAFramework.getResourceSpecifierFactory().createFsIndexKeyDescription(); } public FsIndexDescription getBuiltInIndexDescription() { if (m_builtInIndexDescription == null) { m_builtInIndexDescription = UIMAFramework.getResourceSpecifierFactory() .createFsIndexDescription(); m_builtInIndexDescription.setLabel(ANNOTATION_INDEX_BUILT_IN); m_builtInIndexDescription.setTypeName(CAS.TYPE_NAME_ANNOTATION); m_builtInIndexDescription.setKind("sorted"); FsIndexKeyDescription[] keys = new FsIndexKeyDescription[] { createFsIndexKeyDescription(), createFsIndexKeyDescription(), createFsIndexKeyDescription() }; keys[0].setFeatureName("begin"); keys[0].setComparator(FSIndexComparator.STANDARD_COMPARE); keys[1].setFeatureName("end"); keys[1].setComparator(FSIndexComparator.REVERSE_STANDARD_COMPARE); keys[2].setTypePriority(true); m_builtInIndexDescription.setKeys(keys); } return m_builtInIndexDescription; } private boolean notAllowed(String message) { if (isIndexDescriptor() && !editor.getIsContextLoaded()) { Utility .popMessage( "Not Allowed", "Editing or Adding Indexes can't be done here because the information about the type system is missing.", MessageDialog.INFORMATION); return true; } return false; } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addIndexButton) { if (notAllowed("Adding an Index")) return; // creating the dialog and open it AddIndexDialog dialog = new AddIndexDialog(this); if (dialog.open() == Window.CANCEL) return; FsIndexDescription id = UIMAFramework.getResourceSpecifierFactory() .createFsIndexDescription(); id.setLabel(dialog.indexName); id.setTypeName(dialog.indexType); id.setKeys(dialog.keys); id.setKind(dialog.indexKind); addFsIndexDescription(id); updateIndexSpec(new TableTreeItem(tt, SWT.NONE), id); tt.getTable().setSelection(tt.getTable().getItemCount() - 1); packTable(tt.getTable()); setFileDirty(); } else if (event.widget == addKeyButton) { if (notAllowed("Adding an Index")) return; TableTreeItem parent = tt.getSelection()[0]; if (null != parent.getParentItem()) parent = parent.getParentItem(); if (foolingAroundWithAnnotationIndex(parent)) return; FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent); AddIndexKeyDialog dialog = new AddIndexKeyDialog(this, fsid.getTypeName(), handleDefaultIndexKind(fsid.getKind()), getAlreadyUsedFeatures(fsid)); FsIndexKeyDescription newKey = addOrEditIndexKey(dialog, null); if (null != newKey) { addFsIndexKeyDescription(fsid, newKey); updateKeySpec(new TableTreeItem(parent, SWT.NONE), newKey); parent.setExpanded(true); setFileDirty(); } } else if (event.widget == removeButton) { TableTreeItem item = tt.getSelection()[0]; if (foolingAroundWithAnnotationIndex(item)) return; Object o = item.getData(); if (o instanceof FsIndexDescription) { if (Window.CANCEL == Utility.popOkCancel("Confirm Remove", "Do you want to remove this index?", MessageDialog.WARNING)) return; removeFsIndexDescription((FsIndexDescription) o); } else { if (Window.CANCEL == Utility.popOkCancel("Confirm Remove", "Do you want to remove this key?", MessageDialog.WARNING)) return; TableTreeItem parent = item.getParentItem(); FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent); removeFsIndexKeyDescription(fsid, (FsIndexKeyDescription) o); } tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1); item.dispose(); setFileDirty(); } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) { if (notAllowed("Adding an Index")) return; if (tt.getSelectionCount() != 1) return; TableTreeItem item = tt.getSelection()[0]; if (foolingAroundWithAnnotationIndex(item)) return; Object o = item.getData(); if (o instanceof FsIndexDescription) { FsIndexDescription fsid = (FsIndexDescription) o; AddIndexDialog dialog = new AddIndexDialog(this, fsid); if (dialog.open() == Window.CANCEL) return; valueChanged = false; fsid.setLabel(setValueChanged(dialog.indexName, fsid.getLabel())); fsid.setTypeName(setValueChanged(dialog.indexType, fsid.getTypeName())); fsid.setKeys(setValueChangedKeys(dialog.keys, fsid.getKeys())); fsid.setKind(setValueChanged(dialog.indexKind, handleDefaultIndexKind(fsid.getKind()))); updateIndexSpec(item, fsid); if (valueChanged) { packTable(tt.getTable()); setFileDirty(); } } else { // editing a key if (notAllowed("Adding an Index")) return; FsIndexKeyDescription key = (FsIndexKeyDescription) o; TableTreeItem parent = item.getParentItem(); FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent); AddIndexKeyDialog dialog = new AddIndexKeyDialog(this, fsid.getTypeName(), handleDefaultIndexKind(fsid.getKind()), getAlreadyUsedFeatures(fsid), key); valueChanged = false; addOrEditIndexKey(dialog, key); if (valueChanged) { updateKeySpec(item, key); packTable(tt.getTable()); setFileDirty(); } } } else if (event.widget == upButton) { int i = getIndex(tt.getSelection()[0]); swapIndexKeys(tt.getSelection()[0], i - 1); setFileDirty(); } else if (event.widget == downButton) { int i = getIndex(tt.getSelection()[0]); TableTreeItem[] items = tt.getSelection()[0].getParentItem().getItems(); swapIndexKeys(items[i + 1], i + 1); } else if (event.widget == exportButton) { try { indexImportSection.exportImportablePart("", FsIndexCollectionNewWizard.FSINDEXCOLLECTION_TEMPLATE); } finally { refresh(); // update in case of throw, even } } enable(); } private boolean foolingAroundWithAnnotationIndex(TableTreeItem item) { while (null != item.getParentItem()) item = item.getParentItem(); if (ANNOTATION_INDEX_BUILT_IN.equals(item.getText(0))) { Utility.popMessage("Not Allowed", "You cannot edit or delete the built-in Annotation Index or its keys", MessageDialog.ERROR); return true; } return false; } public void addFsIndexKeyDescription(FsIndexDescription fsid, FsIndexKeyDescription key) { FsIndexKeyDescription[] prevKeys = fsid.getKeys(); FsIndexKeyDescription[] newKeys = new FsIndexKeyDescription[prevKeys == null ? 1 : prevKeys.length + 1]; if (null != prevKeys) System.arraycopy(prevKeys, 0, newKeys, 0, prevKeys.length); newKeys[newKeys.length - 1] = key; fsid.setKeys(newKeys); } public void addFsIndexDescription(FsIndexDescription fsid) { FsIndexDescription[] oldFsIndexes = getAnalysisEngineMetaData().getFsIndexes(); FsIndexDescription[] newFsIndexes = new FsIndexDescription[oldFsIndexes == null ? 1 : oldFsIndexes.length + 1]; if (null != oldFsIndexes) System.arraycopy(oldFsIndexes, 0, newFsIndexes, 0, oldFsIndexes.length); newFsIndexes[newFsIndexes.length - 1] = fsid; getAnalysisEngineMetaData().setFsIndexes(newFsIndexes); } public void removeFsIndexDescription(FsIndexDescription fsid) { getAnalysisEngineMetaData().setFsIndexes( (FsIndexDescription[]) Utility.removeElementFromArray(getAnalysisEngineMetaData() .getFsIndexes(), fsid, FsIndexDescription.class)); } public void removeFsIndexKeyDescription(FsIndexDescription fsid, FsIndexKeyDescription key) { fsid.setKeys((FsIndexKeyDescription[]) Utility.removeElementFromArray(fsid.getKeys(), key, FsIndexKeyDescription.class)); } public List getAlreadyUsedFeatures(FsIndexDescription ndx) { List result = new ArrayList(); FsIndexKeyDescription[] items = ndx.getKeys(); if (null == items) return result; for (int i = 0; i < items.length; i++) { result.add(items[i].getFeatureName()); } return result; } public FsIndexKeyDescription addOrEditIndexKey(AddIndexKeyDialog dialog, FsIndexKeyDescription key) { if (dialog.open() == Window.CANCEL) { return null; } if (null == key) key = UIMAFramework.getResourceSpecifierFactory().createFsIndexKeyDescription(); if (dialog.typePriority) { key.setTypePriority(setValueChangedBoolean(true, key.isTypePriority())); key.setFeatureName(null); } else { key.setFeatureName(setValueChanged(dialog.featureName, key.getFeatureName())); key.setComparator(setValueChangedInt(dialog.direction, key.getComparator())); key.setTypePriority(false); } return key; } /** * This has to check the resolvedImports, mergedWithDelegates version of the fsindexes * * @param indexLabel * @return */ public boolean isDuplicateIndexLabel(String indexLabel) { FsIndexDescription[] indexes = getAnalysisEngineMetaData().getFsIndexes(); if (indexes == null) { return false; } for (int i = 0; i < indexes.length; i++) { if (indexes[i].getLabel().equals(indexLabel)) { return true; } } return false; } public void enable() { boolean selected = tt.getSelectionCount() == 1; TableTreeItem item = null; TableTreeItem parent = null; if (selected) { item = tt.getSelection()[0]; parent = item.getParentItem(); } boolean notBuiltInSelected = (selected && item != tt.getItems()[0]); notBuiltInSelected &= !(null != parent && parent == tt.getItems()[0]); addIndexButton.setEnabled(true); addKeyButton.setEnabled(notBuiltInSelected && (null != parent || /* null == parent && */!"bag".equals(item .getText(INDEX_KIND_COL)))); editButton.setEnabled(notBuiltInSelected); removeButton.setEnabled(notBuiltInSelected); exportButton.setEnabled(tt.getItemCount() > 1); // always one "built-in" upButton.setEnabled(false); downButton.setEnabled(false); if (selected) { if (null != parent && notBuiltInSelected) { TableTreeItem firstItem = parent.getItems()[0]; TableTreeItem lastItem = parent.getItems()[parent.getItems().length - 1]; upButton.setEnabled(item != firstItem); downButton.setEnabled(item != lastItem); } } } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPageWithSash.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPag0000644000175000017500000000602511665471220033360 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.jface.action.Action; import org.eclipse.swt.SWT; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.widgets.ScrolledForm; /** */ public class HeaderPageWithSash extends HeaderPage { /** * @param formEditor * @param id * @param keyPageTitle */ protected Action haction; protected Action vaction; public HeaderPageWithSash(MultiPageEditor formEditor, String id, String keyPageTitle) { super(formEditor, id, keyPageTitle); } /** * @param formEditor * @param pageTitle */ public HeaderPageWithSash(MultiPageEditor formEditor, String pageTitle) { super(formEditor, pageTitle); } protected void createToolBarActions(IManagedForm managedForm) { final ScrolledForm form = managedForm.getForm(); haction = new Action("hor", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$ public void run() { sashForm.setOrientation(SWT.HORIZONTAL); form.reflow(true); } }; haction.setChecked(true); haction.setToolTipText("Horizontal Orientation"); haction.setImageDescriptor(TAEConfiguratorPlugin .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_HORIZONTAL)); haction.setDisabledImageDescriptor(TAEConfiguratorPlugin .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_HORIZONTAL)); vaction = new Action("ver", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$ public void run() { sashForm.setOrientation(SWT.VERTICAL); form.reflow(true); } }; vaction.setChecked(false); vaction.setToolTipText("Vertical Orientation"); vaction.setImageDescriptor(TAEConfiguratorPlugin .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_VERTICAL)); vaction.setDisabledImageDescriptor(TAEConfiguratorPlugin .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_VERTICAL)); form.getToolBarManager().add(haction); form.getToolBarManager().add(vaction); form.updateToolBar(); maybeInitialize(managedForm); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportResBindSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportRes0000644000175000017500000000725311665471220033470 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.impl.ResourceManagerConfiguration_impl; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.util.InvalidXMLException; import org.eclipse.swt.widgets.Composite; /** */ public class ImportResBindSection extends ImportSection { public ImportResBindSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Imports for External Resources and Bindings", "The following definitions are included:"); // or ! DESCRIPTION } // ************************************** // * Code to support type import section // ************************************** protected boolean isAppropriate() { return true; // always show } /** * used when hovering */ protected String getDescriptionFromImport(String source) { return ""; // imports for resource bindings don't have descriptions } protected Import[] getModelImportArray() { return getResourceManagerConfiguration().getImports(); } protected void setModelImportArray(Import[] imports) { getResourceManagerConfiguration().setImports(imports); } protected void clearModelBaseValue() { getResourceManagerConfiguration().setExternalResourceBindings(externalResourceBinding0); getResourceManagerConfiguration().setExternalResources(externalResourceDescription0); } // indexes are checked and merged when the CAS is built protected boolean isValidImport(String title, String message) { ResourceManagerConfiguration savedRmc = editor.getResolvedExternalResourcesAndBindings(); if (null != savedRmc) savedRmc = (ResourceManagerConfiguration) ((ResourceManagerConfiguration_impl) savedRmc) .clone(); try { editor.setResolvedExternalResourcesAndBindings(); } catch (InvalidXMLException e) { Utility.popMessage(title, message + editor.getMessagesToRootCause(e), Utility.ERROR); revert(savedRmc); return false; } if (!isValidAe()) { revert(savedRmc); return false; } return true; } private void revert(ResourceManagerConfiguration rmc) { getResourceManagerConfiguration() .setExternalResourceBindings(rmc.getExternalResourceBindings()); getResourceManagerConfiguration().setExternalResources(rmc.getExternalResources()); editor.setResolvedExternalResourcesAndBindings(rmc); } protected void finishImportChangeAction() { editor.getResourcesPage().getResourceDependencySection().refresh(); // to change Binding flag } public void enable() { super.enable(); addButton.setEnabled(true); // can add buttons even for aggregate } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/OverviewPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/OverviewP0000644000175000017500000000466511665471220033476 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.swt.SWT; import org.eclipse.ui.forms.IManagedForm; /** * */ public class OverviewPage extends HeaderPageWithSash { private PrimitiveSection primitiveSection; // should always exist private MetaDataSection metadataSection; /** */ public OverviewPage(MultiPageEditor aEditor) { super(aEditor, "UID_OverviewPage", "Overview"); } /** * Called by the 3.0 framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { final Form2Panel form = setup2ColumnLayout(managedForm, EQUAL_WIDTH); managedForm.getForm().setText("Overview"); if (isLocalProcessingDescriptor()) { managedForm.addPart(new GeneralSection(editor, form.left)); managedForm.addPart(primitiveSection = new PrimitiveSection(editor, form.left)); managedForm.addPart(metadataSection= new MetaDataSection(editor, form.right)); } else { managedForm.addPart(metadataSection = new MetaDataSection(editor, form.left)); } createToolBarActions(managedForm); sashForm.setOrientation(SWT.HORIZONTAL); vaction.setChecked(false); haction.setChecked(true); if (!isLocalProcessingDescriptor()) { sashForm.setWeights(new int[] { 95, 5 }); } } public PrimitiveSection getPrimitiveSection() { return primitiveSection; } public MetaDataSection getMetaDataSection() { return metadataSection; } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePriorityImportSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePrior0000644000175000017500000000630411665471220033475 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.IOException; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.eclipse.swt.widgets.Composite; /** */ public class TypePriorityImportSection extends ImportSection { public TypePriorityImportSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Type Priority Imports", "The following type priority imports are included as part of the type priorities:"); } // ************************************** // * Code to support type import section // ************************************** protected boolean isAppropriate() { return true; // always show } /** * used when hovering */ protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException { TypePriorities parsedImportItem = UIMAFramework.getXMLParser().parseTypePriorities( new XMLInputSource(source)); return parsedImportItem.getDescription(); } protected Import[] getModelImportArray() { return getTypePriorities().getImports(); } protected void setModelImportArray(Import[] imports) { getTypePriorities().setImports(imports); } protected void clearModelBaseValue() { getTypePriorities().setPriorityLists(typePriorityList0); } // indexes are checked and merged when the CAS is built protected boolean isValidImport(String title, String message) { CAS savedCAS = editor.getCurrentView(); TypePriorities savedTP = editor.getMergedTypePriorities(); if (null != savedTP) savedTP = (TypePriorities) savedTP.clone(); try { editor.setMergedTypePriorities(); editor.descriptorCAS.validate(); } catch (ResourceInitializationException e1) { revertMsg(title, message, editor.getMessagesToRootCause(e1)); editor.setMergedTypePriorities(savedTP); editor.descriptorCAS.set(savedCAS); return false; } return true; } protected void finishImportChangeAction() { } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FileAndShortName.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FileAndSh0000644000175000017500000000307511665471220033337 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; public class FileAndShortName { public String fileName; public String shortName; public FileAndShortName(Object o) { if (o instanceof IFile) { IFile file = (IFile) o; fileName = file.getLocation().toString(); shortName = file.getName(); } else if (o instanceof String) { fileName = (String)o; int lastSlash = fileName.lastIndexOf('/'); shortName = (lastSlash >= 0) ? fileName.substring(lastSlash + 1) : fileName; } else { IPath path = (IPath) o; fileName = path.toString(); shortName = path.toFile().getName(); } } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/0000755000175000017500000000000011665471216033241 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddAllowedValueDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000000602111665471216033343 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class AddAllowedValueDialog extends AbstractDialogKeyVerify { private StyledText allowedValueUI; private Text descriptionUI; public String allowedValue; public String description; private AllowedValue existingAv; /** * Constructor for Adding or Editing an Allowed Value. * * @param aSection * @param aExistingTd */ public AddAllowedValueDialog(AbstractSection aSection, AllowedValue aExistingAv) { super(aSection, "Add an Allowed Value for a String subtype", "Use this panel to add or edit an allowed value. The allowed value is any string."); existingAv = aExistingAv; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingAv); // This part of the form looks like this sketch // // Allowed Value: Text field << in 2 grid composite // description: Text field << in 2 grid composite Composite twoCol = new2ColumnComposite(mainArea); allowedValueUI = newLabeledSingleLineStyledText(twoCol, "Allowed Value", "A literal string value which this string is allowed to have"); descriptionUI = newDescription(twoCol, "Description of the allowed value"); newErrorMessage(twoCol, 2); if (null != existingAv) { descriptionUI.setText(convertNull(existingAv.getDescription())); allowedValueUI.setText(convertNull(existingAv.getString())); } return mainArea; } public void copyValuesFromGUI() { allowedValue = allowedValueUI.getText(); description = nullIf0lengthString(descriptionUI.getText()); } public boolean isValid() { if (allowedValue.length() == 0) return false; return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(allowedValue.length() > 0); } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityFeatureDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001513611665471216033352 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection; import org.apache.uima.taeconfigurator.editors.ui.Utility; public class AddCapabilityFeatureDialog extends AbstractDialogMultiColTable { public String[] features; // this is the selection public boolean[] inputs; public boolean[] outputs; public boolean allFeaturesInput = false; public boolean allFeaturesOutput = false; private Feature[] allFeatures; private Capability capability; private Type selectedType; private boolean inputNotAllowed = true; private static Feature[] featureArray0 = new Feature[0]; public AddCapabilityFeatureDialog(AbstractSection aSection, Type aSelectedType, Capability c) { super( aSection, "Specify features input and / or output", "Designate by mouse clicking one or more features in the Input and/or Output column, to designate as Input and/or Output press \"OK\""); selectedType = aSelectedType; allFeatures = (Feature[]) selectedType.getFeatures().toArray(featureArray0); Arrays.sort(allFeatures); capability = c; TypeOrFeature[] localInputs = c.getInputs(); String typeName = selectedType.getName(); if (null != localInputs) { for (int i = 0; i < localInputs.length; i++) { if (localInputs[i].isType() && typeName.equals(localInputs[i].getName())) { inputNotAllowed = false; break; } } } } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); ((GridData) table.getLayoutData()).heightHint = 100; table.setHeaderVisible(true); table.setLinesVisible(true); new TableColumn(table, SWT.NONE).setText("Feature Name"); new TableColumn(table, SWT.NONE).setText("Input"); new TableColumn(table, SWT.NONE).setText("Output"); TableItem item = new TableItem(table, SWT.NONE); item.setText(0, CapabilitySection.ALL_FEATURES); TypeOrFeature tof = CapabilitySection.getTypeOrFeature(capability.getInputs(), selectedType .getName()); setChecked(item, 1, null == tof ? false : tof.isAllAnnotatorFeatures()); tof = CapabilitySection.getTypeOrFeature(capability.getOutputs(), selectedType.getName()); setChecked(item, 2, null == tof ? false : tof.isAllAnnotatorFeatures()); for (int i = 0; i < allFeatures.length; i++) { item = new TableItem(table, SWT.NONE); item.setText(0, allFeatures[i].getShortName()); setChecked(item, 1, CapabilitySection.isInput(getTypeFeature(allFeatures[i]), capability)); setChecked(item, 2, CapabilitySection.isOutput(getTypeFeature(allFeatures[i]), capability)); } table.removeListener(SWT.Selection, this); table.addListener(SWT.MouseDown, this); // for i / o toggling section.packTable(table); newErrorMessage(composite); return composite; } /** * return the actual type name : short-feature-name * * @param feature * @return */ protected String getTypeFeature(Feature feature) { return selectedType.getName() + ':' + feature.getShortName(); } protected void toggleValue(TableItem item, int col) { if (1 == col && inputNotAllowed) { Utility.popMessage("Input not allowed", "Input not allowed unless the type itself is also marked as an input.", MessageDialog.ERROR); return; } super.toggleValue(item, col); // updates numberChecked for this item if (item.getText(col).equals(checkedIndicator(col))) if (item.getText(0).equals(CapabilitySection.ALL_FEATURES)) uncheckAllOtherFeatures(col); else setChecked(table.getItem(0), col, false); // uncheck all-features } private void uncheckAllOtherFeatures(int column) { TableItem[] items = table.getItems(); for (int i = 1; i < items.length; i++) { setChecked(items[i], column, false); } } public void copyValuesFromGUI() { List names = new ArrayList(); List ins = new ArrayList(); List outs = new ArrayList(); for (int i = table.getItemCount() - 1; i >= 1; i--) { TableItem item = table.getItem(i); if (item.getText(1).equals(checkedIndicator(1)) || item.getText(2).equals(checkedIndicator(2))) { names.add(item.getText(0)); ins.add(Boolean.valueOf(item.getText(1).equals(checkedIndicator(1)))); outs.add(Boolean.valueOf(item.getText(2).equals(checkedIndicator(2)))); } } features = (String[]) names.toArray(stringArray0); inputs = new boolean[features.length]; outputs = new boolean[features.length]; for (int i = 0; i < features.length; i++) { inputs[i] = ((Boolean) ins.get(i)).booleanValue(); outputs[i] = ((Boolean) outs.get(i)).booleanValue(); } TableItem item = table.getItem(0); allFeaturesInput = item.getText(1).equals(checkedIndicator(1)); allFeaturesOutput = item.getText(2).equals(checkedIndicator(2)); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000004160411665471216033351 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Arrays; import java.util.Comparator; import java.util.Set; import org.apache.uima.taeconfigurator.StandardStrings; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; public abstract class AbstractDialog extends Dialog implements Listener, StandardStrings { private final static boolean contentAssistAvailable; static { boolean contentAssistIsOK = false; try { Class.forName("org.eclipse.ui.fieldassist.ContentAssistField"); contentAssistIsOK = true; } catch (ClassNotFoundException e) { } contentAssistAvailable = contentAssistIsOK; } protected MultiPageEditor editor; protected AbstractSection section; protected Button okButton; protected Label errorMessageUI; protected String title; protected String dialogDescription; /** * @param parentShell */ protected AbstractDialog(AbstractSection section, String title, String description) { // maintainers: don't use new shell; see comment in Dialog class super(section.getSection().getShell()); commonInit(section, title, description); } protected AbstractDialog(Shell shell, String title, String description) { super(shell); commonInit(null, title, description); } private void commonInit(AbstractSection aSection, String aTitle, String aDescription) { section = aSection; editor = (null == section)? null : section.editor; setShellStyle(getShellStyle() | SWT.RESIZE); title = aTitle; dialogDescription = aDescription; } public void setTitle(String title) { this.title = title; } public void setMessage(String msg) { this.dialogDescription = msg; } protected Control createDialogArea(Composite parent) { // create composite Composite composite = (Composite) super.createDialogArea(parent); createWideLabel(composite, dialogDescription); return composite; } protected Control createDialogArea(Composite parent, Object existing) { Composite composite = (Composite) super.createDialogArea(parent); createWideLabel(composite, dialogDescription); if (null != existing) getShell().setText(getShell().getText().replaceFirst("Add", "Edit")); return composite; } protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText(title); } protected Label createWideLabel(Composite parent, String message) { Label label = null; label = new Label(parent, SWT.WRAP); label.setText(null != message ? message : ""); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); label.setLayoutData(data); return label; } protected void createButtonsForButtonBar(Composite parent) { super.createButtonsForButtonBar(parent); okButton = getButton(IDialogConstants.OK_ID); okButton.setEnabled(false); } public static final String[] stringArray0 = new String[0]; protected void setTextAndTip(Button c, String label, String tip) { c.setText(label); c.setToolTipText(tip); } protected void setTextAndTip(CCombo c, String label, String tip) { c.setText(label); c.setToolTipText(tip); } protected void setTextAndTip(Label c, String label, String tip) { c.setText(label); c.setToolTipText(tip); } protected Composite new2ColumnComposite(Composite parent) { Composite twoCol = new Composite(parent, SWT.NONE); twoCol.setLayout(new GridLayout(2, false)); // false = not equal width ((GridLayout) twoCol.getLayout()).marginHeight = 0; ((GridLayout) twoCol.getLayout()).marginWidth = 0; twoCol.setLayoutData(new GridData(GridData.FILL_BOTH)); return twoCol; } protected Text newDescription(Composite twoCol, String tip) { setTextAndTip(new Label(twoCol, SWT.NONE), S_DESCRIPTION, tip); Text t = new Text(twoCol, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); t.setLayoutData(new GridData(GridData.FILL_BOTH)); ((GridData) t.getLayoutData()).heightHint = 100; t.setToolTipText(tip); return t; } protected CCombo newLabeledCCombo(Composite parent, String label, String tip) { setTextAndTip(new Label(parent, SWT.NONE), label, tip); return newCCombo(parent, tip); } protected CCombo newCCombo(Composite parent, String tip) { final CCombo cc = new CCombo(parent, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY); cc.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_WHITE)); cc.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // without these next lines, the height of the ccombo is too small // especially on a Mac FontData [] fontData = cc.getFont().getFontData(); ((GridData) cc.getLayoutData()).heightHint = 2 * fontData[0].getHeight(); cc.addListener(SWT.Selection, this); cc.setToolTipText(tip); cc.addKeyListener(new KeyListener() { private final StringBuffer b = new StringBuffer(); public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { if (e.keyCode == SWT.BS) { if (b.length() > 0) b.deleteCharAt(b.length() - 1); } else if (Character.isJavaIdentifierPart(e.character) || e.character == '.') b.append(e.character); else return; final String[] ccItems = cc.getItems(); final String partial = b.toString(); int iBefore = -1; for (int i = 0; i < ccItems.length; i++) { if (ccItems[i].startsWith(partial)) { iBefore = i; break; } } if (iBefore >= 0) cc.setText(cc.getItem(iBefore)); } }); return cc; } protected Button newButton(Composite parent, int style, String name, String tip) { Button b = new Button(parent, style); setTextAndTip(b, name, tip); b.addListener(SWT.Selection, this); return b; } protected Text newText(Composite parent, int style, String tip) { Text t = new Text(parent, style | SWT.BORDER); t.setToolTipText(tip); t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); t.addListener(SWT.KeyUp, this); t.addListener(SWT.MouseUp, this); // for paste operation return t; } protected Text newLabeledText(Composite parent, int style, String label, String tip) { setTextAndTip(new Label(parent, SWT.NONE), label, tip); return newText(parent, style, tip); } protected Tree newTree(Composite parent, int style) { Tree tree = new Tree(parent, style | SWT.BORDER); GridData gd = new GridData(GridData.FILL_BOTH); tree.setLayoutData(gd); return tree; } /** * Styles = SWT.SINGLE / MULTI / CHECK / FULL_SELECTION / HIDE_SELECTION * * @param parent * @param style * @return the new table widget */ protected Table newTable(Composite parent, int style) { Table table = new Table(parent, style | SWT.BORDER); GridData gd = new GridData(GridData.FILL_BOTH); table.setLayoutData(gd); table.addListener(SWT.Selection, this); table.addListener(SWT.KeyUp, this); // delete key return table; } public int getHitColumn(TableItem item, Point p) { for (int i = item.getParent().getColumnCount() - 1; i >= 0; i--) { Rectangle columnBounds = item.getBounds(i); if (columnBounds.contains(p)) return i; } return -1; } public Composite newButtonContainer(Composite parent) { Composite buttonContainer = new Composite(parent, SWT.NONE); buttonContainer.setLayout(new GridLayout()); buttonContainer.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); return buttonContainer; } public Button newPushButton(Composite parent, String label, String tip) { Button button = new Button(parent, SWT.PUSH); button.setText(label); button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); // button.pack(); button.setToolTipText(tip); button.addListener(SWT.Selection, this); return button; } protected void newErrorMessage(Composite c) { newErrorMessage(c, 1); } protected void newErrorMessage(Composite twoCol, int span) { Label m = new Label(twoCol, SWT.WRAP); m.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); ((GridData) m.getLayoutData()).horizontalSpan = span; ((GridData) m.getLayoutData()).widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH); errorMessageUI = m; } protected void setErrorMessage(String msg) { errorMessageUI.setText(msg); Composite shell = errorMessageUI.getParent(); while (!(shell instanceof Shell)) shell = shell.getParent(); shell.setSize(shell.computeSize(-1, -1)); } // subclasses override, and often use super.handleEvent to call this public void handleEvent(Event event) { if (okButton != null) // may be null if handler called from // main area setText event, during construction // because button bar is constructed after main area enableOK(); } protected void superButtonPressed(int buttonId) { super.buttonPressed(buttonId); } // overridden where needed protected void buttonPressed(int buttonId) { if (buttonId == IDialogConstants.OK_ID) { copyValuesFromGUI(); if (!isValid()) return; // keeps dialog open } super.buttonPressed(buttonId); } public abstract void copyValuesFromGUI(); public abstract boolean isValid(); protected Control createButtonBar(Composite c) { Control returnValue = super.createButtonBar(c); enableOK(); return returnValue; } public abstract void enableOK(); public boolean useQualifiedTypes() { return MultiPageEditorContributor.getUseQualifiedTypes(); } protected String[] getAllTypesAsSortedArray() { String[] allTypes = (String[]) section.editor.allTypes.get().keySet().toArray(stringArray0); Arrays.sort(allTypes, new Comparator() { public int compare(Object o1, Object o2) { String shortName1 = AbstractSection.getShortName((String) o1); String shortName2 = AbstractSection.getShortName((String) o2); if (!shortName1.equals(shortName2)) return shortName1.compareTo(shortName2); String namespace1 = AbstractSection.getNameSpace((String) o1); String namespace2 = AbstractSection.getNameSpace((String) o2); return namespace1.compareTo(namespace2); } }); return allTypes; } protected Text newLabeledTypeInput(AbstractSection aSection, Composite parent, String label, String tip) { setTextAndTip(new Label(parent, SWT.NONE), label, tip); return newTypeInput(aSection, parent); } /** * @param twoCol */ protected Text newTypeInput(AbstractSection aSection, Composite twoCol) { Composite tc = new2ColumnComposite(twoCol); final TypesWithNameSpaces candidatesToPickFrom = getTypeSystemInfoList(); // provide an ArrayList of final Text text; if (contentAssistAvailable) { ContentAssistField32 caf = new ContentAssistField32(tc, candidatesToPickFrom); text = caf.getControl(); } else { text = newText(tc, SWT.BORDER, ""); } text.setToolTipText("Enter a Type name." + (contentAssistAvailable ? "Content Assist is available (press Ctrl + Space)" : "")); text.getParent().setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); text.addListener(SWT.KeyUp, this); text.addListener(SWT.MouseUp, this); // for paste operation text.addListener(SWT.Modify, this); // for content assist // newText(tc, SWT.NONE, // "Enter a Type name. Content Assist is available on Eclipse 3.2 and beyond (press Ctrl + Space)"); // ContentProposalAdapter adapter = new ContentProposalAdapter( // text, new TextContentAdapter(), // candidatesToPickFrom, // contentAssistActivationKey, // contentAssistActivationChars); // adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE); Button browseButton = newPushButton(tc, "Browse", "Click here to browse possible types"); browseButton.removeListener(SWT.Selection, this); final AbstractSection finalSection = aSection; browseButton.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { errorMessageUI.setText(""); SelectTypeDialog dialog = new SelectTypeDialog(finalSection, candidatesToPickFrom); // OpenTypeSystemSelectionDialog dialog = // new OpenTypeSystemSelectionDialog(getShell(), typeList); if (dialog.open() != IDialogConstants.OK_ID) return; text.setText((null == dialog.nameSpaceName || "".equals(dialog.nameSpaceName)) ? dialog.typeName : dialog.nameSpaceName + "." + dialog.typeName); if (okButton != null) enableOK(); /* Object[] types = dialog.getResult(); if (types != null && types.length > 0) { ITypeSystemInfo selectedType = (ITypeSystemInfo) types[0]; text.setText(selectedType.getFullName()); enableOK(); } */ } }); /* TypeSystemCompletionProcessor processor = new TypeSystemCompletionProcessor( candidatesToPickFrom); ControlContentAssistHelper.createTextContentAssistant(text, processor); text.addListener(SWT.KeyDown, new Listener() { public void handleEvent(Event e) { errorMessageUI.setText(""); } }); text.addListener(SWT.Modify, new Listener() { public void handleEvent(Event e) { textModifyCallback(e); } }); */ return text; } public void textModifyCallback(Event e) { } // default implementation - always overridden when used public TypesWithNameSpaces getTypeSystemInfoList() { return new TypesWithNameSpaces(); } protected boolean typeContainedInTypeSystemInfoList(String fullTypeName, TypesWithNameSpaces types) { String key = AbstractSection.getShortName(fullTypeName); String nameSpace = AbstractSection.getNameSpace(fullTypeName); Set s = (Set)types.sortedNames.get(key); if (null == s) return false; return s.contains(nameSpace); } /** * In XML, a 0 - length string is represented as , while a null value causes the element to * be omitted. Fix up values to be null if empty. * * @param v * @return null for 0 length string */ public static String nullIf0lengthString(String v) { if ("".equals(v)) return null; return v; } public static String convertNull(String v) { if (null == v) return ""; return v; } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ExportImportablePartDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/E0000644000175000017500000001245611665471216033360 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.text.MessageFormat; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class ExportImportablePartDialog extends AbstractDialog { private Text baseFileNameUI; private Button importByNameUI; private Button importByLocationUI; public boolean isImportByName; private String rootPath; private DialogModifyListener m_dialogModifyListener = new DialogModifyListener(); private Text genFilePathUI; public String genFilePath; public String baseFileName; private class DialogModifyListener implements ModifyListener { public void modifyText(ModifyEvent e) { String text = genFilePathUI.getText(); int pos = text.lastIndexOf(baseFileName + ".xml"); if (pos == -1) pos = text.length(); baseFileName = baseFileNameUI.getText(); genFilePathUI.setText(text.substring(0, pos) + baseFileName + ".xml"); if (okButton != null) enableOK(); } } private class DialogVerifyListener implements VerifyListener { public void verifyText(VerifyEvent e) { if (0 <= e.text.indexOf('.')) { setErrorMessage(MessageFormat.format("invalid character(s): ''{0}''", new Object[] { e.text })); e.doit = false; } else setErrorMessage(""); } } public ExportImportablePartDialog(AbstractSection aSection) { super(aSection, "Export an importable part", "Specify a base file name, and perhaps alter the path where it should be stored, and press OK"); rootPath = aSection.editor.getFile().getParent().getLocation().toString() + '/'; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); AbstractSection.spacer(composite); createWideLabel(composite, "Base file name (without path or following \".xml\":"); baseFileNameUI = new Text(composite, SWT.BORDER); baseFileNameUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); baseFileNameUI.addModifyListener(m_dialogModifyListener); baseFileNameUI.addVerifyListener(new DialogVerifyListener()); baseFileName = ""; newErrorMessage(composite); createWideLabel(composite, "Where the generated part descriptor file will be stored:"); genFilePathUI = new Text(composite, SWT.BORDER | SWT.H_SCROLL); genFilePathUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); genFilePathUI.setText(rootPath + ".xml"); new Label(composite, SWT.NONE).setText(""); importByNameUI = new Button(composite, SWT.RADIO); importByNameUI.setText("Import by Name"); importByNameUI .setToolTipText("Importing by name looks up the name on the classpath and datapath."); importByLocationUI = new Button(composite, SWT.RADIO); importByLocationUI.setText("Import By Location"); importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL"); String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject()); if (defaultBy.equals("location")) { importByNameUI.setSelection(false); importByLocationUI.setSelection(true); } else { importByNameUI.setSelection(true); importByLocationUI.setSelection(false); } baseFileNameUI.setFocus(); return composite; } public void enableOK() { boolean bEnableOk = (baseFileNameUI != null && !baseFileNameUI.getText().trim().equals("")); okButton.setEnabled(bEnableOk); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { genFilePath = genFilePathUI.getText(); isImportByName = importByNameUI.getSelection(); CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location"); } public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ResourcePickerDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/R0000644000175000017500000001451011665471216033366 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Arrays; import java.util.Comparator; import java.util.List; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.swt.widgets.TreeItem; public class ResourcePickerDialog extends AbstractDialog { protected Tree resourcesUI; protected TreeColumn resourcesUIc1; protected TreeColumn resourcesUIc2; public IResource pickedResource; protected Object [] result; public ResourcePickerDialog(Shell shell) { super(shell, "Select a File", "Use this panel to select a file in the Workspace"); } private static final Comparator resourceComparator = new Comparator () { public int compare(Object arg0, Object arg1) { IResource r0 = (IResource) arg0; IResource r1 = (IResource) arg1; return r0.getName().compareTo(r1.getName()); } }; private void populate(TreeItem parent, IResource[] resources) { Arrays.sort(resources, resourceComparator); for (int i = 0; i < resources.length; i++) { TreeItem item = new TreeItem(parent, SWT.NULL); IResource r = resources[i]; item.setText(r.getName()); item.setData(r); if (r instanceof IContainer) { new TreeItem(item, SWT.NULL); } } } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent); resourcesUI = newTree(mainArea, SWT.SINGLE); ((GridData)resourcesUI.getLayoutData()).heightHint = 400; resourcesUIc1 = new TreeColumn(resourcesUI, SWT.LEFT); resourcesUIc2 = new TreeColumn(resourcesUI, SWT.LEFT); setupResourcesByLocation(); return mainArea; } protected void setupResourcesByLocation() { resourcesUI.removeAll(); resourcesUI.removeListener(SWT.Expand, this); // remove to prevent triggering while setting up resourcesUI.removeListener(SWT.Selection, this); // remove to prevent triggering while setting up resourcesUIc1.setWidth(500); resourcesUIc2.setWidth(0); resourcesUI.setHeaderVisible(false); TreeItem topItem = new TreeItem(resourcesUI, SWT.NONE); topItem.setText("Workspace"); IWorkspaceRoot root = TAEConfiguratorPlugin.getWorkspace().getRoot().getWorkspace().getRoot(); try { IResource[] projects = root.members(); populate(topItem, projects); } catch (CoreException e) { throw new InternalErrorCDE("unhandled exception", e); } topItem.setExpanded(true); resourcesUI.addListener(SWT.Expand, this); resourcesUI.addListener(SWT.Selection, this); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == resourcesUI && event.type == SWT.Expand) { TreeItem expandedNode = (TreeItem) event.item; TreeItem maybeDummy = expandedNode.getItem(0); if (null == maybeDummy.getData()) { maybeDummy.dispose(); IResource parentResource = (IResource)expandedNode.getData(); try { populate(expandedNode, ((IContainer)parentResource).members()); } catch (CoreException e) { throw new InternalErrorCDE("unhandled exception", e); } } } else if (event.widget == resourcesUI && event.type == SWT.Selection) { copyValuesFromGUI(); } super.handleEvent(event); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { if (resourcesUI.getSelectionCount() > 0) { pickedResource = (IResource)resourcesUI.getSelection()[0].getData(); IPath ipath = (null == pickedResource) ? null : pickedResource.getFullPath(); result = (null == ipath || (2 > ipath.segmentCount())) // project name alone cant be given to getFile ? null : new IFile[] {TAEConfiguratorPlugin.getWorkspace().getRoot().getFile(ipath)}; } } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { if ( (0 < resourcesUI.getSelectionCount()) && (resourcesUI.getSelection()[0].getData() instanceof IFile)) { okButton.setEnabled(true); } else { okButton.setEnabled(false); } } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid() */ public boolean isValid() { return true; } public Object[] getResult() { return result; } public void setResult(List aResult) { if (null == aResult) { result = null; } else { aResult.toArray(result = new Object[aResult.size()]); } } } ././@LongLink0000000000000000000000000000020200000000000011557 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001473411665471216033355 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.FileLanguageResourceSpecifier; import org.apache.uima.resource.FileResourceSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.ExtnlResBindSection; import org.apache.uima.taeconfigurator.editors.ui.Utility; public class AddExternalResourceDialog extends AbstractDialogKeyVerify { private ExternalResourceDescription existingXRD = null; private StyledText xrNameUI; private String originalXrName; private Text xrDescriptionUI; private StyledText xrUrlUI; private StyledText xrUrlSuffixUI; private StyledText xrImplementationUI; private ExtnlResBindSection extnlResBindSection; public String xrName; public String xrDescription; public String xrUrl; public String xrUrlSuffix; public String xrImplementation; public AddExternalResourceDialog(AbstractSection aSection) { super(aSection, "Add an External Resource Definition", "Define and name an external resource"); extnlResBindSection = (ExtnlResBindSection) aSection; } public AddExternalResourceDialog(AbstractSection aSection, ExternalResourceDescription aExistingXRD) { this(aSection); existingXRD = aExistingXRD; originalXrName = existingXRD.getName(); } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent, existingXRD); // name: styledText name // description: Text multi-line // URL or // URL_Prefix: styledText URL // (optional) // // URL_Suffix: styledText URL_Suffix // (optional) // // Implementation: styledText // (optional) createWideLabel( composite, "The first URL field is used to identify the external resource.\nIf both URL fields are used, they form a name by concatenating the first with the document language and then with the second (suffix) URL.\nThe (optional) Implementation specifies a Java class which implements the interface used by the Analysis Engine to access the resource."); Composite twoCol = new2ColumnComposite(composite); xrNameUI = newLabeledSingleLineStyledText(twoCol, "Name:", "(Required) The name of this resource; it must be unique in this Analysis Engine."); xrDescriptionUI = newDescription(twoCol, "(Optional) Description of the External Resource"); xrUrlUI = newLabeledSingleLineStyledText(twoCol, "URL:", "(Required) A URL for this resource, or the URL prefix if a suffix is being used"); xrUrlSuffixUI = newLabeledSingleLineStyledText( twoCol, "URL Suffix", "(Optional) A URL part that will be suffixed to the prefix with the language being used inserted in-between"); xrImplementationUI = newLabeledSingleLineStyledText( twoCol, "Implementation", "(Optional) The name of a Java class implementing the interface used by the Analysis Engine to access this resource."); newErrorMessage(twoCol, 2); if (null != existingXRD) { xrNameUI.setText(existingXRD.getName()); xrDescriptionUI.setText(convertNull(existingXRD.getDescription())); ResourceSpecifier rs = existingXRD.getResourceSpecifier(); if (rs instanceof FileResourceSpecifier) xrUrlUI.setText(((FileResourceSpecifier) rs).getFileUrl()); else if (rs instanceof FileLanguageResourceSpecifier) { xrUrlUI.setText(((FileLanguageResourceSpecifier) rs).getFileUrlPrefix()); xrUrlSuffixUI.setText(((FileLanguageResourceSpecifier) rs).getFileUrlSuffix()); } else { Utility.popMessage("Unknown resource type", "The resource type '" + rs.getClass().getName() + "' is unknown. Editing should be done by hand in the source view.", MessageDialog.WARNING); } String impName = existingXRD.getImplementationName(); xrImplementationUI.setText(convertNull(impName)); } return composite; } public void copyValuesFromGUI() { xrName = xrNameUI.getText(); xrDescription = nullIf0lengthString(xrDescriptionUI.getText()); xrUrl = xrUrlUI.getText(); xrUrlSuffix = nullIf0lengthString(xrUrlSuffixUI.getText()); xrImplementation = nullIf0lengthString(xrImplementationUI.getText()); } /** * Called for many widgets */ public boolean verifyKeyChecks(VerifyEvent event) { if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB) return true; if (Character.isJavaIdentifierPart(event.character) || event.character == '.') return true; if ((event.widget == xrUrlUI || event.widget == xrUrlSuffixUI) && (event.character == '/' || event.character == ':')) return true; return false; } public boolean isValid() { if (xrName.length() == 0) return false; if (!xrName.equals(originalXrName) && extnlResBindSection.resourceNameAlreadyDefined(xrName)) return false; if (xrUrl.length() == 0) return false; return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(xrName.length() > 0 && xrUrl.length() > 0); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SelectTypeDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/S0000644000175000017500000001376511665471216033402 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; public class SelectTypeDialog extends AbstractDialog { private Text typeNameUI; private Table matchingTypesUI; private Table nameSpacesUI; public String typeName = "error-TypeName-never-set"; public String nameSpaceName = "error-NameSpaceName-never-set"; private TypesWithNameSpaces types; /** * @param aSection * @param title * @param description */ public SelectTypeDialog(AbstractSection section, TypesWithNameSpaces types) { super(section, "Select Type Name", "Select an Existing CAS Type name from the set of defined types"); this.types = types; } /* * (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#createDialogArea(org.eclipse.swt.widgets.Composite) * * Use labels on left (2 column layout) * Create a text input area labeled: Type: * Create a list output area labeled: Matching: * Create a list output area labeled: NameSpaces: * Bottom gets normal OK / Cancel buttons */ protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite)super.createDialogArea(parent); createWideLabel(mainArea, "Type Name:"); typeNameUI = newText(mainArea, SWT.SINGLE, "Specify the type name"); typeNameUI.addListener(SWT.Modify, this); createWideLabel(mainArea, "Matching Types:"); matchingTypesUI = newTable(mainArea, SWT.SINGLE); ((GridData)matchingTypesUI.getLayoutData()).heightHint = 250; ((GridData)matchingTypesUI.getLayoutData()).minimumHeight = 100; typeNameUI.addListener(SWT.Selection, this); createWideLabel(mainArea, "NameSpaces:"); nameSpacesUI = newTable(mainArea, SWT.SINGLE); ((GridData)nameSpacesUI.getLayoutData()).heightHint = 75; ((GridData)nameSpacesUI.getLayoutData()).minimumHeight = 40; displayFilteredTypes(""); return mainArea; } private void displayFilteredTypes(String aTypeName) { matchingTypesUI.setRedraw(false); matchingTypesUI.removeAll(); Map.Entry topEntry = null; aTypeName = aTypeName.toLowerCase(); for (Iterator it = types.sortedNames.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String candidateTypeName = ((String)entry.getKey()).toLowerCase(); if (candidateTypeName.startsWith(aTypeName)) { if (null == topEntry) topEntry = entry; TableItem item = new TableItem(matchingTypesUI, SWT.NULL); item.setText((String) entry.getKey()); item.setData(entry); } } if (matchingTypesUI.getItemCount() > 0) { matchingTypesUI.select(0); displayNameSpacesForSelectedItem(topEntry); } matchingTypesUI.setRedraw(true); } private void displayNameSpacesForSelectedItem(Map.Entry entry) { Set nameSpaces = (Set)entry.getValue(); nameSpacesUI.removeAll(); for (Iterator it = nameSpaces.iterator(); it.hasNext();) { String nameSpace = (String) it.next(); TableItem item = new TableItem(nameSpacesUI, SWT.NULL); item.setText(nameSpace); item.setData(entry); } if (nameSpacesUI.getItemCount() > 0) { nameSpacesUI.select(0); } } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == typeNameUI && event.type == SWT.Modify) { typeName = typeNameUI.getText(); displayFilteredTypes(typeName); } else if (event.widget == matchingTypesUI && event.type == SWT.Selection) { displayNameSpacesForSelectedItem( (Map.Entry)(matchingTypesUI.getSelection()[0].getData())); } super.handleEvent(event); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { if (0 < matchingTypesUI.getSelectionCount()) { typeName = matchingTypesUI.getSelection()[0].getText(); } if (0 < nameSpacesUI.getSelectionCount()) { nameSpaceName = nameSpacesUI.getSelection()[0].getText(); } } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { copyValuesFromGUI(); okButton.setEnabled( (0 < nameSpacesUI.getSelectionCount()) && (0 < matchingTypesUI.getSelectionCount())); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid() */ public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeToPriorityListDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000000720611665471216033351 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Arrays; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.List; import org.apache.uima.cas.CAS; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class AddTypeToPriorityListDialog extends AbstractDialog { private String[] m_selectedTypeNames; // this is the selection private String[] m_availableTypeNames; private List typeList; /** * @param parentShell */ public AddTypeToPriorityListDialog(AbstractSection aSection, Set allowableTypeNameHash, String[] typesInList) { super(aSection, "Add Types to Priority List", "Select one or more types and press OK"); m_availableTypeNames = getAvailableTypeNames(allowableTypeNameHash, typesInList); } private String[] getAvailableTypeNames(Set allowableTypeNameHash, String[] alreadyUsedTypes) { Arrays.sort(alreadyUsedTypes); HashSet availableHash = new HashSet(); Iterator typeNameIterator = allowableTypeNameHash.iterator(); while (typeNameIterator.hasNext()) { String sTypeName = (String) typeNameIterator.next(); if (0 > Arrays.binarySearch(alreadyUsedTypes, sTypeName) && !CAS.TYPE_NAME_TOP.equals(sTypeName)) { availableHash.add(sTypeName); } } String[] availableTypeNames = (String[]) availableHash.toArray(stringArray0); Arrays.sort(availableTypeNames); return availableTypeNames; } protected Control createDialogArea(Composite parent) { // create composite Composite composite = (Composite) super.createDialogArea(parent); typeList = new List(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.heightHint = 100; typeList.setLayoutData(gridData); for (int i = 0; i < m_availableTypeNames.length; i++) { typeList.add(m_availableTypeNames[i]); } return composite; } public String[] getSelectedTypeNames() { return (String[]) m_selectedTypeNames.clone(); } public void copyValuesFromGUI() { m_selectedTypeNames = new String[typeList.getSelectionCount()]; for (int i = 0, j = 0; i < m_availableTypeNames.length; i++) { if (typeList.isSelected(i)) { m_selectedTypeNames[j++] = m_availableTypeNames[i]; } } } public boolean isValid() { return true; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { okButton.setEnabled(true); } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerify.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000000501611665471216033346 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public abstract class AbstractDialogKeyVerify extends AbstractDialog implements VerifyKeyListener { protected AbstractDialogKeyVerify(AbstractSection aSection, String title, String description) { super(aSection, title, description); } protected StyledText newLabeledSingleLineStyledText(Composite twoCol, String label, String tip) { setTextAndTip(new Label(twoCol, SWT.NONE), label, tip); return newSingleLineStyledText(twoCol, tip); } protected StyledText newSingleLineStyledText(Composite parent, String tip) { StyledText w = new StyledText(parent, SWT.SINGLE | SWT.BORDER); w.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); w.setToolTipText(tip); w.addListener(SWT.KeyUp, this); w.addVerifyKeyListener(this); w.addListener(SWT.MouseUp, this); // for paste operation return w; } public void verifyKey(VerifyEvent event) { event.doit = true; errorMessageUI.setText(""); if (verifyKeyChecks(event)) return; event.doit = false; setErrorMessage("An invalid key press was ignored. Please try again."); return; } // overridden in methods needing other key checks /** * Default verify key checks */ public boolean verifyKeyChecks(VerifyEvent event) { return true; } } ././@LongLink0000000000000000000000000000020000000000000011555 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityTypeDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000002350011665471216033344 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.cas.CAS; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection; public class AddCapabilityTypeDialog extends AbstractDialogMultiColTable { public String[] types; // this is the selection public boolean[] inputs; public boolean[] outputs; private static final int NAME = 0; private static final int INPUT = 1; private static final int OUTPUT = 2; private static final int NAMESPACE = 3; CapabilitySection capabilitySection; private Capability capability; private TableTreeItem existing = null; private static List excludedTypes = new ArrayList(); { excludedTypes.add(CAS.TYPE_NAME_ARRAY_BASE); excludedTypes.add(CAS.TYPE_NAME_EMPTY_FS_LIST); excludedTypes.add(CAS.TYPE_NAME_EMPTY_FLOAT_LIST); excludedTypes.add(CAS.TYPE_NAME_EMPTY_INTEGER_LIST); excludedTypes.add(CAS.TYPE_NAME_EMPTY_STRING_LIST); excludedTypes.add(CAS.TYPE_NAME_FS_ARRAY); excludedTypes.add(CAS.TYPE_NAME_FS_LIST); excludedTypes.add(CAS.TYPE_NAME_FLOAT); excludedTypes.add(CAS.TYPE_NAME_FLOAT_ARRAY); excludedTypes.add(CAS.TYPE_NAME_FLOAT_LIST); excludedTypes.add(CAS.TYPE_NAME_INTEGER); excludedTypes.add(CAS.TYPE_NAME_INTEGER_ARRAY); excludedTypes.add(CAS.TYPE_NAME_INTEGER_LIST); excludedTypes.add(CAS.TYPE_NAME_BOOLEAN); excludedTypes.add(CAS.TYPE_NAME_BOOLEAN_ARRAY); excludedTypes.add(CAS.TYPE_NAME_BYTE); excludedTypes.add(CAS.TYPE_NAME_BYTE_ARRAY); excludedTypes.add(CAS.TYPE_NAME_SHORT); excludedTypes.add(CAS.TYPE_NAME_SHORT_ARRAY); excludedTypes.add(CAS.TYPE_NAME_LONG); excludedTypes.add(CAS.TYPE_NAME_LONG_ARRAY); excludedTypes.add(CAS.TYPE_NAME_DOUBLE); excludedTypes.add(CAS.TYPE_NAME_DOUBLE_ARRAY); excludedTypes.add(CAS.TYPE_NAME_LIST_BASE); excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_FS_LIST); excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_FLOAT_LIST); excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_INTEGER_LIST); excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_STRING_LIST); excludedTypes.add(CAS.TYPE_NAME_SOFA); excludedTypes.add(CAS.TYPE_NAME_STRING); excludedTypes.add(CAS.TYPE_NAME_STRING_ARRAY); excludedTypes.add(CAS.TYPE_NAME_STRING_LIST); excludedTypes.add(CAS.TYPE_NAME_TOP); } public AddCapabilityTypeDialog(AbstractSection aSection, Capability c) { super(aSection, "Add Types to a Capability Set", "Mark one or more types as " + ((aSection.isCasConsumerDescriptor()) ? "Input" : (aSection.isCasInitializerDescriptor() || aSection .isCollectionReaderDescriptor()) ? "Output" : "Input and/or Output") + " by clicking the mouse in the corresponding column, and press OK"); capabilitySection = (CapabilitySection) aSection; capability = c; enableCol1 = !aSection.isCasInitializerDescriptor() && !aSection.isCollectionReaderDescriptor(); enableCol2 = !aSection.isCasConsumerDescriptor(); } public AddCapabilityTypeDialog(AbstractSection aSection, Capability c, TableTreeItem aExisting) { this(aSection, c); existing = aExisting; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent, existing); table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION); // ((GridData)table.getLayoutData()).heightHint = 100; table.setHeaderVisible(true); table.setLinesVisible(true); new TableColumn(table, SWT.NONE).setText("Type Name"); new TableColumn(table, SWT.NONE).setText("Input"); new TableColumn(table, SWT.NONE).setText("Output"); new TableColumn(table, SWT.NONE).setText("Type Namespace"); if (null == existing) { String[] allTypes = getAllTypesAsSortedArray(); for (int i = 0; i < allTypes.length; i++) { if (!excludedTypes.contains(allTypes[i]) && !hasType(capability.getInputs(), allTypes[i]) && !hasType(capability.getOutputs(), allTypes[i])) { TableItem item = new TableItem(table, SWT.NONE); setGuiTypeName(item, allTypes[i]); } } } else { // existing item being edited - just show one item TableItem item = new TableItem(table, SWT.NONE); item.setText(NAME, existing.getText(CapabilitySection.NAME_COL)); item.setText(NAMESPACE, existing.getText(CapabilitySection.NAMESPACE_COL)); TypeOrFeature tof = CapabilitySection.getTypeOrFeature(capability.getInputs(), capabilitySection.getFullyQualifiedName(existing)); setChecked(item, 1, null != tof); tof = CapabilitySection.getTypeOrFeature(capability.getOutputs(), capabilitySection .getFullyQualifiedName(existing)); setChecked(item, 2, null != tof); } section.packTable(table); // can't use selection event because it doesn't return mouse position table.removeListener(SWT.Selection, this); table.addListener(SWT.MouseDown, this); // for i / o toggling newErrorMessage(composite); return composite; } private boolean hasType(TypeOrFeature[] items, String name) { if (null == items) return false; for (int i = 0; i < items.length; i++) { if (items[i].isType() && items[i].getName().equals(name)) return true; } return false; } /** * Return values having at least one of input or output selected */ public void copyValuesFromGUI() { List names = new ArrayList(); List ins = new ArrayList(); List outs = new ArrayList(); for (int i = table.getItemCount() - 1; i >= 0; i--) { TableItem item = table.getItem(i); if (item.getText(INPUT).equals(checkedIndicator(INPUT)) || item.getText(OUTPUT).equals(checkedIndicator(OUTPUT))) { names.add(capabilitySection.getFullyQualifiedName(item.getText(NAMESPACE), item .getText(NAME))); ins.add(Boolean.valueOf(item.getText(INPUT).equals(checkedIndicator(INPUT)))); outs.add(Boolean.valueOf(item.getText(OUTPUT).equals(checkedIndicator(OUTPUT)))); } } types = (String[]) names.toArray(stringArray0); inputs = new boolean[types.length]; outputs = new boolean[types.length]; for (int i = 0; i < types.length; i++) { inputs[i] = ((Boolean) ins.get(i)).booleanValue(); outputs[i] = ((Boolean) outs.get(i)).booleanValue(); } } // used by dialog public void setGuiTypeName(TableItem item, String typeName) { item.setText(NAME, AbstractSection.getShortName(typeName)); item.setText(NAMESPACE, AbstractSection.getNameSpace(typeName)); } public boolean isValid() { for (int i = 0; i < types.length; i++) { if (!inputs[i]) { if (someFeatureOnType(types[i], INPUT)) { setErrorMessage("This type has one or more features marked for input and can''t be removed as an Input.\nIf you want to do this, first remove the Input designation for all features on this type."); return false; } // Use case: You can have // a Type with output features, where the type itself is not output. // In this case, the type must be in an input. The meaning is that // the AE sets or populates features on existing types. if (!outputs[i] && someFeatureOnType(types[i], OUTPUT) && !inputs[i]) { setErrorMessage("This type has features which are output, and so must either be specified as INPUT (meaning features are populated or \"outputted\" on existing instances), or OUTPUT (meaning new instances of this type are created). It can't be removed completely.\nIf you want to do this, first remove the features which are output for this type."); return false; } } } return true; } /** * return true if the type has a feature (except all-features) marked as INPUT (OUTPUT) * * @param typeName * @param IO * @return */ private boolean someFeatureOnType(String typeName, int IO) { // special case for all-features TypeOrFeature[] tofs = (IO == INPUT) ? capability.getInputs() : capability.getOutputs(); // you can remove the "INPUT" or "OUTPUT" designation from a type // even if it has the all-features flag on. String typeNamePlusColon = typeName + ':'; for (int i = 0; i < tofs.length; i++) { if (!tofs[i].isType() && tofs[i].getName().startsWith(typeNamePlusColon)) return true; } return false; } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/T0000644000175000017500000000301511665471216033366 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class TypesWithNameSpaces { public SortedMap sortedNames = new TreeMap(); public void add(String fullname) { String key = AbstractSection.getShortName(fullname); String nameSpace = AbstractSection.getNameSpace(fullname); Set entry = (Set) sortedNames.get(key); if (null == entry) { entry = new TreeSet(); entry.add(nameSpace); sortedNames.put(key, entry); } else { entry.add(nameSpace); } } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexKeyDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001460111665471216033346 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class AddIndexKeyDialog extends AbstractDialog { static private final String ASCENDING = "Ascending (Standard)"; static private final String DESCENDING = "Descending (Reverse)"; static private final String TYPE_PRIORITY = "Type Priority"; public boolean typePriority; public String featureName; public int direction; private String[] features; private FsIndexKeyDescription existingKey = null; private List alreadyUsedKeys; private String indexKind; // bag, sorted, set private CCombo featureUI; // private Button browseButton; private CCombo kindUI; private Label featureLabel; // private Composite tc; public AddIndexKeyDialog(AbstractSection aSection, String typeName, String indexKind, List alreadyUsedKeys) { super(aSection, "Add index key", "Add or edit an index key for a type"); this.indexKind = indexKind; this.alreadyUsedKeys = alreadyUsedKeys; features = getSortableFeatureNames(typeName); } public AddIndexKeyDialog(AbstractSection aSection, String typeName, String indexKind, List alreadyUsedKeys, FsIndexKeyDescription existingKey) { this(aSection, typeName, indexKind, alreadyUsedKeys); this.existingKey = existingKey; } /** * * @param taeDescription * @param selectedType * @return an array of features whose range is primitive */ private String[] getSortableFeatureNames(String selectedTypeName) { Type selectedType = section.editor.getCurrentView().getTypeSystem().getType(selectedTypeName); List feats = selectedType.getFeatures(); Collection sortableFeatureNames = new ArrayList(); for (int i = 0; i < feats.size(); i++) { Feature feature = (Feature) feats.get(i); Type rangeType = feature.getRange(); if (AbstractSection.isIndexableRange(rangeType.getName())) { if (!alreadyUsedKeys.contains(feature.getShortName())) sortableFeatureNames.add(feature.getShortName()); } } String[] result = (String[]) sortableFeatureNames.toArray(stringArray0); Arrays.sort(result); return result; } // Kind: combo (up, down, or typePriority) // Feature: text with assist protected Control createDialogArea(Composite parent) { // create composite Composite mainComposite = (Composite) super.createDialogArea(parent, existingKey); Composite twoCol = new2ColumnComposite(mainComposite); if ("sorted".equals(indexKind)) { kindUI = newLabeledCCombo(twoCol, "Sort order, or Type Priority", "Specify the sort direction, or specify Type Priorities"); kindUI.add(ASCENDING); kindUI.add(DESCENDING); kindUI.add(TYPE_PRIORITY); } featureLabel = new Label(twoCol, SWT.NONE); featureLabel.setText("Feature Name"); featureUI = newCCombo(twoCol, "Pick a feature to use as a key from the available features"); for (int i = 0; i < features.length; i++) { featureUI.add(features[i]); } if (null == existingKey) { // default initialization if ("sorted".equals(indexKind)) kindUI.setText(kindUI.getItem(0)); } else if ("sorted".equals(indexKind)) { kindUI.setText(existingKey.isTypePriority() ? TYPE_PRIORITY : existingKey.getComparator() == FSIndexComparator.STANDARD_COMPARE ? ASCENDING : DESCENDING); if (!existingKey.isTypePriority()) featureUI.setText(existingKey.getFeatureName()); } else featureUI.setText(existingKey.getFeatureName()); boolean makeFeatureVisible = "set".equals(indexKind) || !TYPE_PRIORITY.equals(kindUI.getText()); featureUI.setVisible(makeFeatureVisible); featureLabel.setVisible(makeFeatureVisible); if ("sorted".equals(indexKind)) kindUI.addListener(SWT.Modify, this); return mainComposite; } public void handleEvent(Event event) { if (event.widget == kindUI) { boolean makeFeatureVisible = "set".equals(indexKind) || !TYPE_PRIORITY.equals(kindUI.getText()); featureUI.setVisible(makeFeatureVisible); featureLabel.setVisible(makeFeatureVisible); } super.handleEvent(event); } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(typePriority || !(null != featureName && "".equals(featureName))); } public void copyValuesFromGUI() { if ("sorted".equals(indexKind) && TYPE_PRIORITY.equals(kindUI.getText())) { typePriority = true; featureName = ""; } else { typePriority = false; if ("sorted".equals(indexKind)) { direction = ASCENDING.equals(kindUI.getText()) ? FSIndexComparator.STANDARD_COMPARE : FSIndexComparator.REVERSE_STANDARD_COMPARE; } else direction = FSIndexComparator.STANDARD_COMPARE; featureName = featureUI.getText(); } } public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000020400000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogMultiColTable.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000000720711665471216033352 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Widget; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.Utility; public abstract class AbstractDialogMultiColTable extends AbstractDialog { protected String checkedIndicator(int col) { if (col == 1) return "In"; else return "Out"; } protected static final String UNCHECKED = ""; Table table; protected boolean enableCol1 = true; protected boolean enableCol2 = true; protected int numberChecked = 0; protected AbstractDialogMultiColTable(AbstractSection aSection, String title, String description) { super(aSection, title, description); } public void handleEvent(Event event) { if (event.type == SWT.MouseDown && event.widget == table) { Point mousePosition = new Point(event.x, event.y); TableItem item = table.getItem(mousePosition); if (null == item) { jitHowTo(event.widget); return; } int col = getHitColumn(item, mousePosition); if (col != 1 && col != 2) { jitHowTo(event.widget); return; } if (col == 1 && !enableCol1) { setErrorMessage("This resource can't be marked as input"); return; } if (col == 2 && !enableCol2) { setErrorMessage("This resource can't be marked as output"); return; } errorMessageUI.setText(""); toggleValue(item, col); } super.handleEvent(event); } private void jitHowTo(Widget w) { Utility.popMessage(w, "Where to mouse click", "Please click the mouse in the input or output columns to toggle the selection.", MessageDialog.INFORMATION); } protected void toggleValue(TableItem item, int col) { item.setText(col, item.getText(col).equals(checkedIndicator(col)) ? UNCHECKED : checkedIndicator(col)); if (item.getText(col).equals(checkedIndicator(col))) numberChecked++; else numberChecked--; } public boolean isValid() { return true; } public void enableOK() { errorMessageUI.setText(""); okButton.setEnabled(numberChecked > 0); } protected void setChecked(TableItem item, int col, boolean value) { boolean prevChecked = checkedIndicator(col).equals(item.getText(col)); item.setText(col, value ? checkedIndicator(col) : UNCHECKED); if (value && !prevChecked) numberChecked++; else if (!value && prevChecked) numberChecked--; } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddParameterDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001257611665471216033357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; /* * Collects the following information parm name (suggests they must be unique within the descriptor) * MultiValued Mandatory (for aggregates:) 1st overrides * * For overrides, uses common code in section to allow use of a hierarchical browser that will go * thru defined/available keys, with parms at the bottom. Next sentence I think is false: This is * optional - user may not have fully defined things below. So won't be an error, here, but will be * when validated. */ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.ParameterSection; public class AddParameterDialog extends AbstractDialogKeyVerifyJavaNames { private StyledText parmNameUI; public Button multiValueUI; private Button mandatoryUI; public CCombo parmTypeUI; private Text descriptionUI; public String parmName; public boolean multiValue; public boolean mandatory; public String parmType; public String description; private ParameterSection parmSection; private ConfigurationParameter existingCP; private String originalParmName; public AddParameterDialog(AbstractSection aSection) { super(aSection, "Add Parameter", "Specify a parameter name and press OK"); parmSection = (ParameterSection) section; } /** * Constructor for Editing an existing parameter * * @param aSection * @param aExistingCP */ public AddParameterDialog(AbstractSection aSection, ConfigurationParameter aExistingCP) { this(aSection); existingCP = aExistingCP; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingCP); createWideLabel(mainArea, "Parameter names must be unique within this descriptor"); // This part of the form looks like this sketch // // parmName: Text field << in 2 grid composite // parmType: CCombo << in 2 grid composite // description: Text field << in 2 grid composite // (checkbox) is MultiValued // (checkbox) is Mandatory // Composite twoCol = new2ColumnComposite(mainArea); parmNameUI = newLabeledSingleLineStyledText(twoCol, "Parameter Name", "The unique name of the parameter"); parmTypeUI = newLabeledCCombo(twoCol, "Parameter Type", "Select the type of the parameter from the pull-down list"); parmTypeUI.add("String"); parmTypeUI.add("Float"); parmTypeUI.add("Integer"); parmTypeUI.add("Boolean"); descriptionUI = newDescription(twoCol, S_); multiValueUI = newButton(mainArea, SWT.CHECK, "Parameter is multi-valued", "Check the box if the parameter is multi-valued"); mandatoryUI = newButton(mainArea, SWT.CHECK, "Parameter is mandatory", "Check the box if the parameter is mandatory"); if (section.isAggregate()) { multiValueUI.setEnabled(false); // can't change this parmTypeUI.setEnabled(false); } newErrorMessage(mainArea); if (null != existingCP) { descriptionUI.setText(convertNull(existingCP.getDescription())); multiValueUI.setSelection(existingCP.isMultiValued()); mandatoryUI.setSelection(existingCP.isMandatory()); parmNameUI.setText(convertNull(existingCP.getName())); parmTypeUI.setText(convertNull(existingCP.getType())); } originalParmName = parmNameUI.getText(); // for validity testing in edit case return mainArea; } public void copyValuesFromGUI() { parmName = parmNameUI.getText(); multiValue = multiValueUI.getSelection(); mandatory = mandatoryUI.getSelection(); description = nullIf0lengthString(descriptionUI.getText()); parmType = parmTypeUI.getText(); } public boolean isValid() { if (parmName.length() == 0) return false; if (!parmName.equals(originalParmName) && parmSection.parameterNameAlreadyDefined(parmName)) return false; if (parmType.length() == 0) return false; return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled((parmName.length() > 0) && (parmType.length() > 0)); } } ././@LongLink0000000000000000000000000000021100000000000011557 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerifyJavaNames.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000000675011665471216033354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.VerifyKeyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.widgets.Composite; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public abstract class AbstractDialogKeyVerifyJavaNames extends AbstractDialogKeyVerify implements VerifyKeyListener, VerifyListener { protected StyledText newSingleLineStyledText(Composite parent, String tip) { StyledText w = super.newSingleLineStyledText(parent, tip); w.addVerifyListener(this); return w; } protected AbstractDialogKeyVerifyJavaNames(AbstractSection aSection, String title, String description) { super(aSection, title, description); } /** * Java name space names verify key checks for java identifier and periods */ public boolean verifyKeyChecks(VerifyEvent event) { if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB) return true; if (Character.isJavaIdentifierPart(event.character)) return true; StyledText w = (StyledText) event.widget; String text = w.getText(); int len = text.length(); if (event.character == '.') { if (len == 0) return false; return true; } return false; } /** * @param event * the text change event. *

    *
  • event.start - the replace start offset
  • *
  • event.end - the replace end offset
  • *
  • event.text - the new text
  • *
*/ public void verifyText(VerifyEvent event) { event.doit = true; String oldStr = ((StyledText) event.widget).getText(); String newStr = oldStr.substring(0, event.start) + event.text + oldStr.substring(event.end); if (newStr.indexOf("..") >= 0) { event.doit = false; setErrorMessage("You cannot have two periods in a row."); return; } if (namePartStartsWithDigit(newStr)) { event.doit = false; setErrorMessage("Name parts cannot start with a digit."); return; } } private boolean namePartStartsWithDigit(final String s) { if (null == s || s.length() == 0) return false; int testloc = 0; if (Character.isDigit(s.charAt(testloc))) return true; for (testloc = 1 + s.indexOf('.', testloc); testloc > 0 && testloc < s.length(); testloc = 1 + s .indexOf('.', testloc)) if (Character.isDigit(s.charAt(testloc))) return true; return false; } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddRemoteServiceDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000002207711665471216033354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.text.MessageFormat; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class AddRemoteServiceDialog extends AbstractDialog { private String m_selectedServiceTypeName = null; private String m_selectedUri = null; private String m_selectedKey = null; private boolean m_bAutoAddToFlow; public String vnsPort; public String vnsHost; public String timeout; public String aeOrCc; private CCombo serviceTypeCombo; private Text uriText; private Text keyText; private Text timeoutText; private Button autoAddToFlowButton; private Button importByNameUI; private Button importByLocationUI; public boolean isImportByName; private String rootPath; private DialogModifyListener m_dialogModifyListener = new DialogModifyListener(); private Text genFilePathUI; public String genFilePath; private String keyTextPrev; private Label vnsHostLabel; private Text vnsHostUI; private Label vnsPortLabel; private Text vnsPortUI; private boolean portNumberWasBad; private boolean portNumberIsOK; private CCombo aeOrCcCombo; private class DialogModifyListener implements ModifyListener { public void modifyText(ModifyEvent e) { String text = genFilePathUI.getText(); int pos = text.lastIndexOf(keyTextPrev); if (pos == -1) pos = text.length(); keyTextPrev = keyText.getText() + ".xml"; genFilePathUI.setText(text.substring(0, pos) + keyTextPrev); if (okButton != null) enableOK(); } } private class DialogVerifyListener implements VerifyListener { public void verifyText(VerifyEvent e) { if (0 <= e.text.indexOf('.')) { setErrorMessage(MessageFormat.format("invalid character(s): ''{0}''", new Object[] { e.text })); e.doit = false; } else setErrorMessage(""); } } public AddRemoteServiceDialog(AbstractSection aSection, String aRootPath) { super(aSection, "Add Remote Service", "Fill in the information about the remote service and press OK"); rootPath = aRootPath; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); createWideLabel(composite, "Service kind: Analysis Engine or Cas Consumer:"); aeOrCcCombo = newCCombo(composite, "Specify whether the Service is an Analysis Engine or a Cas Consumer"); aeOrCcCombo.add("AnalysisEngine"); aeOrCcCombo.add("CasConsumer"); aeOrCcCombo.select(0); createWideLabel(composite, "Protocol Service Type:"); serviceTypeCombo = newCCombo(composite, S_); serviceTypeCombo.add("SOAP"); serviceTypeCombo.add("Vinci"); serviceTypeCombo.select(0); createWideLabel(composite, "URI:"); uriText = new Text(composite, SWT.BORDER); uriText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); uriText.addModifyListener(m_dialogModifyListener); createWideLabel(composite, "Key (a short mnemonic for this service):"); keyText = new Text(composite, SWT.BORDER); keyText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); keyText.addModifyListener(m_dialogModifyListener); keyText.addVerifyListener(new DialogVerifyListener()); keyTextPrev = ".xml"; createWideLabel(composite, "Where the generated remote descriptor file will be stored:"); genFilePathUI = new Text(composite, SWT.BORDER | SWT.H_SCROLL); genFilePathUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); genFilePathUI.setText(rootPath + ".xml"); createWideLabel( composite, "Timeout, in milliseconds. This is ignored for the Vinci protocol. Specify 0 to wait forever. If not specified, a default timeout is used."); timeoutText = new Text(composite, SWT.BORDER); timeoutText.setEnabled(false); createWideLabel(composite, "For the Vinci protocol, you can optionally specify the Host/Port for the Vinci Name Service"); Composite tc = new2ColumnComposite(composite); setTextAndTip(vnsHostLabel = new Label(tc, SWT.NONE), "VNS HOST", "An IP name or address, e.g. localhost"); vnsHostUI = newText(tc, SWT.NONE, "An IP name or address, e.g. localhost"); setTextAndTip(vnsPortLabel = new Label(tc, SWT.NONE), "VNS PORT", "A port number, e.g. 9000"); vnsPortUI = newText(tc, SWT.NONE, "A port number, e.g. 9000"); newErrorMessage(composite); autoAddToFlowButton = new Button(composite, SWT.CHECK); autoAddToFlowButton.setText("Add to end of flow"); autoAddToFlowButton.setSelection(true); new Label(composite, SWT.NONE).setText(""); importByNameUI = new Button(composite, SWT.RADIO); importByNameUI.setText("Import by Name"); importByNameUI .setToolTipText("Importing by name looks up the name on the classpath and datapath."); importByNameUI.setSelection(true); importByLocationUI = new Button(composite, SWT.RADIO); importByLocationUI.setText("Import By Location"); importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL"); String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject()); if (defaultBy.equals("location")) { importByNameUI.setSelection(false); importByLocationUI.setSelection(true); } else { importByNameUI.setSelection(true); importByLocationUI.setSelection(false); } return composite; } public void enableOK() { boolean isVinci = serviceTypeCombo.getSelectionIndex() == 1; vnsHostLabel.setEnabled(isVinci); vnsHostUI.setEnabled(isVinci); vnsPortLabel.setEnabled(isVinci); vnsPortUI.setEnabled(isVinci); timeoutText.setEnabled(!isVinci); boolean bEnableOk = (serviceTypeCombo.getText() != null && !serviceTypeCombo.getText().equals( "")) && (uriText != null && !uriText.getText().trim().equals("")) && (keyText != null && !keyText.getText().trim().equals("")); portNumberIsOK = true; if (isVinci && vnsPortUI.getText().length() > 0) { try { Integer.parseInt(vnsPortUI.getText()); } catch (NumberFormatException e) { bEnableOk = false; portNumberWasBad = true; portNumberIsOK = false; setErrorMessage("Invalid number, please correct."); } } okButton.setEnabled(bEnableOk); if (portNumberWasBad && portNumberIsOK) { setErrorMessage(""); portNumberWasBad = false; } } public String getSelectedServiceTypeName() { return m_selectedServiceTypeName; } public String getSelectedUri() { return m_selectedUri; } public String getSelectedKey() { return m_selectedKey; } public boolean getAutoAddToFlow() { return m_bAutoAddToFlow; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { genFilePath = genFilePathUI.getText(); isImportByName = importByNameUI.getSelection(); m_selectedServiceTypeName = serviceTypeCombo.getText(); aeOrCc = aeOrCcCombo.getText(); m_selectedUri = uriText.getText(); m_selectedKey = keyText.getText(); m_bAutoAddToFlow = autoAddToFlowButton.getSelection(); timeout = timeoutText.getText(); vnsHost = vnsHostUI.getText(); vnsPort = vnsPortUI.getText(); CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location"); } public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/PickTaeForTypesDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/P0000644000175000017500000002343311665471216033370 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Text; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class PickTaeForTypesDialog extends AbstractDialog { private java.util.List m_DelegateComponentDescriptors, m_delegateComponentDescriptions; private String[] m_selectedDelegateComponentDescriptors; // private boolean m_bAutoAddToFlow; private String m_aggregateFileName; private Text delegateComponentDescriptionText; List delegateComponentListGUI; private List inputTypesList; private List outputTypesList; // private Button autoAddToFlowButton; private DialogSelectionListener dialogSelectionListener = new DialogSelectionListener(); private Button importByNameUI; private Button importByLocationUI; public boolean isImportByName; public class DialogSelectionListener implements SelectionListener { public void widgetSelected(SelectionEvent e) { if (e.widget == delegateComponentListGUI) { update(); } else { if (okButton != null) enableOK(); } } public void widgetDefaultSelected(SelectionEvent e) { // nothing to do in this case } } /** * @param parentShell */ public PickTaeForTypesDialog(AbstractSection aSection, String aggregateFileName, java.util.List delegateComponentDescriptors, java.util.List delegateComponentDescriptions) { super(aSection, "Select Delegate Component Descriptor(s)", "Select one or more delegate components to add and press OK"); m_aggregateFileName = aggregateFileName; m_DelegateComponentDescriptors = delegateComponentDescriptors; m_delegateComponentDescriptions = delegateComponentDescriptions; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); Label specialMsgLabel = new Label(composite, SWT.WRAP); AbstractSection.spacer(composite); // create m_taePrompt createWideLabel(composite, "Delegate Components:"); delegateComponentListGUI = new List(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); gridData.heightHint = 100; delegateComponentListGUI.setLayoutData(gridData); boolean bContainsConstituentsAlreadyInAggregate = false; boolean bContainsAggregate = false; for (int i = 0; i < m_DelegateComponentDescriptors.size(); i++) { String sAdditional = ""; if (m_aggregateFileName.equals(m_DelegateComponentDescriptors.get(i))) { sAdditional = "**"; bContainsAggregate = true; } delegateComponentListGUI.add((String) m_DelegateComponentDescriptors.get(i) + sAdditional); } delegateComponentListGUI.addSelectionListener(dialogSelectionListener); if (bContainsConstituentsAlreadyInAggregate && bContainsAggregate) { specialMsgLabel .setText("(* indicates delegate component is already part of aggregate, ** is aggregate currently being configured)"); } else if (bContainsConstituentsAlreadyInAggregate) { specialMsgLabel.setText("(* indicates delegate component is already part of aggregate)"); } else if (bContainsAggregate) { specialMsgLabel.setText("(** is aggregate currently being configured)"); } createWideLabel(composite, "Delegate Component Description:"); delegateComponentDescriptionText = new Text(composite, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL | SWT.BORDER); delegateComponentDescriptionText.setLayoutData(new GridData(GridData.FILL_BOTH)); GridData dcgd = new GridData(GridData.FILL_HORIZONTAL); dcgd.heightHint = 50; delegateComponentDescriptionText.setLayoutData(dcgd); delegateComponentDescriptionText.setEditable(false); createWideLabel(composite, "Input Types:"); inputTypesList = new List(composite, SWT.BORDER | SWT.V_SCROLL); inputTypesList.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); createWideLabel(composite, "Output Types:"); outputTypesList = new List(composite, SWT.BORDER | SWT.V_SCROLL); outputTypesList.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // autoAddToFlowButton = new Button(composite, SWT.CHECK); // autoAddToFlowButton.setText("Add selected delegate components to end of flow"); // autoAddToFlowButton.setSelection(true); // autoAddToFlowButton.setBackground(null); importByNameUI = newButton(composite, SWT.RADIO, "Import by Name", "Importing by name looks up the name on the classpath and datapath."); importByLocationUI = newButton(composite, SWT.RADIO, "Import by Location", "Importing by location requires a relative or absolute URL"); String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject()); if (defaultBy.equals("location")) { importByNameUI.setSelection(false); importByLocationUI.setSelection(true); } else { importByNameUI.setSelection(true); importByLocationUI.setSelection(false); } return composite; } public void update() { int nSelectedAeIndex = delegateComponentListGUI.getSelectionIndices()[0]; ResourceSpecifier rs = (ResourceSpecifier) m_delegateComponentDescriptions .get(nSelectedAeIndex); String description = rs instanceof ResourceCreationSpecifier ? ((ResourceCreationSpecifier) rs) .getMetaData().getDescription() : "No Description - remote service descriptor"; delegateComponentDescriptionText.setText(convertNull(description)); inputTypesList.removeAll(); outputTypesList.removeAll(); Capability[] capabilities = AbstractSection.getCapabilities(rs); if (capabilities != null && capabilities.length > 0) { TypeOrFeature[] inputs = capabilities[0].getInputs(); if (inputs != null) { for (int i = 0; i < inputs.length; i++) { if (inputs[i].isType()) { inputTypesList.add(section.formatName(inputs[i].getName())); } } } TypeOrFeature[] outputs = capabilities[0].getOutputs(); if (outputs != null) { for (int i = 0; i < outputs.length; i++) { if (outputs[i].isType()) { outputTypesList.add(section.formatName(outputs[i].getName())); } } } } if (okButton != null) enableOK(); } public void enableOK() { boolean bEnableOk = false; String[] selections = delegateComponentListGUI.getSelection(); for (int i = 0; i < selections.length; i++) { if (!selections[i].endsWith("*")) { bEnableOk = true; i = selections.length; } } okButton.setEnabled(bEnableOk); } public String[] getSelectedDelegateComponentDescriptors() { return (String[]) m_selectedDelegateComponentDescriptors.clone(); } // public boolean getAutoAddToFlow() { // return m_bAutoAddToFlow; // } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { // this is where we do rollup and detect if we need any additional // types based on types of features and whether we are a supertype // of a type that is not yet defined int[] selIndices = delegateComponentListGUI.getSelectionIndices(); int nRealCount = 0; for (int i = 0; i < selIndices.length; i++) { if (!delegateComponentListGUI.getItem(selIndices[i]).endsWith("*")) { nRealCount++; } } m_selectedDelegateComponentDescriptors = new String[nRealCount]; for (int i = 0, j = 0; i < selIndices.length; i++) { if (!delegateComponentListGUI.getItem(selIndices[i]).endsWith("*")) { m_selectedDelegateComponentDescriptors[j] = (String) m_DelegateComponentDescriptors .get(selIndices[i]); } } // m_bAutoAddToFlow = autoAddToFlowButton.getSelection(); isImportByName = importByNameUI.getSelection(); CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location"); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid() */ public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/EditSofaBindingsDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/E0000644000175000017500000000672211665471216033357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Iterator; import java.util.Map; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class EditSofaBindingsDialog extends AbstractDialog { public String[] selectedSofaNames; // this is the selection indexes into next private Map availAndBoundSofas; private String aggrSofaName; private Table table; /** * @param parentShell */ public EditSofaBindingsDialog(AbstractSection aSection, String aAggrSofaName, Map aAvailAndBoundSofas) { super(aSection, "Assign Components and their sofas to an Aggregate Sofa Name", "Change the selection as needed to reflect bindings."); availAndBoundSofas = aAvailAndBoundSofas; aggrSofaName = aAggrSofaName; } protected Control createDialogArea(Composite parent) { // create composite // // Bindings for aggregate sofa name xxxxxx: // // component/sofa-name // component // Composite composite = (Composite) super.createDialogArea(parent); Label info = new Label(composite, SWT.NONE); info.setText("Select all the delegate sofas from the list below which should be " + "associated with the aggregate sofa name \"" + aggrSofaName + "\".\n" + "Hold down the Shift or Control keys to select multiple items."); table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); int i = 0; for (Iterator it = availAndBoundSofas.entrySet().iterator(); it.hasNext(); i++) { TableItem item = new TableItem(table, SWT.NONE); Map.Entry entry = (Map.Entry) it.next(); item.setText((String) entry.getKey()); if (null != entry.getValue()) table.select(i); } table.pack(); return composite; } public void copyValuesFromGUI() { selectedSofaNames = new String[table.getSelectionCount()]; for (int i = 0, j = 0; i < table.getItemCount(); i++) { if (table.isSelected(i)) { selectedSofaNames[j++] = table.getItem(i).getText(); } } } public boolean isValid() { // TODO Auto-generated method stub return true; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { okButton.setEnabled(true); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchThread.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/S0000644000175000017500000002212211665471216033365 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.List; import java.util.regex.Pattern; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.swt.widgets.Display; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class SearchThread implements Runnable /* extends Thread */{ private Pattern m_fileNameSearch; private Pattern m_inputTypeSearch; private Pattern m_outputTypeSearch; private String m_projectToSearch; FindComponentDialog m_dialog; private AbstractSection m_aggregateSection; private List m_matchingDelegateComponentDescriptors; private List m_matchingDelegateComponentDescriptions; int m_nWhichStatusMsg; String m_statusMsg; private String[] m_componentHeaders; public SearchThread(FindComponentDialog dialog, AbstractSection aggregateSection, String fileNameSearch, String inputTypeSearch, String outputTypeSearch, String projectToSearch, String[] componentHeaders) { m_dialog = dialog; m_aggregateSection = aggregateSection; m_fileNameSearch = (null == fileNameSearch)? null : Pattern.compile(fileNameSearch); m_inputTypeSearch = (null == inputTypeSearch)? null : Pattern.compile(inputTypeSearch); m_outputTypeSearch = (null == outputTypeSearch)? null : Pattern.compile(outputTypeSearch); m_projectToSearch = projectToSearch; m_componentHeaders = componentHeaders; } private boolean m_bDieNow = false; private boolean m_bDone = false; public void setDieNow() { m_bDieNow = true; } public boolean getDieNow() { return m_bDieNow; } public boolean isDone() { return m_bDone; } public void run() { m_matchingDelegateComponentDescriptors = new ArrayList(); m_matchingDelegateComponentDescriptions = new ArrayList(); getDelegateComponentsByInputOutputTypes(m_projectToSearch); m_bDone = true; } private void testOneResource(IResource resource) { switch (resource.getType()) { case IResource.FILE: if (resource.getName().toLowerCase().endsWith(".xml") // exclude potentially many data files, not descriptors && !resource.getName().toLowerCase().endsWith(".txt.xml") && (m_fileNameSearch == null || m_fileNameSearch.matcher(resource.getName()).find())) { String fileDescriptorRelPath = m_aggregateSection.editor .getDescriptorRelativePath(resource.getLocation().toString()); setStatusMsg(2, "Examining " + getBriefDisplayVersion(fileDescriptorRelPath)); ResourceSpecifier rs = MultiPageEditor.getDelegateResourceSpecifier((IFile) resource, m_componentHeaders); // rs == null if wrong kind of descriptor if (null == rs) return; if (!(rs instanceof ResourceCreationSpecifier)) // is a remote descriptor if (m_inputTypeSearch != null || m_outputTypeSearch != null) return; // don't find remote descriptors when types are wanted if (!(rs instanceof ResourceCreationSpecifier) || // is a remote descriptor delegateComponentMatchesCapabilityReqs((ResourceCreationSpecifier) rs, m_inputTypeSearch, m_outputTypeSearch)) { m_matchingDelegateComponentDescriptors.add(fileDescriptorRelPath); m_matchingDelegateComponentDescriptions.add(rs); } } break; case IResource.FOLDER: getDelegateComponentsByIOTypesBeginningAt((IFolder) resource); break; } } // populates the Vector of matchingAnalysisEngineDescriptors and // matchingAnalysisEngineDescriptions private void getDelegateComponentsByInputOutputTypes(String projectToSearch) { IWorkspace workspace = TAEConfiguratorPlugin.getWorkspace(); IProject[] projects = workspace.getRoot().getProjects(); if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) { setStatusMsg(1, "0 of " + projects.length + " projects processed."); } for (int i = 0; i < projects.length; i++) { try { if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS) || projects[i].getName().equals(projectToSearch)) { if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) { setStatusMsg(2, "Looking in " + projects[i].getName() + "...."); } else { setStatusMsg(2, "Searching " + projects[i].getName() + " for matching TAEs..."); } IResource[] projectContents = projects[i].members(); for (int j = 0; j < projectContents.length; j++) { testOneResource(projectContents[j]); } if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) { setStatusMsg(1, (i + 1) + " of " + projects.length + " projects processed."); } } } catch (Exception ex) { System.out.println(ex.getMessage()); } } } // populates the Vector of matchingAnalysisEngineDescriptors and // matchingAnalysisEngineDescriptions private void getDelegateComponentsByIOTypesBeginningAt(IFolder beginFolder) { if (m_bDieNow) { return; } try { for (int i = 0; i < beginFolder.members().length; i++) { testOneResource(beginFolder.members()[i]); } } catch (Exception ex) { ex.printStackTrace(); } } private boolean delegateComponentMatchesCapabilityReqs(ResourceCreationSpecifier rs, Pattern inputTypeSearch, Pattern outputTypeSearch) { if (inputTypeSearch == null && outputTypeSearch == null) { return true; } Capability[] capabilities = AbstractSection.getCapabilities(rs); if (capabilities == null || capabilities.length == 0) { return false; } boolean inputSatisfied = matchCapabilitiesTo(capabilities, inputTypeSearch, INPUT); boolean outputSatisfied = matchCapabilitiesTo(capabilities, outputTypeSearch, OUTPUT); return inputSatisfied && outputSatisfied; } private static final boolean INPUT = true; private static final boolean OUTPUT = false; private boolean matchCapabilitiesTo(Capability[] capabilities, Pattern search, boolean isInput) { if (null == search) return true; for (int i = 0; i < capabilities.length; i++) { TypeOrFeature[] typeOrFeatures = isInput ? capabilities[i].getInputs() : capabilities[i] .getOutputs(); if (null != typeOrFeatures) { for (int j = 0; j < typeOrFeatures.length; j++) { if (search.matcher(typeOrFeatures[j].getName()).find()) { return true; } } } } return false; } public List getMatchingDelegateComponentDescriptors() { return m_matchingDelegateComponentDescriptors; } public List getMatchingDelegateComponentDescriptions() { return m_matchingDelegateComponentDescriptions; } private void setStatusMsg(int nWhich, String msg) { m_nWhichStatusMsg = nWhich; m_statusMsg = msg; if (m_dialog.getStatusLabel1().isDisposed()) return; Display display = m_dialog.getStatusLabel1().getDisplay(); display.syncExec(new Runnable() { public void run() { if (m_nWhichStatusMsg == 1) { m_dialog.getStatusLabel1().setText(m_statusMsg); } else { m_dialog.getStatusLabel2().setText(m_statusMsg); } } }); } private String getBriefDisplayVersion(String filePathName) { if (filePathName == null) { return null; } filePathName = AbstractSection.maybeShortenFileName(filePathName); return filePathName; } } ././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ContentAssistField32.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/C0000644000175000017500000000341111665471216033345 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Isolates Eclipse 3.2 content assist types */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.fieldassist.ContentAssistField; public class ContentAssistField32 { final private ContentAssistField caf; ContentAssistField32(Composite tc, TypesWithNameSpaces candidatesToPickFrom) { TypesWithNameSpaces32 twns32 = new TypesWithNameSpaces32(candidatesToPickFrom); caf = new ContentAssistField(tc, SWT.BORDER, new org.eclipse.jface.fieldassist.TextControlCreator(), new org.eclipse.jface.fieldassist.TextContentAdapter(), twns32, null, null); caf.getContentAssistCommandAdapter().setProposalAcceptanceStyle(org.eclipse.jface.fieldassist.ContentProposalAdapter.PROPOSAL_REPLACE); } public Text getControl() { return (Text) caf.getControl(); } } ././@LongLink0000000000000000000000000000021400000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDependencyDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001077711665471216033360 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Text; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.ResourceDependencySection; public class AddExternalResourceDependencyDialog extends AbstractDialogKeyVerifyJavaNames { private StyledText keyNameUI; public Button optionalUI; private StyledText interfaceNameUI; private Text descriptionUI; public String keyName; private String originalKeyName; public boolean optional; public String interfaceName; public String description; private ResourceDependencySection rdSection; private ExternalResourceDependency existingXRD; public AddExternalResourceDependencyDialog(AbstractSection aSection) { super(aSection, "Add External Resource Dependency", "Add an External Resource Dependency"); rdSection = (ResourceDependencySection) aSection; } /** * Constructor for Editing an existing XRD * * @param aSection * @param aExistingXRD */ public AddExternalResourceDependencyDialog(AbstractSection aSection, ExternalResourceDependency aExistingXRD) { this(aSection); existingXRD = aExistingXRD; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingXRD); createWideLabel( mainArea, "The only required field is the key name,\nwhich must be unique within this primitive Analysis Engine descriptor."); // This part of the form looks like this sketch // // keyName: Text field << in 2 grid composite // description: Text field << in 2 grid composite // impl Name: Text field << in 2 grid composite // (checkbox) is Optional // Composite twoCol = new2ColumnComposite(mainArea); keyNameUI = newLabeledSingleLineStyledText(twoCol, "Key", "Name used by the Primitive Analysis Engine to refer to the resource"); descriptionUI = newDescription(twoCol, "(Optional)Describes this resource dependency"); interfaceNameUI = newLabeledSingleLineStyledText( twoCol, "Interface", "The fully qualified name of the Java Interface class used by the Analysis Engine to refer to the External Resource"); newErrorMessage(twoCol, 2); optionalUI = newButton(mainArea, SWT.CHECK, "Check this box if this resource is optional", "Uncheck if this resource is required"); if (null != existingXRD) { descriptionUI.setText(convertNull(existingXRD.getDescription())); optionalUI.setSelection(existingXRD.isOptional()); keyNameUI.setText(originalKeyName = existingXRD.getKey()); interfaceNameUI.setText(convertNull(existingXRD.getInterfaceName())); } return mainArea; } public void copyValuesFromGUI() { keyName = keyNameUI.getText(); optional = optionalUI.getSelection(); description = nullIf0lengthString(descriptionUI.getText()); interfaceName = nullIf0lengthString(interfaceNameUI.getText()); } public boolean isValid() { if (keyName.length() == 0) return false; if (!keyName.equals(originalKeyName) && rdSection.keyNameAlreadyDefined(keyName)) return false; return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(keyName.length() > 0); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddFeatureDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000002040711665471216033347 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.apache.uima.cas.Type; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.TypeSection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Text; public class AddFeatureDialog extends AbstractDialogKeyVerify { private static final int ONLY_NON_PRIMITIVE_TYPES = 0; private static final int ALL_TYPES = 1; private StyledText featureNameUI; private Text featureRangeNameUI; private Text descriptionUI; public String featureName; private String originalFeatureName; public String featureRangeName; public String description; public String elementRangeName; public Boolean multiRef; private TypeSection typeSection; private TypeDescription td; private FeatureDescription existingFd; private TypesWithNameSpaces allTypesList; private Composite multiRefComposite; private CCombo multiRefUI; private Composite elementTypeComposite; private Text elementRangeNameUI; private int typeFilter; /** * @param aSection * @param aExistingTd */ public AddFeatureDialog(AbstractSection aSection, TypeDescription aTd, FeatureDescription aExistingFd) { super(aSection, "Add a Feature", "Use this panel to add or edit a feature"); typeSection = (TypeSection) aSection; td = aTd; existingFd = aExistingFd; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingFd); createWideLabel(mainArea, "The feature name must be unique within this type"); // This part of the form looks like this sketch // // Feature Name: Text field << in 2 grid composite // Range Type: CCombo << in 2 grid composite // checkbox: multiple references allowed (hidden if not applicable) // Element Type: same as above (hidden if not applicable) // description: Text field << in 2 grid composite Composite twoCol = new2ColumnComposite(mainArea); featureNameUI = newLabeledSingleLineStyledText(twoCol, "Feature Name", S_); typeFilter = ALL_TYPES; featureRangeNameUI = newLabeledTypeInput(section, twoCol, "Range Type:", "The range type specifies the type of value this feature can hold."); multiRefComposite = new2ColumnComposite(twoCol); ((GridData) multiRefComposite.getLayoutData()).horizontalSpan = 2; multiRefUI = newLabeledCCombo(multiRefComposite, "References:", "Specify if this reference is the only reference to the collection object"); multiRefUI.add("Not Specified - defaults to multiple references not allowed"); multiRefUI.add("Multiple references not allowed"); multiRefUI.add("Multiple references allowed"); multiRefUI.select(0); elementTypeComposite = new2ColumnComposite(twoCol); ((GridData) elementTypeComposite.getLayoutData()).horizontalSpan = 2; typeFilter = ONLY_NON_PRIMITIVE_TYPES; elementRangeNameUI = newLabeledTypeInput(section, elementTypeComposite, "Element Type:", "The element type of each element in the Array or List object"); descriptionUI = newDescription(twoCol, S_); newErrorMessage(twoCol, 2); if (null != existingFd) { descriptionUI.setText(convertNull(existingFd.getDescription())); featureNameUI.setText(originalFeatureName = existingFd.getName()); featureRangeNameUI.setText(existingFd.getRangeTypeName()); Boolean mra = existingFd.getMultipleReferencesAllowed(); multiRefUI.select((null == mra) ? 0 : (mra.booleanValue()) ? 2 : 1); String ert = existingFd.getElementType(); elementRangeNameUI.setText((null == ert) ? "" : ert); } manageVisibleFields(); return mainArea; } private void manageVisibleFields() { String range = featureRangeNameUI.getText(); if (AbstractSection.isArrayOrListType(range)) { multiRefComposite.setVisible(true); if (AbstractSection.isFSArrayOrListType(range)) { elementTypeComposite.setVisible(true); } else { elementTypeComposite.setVisible(false); } } else { multiRefComposite.setVisible(false); elementTypeComposite.setVisible(false); } } public void handleEvent(Event event) { super.handleEvent(event); if (event.type == SWT.Modify && event.widget == featureRangeNameUI) manageVisibleFields(); } public TypesWithNameSpaces getTypeSystemInfoList() { TypesWithNameSpaces result = super.getTypeSystemInfoList(); Type[] allTypes = (Type[]) editor.allTypes.get().values().toArray(new Type[0]); /* Arrays.sort(allTypes, new Comparator() { public int compare(Object o1, Object o2) { Type t1 = (Type) o1; Type t2 = (Type) o2; return t1.getShortName().compareTo(t2.getShortName()); } }); */ for (int i = 0; i < allTypes.length; i++) { Type type = allTypes[i]; if (typeFilter == ONLY_NON_PRIMITIVE_TYPES) { if (!type.isPrimitive()) { result.add(type.getName()); } } else { result.add(type.getName()); } } if (typeFilter == ALL_TYPES) allTypesList = result; return result; } public void copyValuesFromGUI() { featureName = featureNameUI.getText(); description = nullIf0lengthString(descriptionUI.getText()); featureRangeName = featureRangeNameUI.getText(); multiRef = (1 == multiRefUI.getSelectionIndex()) ? Boolean.FALSE : (2 == multiRefUI .getSelectionIndex()) ? Boolean.TRUE : null; if (TypeSection.isFSArrayOrListType(featureRangeName)) { elementRangeName = elementRangeNameUI.getText(); if ("".equals(elementRangeName)) { elementRangeName = null; } } else { elementRangeName = null; } } public boolean verifyKeyChecks(VerifyEvent event) { if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB) return true; if (Character.isJavaIdentifierPart(event.character)) return true; if (event.widget == featureRangeNameUI && event.character == '.') return true; return false; } public boolean isValid() { if (featureName.length() == 0 || featureRangeName.length() == 0) return false; if (!featureName.equals(originalFeatureName)) { String errMsg = typeSection.checkFeature(this, td, existingFd); if (null != errMsg) { setErrorMessage(errMsg); return false; } } if (!typeContainedInTypeSystemInfoList(featureRangeName, allTypesList)) { setErrorMessage("RangeType '" + featureRangeName + "' is unknown. If this is intended, please define it first."); return false; } return true; } public void textModifyCallback(Event e) { manageVisibleFields(); } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(featureName.length() > 0 && featureRangeName.length() > 0); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddSofaDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001715111665471216033351 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection; public class AddSofaDialog extends AbstractDialogKeyVerify { private StyledText sofaNameUI; private CapabilitySection capabilitySection; private Capability capability; private String existingSofa; private boolean existingIsInput; private String originalSofa; public String sofaName; public boolean isInput; private Button inputButton; private Button outputButton; public AddSofaDialog(AbstractSection aSection, Capability c) { super(aSection, "Add a Sofa", "Use this panel to specify a Sofa Name."); capabilitySection = (CapabilitySection) aSection; capability = c; } /** * Constructor for Editing an existing Sofa Name * * @param aSection * @param aExistingTd */ public AddSofaDialog(AbstractSection aSection, Capability c, String aExistingSofa, boolean aIsInput) { this(aSection, c); existingSofa = aExistingSofa; existingIsInput = aIsInput; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingSofa); createWideLabel(mainArea, "Sofa names must be unique within a Capability Set, and are" + " simple names without name spaces (no dots in the name).\n\n" + " As a special case, they may end in .*\n" + " - Use this form to designate a class of sofa names, where the class\n" + " is all names that match the part up to the dot.\n\n" + "Type the name in the box below, and specify if it is an input Sofa\n" + "(created outside of this component), or an output Sofa (created by this component)."); // This part of the form looks like this sketch // // SofaName: Text field << in 2 grid composite // Input / Output: 2 radio checkboxes << in 2 grid composite // // Later: for Aggregates: // a table with sofa name, component key-name, input / output x's in columns // to allow easy "picking" for same-name things Composite twoCol = new Composite(mainArea, SWT.NONE); twoCol.setLayout(new GridLayout(2, false)); // false = not equal width twoCol.setLayoutData(new GridData(GridData.FILL_BOTH)); sofaNameUI = newLabeledSingleLineStyledText(twoCol, "Sofa Name", S_); sofaNameUI.setText("someNewSofaName"); new Label(twoCol, SWT.NONE).setText("Input / Output:"); Composite io = new Composite(twoCol, SWT.NONE); io.setLayout(new GridLayout(2, true)); io.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); inputButton = newButton(io, SWT.RADIO, "Input", "Click here to specify this Sofa is an input."); outputButton = newButton(io, SWT.RADIO, "Output", "Click here to specify this Sofa as an output."); inputButton.setSelection(true); outputButton.setSelection(false); newErrorMessage(twoCol, 2); if (null != existingSofa) { sofaNameUI.setText(originalSofa = existingSofa); if (existingIsInput) { inputButton.setSelection(true); outputButton.setSelection(false); } else { outputButton.setSelection(true); inputButton.setSelection(false); } } return mainArea; } public void copyValuesFromGUI() { sofaName = sofaNameUI.getText(); isInput = inputButton.getSelection(); } /** * Duplicate validity check: Duplicates are OK for sofas belonging to other capability sets, * provided they have the same Input or Output setting. */ public boolean isValid() { if (sofaName.length() == 0) return false; if (!sofaName.equals(originalSofa) || // true for adding new sofa, or sofa name changed on edit isInput != existingIsInput) { // true if input / output switched for editing // sofa, not changed name String errMsg = checkDuplSofaName(); if (null != errMsg) { setErrorMessage(errMsg); return false; } } if ((sofaName.contains(".") || sofaName.contains("*")) && (sofaName.indexOf('.') != (sofaName.length() - 2) || sofaName.indexOf('*') != (sofaName.length() - 1))) { setErrorMessage("Sofa Name cannot have the characters '.' or '*' except as the last 2 characters"); return false; } return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(sofaName.length() > 0); } private String checkDuplSofaName() { Capability[] cSets = capabilitySection.getCapabilities(); // check for dis-allowed duplicates in other capability sets for (int i = 0; i < cSets.length; i++) { Capability ci = cSets[i]; if (ci == capability) continue; // "reverse" i and o - if input validate name not exist as output in other sets, etc. String[] sofaNames = isInput ? ci.getOutputSofas() : ci.getInputSofas(); if (null != sofaNames) for (int j = 0; j < sofaNames.length; j++) { if (sofaName.equals(sofaNames[j])) return "This name exists as an " + (isInput ? "output" : "input") + " in some capability set. Please choose another name, or " + "switch the input/output specification to the opposite setting."; } } // check for duplicates in this capability if (!sofaName.equals(originalSofa)) { // means adding new sofa or changing name of existing one if (checkDuplSofaName1(sofaName, capability.getInputSofas()) || checkDuplSofaName1(sofaName, capability.getOutputSofas())) return "This name already in use; please choose a different name."; } return null; } private boolean checkDuplSofaName1(String name, String[] names) { if (null == names) return false; for (int i = 0; i < names.length; i++) { if (name.equals(names[i])) return true; } return false; } public boolean verifyKeyChecks(VerifyEvent event) { if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB) return true; if (Character.isJavaIdentifierPart(event.character) || event.character == '*' || event.character == '.') return true; return false; } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/FindComponentDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/F0000644000175000017500000001702611665471216033357 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; public class FindComponentDialog extends AbstractDialog { private Text searchByNameText, inputTypeText, outputTypeText; private CCombo lookInCombo; private List m_matchingDelegateComponetDescriptors; private List m_matchingDelegateComponentDescriptions; private Button cancelButton; public static final String ALL_PROJECTS = "All projects"; private Label statusLabel1, statusLabel2; private SearchThread m_searchThread = null; private String[] componentHeaders; /** * @param parentShell */ public FindComponentDialog(AbstractSection aSection, String title, String header, String[] componentHeaders) { super(aSection, title, header); this.componentHeaders = componentHeaders; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); AbstractSection.spacer(composite); new Label(composite, SWT.WRAP).setText("Descriptor file name pattern (e.g. ab*cde):"); searchByNameText = new Text(composite, SWT.BORDER); searchByNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); new Label(composite, SWT.WRAP).setText("Descriptor must specify the input type:"); inputTypeText = new Text(composite, SWT.BORDER); inputTypeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); new Label(composite, SWT.WRAP).setText("Descriptor must specify the output type:"); outputTypeText = new Text(composite, SWT.BORDER); outputTypeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); new Label(composite, SWT.WRAP).setText("Look in:"); lookInCombo = new CCombo(composite, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY); String[] projectNames = getProjectNames(); lookInCombo.add(' ' + ALL_PROJECTS); for (int i = 0; i < projectNames.length; i++) { lookInCombo.add(' ' + projectNames[i]); } lookInCombo.setText(' ' + ALL_PROJECTS); statusLabel1 = new Label(composite, SWT.NONE); statusLabel1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); statusLabel2 = new Label(composite, SWT.NONE); statusLabel2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); newErrorMessage(composite); return composite; } protected void createButtonsForButtonBar(Composite parent) { // create OK and Cancel buttons by default createButton(parent, IDialogConstants.OK_ID, "Search", true); cancelButton = createButton(parent, IDialogConstants.CANCEL_ID, "Stop Search", false); cancelButton.setEnabled(false); } private String[] getProjectNames() { IProject[] projects = TAEConfiguratorPlugin.getWorkspace().getRoot().getProjects(); String[] projectNames = new String[projects.length]; for (int i = 0; i < projects.length; i++) { projectNames[i] = projects[i].getName(); } return projectNames; } // also called by Search Monitoring Thread when // it notices the search thread is finished protected void buttonPressed(int buttonId) { if (buttonId == IDialogConstants.OK_ID) { // start search if (null != m_searchThread) errorMessageUI.setText("Search already in progress"); else copyValuesFromGUI(); } else { // cancel in-progress search if (m_searchThread.isDone()) { m_matchingDelegateComponetDescriptors = m_searchThread .getMatchingDelegateComponentDescriptors(); m_matchingDelegateComponentDescriptions = m_searchThread .getMatchingDelegateComponentDescriptions(); m_searchThread = null; super.superButtonPressed(IDialogConstants.OK_ID); } else { m_searchThread.setDieNow(); this.handleShellCloseEvent(); } return; } } private static final String needToEscapeTheseChars = ".+{}()\\"; private String convertToRegexSearchPattern(String searchPattern) { if (searchPattern == null || searchPattern.equals("")) { return null; } String searchPatternLowerCase = searchPattern.toLowerCase(); StringBuffer buffer = new StringBuffer("(?i)"); // case insensitive for (int i = 0; i < searchPatternLowerCase.length(); i++) { char ch = searchPatternLowerCase.charAt(i); if (ch == '*') { buffer.append(".*"); } else if (0 <= needToEscapeTheseChars.indexOf(ch)) { buffer.append('\\').append(ch); } else { buffer.append(ch); } } return new String(buffer); } public List getMatchingDelegateComponentDescriptors() { return m_matchingDelegateComponetDescriptors; } public List getMatchingDelegateComponentDescriptions() { return m_matchingDelegateComponentDescriptions; } public Label getStatusLabel1() { return statusLabel1; } public Label getStatusLabel2() { return statusLabel2; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { String fileNameSearch = convertToRegexSearchPattern(searchByNameText.getText()); String inputTypeSearch = convertToRegexSearchPattern(inputTypeText.getText()); String outputTypeSearch = convertToRegexSearchPattern(outputTypeText.getText()); String projectToSearch = lookInCombo.getText().substring(1); m_searchThread = new SearchThread(this, section, fileNameSearch, inputTypeSearch, outputTypeSearch, projectToSearch, componentHeaders); cancelButton.setEnabled(true); Thread searchThreadThread = new Thread(m_searchThread); searchThreadThread.start(); SearchMonitoringThread monitoringThread = new SearchMonitoringThread(this, m_searchThread); monitoringThread.start(); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid() */ public boolean isValid() { return true; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000002516511665471216033355 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.List; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.admin.FSIndexComparator; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.IndexSection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; public class AddIndexDialog extends AbstractDialogKeyVerifyJavaNames { private static final String TYPE_PRIORITY = "Type Priority"; private static final String STANDARD = "Standard"; private static final String REVERSE = "Reverse"; private StyledText indexNameUI; private Text indexTypeUI; private CCombo indexKindUI; private Table table; private Button addButton; private Button editButton; private Button removeButton; private Button upButton; private Button downButton; private Composite tableContainer; private Label keyTable; public String indexName; public String indexType; public String indexKind; public FsIndexKeyDescription[] keys; private String originalIndexName; private IndexSection indexSection; private FsIndexDescription existingNDX; public AddIndexDialog(AbstractSection aSection) { super(aSection, "Add an index", "Add or Edit an index specification"); indexSection = (IndexSection) aSection; } /** * Constructor for Editing an existing XRD * * @param aSection * @param aExistingXRD */ public AddIndexDialog(AbstractSection aSection, FsIndexDescription aExistingNDX) { this(aSection); existingNDX = aExistingNDX; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingNDX); createWideLabel(mainArea, "The Index name must be globally unique."); // This part of the form looks like this sketch // // IndexName: Text field << in 2 grid composite // IndexKind: combo // IndexType: Text field << assisted // description: Text field << in 2 grid composite // keys: first is text field assisted // 2nd is combo asc/desc/typePriority Composite twoCol = new2ColumnComposite(mainArea); indexNameUI = newLabeledSingleLineStyledText(twoCol, "Index Name:", "The globally unique index name"); indexKindUI = newLabeledCCombo(twoCol, "Index Kind:", "Specify the kind of index - sorted, set, or bag"); indexKindUI.add("sorted"); indexKindUI.add("bag"); indexKindUI.add("set"); new Label(twoCol, SWT.NONE).setText("CAS Type"); indexTypeUI = newTypeInput(section, twoCol); setTextAndTip( keyTable = new Label(twoCol, SWT.NONE), "Index Keys:", "For Set and Sorted index kinds, specify the keys; for Sorted indexes specify also the sort direction."); tableContainer = new2ColumnComposite(twoCol); table = newTable(tableContainer, SWT.SINGLE | SWT.FULL_SELECTION); table.setHeaderVisible(true); new TableColumn(table, SWT.NONE).setText("Feature Name"); new TableColumn(table, SWT.NONE).setText("Sorting Direction"); table.addListener(SWT.MouseDoubleClick, this); Composite buttonContainer = newButtonContainer(tableContainer); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add an Index key"); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP); downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP); newErrorMessage(twoCol, 2); if (null == existingNDX) { // set up defaults indexNameUI.setText("some.default.Name"); indexKindUI.setText(indexKindUI.getItem(0)); } else { indexNameUI.setText(originalIndexName = existingNDX.getLabel()); indexKindUI.setText(AbstractSection.handleDefaultIndexKind(existingNDX.getKind())); indexTypeUI.setText(existingNDX.getTypeName()); keys = existingNDX.getKeys(); if (null != keys) { for (int i = 0; i < keys.length; i++) { addKey(keys[i]); } } } section.packTable(table); indexKindUI.addListener(SWT.Modify, this); boolean showKeys = "sorted".equals(indexKindUI.getText()) || "set".equals(indexKindUI.getText()); tableContainer.setVisible(showKeys); keyTable.setVisible(showKeys); return mainArea; } public TypesWithNameSpaces getTypeSystemInfoList() { TypesWithNameSpaces result = super.getTypeSystemInfoList(); String[] allTypes = getAllTypesAsSortedArray(); for (int i = 0; i < allTypes.length; i++) { result.add(allTypes[i]); } return result; } private void addKey(FsIndexKeyDescription key) { if (null == key) return; TableItem item = new TableItem(table, SWT.NONE); updateKey(item, key); } private void updateKey(TableItem item, FsIndexKeyDescription key) { if (null == key) return; if (key.isTypePriority()) { item.setText(0, S_); item.setText(1, TYPE_PRIORITY); } else { item.setText(0, key.getFeatureName()); item.setText(1, key.getComparator() == FSIndexComparator.STANDARD_COMPARE ? STANDARD : REVERSE); } } public void handleEvent(Event event) { if (event.widget == indexKindUI) { boolean showKeys = "sorted".equals(indexKindUI.getText()) || "set".equals(indexKindUI.getText()); tableContainer.setVisible(showKeys); keyTable.setVisible(showKeys); } else if (event.widget == addButton) { AddIndexKeyDialog dialog = new AddIndexKeyDialog(section, indexTypeUI.getText(), indexKindUI .getText(), alreadyDefined(table.getItems())); addKey(indexSection.addOrEditIndexKey(dialog, null)); section.packTable(table); } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) { TableItem item = table.getItem(table.getSelectionIndex()); AddIndexKeyDialog dialog = new AddIndexKeyDialog(section, indexTypeUI.getText(), indexKindUI .getText(), alreadyDefined(table.getItems()), makeKey(item)); FsIndexKeyDescription key = indexSection.addOrEditIndexKey(dialog, null); updateKey(item, key); section.packTable(table); } else if (event.widget == removeButton) { TableItem item = table.getItem(table.getSelectionIndex()); table.setSelection(table.getSelectionIndex() - 1); item.dispose(); section.packTable(table); } else if (event.widget == upButton) { AbstractSection.swapTableItems(table.getSelection()[0], table.getSelectionIndex() - 1); } else if (event.widget == downButton) { int i = table.getSelectionIndex(); TableItem[] items = table.getItems(); AbstractSection.swapTableItems(items[i + 1], i + 1); } super.handleEvent(event); } public List alreadyDefined(TableItem[] items) { List result = new ArrayList(); if (null == items) return result; for (int i = 0; i < items.length; i++) { result.add(items[i].getText(0)); } return result; } public void copyValuesFromGUI() { indexName = indexNameUI.getText(); indexKind = indexKindUI.getText(); indexType = indexTypeUI.getText(); TableItem[] items = table.getItems(); if (null != items) { keys = new FsIndexKeyDescription[items.length]; for (int i = 0; i < items.length; i++) { keys[i] = makeKey(items[i]); } } else keys = null; } private FsIndexKeyDescription makeKey(TableItem item) { FsIndexKeyDescription key = UIMAFramework.getResourceSpecifierFactory() .createFsIndexKeyDescription(); boolean typePriority = TYPE_PRIORITY.equals(item.getText(1)); key.setTypePriority(typePriority); if (!typePriority) { key.setFeatureName(item.getText(0)); key.setComparator(STANDARD.equals(item.getText(1)) ? FSIndexComparator.STANDARD_COMPARE : FSIndexComparator.REVERSE_STANDARD_COMPARE); } return key; } public boolean isValid() { if (indexName.length() == 0 || indexType.length() == 0) return false; if (!indexName.equals(originalIndexName) && indexSection.isDuplicateIndexLabel(indexName)) { errorMessageUI .setText("The name on this index duplicates anexisting name. Please specify a globally unique name."); return false; } return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(indexName.length() > 0); boolean keysUsed = "sorted".equals(indexKind) || "set".equals(indexKind); addButton.setEnabled(indexName.length() != 0 && indexType.length() != 0 && keysUsed); boolean selected = table.getSelectionCount() == 1; removeButton.setEnabled(selected); editButton.setEnabled(selected); upButton.setEnabled(false); downButton.setEnabled(false); if (selected) { upButton.setEnabled(table.getSelectionIndex() != 0); downButton.setEnabled(table.getSelectionIndex() != (table.getItemCount() - 1)); } } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/A0000644000175000017500000001534611665471216033355 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.Arrays; import java.util.Comparator; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Type; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.TypeSection; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; public class AddTypeDialog extends AbstractDialogKeyVerifyJavaNames { private StyledText typeNameUI; private Text supertypeNameUI; private Text descriptionUI; public String typeName; private String originalTypeName; public String supertypeName; public String description; private TypeSection typeSection; private TypeDescription existingTd = null; private TypesWithNameSpaces allTypesList; // private boolean seenThisAlready = false; public AddTypeDialog(AbstractSection aSection) { super(aSection, "Add a Type", "Use this panel to specify a type."); typeSection = (TypeSection) aSection; } /** * Constructor for Editing an existing Type DescriptionD * * @param aSection * @param aExistingTd */ public AddTypeDialog(AbstractSection aSection, TypeDescription aExistingTd) { this(aSection); existingTd = aExistingTd; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existingTd); createWideLabel(mainArea, "Type names must be globally unique, unless you are intentionally redefining another type."); // This part of the form looks like this sketch // // typeName: Text field << in 2 grid composite // supertypeName: Text field << in 2 grid composite // description: Text field << in 2 grid composite Composite twoCol = new Composite(mainArea, SWT.NONE); twoCol.setLayout(new GridLayout(2, false)); // false = not equal width twoCol.setLayoutData(new GridData(GridData.FILL_BOTH)); typeNameUI = newLabeledSingleLineStyledText(twoCol, "Type Name", S_); typeNameUI.setText("some.typename.you.Choose"); new Label(twoCol, SWT.NONE).setText("Supertype:"); supertypeNameUI = newTypeInput(section, twoCol); descriptionUI = newDescription(twoCol, S_); newErrorMessage(twoCol, 2); if (null != existingTd) { descriptionUI.setText(convertNull(existingTd.getDescription())); typeNameUI.setText(originalTypeName = existingTd.getName()); supertypeNameUI.setText(convertNull(existingTd.getSupertypeName())); } // setting this triggers the handle event for modify // so this has to follow setting up the other widgets // because handle event reads them else supertypeNameUI.setText(CAS.TYPE_NAME_ANNOTATION); return mainArea; } /* * Supplies the list of valid types * * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#getTypeSystemInfoList() */ public TypesWithNameSpaces getTypeSystemInfoList() { TypesWithNameSpaces result = super.getTypeSystemInfoList(); boolean hasFeatures = false; boolean hasAllowedValues = false; if (null != existingTd) { hasFeatures = ((null != existingTd.getFeatures()) && (existingTd.getFeatures().length > 0)); hasAllowedValues = ((null != existingTd.getAllowedValues()) && (existingTd.getAllowedValues().length > 0)); if (hasAllowedValues) { result.add(CAS.TYPE_NAME_STRING); allTypesList = result; return result; } } Type[] allTypes = (Type[]) editor.allTypes.get().values().toArray(new Type[0]); Arrays.sort(allTypes, new Comparator() { public int compare(Object o1, Object o2) { Type t1 = (Type) o1; Type t2 = (Type) o2; return t1.getShortName().compareTo(t2.getShortName()); } }); for (int i = 0; i < allTypes.length; i++) { Type type = allTypes[i]; if (type.isInheritanceFinal() && !CAS.TYPE_NAME_STRING.equals(type.getName())) continue; if (hasFeatures && CAS.TYPE_NAME_STRING.equals(type.getName())) continue; result.add(type.getName()); } allTypesList = result; return result; } public void copyValuesFromGUI() { typeName = typeNameUI.getText(); description = nullIf0lengthString(descriptionUI.getText()); supertypeName = supertypeNameUI.getText(); } public boolean isValid() { if (typeName.length() == 0) return false; if (typeName.charAt(typeName.length() - 1) == '.') { setErrorMessage("Name cannot end with a period (.)"); return false; } if (!typeName.equals(originalTypeName)) { String errMsg = typeSection.checkDuplTypeName(typeName); if (null != errMsg) { setErrorMessage(errMsg); return false; } } if (!typeContainedInTypeSystemInfoList(supertypeName, allTypesList)) { setErrorMessage("SuperType '" + supertypeName + "' is unknown. If this is intended, please define it first."); return false; } TypeDescription importedType = editor.getImportedTypeSystemDesription().getType(typeName); if (null != importedType) { if (!supertypeName.equals(importedType.getSupertypeName())) { setErrorMessage("The supertype specified must be '" + importedType.getSupertypeName() + "' due to merging with imported types. Please change it to this type."); return false; } } return true; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled(typeName.length() > 0); } } ././@LongLink0000000000000000000000000000017700000000000011572 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchMonitoringThread.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/S0000644000175000017500000000340311665471216033366 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.widgets.Display; public class SearchMonitoringThread extends Thread { private SearchThread m_searchThread; FindComponentDialog m_dialog; public SearchMonitoringThread(FindComponentDialog dialog, SearchThread searchThread) { m_dialog = dialog; m_searchThread = searchThread; } public void run() { while (true) { if (m_searchThread.isDone()) { if (!m_dialog.getStatusLabel1().isDisposed()) { Display display = m_dialog.getStatusLabel1().getDisplay(); display.syncExec(new Runnable() { public void run() { m_dialog.buttonPressed(IDialogConstants.CANCEL_ID); } }); } return; } try { Thread.sleep(500); } catch (Exception ex) { } } } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces32.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/T0000644000175000017500000001233611665471216033374 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import org.eclipse.jface.fieldassist.IContentProposal; import org.eclipse.jface.fieldassist.IContentProposalProvider; /* * This class forwards to TypesWithNameSpaces * Purpose: provide content assist under Eclipse 3.2 * (The other class is set up to provide browse assist under 3.1 or higher Eclipse) */ public class TypesWithNameSpaces32 implements IContentProposalProvider { final private SortedMap sortedNames; public TypesWithNameSpaces32(TypesWithNameSpaces aBase) { sortedNames = aBase.sortedNames; } private CasTypeProposal [] proposalArray = null; public static class CasTypeProposal implements IContentProposal, Comparable { private final String labelForm; private final String fullName; private final String compareKey; /* (non-Javadoc) * @see org.eclipse.jface.fieldassist.IContentProposal#getContent() */ CasTypeProposal(String aCompareKey, String shortName, String nameSpace) { fullName = (null == nameSpace || "".equals(nameSpace))? shortName : nameSpace + "." + shortName; labelForm = (null == nameSpace || "".equals(nameSpace))? shortName : shortName + " - " + nameSpace; compareKey = aCompareKey.toLowerCase(); } public String getContent() { return fullName; } /* (non-Javadoc) * @see org.eclipse.jface.fieldassist.IContentProposal#getCursorPosition() */ public int getCursorPosition() { return fullName.length(); } /* (non-Javadoc) * @see org.eclipse.jface.fieldassist.IContentProposal#getDescription() */ public String getDescription() { return null; } /* (non-Javadoc) * @see org.eclipse.jface.fieldassist.IContentProposal#getLabel() */ public String getLabel() { if (labelForm.toLowerCase().startsWith(compareKey)) return labelForm; else return fullName; } public String getCompareKey() { return compareKey; } /* (non-Javadoc) * @see java.lang.Comparable#compareTo(java.lang.Object) */ public int compareTo(Object arg0) throws ClassCastException { final CasTypeProposal c = (CasTypeProposal) arg0; return this.compareKey.compareTo(c.getCompareKey()); } } public void createProposalArray() { List r = new ArrayList(sortedNames.size()*2); // item a.b.c.name creates 2 entries in the suggestions: // compare key: a.b.c.name label: name - a.b.c content: a.b.c.name // compare key: name label: name - a.b.c content: a.b.c.name for (Iterator it = sortedNames.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); Set nameSpaces = (Set)entry.getValue(); for (Iterator nsi = nameSpaces.iterator(); nsi.hasNext();) { String nameSpace = (String)nsi.next(); String shortName = (String)entry.getKey(); r.add(new CasTypeProposal(shortName, shortName, nameSpace)); if (null != nameSpace) { r.add(new CasTypeProposal(nameSpace + "." + shortName, shortName, nameSpace)); } } } proposalArray = (CasTypeProposal[])r.toArray(new CasTypeProposal[r.size()]); Arrays.sort(proposalArray); } public CasTypeProposal [] getProposalArray() { return proposalArray; } /* (non-Javadoc) * @see org.eclipse.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int) */ public IContentProposal[] getProposals(String contents, int position) { if (null == proposalArray) createProposalArray(); String keyString = contents.substring(0, position).toLowerCase(); CasTypeProposal key = new CasTypeProposal(keyString, null, null); int i = Arrays.binarySearch(proposalArray, key); if (i < 0) { i = Math.abs(i + 1); } List rl = new ArrayList(proposalArray.length - i); for (; i < proposalArray.length; i++) { if (proposalArray[i].getCompareKey().startsWith(keyString)) { rl.add(proposalArray[i]); } else break; } return (CasTypeProposal[])rl.toArray(new CasTypeProposal[rl.size()]); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/CommonInputDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/C0000644000175000017500000001046511665471216033354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui.dialogs; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; /** */ public class CommonInputDialog extends AbstractDialogKeyVerify { public static final int PLAIN_NAME = 1; public static final int DOTTED_NAME = 1 << 1; public static final int SPACED_NAMES = 1 << 2; public static final int LANGUAGE = 1 << 3; public static final int ALLOK = 1 << 4; public static final int TRUE_FALSE = 1 << 5; public static final int INTEGER = 1 << 6; public static final int FLOAT = 1 << 7; public static final int GROUP_NAMES = DOTTED_NAME | SPACED_NAMES | LANGUAGE; private int validation; private String existing; private StyledText text; private String result; public CommonInputDialog(AbstractSection aSection, String title, String dialogDescription, int aKind) { super(aSection, title, dialogDescription); validation = aKind; } public CommonInputDialog(AbstractSection aSection, String title, String dialogDescription, int aKind, String aExisting) { this(aSection, title, dialogDescription, aKind); existing = aExisting; } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite) super.createDialogArea(parent, existing); text = newSingleLineStyledText(mainArea, ""); AbstractSection.spacer(mainArea); newErrorMessage(mainArea); if (null != existing) text.setText(existing); else text.setText(S_); return mainArea; } public boolean verifyKeyChecks(VerifyEvent event) { char ch = event.character; boolean validateDottedName = ((validation & DOTTED_NAME) == DOTTED_NAME); boolean validateSpaces = ((validation & SPACED_NAMES) == SPACED_NAMES); boolean validateLanguage = ((validation & LANGUAGE) == LANGUAGE); boolean validateAllOK = ((validation & ALLOK) == ALLOK); boolean validateTrueFalse = ((validation & TRUE_FALSE) == TRUE_FALSE); boolean validateInteger = ((validation & INTEGER) == INTEGER); boolean validateFloat = ((validation & FLOAT) == FLOAT); if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB || event.keyCode == SWT.BS) return true; if (validateTrueFalse) { return ("truefalse".indexOf(ch) >= 0); } if (validateSpaces && ch == ' ') return true; if (validateDottedName && ch == '.') return true; if ((!validateTrueFalse) && (!validateInteger) && (!validateFloat) && Character.isJavaIdentifierPart(ch)) return true; if (validateLanguage && ch == '-') return true; if (validateAllOK) return true; if (validateInteger) if (Character.isDigit(ch) || ch == '-') return true; if (validateFloat) { if (Character.isDigit(ch) || ch == '-' || ch == 'E' || ch == 'e' || ch == '.') return true; } return false; } public String getValue() { return result; } public void enableOK() { copyValuesFromGUI(); okButton.setEnabled("".equals(errorMessageUI.getText()) && (text.getText().length() > 0)); } public void copyValuesFromGUI() { result = text.getText(); } public boolean isValid() { return true; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilityPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Capabilit0000644000175000017500000000405611665471220033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.swt.SWT; import org.eclipse.ui.forms.IManagedForm; public class CapabilityPage extends HeaderPageWithSash { private SofaMapSection sofaMapSection; public CapabilityPage(MultiPageEditor aEditor) { super(aEditor, "Capabilities"); } /** * Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { final Form2Panel form2Panel = setup2ColumnLayout(managedForm, editor.isAggregate() ? 50 : 90, editor.isAggregate() ? 50 : 10); managedForm.getForm().setText("Capabilities: Inputs and Outputs"); managedForm.addPart(/* inputSection = */new CapabilitySection(editor, form2Panel.left)); managedForm.addPart(sofaMapSection = new SofaMapSection(editor, form2Panel.right)); createToolBarActions(managedForm); sashForm.setOrientation(SWT.VERTICAL); vaction.setChecked(true); haction.setChecked(false); managedForm.getForm().reflow(true); } public SofaMapSection getSofaMapSection() { return sofaMapSection; } } ././@LongLink0000000000000000000000000000017600000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractImportablePartSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractI0000644000175000017500000001465611665471220033425 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.model.BuiltInTypes; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.widgets.Composite; public abstract class AbstractImportablePartSection extends AbstractSection { /** * @param editor * @param parent * @param headerText * @param description */ public AbstractImportablePartSection(MultiPageEditor aEditor, Composite parent, String headerText, String description) { super(aEditor, parent, headerText, description); } // ******************************** // * GUI methods // ******************************** protected boolean isLocalItem(TableTreeItem item) { return !item.getForeground().equals(editor.getFadeColor()); } // ******************************** // * Universal Getters // ******************************** /** * returns null if no feature by this name * * @param name * @param td * @return */ public FeatureDescription getFeatureFromTypeDescription(String name, TypeDescription td) { FeatureDescription[] fds = td.getFeatures(); if (fds == null) return null; for (int i = 0; i < fds.length; i++) { if (name.equals(fds[i].getName())) return fds[i]; } return null; } public AllowedValue getAllowedValue(String value, TypeDescription td) { AllowedValue[] avs = td.getAllowedValues(); if (null == avs) return null; for (int i = 0; i < avs.length; i++) { if (value.equals(avs[i].getString())) return avs[i]; } return null; } // ******************************** // * Local Getters // ******************************** protected TypeDescription getLocalTypeDefinition(TypeDescription td) { TypeSystemDescription tsdLocal = getTypeSystemDescription(); if (null == tsdLocal) return null; return tsdLocal.getType(td.getName()); } protected FeatureDescription getLocalFeatureDefinition(TypeDescription td, FeatureDescription fd) { return getLocalFeatureDefinition(td, fd.getName()); } protected FeatureDescription getLocalFeatureDefinition(TypeDescription td, String featureName) { TypeDescription localTd = getLocalTypeDefinition(td); if (null == localTd) return null; return getFeatureFromTypeDescription(featureName, localTd); } protected AllowedValue getLocalAllowedValue(TypeDescription td, AllowedValue unchangedAv) { TypeDescription localTd = getLocalTypeDefinition(td); if (null == localTd) return null; return getAllowedValue(unchangedAv.getString(), localTd); } // ******************************** // * Built-in Getters // * used to do GUI "merge" with built-in things // ******************************** public TypeDescription getBuiltInTypeDescription(TypeDescription td) { return (TypeDescription) BuiltInTypes.typeDescriptions.get(td.getName()); } // ******************************** // * Local Testers // ******************************** protected boolean isLocalType(TypeDescription td) { return (null != getLocalTypeDefinition(td)); } protected boolean isLocalType(String typeName) { return null != editor.getTypeSystemDescription().getType(typeName); } protected boolean isLocalFeature(String featureName, TypeDescription td) { return (null != getLocalFeatureDefinition(td, featureName)); } protected boolean isLocalAllowedValue(String avString, TypeDescription td) { TypeDescription localTd = getLocalTypeDefinition(td); if (null == localTd) return false; return Utility.arrayContains(localTd.getAllowedValues(), avString); } // ******************************** // * Imported Testers // ******************************** public boolean isImportedType(String typeName) { return null != editor.getImportedTypeSystemDesription().getType(typeName); } protected boolean isImportedType(TypeDescription td) { return null != editor.getImportedTypeSystemDesription().getType(td.getName()); } protected boolean isImportedFeature(String name, TypeDescription td) { TypeDescription importedTd = editor.getImportedTypeSystemDesription().getType(td.getName()); if (null == importedTd) return false; return null != getFeatureFromTypeDescription(name, importedTd); } protected boolean isImportedAllowedValue(TypeDescription td, AllowedValue av) { TypeDescription importedTd = editor.getImportedTypeSystemDesription().getType(td.getName()); if (null == importedTd) return false; return null != getAllowedValue(av.getString(), importedTd); } // ******************************** // * Built-in Testers // ******************************** protected boolean isBuiltInType(TypeDescription td) { return null != getBuiltInTypeDescription(td); } protected boolean isBuiltInType(String typeName) { return null != BuiltInTypes.typeDescriptions.get(typeName); } protected boolean isBuiltInFeature(String name, TypeDescription td) { TypeDescription builtInTd = (TypeDescription) BuiltInTypes.typeDescriptions.get(td.getName()); if (null == builtInTd) return false; return null != getFeatureFromTypeDescription(name, builtInTd); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PriorityListSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PriorityL0000644000175000017500000002460411665471220033500 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.UIMAFramework; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddTypeToPriorityListDialog; import org.apache.uima.taeconfigurator.wizards.TypePrioritiesNewWizard; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.IManagedForm; public class PriorityListSection extends AbstractSection { public static final String PRIORITY_LIST = ""; private Tree tree; private Button addSetButton; private Button addButton; private Button removeButton; private Button upButton; private Button downButton; private TypePriorityImportSection typePriorityImportSection; private Button exportButton; public PriorityListSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Priority Lists", "This section shows the defined Prioirity Lists"); } public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); tree = newTree(sectionClient); final Composite buttonContainer = newButtonContainer(sectionClient); addSetButton = newPushButton(buttonContainer, "Add Set", "Click here to add another priority list."); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a type"); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); new Button(buttonContainer, SWT.PUSH).setVisible(false); // spacer upButton = newPushButton(buttonContainer, S_UP, "Click here to move the selected item up in the priority order."); downButton = newPushButton(buttonContainer, S_DOWN, "Click here to move the selected item down in the priority order"); exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { if (null == typePriorityImportSection) typePriorityImportSection = editor.getIndexesPage().getTypePriorityImportSection(); super.refresh(); tree.removeAll(); TypePriorities typePriorities = getTypePriorities(); if (typePriorities != null) { TypePriorityList[] priorityLists = typePriorities.getPriorityLists(); for (int i = 0; i < priorityLists.length; i++) { TreeItem item = new TreeItem(tree, SWT.NONE); item.setText(PRIORITY_LIST); String[] types = priorityLists[i].getTypes(); if (null != types) { for (int j = 0; j < types.length; j++) { TreeItem tItem = new TreeItem(item, SWT.NONE); tItem.setText(formatName(types[j])); } } item.setExpanded(true); } } if (tree.getItemCount() > 0) tree.setSelection(new TreeItem[] { tree.getItems()[0] }); enable(); } public TypePriorityList getTypePriorityListFromTreeItem(TreeItem item) { TypePriorityList[] typePriorityLists = getAnalysisEngineMetaData().getTypePriorities() .getPriorityLists(); return typePriorityLists[tree.indexOf(item)]; } public void handleEvent(Event event) { if (event.widget == addSetButton) { TypePriorityList typePriorityList = UIMAFramework.getResourceSpecifierFactory() .createTypePriorityList(); TypePriorities typePriorities = getTypePriorities(); if (typePriorities == null) { typePriorities = UIMAFramework.getResourceSpecifierFactory().createTypePriorities(); getAnalysisEngineMetaData().setTypePriorities(typePriorities); } getTypePriorities().addPriorityList(typePriorityList); TreeItem item = new TreeItem(tree, SWT.NONE); item.setText(PRIORITY_LIST); tree.setSelection(new TreeItem[] { item }); setFileDirty(); } else if (event.widget == addButton) { // add type to set if (editor.isTypePriorityDescriptor() && !editor.getIsContextLoaded()) { Utility .popMessage( "Can''t add types here", "Types cannot be added here, because there is no loaded context type system to pick the types from", MessageDialog.WARNING); return; } TreeItem parent = tree.getSelection()[0]; if (null != parent.getParentItem()) parent = parent.getParentItem(); AddTypeToPriorityListDialog dialog = new AddTypeToPriorityListDialog(this, editor.definedTypesWithSupers.get(), // types getTypePriorityListFromTreeItem(parent).getTypes()); // types already in list if (dialog.open() == Window.CANCEL) return; TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent); String[] newTypeNames = dialog.getSelectedTypeNames(); for (int i = 0; i < newTypeNames.length; i++) { typePriorityList.addType(newTypeNames[i]); TreeItem item = new TreeItem(parent, SWT.NONE); item.setText(formatName(newTypeNames[i])); } setFileDirty(); } else if (event.widget == removeButton) { TreeItem item = tree.getSelection()[0]; TreeItem parent = item.getParentItem(); if (null == parent) { // removing a priority set if (Window.CANCEL == Utility.popOkCancel("ConfirmRemove", "ConfirmRemoveSet", MessageDialog.WARNING)) return; TypePriorityList removedTypePriorityList = getTypePriorityListFromTreeItem(item); TypePriorityList[] oldPriorityLists = getAnalysisEngineMetaData().getTypePriorities() .getPriorityLists(); TypePriorityList[] newPriorityLists = new TypePriorityList[oldPriorityLists.length - 1]; for (int i = 0, j = 0; i < oldPriorityLists.length; i++) { if (oldPriorityLists[i] != removedTypePriorityList) { newPriorityLists[j++] = oldPriorityLists[i]; } } getAnalysisEngineMetaData().getTypePriorities().setPriorityLists(newPriorityLists); } else { // removing a type if (Window.CANCEL == Utility.popOkCancel("ConfirmRemove", "ConfirmRemoveType", MessageDialog.WARNING)) return; TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent); typePriorityList.removeType(item.getText()); } TreeItem previousSelection = getPreviousSelection(parent == null ? tree.getItems() : parent .getItems(), item); if (null != previousSelection) tree.setSelection(new TreeItem[] { previousSelection }); item.dispose(); setFileDirty(); } // only enabled for types else if (event.widget == downButton || event.widget == upButton) { TreeItem item = tree.getSelection()[0]; TreeItem parent = item.getParentItem(); TreeItem[] items = parent.getItems(); int i = getItemIndex(items, item); TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent); String[] types = typePriorityList.getTypes(); String temp = types[i]; if (event.widget == downButton) { types[i] = types[i + 1]; types[i + 1] = temp; typePriorityList.setTypes(types); new TreeItem(parent, SWT.NONE, i).setText(formatName(types[i])); TreeItem t = new TreeItem(parent, SWT.NONE, i + 1); t.setText(formatName(types[i + 1])); tree.setSelection(new TreeItem[] { t }); items[i].dispose(); items[i + 1].dispose(); } else { types[i] = types[i - 1]; types[i - 1] = temp; typePriorityList.setTypes(types); TreeItem t = new TreeItem(parent, SWT.NONE, i - 1); t.setText(formatName(types[i - 1])); tree.setSelection(new TreeItem[] { t }); new TreeItem(parent, SWT.NONE, i).setText(formatName(types[i])); items[i - 1].dispose(); items[i].dispose(); setFileDirty(); } TypePriorityList[] tpl = getTypePriorities().getPriorityLists(); tpl[tree.indexOf(parent)] = typePriorityList; getTypePriorities().setPriorityLists(tpl); } else if (event.widget == exportButton) { typePriorityImportSection.exportImportablePart("", TypePrioritiesNewWizard.TYPEPRIORITIES_TEMPLATE); refresh(); } enable(); } public void enable() { if (tree.getSelectionCount() == 1) { addButton.setEnabled(true); TreeItem item = tree.getSelection()[0]; removeButton.setEnabled(true); if (null != item.getParentItem()) { TreeItem[] items = item.getParentItem().getItems(); int i = getItemIndex(items, item); upButton.setEnabled(i > 0); downButton.setEnabled(i < (items.length - 1)); } } else { addButton.setEnabled(false); removeButton.setEnabled(false); upButton.setEnabled(false); downButton.setEnabled(false); } exportButton.setEnabled(tree.getItemCount() > 0); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Parameter0000644000175000017500000013255611665471220033471 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; /* * Created on 15.07.2003 * * Redesign Feb 7 2005 Redesign Feb 9 2005 Changed Description to hover style Feb 27 * * Add Two case: primitive and aggregate Primitive: allow groups to be defined, * including Allow multi def of parmnames (with same decls) as long as * they're in different groups. Same name not allowed in both and named group but are * allowed in both and * * A parm name declared in different groups which don't overlap can have a different declaration. * * Parm names are unique within a within the group-set formed by the union of all groups where the * parm is defined. This means that a parm name P1 in group g1, g2 must match the definition of a * parm name P1 in group g2, g3. * * Two parm names with the same name, in different non-intersecting groups, are distinct. * * Two parm names with the same name, in different delegates, even if in the same group, are * distinct. They can have different definitions. They can be seperately overridden in each * delegate. This allows separate development of primitives, with future combining. * * Two parm names with the same name in the same primitive that is used twice in the delegates list * are distinct. They can be separately overridden, with different values. In this case, though, the * definitions (type, multi-value, mandatory) are the same. * * Aggregate: groups are the union of immediate delegate groups, except Common at lower * level defines parms that are in all named groups at that level. * * Treatment of : in a delegate is translated into G1, G2, ... Gn (all groups * defined in that delegate). * * Common at aggregate level defines parms that are in all named groups at aggregate level. This is * a bigger set of group names than exist at any lower delegate level. Note: Cannot add or remove * groups at aggregate level: the groups are pre-defined based on the delegates * * Check of the model done at first refresh to validate it. If model has extra groups (not in * delegates) - these are removed. If model is missing groups (in delegates) - these are added. * * 2 panel design for aggregate. Right panel is tree, delegate-keys, groups, parms Left panel is * like primitive panel. * * Operations: Adding an override: double click on right panel element. click on delegate: add all * parms all groups click on group: add group and all parms click on parm: add parm * * On left panel: add override - adds additional override. Edit - applies to override - change the * override. Remove - applies to override, to param, to group * * When adding overriding parm for a delegate, use as a default the same name as the name being * overridden. Change name if there exists parm in the groups with same name but different def * Change name if there exists parm but group membership is not equal. * * User may change the name in any case. If user does this, check for name collision as above. This * is useful, for instance, when more than one delegate defines that parameter name - to allow each * delegate to have a different override. * * Adding a parm under a group: set default, allow overtyping - auto fill in type, mandatory, and * multivalue from picked parm name setting override: based on what was clicked * * OK ToDo: When adding a parm, if it is an aggregate, include OK ToDo; When adding a * parm, have custom dialog, set multivalued, mandatory, and 1st override OK ToDo: add button add * override (for case: aggregate) OK ToDo: make remove work for override, and edit too Later: ToDo: * For overrides: lookup key names, lookup parm names in delegates. If delegate is another * aggregate, do additional key All this done as optional - in case sub things not yet defined. What * about a "browse" like file system? for descending thru aggr to parm? * * Todos: MaybeNot 1) make model for all parmDefs following other models MaybeNot 2) make model for * all parmSettings following other models 2a) Have all changes (add, edit, and remove) affect * ParameterSettingsSection 2aa) For Edit of each kind including changing name consider effect on * settings OK 3) Checking: if change type - what to do about existing setting? Message it will be * deleted OK 4) Checking: if change MultiV - same as above. OK 5) Checking: overrides: only show * parm names which match on type and mv and mandatory < override OK 6) Model for editing overrides: * using same dialog, plus combo to select which override, autoselected when dbl-clicking / edit * existing , or adding new. Make base parm info read-only to avoid accidents NO 7) detail window: * for groups: has list of group names; line per name, editable. for parm: has description; editable * for overrides: has override string; line per segment, editable. OK 8) Checking: overrides: last * level must have parm style match. 9) add value fixups and change awareness; use change awareness * to trigger model updates OK 10) add name character-set checking OK 11) Fix shash for borders, for * initial ratio, move to HeaderSection. Note: not appropriate for things with centered import box * on bottom. * * March 24 2005 - finish impl of overrides for aggregates: Disallow editing of parameters or adding * parameters (parameters only to be created via the double-click on the delegate parameter). * * Have the double-click on the deletage handle Common properly by setting up a special group with * all the groups for that delegate. * * Allow adding additional overrides. Do in pickOverrides dialog. * * */ import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl; import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddParameterDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog; import org.apache.uima.taeconfigurator.files.PickOverrideKeysAndParmName; import org.apache.uima.taeconfigurator.model.ConfigGroup; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.IManagedForm; public class ParameterSection extends AbstractSectionParm { public final static int NEW_OVERRIDE = -1; public final static boolean REMOVE_FROM_GUI = true; public final static boolean GIVE_WARNING_MESSAGE = true; private Text defaultGroup; private CCombo searchStrategy; private Button addButton; private Button addGroupButton; private Button editButton; private Button removeButton; private Button usingGroupsButton; private Composite groupingControl; private boolean firstTime = true; /** * Creates a section to show a list of all parameters * * @param editor * backpointer to the main multipage editor * @param parent * the Composite where this section lives */ public ParameterSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Configuration Parameters", "This section shows all configuration parameters defined for this engine."); } // This page shows the configuration parameters // Organization: top section for switching between simple and groups, and // for groups: default Group name, + search strat (combo) // Main body: a tree, 2 hierarchies: // 1) for groups // 2) for aggregates: overrides // Tree is one of 3 entries: // parm entry: multi/single, req/opt, boolean/string/int/float, name // group entry: , , , names // (aggregates) key/key/.../key/parmname // // Checking: parmNames are unique for primitive and each aggr level // overrides: lookup valid keys and parmnames // names: well-formed with proper char sets, like java pkg names // // Editing: via double click, or edit button + select. // using same dialog as for create // // Tree and corresponding tree (if created) in ParameterSettings are // both incrementally updated, so rebuild is not needed. This preserves // user-specified expansion of nodes. public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = newComposite(getSection()); usingGroupsButton = newCheckBox(sectionClient, "Use Parameter Groups", "Check this box if Groups are being used with Parameters"); groupingControl = new2ColumnComposite(sectionClient); ((GridData) groupingControl.getLayoutData()).grabExcessVerticalSpace = false; enableBorders(groupingControl); toolkit.paintBordersFor(groupingControl); defaultGroup = newLabeledTextField(groupingControl, "Default Group", "Specify the name of the default group."); newLabelWithData(groupingControl, "SearchStrategy"); searchStrategy = newCComboWithTip(groupingControl, "SearchStrategyToolTip"); searchStrategy.add("language_fallback"); searchStrategy.add("default_fallback"); searchStrategy.add("none"); // main table + buttons on left Composite tableContainer = new2ColumnComposite(sectionClient); enableBorders(tableContainer); toolkit.paintBordersFor(tableContainer); // SWT.SINGLE to support deselecting // SWT.FULL_SELECTION to select whole row parameterSectionTree = tree = newTree(tableContainer); // Buttons Composite buttonContainer = newButtonContainer(tableContainer); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a new parameter"); addGroupButton = newPushButton(buttonContainer, "AddGroup", "Click here to add a group specification. A group specification names one or more group names."); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); tree.addListener(SWT.MouseDoubleClick, this); // for Editing tree.addListener(SWT.MouseHover, this); // for Description } /* * refresh() called when UI is stale with respect to the model. Updates the UI to be in sync with * the model Not called when model updated thru UI interaction. Called initially, and called when * switching from sourcePage because user may have arbitrarilly changed things. (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); // clears stale and dirty bits in AbstractFormPart // superclass cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations(); if ((firstTime && isParmGroup()) || isAggregate() || (!firstTime && usingGroupsButton.getSelection())) { usingGroupsButton.setSelection(true); groupingControl.setVisible(true); defaultGroup.setText(convertNull(cpd.getDefaultGroupName())); if (null == cpd.getSearchStrategy()) cpd.setSearchStrategy("language_fallback"); searchStrategy.setText(cpd.getSearchStrategy()); } else { groupingControl.setVisible(false); usingGroupsButton.setSelection(false); } firstTime = false; showOverrides = true; splitGroupNames = false; clearAndRefillTree(usingGroupsButton.getSelection()); tree.setSelection(new TreeItem[] { tree.getItems()[0] }); enable(); // sync settings page to catch use case of switching from sourceEditor // to this page after having shown settings page - may be out of date ParameterSettingsSection settingsSection = editor.getSettingsPage() .getParameterSettingsSection(); if (null != settingsSection) { setSettings(settingsSection); settings.refresh(); } } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations(); if (event.type == SWT.MouseHover) { showDescriptionAsToolTip(event); } else if (event.widget == usingGroupsButton) { if (usingGroupsButton.getSelection()) { } else { if (Window.CANCEL == Utility .popOkCancel( "Confirm Remove Groups", "This action will delete any group information that may be present in this descriptor. Proceed?", MessageDialog.WARNING)) { usingGroupsButton.setSelection(true); return; } // remove all top level items (groups) except the 1st one, // which is NOT_IN_ANY_GROUP TreeItem[] items = tree.getItems(); TreeItem[] removeItems = new TreeItem[items.length - 1]; System.arraycopy(items, 1, removeItems, 0, removeItems.length); removeItems(removeItems, !GIVE_WARNING_MESSAGE); cpd.setCommonParameters(AbstractSection.configurationParameterArray0); cpd.setConfigurationGroups(AbstractSection.configurationGroupArray0); } setFileDirty(); // maybe slightly overkill refresh(); } else if (event.widget == searchStrategy) { valueChanged = false; cpd.setSearchStrategy(setValueChanged(searchStrategy.getText(), cpd.getSearchStrategy())); if (valueChanged) setFileDirty(); } else if (event.widget == defaultGroup) { valueChanged = false; cpd.setDefaultGroupName(setValueChanged(defaultGroup.getText(), cpd.getDefaultGroupName())); if (valueChanged) setFileDirty(); } else if (event.widget == addGroupButton) { CommonInputDialog dialog = new CommonInputDialog( this, "Add Group", "Specify one or more unique group names, separated by 1 space character, and press OK", CommonInputDialog.GROUP_NAMES); for (;;) { // stay in loop until get "true" return from add below // used for looping while group name set is duplicate if (dialog.open() == Window.CANCEL) return; if (addNewOrEditExistingGroup(dialog.getValue(), null)) break; } commonActionFinish(); } else if (event.widget == addButton) { // add parameter or add override action boolean valid = tree.getSelectionCount() == 1; if (isPrimitive()) valid = valid && (isGroupSelection() || isParmSelection()); else valid = valid && (isParmSelection() || isOverrideSelection()); if (!valid) { if (isPrimitive()) Utility.popMessage("Wrong item selected", "Please first select the group under which to add a parameter", MessageDialog.ERROR); else Utility.popMessage("Wrong item selected", "Please first select the parameter under which to add an override", MessageDialog.ERROR); return; } if (isPrimitive()) { // adding a parameter TreeItem parentGroup = tree.getSelection()[0]; if (isParmSelection()) parentGroup = parentGroup.getParentItem(); AddParameterDialog dialog = new AddParameterDialog(this); if (dialog.open() == Window.CANCEL) return; addNewConfigurationParameter(dialog, parentGroup); if (null != parentGroup) parentGroup.setExpanded(true); commonActionFinish(); } else { // is aggregate - add an override TreeItem parentParm = tree.getSelection()[0]; if (isOverride(parentParm)) parentParm = parentParm.getParentItem(); addOrEditOverride(parentParm, -1); } } else if ((event.widget == editButton) || (event.type == SWT.MouseDoubleClick)) { TreeItem editItem = tree.getSelection()[0]; if (isParameter(editItem) && isPrimitive()) { AddParameterDialog dialog = new AddParameterDialog(this, getCorrespondingModelParm(editItem)); if (dialog.open() == Window.CANCEL) return; // update the existing item alterExistingConfigurationParameter(dialog, editItem); // TODO consequences of changes in rest of model? commonActionFinishDirtyIfChange(); } else if (isParameter(editItem) && isAggregate()) { // can edit name and description, but not Type (set from override) ConfigurationParameter existingCP = getCorrespondingModelParm(editItem); AddParameterDialog dialog = new AddParameterDialog(this, existingCP); if (dialog.open() == Window.CANCEL) return; alterExistingConfigurationParameter(dialog, editItem); // TODO consequences of changes in rest of model? commonActionFinishDirtyIfChange(); } else if (isOverride(editItem)) { TreeItem parent = editItem.getParentItem(); int overrideIndex = getItemIndex(parent, editItem); addOrEditOverride(parent, overrideIndex); } else if (isGroup(editItem)) { String groupNames = getName(editItem.getText()); if (groupNames.equals(COMMON_GROUP) || groupNames.equals(NOT_IN_ANY_GROUP)) return; // can't change the name of these groups CommonInputDialog dialog = new CommonInputDialog( this, "Edit group", "Specify one or more unique group names, separated by 1 space character, and press OK", CommonInputDialog.GROUP_NAMES, groupNames); for (;;) { if (dialog.open() == Window.CANCEL) return; if (addNewOrEditExistingGroup(dialog.getValue(), editItem)) break; } commonActionFinishDirtyIfChange(); } } else if ((event.widget == removeButton) || (event.widget == tree && event.type == SWT.KeyUp && event.character == SWT.DEL)) { // handle remove - of all selected items // if a group is selected, removing the group also removes all the parms in the group // Because this is dangerous, we issue an "are you sure?" prompt. // Other side effects: Any parameter settings for the removed // parameters are also removed. valueChanged = removeItems(tree.getSelection(), GIVE_WARNING_MESSAGE); commonActionFinishDirtyIfChange(); // TODO remove settings for any parameters removed } // end of remove action // handle selection changes else if (event.widget == tree && event.type == SWT.Selection) { } enable(); } private void addOrEditOverride(TreeItem parent, int overrideIndex) { ConfigurationParameter cp = getCorrespondingModelParm(parent); Map delegateMap1 = editor.getResolvedDelegates(); Map delegateMap = null; if (null != delegateMap1) { delegateMap = new HashMap(delegateMap1.size()); delegateMap.putAll(delegateMap1); FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration(); if (null != fcd) { delegateMap.put(fcd.getKey(), fcd.getSpecifier()); } } // only picks one override key - but code is from earlier design where multiple keys were // possible PickOverrideKeysAndParmName dialog = new PickOverrideKeysAndParmName(this, delegateMap, "Override Keys and Parameter Name Selection", cp, cpd, overrideIndex == -1); dialog.setTitle("Delegate Keys and Parameter Name Selection"); dialog .setMessage("Select the override key path from the left panel, and the overridden parameter from the right panel.\nOnly valid parameters will be shown."); if (dialog.open() == Window.CANCEL) return; String delegateKeyName = dialog.delegateKeyName; String delegateParameterName = dialog.delegateParameterName; // update the existing item // have to do a 3 step update because the getOverrides returns a // cloned array valueChanged = false; String overrideSpec = delegateKeyName + '/' + delegateParameterName; // updateOneOverride(cp, overrideIndex, dialog.overrideSpec); if (overrideIndex < 0) { addOverride(cp, overrideSpec); valueChanged = true; } else { String[] overrides = cp.getOverrides(); overrides[overrideIndex] = setValueChanged(overrideSpec, overrides[overrideIndex]); cp.setOverrides(overrides); parent.getItems()[overrideIndex].setText(OVERRIDE_HEADER + overrideSpec); } // TODO consequences of changes in rest of model? commonActionFinishDirtyIfChange(); } private boolean removeItems(TreeItem[] itemsToRemove, boolean giveWarningMsg) { String[] namesToRemove = new String[itemsToRemove.length]; boolean[] isGroup = new boolean[itemsToRemove.length]; StringBuffer msgGroup = new StringBuffer(); StringBuffer msg = new StringBuffer(); StringBuffer oMsg = new StringBuffer(); for (int i = 0; i < itemsToRemove.length; i++) { namesToRemove[i] = getName(itemsToRemove[i].getText()); isGroup[i] = isGroup(itemsToRemove[i]); if (isGroup[i]) { if (NOT_IN_ANY_GROUP.equals(namesToRemove[i])) msgGroup .append("\nThis action removes all parameter descriptions in the section."); else { if (i > 0) msgGroup.append(", "); else if (COMMON_GROUP.equals(namesToRemove[i])) msgGroup .append("\nThis action removes all parameter descriptions in the section."); else msgGroup .append("\nGroups being removed, together with their parameter definitions defined here: \n"); if (!COMMON_GROUP.equals(namesToRemove[i])) msgGroup.append(namesToRemove[i]); } } else if (isParameter(itemsToRemove[i])) { if (i > 0) msg.append(", "); else msg.append("\nParameters being removed: \n"); msg.append(namesToRemove[i]); } else if (isOverride(itemsToRemove[i])) { if (i > 0) oMsg.append(", "); else oMsg.append("\nOverride being removed: \n"); oMsg.append(namesToRemove[i]); } else throw new InternalErrorCDE("invalid state"); } if (giveWarningMsg && Window.CANCEL == Utility.popOkCancel("Confirm Remove", "Please confirm remove, or Cancel.\n" + msgGroup.toString() + msg.toString() + oMsg.toString(), MessageDialog.WARNING)) return false; // loop thru all things being removed, and remove them for (int i = 0; i < itemsToRemove.length; i++) { if (isGroup[i]) { removeGroup(itemsToRemove[i], namesToRemove[i]); } else if (isParameter(itemsToRemove[i])) { // just a plain parameter being // removed removeParameter(itemsToRemove[i], namesToRemove[i]); } else if (isOverride(itemsToRemove[i])) { TreeItem parentItem = itemsToRemove[i].getParentItem(); ConfigurationParameter cp = getCorrespondingModelParm(parentItem); cp.setOverrides(removeOverride(cp, getItemIndex(parentItem, itemsToRemove[i]))); itemsToRemove[i].dispose(); if (cp.getOverrides().length == 0) { removeParameter(parentItem, getName(parentItem)); } } else throw new InternalErrorCDE("Invalid state"); } return true; } private void removeParameter(TreeItem itemToRemove, String nameToRemove) { TreeItem parentItem = itemToRemove.getParentItem(); ConfigurationGroup cg = null; String parentGroupName = getName(parentItem.getText()); if (parentGroupName.equals(NOT_IN_ANY_GROUP)) cpd.setConfigurationParameters(removeConfigurationParameter(cpd.getConfigurationParameters(), nameToRemove)); else if (parentGroupName.equals(COMMON_GROUP)) cpd.setCommonParameters(commonParms = removeConfigurationParameter(cpd.getCommonParameters(), nameToRemove)); else { cg = getConfigurationGroup(parentGroupName); cg.setConfigurationParameters(removeConfigurationParameter(cg.getConfigurationParameters(), nameToRemove)); } removeParmSettingFromMultipleGroups(itemToRemove, REMOVE_FROM_GUI); itemToRemove.dispose(); if (null != cg && cg.getConfigurationParameters().length == 0) { removeGroup(parentItem, getName(parentItem)); } } private void removeGroup(TreeItem itemToRemove, String nameToRemove) { if (nameToRemove.equals(COMMON_GROUP)) { removeCommonParmSettingsFromMultipleGroups(); cpd.setCommonParameters(configurationParameterArray0); commonParms = configurationParameterArray0; // can't really remove the group so remove all the parms disposeAllChildItems(itemToRemove); } else if (nameToRemove.equals(NOT_IN_ANY_GROUP)) { // remove settings for all non-group parm definitions removeIncludedParmSettingsFromSingleGroup(NOT_IN_ANY_GROUP, null); cpd.setConfigurationParameters(configurationParameterArray0); // remove all non-group parm definitions disposeAllChildItems(itemToRemove); } else { ConfigurationGroup cg = getConfigurationGroup(nameToRemove); // remove settings for all parms in the group too // also updates the settings GUI if the GUI is initialized removeIncludedParmSettingsFromMultipleGroups(cg.getNames(), cg.getConfigurationParameters()); // remove group cpd.setConfigurationGroups(removeConfigurationGroup(cpd.getConfigurationGroups(), cg)); itemToRemove.dispose(); // also disposes children of group in // GUI } } public void addParm(String name, ConfigurationParameter modelParm, ConfigGroup group, String override) { TreeItem parentGroup = getTreeItemGroup(group); AddParameterDialog dialog = new AddParameterDialog(this); dialog.parmName = name; dialog.description = modelParm.getDescription(); dialog.mandatory = modelParm.isMandatory(); dialog.multiValue = modelParm.isMultiValued(); dialog.parmType = modelParm.getType(); // dialog.overrideSpec = override; ConfigurationParameter parmInGroup = addNewConfigurationParameter(dialog, parentGroup); addOverride(parmInGroup, override); parentGroup.setExpanded(true); commonActionFinish(); } private ConfigurationGroup getConfigurationGroup(String groupName) { if (groupName.equals(COMMON_GROUP)) throw new InternalErrorCDE("invalid call"); ConfigurationGroup[] groups = cpd.getConfigurationGroups(); for (int i = 0; i < groups.length; i++) { if (groupName.equals(groupNameArrayToString(groups[i].getNames()))) return groups[i]; } throw new InternalErrorCDE("invalid state"); } private ConfigurationGroup[] removeConfigurationGroup(ConfigurationGroup[] groups, ConfigurationGroup cg) { return (ConfigurationGroup[]) Utility.removeElementFromArray(groups, cg, ConfigurationGroup.class); } private ConfigurationParameter[] removeConfigurationParameter(ConfigurationParameter[] parms, String nameToRemove) { ConfigurationParameter[] newParms = new ConfigurationParameter[parms.length - 1]; for (int i = 0, j = 0; i < newParms.length; i++, j++) { if (parms[j].getName().equals(nameToRemove)) j++; newParms[i] = parms[j]; } return newParms; } private String[] removeOverride(ConfigurationParameter cp, int i) { String[] oldOverrides = cp.getOverrides(); String[] newOverrides = new String[oldOverrides.length - 1]; if (i > 0) System.arraycopy(oldOverrides, 0, newOverrides, 0, i); if (oldOverrides.length - 1 - i > 0) System.arraycopy(oldOverrides, i + 1, newOverrides, i, oldOverrides.length - 1 - i); return newOverrides; } /** * Called to add group to aggregate parm decl based on delegate group * * @param group * the delegate group needing to be added to the aggregate */ public ConfigGroup addGroup(ConfigGroup group) { String groupName = group.getName(); String[] groupNameArray = group.getNameArray(); if (group.getKind() == ConfigGroup.COMMON) { groupNameArray = getAllGroupNames(group.getCPD()); groupName = groupNameArrayToString(groupNameArray); } ConfigurationGroup cg = new ConfigurationGroup_impl(); cg.setConfigurationParameters(configurationParameterArray0); TreeItem item = addGroupToGUI(groupName, cg); // fill(commonParms, item); // don't add common parsm, they're added by definition addGroupToModel(cg); cg.setNames(groupNameArray); tree.setSelection(new TreeItem[] { item }); return new ConfigGroup(cpd, cg); } // existing, if not null, doesn't point to which can't be edited /** * @param names - * a sequence of group names separated by blanks * @param existing - * null or an existing tree item being edited */ private boolean addNewOrEditExistingGroup(String names, TreeItem existing) { valueChanged = true; // preset ConfigGroup mcg = null; String[] oldGroupNames = stringArray0; String[] newGroupNames = groupNamesToArray(names); String[] groupNamesToAdd; String[] groupNamesToDrop = stringArray0; if (null != existing) { mcg = getCorrespondingModelGroup(existing); oldGroupNames = mcg.getNameArray(); groupNamesToDrop = setDiff(oldGroupNames, newGroupNames); groupNamesToAdd = setDiff(newGroupNames, oldGroupNames); } else { groupNamesToAdd = newGroupNames; } // it is legal to define a group name more than once, but the same set of group names // shouldn't be defined more than once if (groupNameAlreadyDefined(newGroupNames)) { Utility.popMessage("Group Already Defined", "This set of group names has already been defined." + "\n\nGroup: " + names, MessageDialog.ERROR); return false; } TreeItem item; if (existing == null) { ConfigurationGroup cg = new ConfigurationGroup_impl(); cg.setConfigurationParameters(configurationParameterArray0); cg.setNames(groupNamesToArray(names)); item = addGroupToGUI(names, cg); addGroupToModel(cg); } else { // editing existing group valueChanged = groupNamesToDrop.length != 0 || groupNamesToAdd.length != 0; item = existing; setGroupText(item, names); for (int i = 0; i < groupNamesToDrop.length; i++) { removeIncludedParmSettingsFromSingleGroup(groupNamesToDrop[i], mcg.getConfigParms()); } mcg.setNameArray(groupNamesToArray(names)); if (null != settings) { for (int i = 0; i < groupNamesToAdd.length; i++) { TreeItem settingsItem = getSettingsTreeGroup(groupNamesToAdd[i]); if (null == settingsItem) { settingsItem = new TreeItem(settingsTree, SWT.NONE); setGroupText(settingsItem, groupNamesToAdd[i]); settingsItem.setData(null); fill(mcg.getConfigParms(), settingsItem); fill(commonParms, settingsItem); } else { fillInFrontOfCommon(mcg.getConfigParms(), settingsItem); } } } } tree.setSelection(new TreeItem[] { item }); return true; } private void fillInFrontOfCommon(ConfigurationParameter[] parms, TreeItem settingsTreeGroup) { if (parms != null) { for (int i = parms.length - 1; i >= 0; i--) { fillParmItem(new TreeItem(settingsTreeGroup, SWT.NONE, 0), parms[i]); } } } /** * Calculate s1 - s2 set * * @param s1 * @param s2 * @return */ private String[] setDiff(String[] s1, String[] s2) { Set result = new TreeSet(); for (int i = 0; i < s1.length; i++) result.add(s1[i]); for (int i = 0; i < s2.length; i++) result.remove(s2[i]); return (String[]) result.toArray(stringArray0); } private boolean setEqual(String[] s1, String[] s2) { if (null == s1 && null == s2) return true; if (null == s1 || null == s2) return false; if (s1.length != s2.length) return false; if (setDiff(s1, s2).length == 0) return true; return false; } /** * Called from ParameterDelegatesSection to add an override * * @param parmInGroup * @param override */ public void addOverride(ConfigurationParameter parmInGroup, String override) { addOverride(override, getTreeItemParm(parmInGroup), parmInGroup); } /** * add an override item * * @param parent * @param override */ private void addOverrideToGUI(TreeItem parent, String override) { // addOverride(dialog.overrideSpec, parent, cp); TreeItem item = new TreeItem(parent, SWT.NONE); item.setText(OVERRIDE_HEADER + override); } /** * Called by addNewConfigurationParameter, and fill (via refresh) to add overrides to the tree * list * * @param parent * @param modelCP */ protected void fillOverrides(TreeItem parent, ConfigurationParameter modelCP) { if (isAggregate()) { String[] overrides = modelCP.getOverrides(); if (overrides != null) { for (int i = 0; i < overrides.length; i++) { addOverrideToGUI(parent, overrides[i]); } parent.setExpanded(true); // show added overrides } } } /** * called from add Override action * * @param dialog * @param parent * @param cp */ private void addOverride(String override, TreeItem parent, ConfigurationParameter cp) { cp.setOverrides(addOverrideToArray(cp.getOverrides(), override)); addOverrideToGUI(parent, override); parent.setExpanded(true); commonActionFinish(); } private void alterExistingConfigurationParameter(AddParameterDialog dialog, TreeItem existingTreeItem) { ConfigurationParameter existingCP = getCorrespondingModelParm(existingTreeItem); ConfigurationParameter previousCP = existingCP; previousCP = (ConfigurationParameter) previousCP.clone(); fillModelParm(dialog, existingCP); fillParmItem(existingTreeItem, existingCP); // the following may have changed in an existing param spec, that could // affect the setting: // 1) the name, 2) the type, 3) the multi-value aspect // Description or mandatory changes have no effect on the settings // If the multi-value aspect changes, drop all the settings // If the type changes, drop all the settings // If the name changes, change existing settings for that parm name in all groups if ((!previousCP.getType().equals(existingCP.getType())) || (previousCP.isMultiValued() != existingCP.isMultiValued())) { removeParmSettingFromMultipleGroups(existingTreeItem, !REMOVE_FROM_GUI); } commonParmUpdate(existingTreeItem, existingCP, previousCP.getName()); } private void commonParmUpdate(TreeItem existingTreeItem, ConfigurationParameter existingCP, String prevName) { updateParmInSettingsGUI(existingCP, existingTreeItem, prevName); String newName = existingCP.getName(); if (!newName.equals(prevName)) { // name changed; update the settings model ConfigurationParameterSettings cps = getModelSettings(); String[] allGroupNames = new String[] { null }; if (usingGroupsButton.getSelection()) { allGroupNames = (String[]) Utility .addElementToArray(getAllGroupNames(), null, String.class); } Object value; for (int i = 0; i < allGroupNames.length; i++) { if (null != (value = cps.getParameterValue(allGroupNames[i], prevName))) { cps.setParameterValue(allGroupNames[i], newName, value); cps.setParameterValue(allGroupNames[i], prevName, null); } } } } /** * Fills in the model Configuration Parm from the Add/Edit dialog. called from * addNewConfigurationParameter, and alterExistingConfigurationParameter * * @param dialog * @param existingCP */ private void fillModelParm(AddParameterDialog dialog, ConfigurationParameter existingCP) { valueChanged = false; existingCP.setName(setValueChanged(dialog.parmName, existingCP.getName())); existingCP.setDescription(setValueChanged(multiLineFix(dialog.description), existingCP .getDescription())); existingCP.setMandatory(setValueChangedBoolean(dialog.mandatory, existingCP.isMandatory())); existingCP .setMultiValued(setValueChangedBoolean(dialog.multiValue, existingCP.isMultiValued())); existingCP.setType(setValueChanged(dialog.parmType, existingCP.getType())); if (valueChanged) setFileDirty(); } /** * Called from UI when adding a new Configuraton Parameter Called from refresh when filling params * Called when adding override to new parm * * @param dialog * @param group * @return */ private ConfigurationParameter addNewConfigurationParameter(AddParameterDialog dialog, TreeItem group) { ConfigurationParameter newCP = new ConfigurationParameter_impl(); fillModelParm(dialog, newCP); if (null != group) { String groupName = getName(group.getText()); if (groupName.equals(COMMON_GROUP)) { cpd.setCommonParameters(commonParms = addParmToArray(cpd.getCommonParameters(), newCP)); } else if (groupName.equals(NOT_IN_ANY_GROUP)) { cpd.setConfigurationParameters(addParmToArray(cpd.getConfigurationParameters(), newCP)); } else { ConfigurationGroup cg = getConfigurationGroup(groupName); cg.setConfigurationParameters(addParmToArray(cg.getConfigurationParameters(), newCP)); } } else { // no groups throw new InternalErrorCDE("invalid state"); } addNewConfigurationParameterToGUI(newCP, group); return newCP; } private void addGroupToModel(ConfigurationGroup newCg) { ConfigurationGroup[] oldCgs = cpd.getConfigurationGroups(); ConfigurationGroup[] newCgs; if (null == oldCgs) { newCgs = new ConfigurationGroup[1]; } else { newCgs = new ConfigurationGroup[oldCgs.length + 1]; System.arraycopy(oldCgs, 0, newCgs, 0, oldCgs.length); } newCgs[newCgs.length - 1] = newCg; cpd.setConfigurationGroups(newCgs); } private String[] addOverrideToArray(String[] overrides, String newOverride) { if (null == overrides) return new String[] { newOverride }; String[] newOverrides = new String[overrides.length + 1]; System.arraycopy(overrides, 0, newOverrides, 0, overrides.length); newOverrides[overrides.length] = newOverride; return newOverrides; } private ConfigurationParameter[] addParmToArray(ConfigurationParameter[] cps, ConfigurationParameter newCP) { if (null == cps) { return new ConfigurationParameter[] { newCP }; } ConfigurationParameter[] newCps = new ConfigurationParameter[cps.length + 1]; System.arraycopy(cps, 0, newCps, 0, cps.length); newCps[cps.length] = newCP; return newCps; } /** * * @param names * @return true if there is a group whose names are the same set */ private boolean groupNameAlreadyDefined(String[] names) { ConfigurationGroup[] cgs = cpd.getConfigurationGroups(); if (null != cgs) { for (int i = 0; i < cgs.length; i++) { if (setEqual(names, cgs[i].getNames())) return true; } } return false; } public static boolean parameterNameAlreadyDefinedNoMsg(String name, ConfigurationParameterDeclarations pCpd) { if (pCpd.getCommonParameters() != null) { if (parameterInArray(name, pCpd.getCommonParameters())) return true; } if (pCpd.getConfigurationParameters() != null) { if (parameterInArray(name, pCpd.getConfigurationParameters())) return true; } ConfigurationGroup[] groups; if ((groups = pCpd.getConfigurationGroups()) != null) { for (int i = 0; i < groups.length; i++) { if (parameterInArray(name, groups[i].getConfigurationParameters())) return true; } } return false; } public boolean parameterNameAlreadyDefined(String name) { boolean alreadyDefined = parameterNameAlreadyDefinedNoMsg(name, cpd); if (alreadyDefined) { Utility.popMessage("Parameter Already Defined", "The following parameter is already defined in the list. Parameter names must be unique." + "\n\nParameter: " + name, MessageDialog.ERROR); } return alreadyDefined; } private static boolean parameterInArray(String name, ConfigurationParameter[] cps) { for (int i = 0; i < cps.length; i++) { if (name.equals(cps[i].getName())) return true; } return false; } private void commonActionFinish() { valueChanged = true; commonActionFinishDirtyIfChange(); } /** * called by Edit operations which might not make any changes They set the dirty state if any * changes occur, so don't set it here. * */ private void commonActionFinishDirtyIfChange() { if (valueChanged) setFileDirty(); enable(); } public void enable() { usingGroupsButton.setEnabled(!isAggregate()); boolean usingGroups = usingGroupsButton.getSelection(); groupingControl.setVisible(usingGroups); addButton.setEnabled(isPrimitive() || tree.getSelectionCount() == 1 && (isParmSelection() || isOverrideSelection())); addGroupButton.setEnabled(isPrimitive() && usingGroups); removeButton.setEnabled(tree.getSelectionCount() == 1 && (isParmSelection() || isGroupSelection() || isOverrideSelection())); editButton .setEnabled(tree.getSelectionCount() == 1 && ((/* isPrimitive() && */isParmSelection()) || isOverrideSelection() || (isPrimitive() && isGroupSelection() && !isCommonGroupSelection()))); } public Tree getTree() { return tree; } /** * Given a ConfigurationParameter, find the corresponding item in the tree. Note: parameters with * the same name can exist in different groups, so we don't match using the parm name, but rather * do an "EQ" test * * @param p * @return */ private TreeItem getTreeItemParm(ConfigurationParameter p) { TreeItem[] groups = tree.getItems(); for (int i = 0; i < groups.length; i++) { TreeItem[] parms = groups[i].getItems(); for (int j = 0; j < parms.length; j++) { if (getCorrespondingModelParm(parms[j]) == p) return parms[j]; } } throw new InternalErrorCDE("invalid state"); } /** * Given a ConfigGroup - find the corresponding tree item. Match is done against the display form * of the name(s), with special casing for the not-in-any-group and common. * * @param g * @return */ private TreeItem getTreeItemGroup(ConfigGroup g) { switch (g.getKind()) { case ConfigGroup.NOT_IN_ANY_GROUP: return tree.getItems()[0]; case ConfigGroup.COMMON: return tree.getItems()[1]; } TreeItem[] items = tree.getItems(); for (int i = 2; i < items.length; i++) { if (getName(items[i].getText()).equals(g.getName())) return items[i]; } throw new InternalErrorCDE("invalid state"); } private TreeItem getSettingsTreeGroup(String groupName) { TreeItem[] items = settingsTree.getItems(); for (int i = 0; i < items.length; i++) { if (groupName.equals(getName(items[i].getText()))) return items[i]; } return null; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/GeneralSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/GeneralSe0000644000175000017500000002565111665471220033413 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.Constants; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.metadata.FlowConstraints; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.ui.forms.IManagedForm; public class GeneralSection extends AbstractSection { public void enable() { } private Button cppButton; private Button javaButton; private Button primitiveButton; private Button aggregateButton; /** * Creates a section to edit general information like primitive or aggregate and C++ or Java * * @param editor * the referenced multipage editor */ public GeneralSection(MultiPageEditor aEditor, Composite parent) { super(aEditor, parent, "Implementation Details", null); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { super.initialize(form); ((GridData) this.getSection().getLayoutData()).grabExcessVerticalSpace = false; Composite sectionClient = new2ColumnComposite(this.getSection()); ((GridData) sectionClient.getLayoutData()).grabExcessVerticalSpace = false; // FrameworkImplementation choose, 2 radio buttons if (isAeDescriptor() || isCasConsumerDescriptor()) { toolkit.createLabel(sectionClient, "Implementation Language").setToolTipText( "Choose the implementation language here."); Composite buttons = new2ColumnComposite(sectionClient); cppButton = newRadioButton(buttons, "C/C++", "C/C++", NOT_SELECTED); javaButton = newRadioButton(buttons, "Java", "Java", SELECTED); // DescriptorType choose, 2 radio buttons toolkit.createLabel(sectionClient, "Engine Type").setToolTipText( "Choose the type of the engine here."); buttons = new2ColumnComposite(sectionClient); primitiveButton = newRadioButton(buttons, "Primitive", S_, SELECTED); aggregateButton = newRadioButton(buttons, "Aggregate", S_, NOT_SELECTED); } } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); boolean isPrimitive = isPrimitive(); // select primitive or aggregate if (isAeDescriptor() || isCasConsumerDescriptor()) { primitiveButton.setSelection(isPrimitive); aggregateButton.setSelection(!isPrimitive); // select C++ or Java String implType = editor.getAeDescription().getFrameworkImplementation(); cppButton.setSelection(Constants.CPP_FRAMEWORK_NAME.equals(implType)); javaButton.setSelection(Constants.JAVA_FRAMEWORK_NAME.equals(implType)); } } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == primitiveButton || event.widget == aggregateButton) { boolean isPrimitive = primitiveButton.getSelection(); // Note: events occur when button is selected or deselected if (event.widget == primitiveButton && !isPrimitive) return; // deselecting if (event.widget == aggregateButton && isPrimitive) return; // deselecting if (isPrimitive && isPrimitive()) return; // nothing changed if (!isPrimitive && isAggregate()) return; // nothing changed if (isPrimitive) { if (Window.CANCEL == Utility.popOkCancel("Switching from Aggregate", "This action will clear the capabilities, reset the delegates, " + "reset the flow, reset the parameters, reset any resource information " + "and start with an empty type system. Are you sure?", MessageDialog.WARNING)) { aggregateButton.setSelection(true); primitiveButton.setSelection(false); return; } editor.getAeDescription().setAnnotatorImplementationName(""); } else { // if (isLocalProcessingDescriptor() && !isAeDescriptor()) { // Utility.popMessage("Not Allowed", // "Cas Consumers, Cas Initializers, Collection Readers, and Flow Controllers cannot be // Aggregates.", // MessageDialog.ERROR); // primitiveButton.setSelection(true); // aggregateButton.setSelection(false); // return; // } if (Window.CANCEL == Utility.popOkCancel("Switching from Primitive AE", "This action will clear the capabilities, reset the delegates, " + "reset the parameters, reset any resource information " + "and reset the type system. Are you sure?", MessageDialog.WARNING)) { primitiveButton.setSelection(true); aggregateButton.setSelection(false); return; } editor.getAeDescription().setAnnotatorImplementationName(null); } editor.getAeDescription().setPrimitive(isPrimitive); commonResets(); try { editor.setAeDescription(editor.getAeDescription()); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("invalid state", e); } javaButton.setEnabled(isPrimitive); cppButton.setEnabled(isPrimitive); HeaderPage page = editor.getAggregatePage(); if (null != page) page.markStale(); page = editor.getParameterPage(); if (null != page) page.markStale(); page = editor.getSettingsPage(); if (null != page) page.markStale(); page = editor.getTypePage(); if (null != page) markRestOfPageStale(page.getManagedForm(), null); page = editor.getCapabilityPage(); if (null != page) page.markStale(); page = editor.getIndexesPage(); if (null != page) page.markStale(); page = editor.getResourcesPage(); if (null != page) page.markStale(); } if (event.widget == javaButton || event.widget == cppButton) { valueChanged = false; if (cppButton.getSelection()) { editor.getAeDescription().setFrameworkImplementation( setValueChanged(Constants.CPP_FRAMEWORK_NAME, editor.getAeDescription() .getFrameworkImplementation())); } else { editor.getAeDescription().setFrameworkImplementation( setValueChanged(Constants.JAVA_FRAMEWORK_NAME, editor.getAeDescription() .getFrameworkImplementation())); } if (!valueChanged) return; } PrimitiveSection s = editor.getOverviewPage().getPrimitiveSection(); if (null != s) { s.refresh(); // next line makes the bounding rectangle show up s.getSection().getClient().redraw(); } setFileDirty(); } private void commonResets() { // clear the delegates getDelegateAnalysisEngineSpecifiersWithImports().clear(); editor.getResolvedDelegates().clear(); if (isAggregate()) { // reset the flow to fixed flow with null as the set FlowConstraints flowConstraints = UIMAFramework.getResourceSpecifierFactory() .createFixedFlow(); flowConstraints.setAttributeValue("fixedFlow", stringArray0); getAnalysisEngineMetaData().setFlowConstraints(flowConstraints); } else getAnalysisEngineMetaData().setFlowConstraints(null); // clear capabilities getAnalysisEngineMetaData().setCapabilities(capabilityArray0); addCapabilitySet(); // reset parameters // reset the parameters not declared in a group getConfigurationParameterDeclarations().setConfigurationParameters( new ConfigurationParameter[0]); // reset groups getConfigurationParameterDeclarations().setConfigurationGroups( AbstractSection.configurationGroupArray0); // reset common parameters getConfigurationParameterDeclarations().setCommonParameters(new ConfigurationParameter[0]); // reset default group name getConfigurationParameterDeclarations().setDefaultGroupName(""); // reset search strategy getConfigurationParameterDeclarations().setSearchStrategy(""); // reset the parm settings ConfigurationParameterSettings configParmSettings = UIMAFramework.getResourceSpecifierFactory() .createConfigurationParameterSettings(); getAnalysisEngineMetaData().setConfigurationParameterSettings(configParmSettings); // reset typesystem, needed when going from primitive to aggregate getAnalysisEngineMetaData().setTypeSystem(null); // reset resources editor.getAeDescription().setExternalResourceDependencies(new ExternalResourceDependency[0]); ResourceManagerConfiguration rmc = editor.getAeDescription().getResourceManagerConfiguration(); if (null != rmc) { rmc.setExternalResourceBindings(new ExternalResourceBinding[0]); rmc.setExternalResources(new ExternalResourceDescription[0]); } // reset indexes getAnalysisEngineMetaData().setFsIndexCollection(null); getAnalysisEngineMetaData().setFsIndexes(new FsIndexDescription[0]); // reset index type priorities getAnalysisEngineMetaData().setTypePriorities(null); } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ValueSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ValueSect0000644000175000017500000003653211665471220033441 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.util.Arrays; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.StackLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.IManagedForm; public class ValueSection extends AbstractSectionParm { private Composite valueTextStack; private StackLayout valueTextStackLayout; private Text valueText; private CCombo valueTextCombo; private Composite vtc1; private Composite vtc2; private Table valueTable; private ParameterSettingsSection master; private Button addButton; private Button editButton; private Button removeButton; private Button upButton; private Button downButton; private Composite buttonContainer; private ConfigurationParameter selectedCP; private ConfigurationParameterSettings modelSettings; public ValueSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Values", "Specify the value of the selected configuration parameter."); } /* * Called by the page constructor after all sections are created, to initialize them. * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { super.initialize(form); master = editor.getSettingsPage().getParameterSettingsSection(); Composite sectionClient = new3ColumnComposite(this.getSection()); enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); valueTextStack = newComposite(sectionClient); valueTextStack.setLayoutData(new GridData(GridData.FILL_HORIZONTAL + GridData.VERTICAL_ALIGN_FILL)); ((GridData) valueTextStack.getLayoutData()).horizontalSpan = 2; valueTextStack.setLayout(valueTextStackLayout = new StackLayout()); valueTextStackLayout.marginHeight = 5; valueTextStackLayout.marginWidth = 5; vtc1 = new2ColumnComposite(valueTextStack); vtc2 = new2ColumnComposite(valueTextStack); enableBorders(vtc1); enableBorders(vtc2); toolkit.paintBordersFor(vtc1); toolkit.paintBordersFor(vtc2); valueText = newLabeledTextField(vtc1, "Value", "Specify the value", SWT.NONE); valueTextCombo = newLabeledCComboWithTip(vtc2, "Value", "Use the combo pulldown to pick True or False"); valueTextCombo.add("true"); valueTextCombo.add("false"); spacer(sectionClient); Label valueListLabel = toolkit.createLabel(sectionClient, "Value list:"); valueListLabel.setLayoutData(new GridData(SWT.TOP)); valueTable = newTable(sectionClient, SWT.MULTI, 0); // no column spec in table is an idiom that makes it a fancy list // Buttons buttonContainer = newButtonContainer(sectionClient); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a value to the list."); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP); downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); master = editor.getSettingsPage().getParameterSettingsSection(); valueTextStackLayout.topControl = vtc1; selectedCP = master.getSelectedModelParameter(); if (selectedCP == null) { // no param selected valueText.setText(""); valueTable.removeAll(); } else { // parm selected in master view Object modelValue; modelSettings = getModelSettings(); String groupName = master.getSelectedParamGroupName(); String parmName = selectedCP.getName(); modelValue = (NOT_IN_ANY_GROUP.equals(groupName)) ? modelSettings.getParameterValue(parmName) : modelSettings.getParameterValue(groupName, parmName); if (selectedCP.isMultiValued()) { // use list, not text field valueText.setText(""); valueTable.removeAll(); if (modelValue != null && modelValue instanceof Object[]) { Object[] valArr = (Object[]) modelValue; for (int i = 0; i < valArr.length; i++) { TableItem item = new TableItem(valueTable, SWT.NONE); item.setText(valArr[i].toString()); } } } else { // single-valued parameter - use Text field valueTable.removeAll(); valueText.setText((modelValue == null) ? "" : modelValue.toString()); if ("Boolean".equals(selectedCP.getType())) { valueTextCombo.setText((modelValue == null) ? "" : modelValue.toString()); valueTextStackLayout.topControl = vtc2; } else { valueText.setText((modelValue == null) ? "" : modelValue.toString()); valueTextStackLayout.topControl = vtc1; } } } valueTextStack.layout(); enable(); } public void enable() { boolean mvValue = (null != selectedCP) && (selectedCP.isMultiValued()); valueText.setVisible((null != selectedCP) && (!selectedCP.isMultiValued())); valueTextCombo.setVisible((null != selectedCP) && (!selectedCP.isMultiValued())); addButton.setEnabled(mvValue); int selected = valueTable.getSelectionIndex(); editButton.setEnabled(mvValue && selected > -1); removeButton.setEnabled(mvValue && selected > -1); upButton.setEnabled(mvValue && selected > 0); downButton.setEnabled(mvValue && (selected > -1) && (selected < (valueTable.getItemCount() - 1))); valueText.getParent().redraw(); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == valueText) { setParmValue(valueText.getText()); } else if (event.widget == valueTextCombo) { setParmValue(valueTextCombo.getText()); } else if (event.widget == addButton) { // open dialog to enter value String dataType = selectedCP.getType(); int validationFilter = "Boolean".equals(dataType) ? CommonInputDialog.TRUE_FALSE : "Integer" .equals(dataType) ? CommonInputDialog.INTEGER : "Float".equals(dataType) ? CommonInputDialog.FLOAT : CommonInputDialog.ALLOK; CommonInputDialog dialog = new CommonInputDialog(this, "Add value", "Enter a value", validationFilter); if (dialog.open() == Window.CANCEL) return; TableItem item = new TableItem(valueTable, SWT.NONE); item.setText(dialog.getValue()); // update model setCurrentParameterValue(valueTable.getItems()); } else if (event.widget == editButton) { // open dialog to enter value TableItem item = valueTable.getItems()[valueTable.getSelectionIndex()]; CommonInputDialog dialog = new CommonInputDialog(this, "Add value", "Enter a value", CommonInputDialog.ALLOK, item.getText()); if (dialog.open() == Window.CANCEL) return; item.setText(dialog.getValue()); // update model setCurrentParameterValue(valueTable.getItems()); } else if (event.widget == upButton) { // update both model and gui: swap nodes int selection = valueTable.getSelectionIndex(); TableItem[] items = valueTable.getItems(); String temp = items[selection - 1].getText(); items[selection - 1].setText(items[selection].getText()); items[selection].setText(temp); valueTable.setSelection(selection - 1); setCurrentParameterValue(valueTable.getItems()); } else if (event.widget == downButton) { // update both model and gui: swap nodes int selection = valueTable.getSelectionIndex(); TableItem[] items = valueTable.getItems(); String temp = items[selection + 1].getText(); items[selection + 1].setText(items[selection].getText()); items[selection].setText(temp); valueTable.setSelection(selection + 1); setCurrentParameterValue(valueTable.getItems()); } else if (event.widget == removeButton || (event.widget == valueTable && event.character == SWT.DEL)) { handleRemove(event); } enable(); } private void setParmValue(String value) { if (null != value) { if ("".equals(value)) value = null; // means clear the value setCurrentParameterValue(value); } } public void handleRemove(Event event) { valueTable.remove(valueTable.getSelectionIndices()); // update model setCurrentParameterValue(valueTable.getItems()); } public Button getAddButton() { return addButton; } public Button getRemoveButton() { return removeButton; } public Table getValueTable() { return valueTable; } public Text getValueText() { return valueText; } /** * Sets the currently selected parameter to the specified value. The string value will be * converted to the appropriate data type. This method works only for single-valued parameters. * * @param aValueString */ private void setCurrentParameterValue(String aValueString) { Object value = null; if (null != aValueString) { String paramType = selectedCP.getType(); try { if (ConfigurationParameter.TYPE_STRING.equals(paramType)) { value = aValueString; } else if (ConfigurationParameter.TYPE_INTEGER.equals(paramType)) { value = Integer.valueOf(aValueString); } else if (ConfigurationParameter.TYPE_FLOAT.equals(paramType)) { value = Float.valueOf(aValueString); } else if (ConfigurationParameter.TYPE_BOOLEAN.equals(paramType)) { value = Boolean.valueOf(aValueString); } } catch (NumberFormatException e) { Utility .popMessage( "Invalid Number", "If typing a floating point exponent, please complete the exponent.\nOtherwise, please retype the proper kind of number", MessageDialog.ERROR); return; } } setModelValue(value); } /** * Sets the currently selected parameter to the specified value. This method works only for * multi-valued parameters. The Table Items will be converted to the appropriate data type. * * @param aValues * Table Items, one for each value of the multi-valued param */ private void setCurrentParameterValue(TableItem[] aValues) { Object[] valueArr = null; String paramType = selectedCP.getType(); try { if (ConfigurationParameter.TYPE_STRING.equals(paramType)) { valueArr = new String[aValues.length]; for (int i = 0; i < valueArr.length; i++) { valueArr[i] = aValues[i].getText(); } } else if (ConfigurationParameter.TYPE_INTEGER.equals(paramType)) { valueArr = new Integer[aValues.length]; for (int i = 0; i < valueArr.length; i++) { valueArr[i] = Integer.valueOf(aValues[i].getText()); } } else if (ConfigurationParameter.TYPE_FLOAT.equals(paramType)) { valueArr = new Float[aValues.length]; for (int i = 0; i < valueArr.length; i++) { valueArr[i] = Float.valueOf(aValues[i].getText()); } } else if (ConfigurationParameter.TYPE_BOOLEAN.equals(paramType)) { valueArr = new Boolean[aValues.length]; for (int i = 0; i < valueArr.length; i++) { valueArr[i] = Boolean.valueOf(aValues[i].getText()); } } else throw new InternalErrorCDE("invalid state"); } catch (NumberFormatException e) { Utility.popMessage("Invalid Number", "One or more values is not of the proper kind of number." + " If this entry is the only one with the wrong numeric type," + " Please retype the proper kind of number. Otherwise," + " use the source page to change all the values to the proper type.", MessageDialog.ERROR); return; } setModelValue(valueArr); } private void setModelValue(Object value) { String groupName = master.getSelectedParamGroupName(); boolean changed = false; if (COMMON_GROUP.equals(groupName)) { ConfigurationGroup[] groups = getConfigurationParameterDeclarations() .getConfigurationGroups(); for (int i = 0; i < groups.length; i++) { String[] groupNames = groups[i].getNames(); for (int j = 0; j < groupNames.length; j++) { if (isSameValue(value, modelSettings.getParameterValue(groupNames[j], selectedCP .getName()))) continue; modelSettings.setParameterValue(groupNames[j], selectedCP.getName(), value); changed = true; } } } else if (NOT_IN_ANY_GROUP.equals(groupName)) { if (!isSameValue(value, modelSettings.getParameterValue(selectedCP.getName()))) { modelSettings.setParameterValue(selectedCP.getName(), value); changed = true; } } else { if (!isSameValue(value, modelSettings.getParameterValue(groupName, selectedCP.getName()))) { modelSettings.setParameterValue(groupName, selectedCP.getName(), value); changed = true; } } if (changed) editor.setFileDirty(); } private boolean isSameValue(Object v1, Object v2) { if (v1 instanceof Object[]) { return (Arrays.equals((Object[]) v1, (Object[]) v2)); } else { if (null == v1) return null == v2; return v1.equals(v2); } } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePage.0000644000175000017500000000373711665471220033343 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; public class TypePage extends HeaderPageWithSash { private TypeSection typeSection; private TypeImportSection typeImportSection; public TypePage(MultiPageEditor editor) { super(editor, "Type Definitions"); } /** * Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { // always show same screen layout - user could dynamically switch managedForm.getForm().setText("Type System Definition"); Form2Panel form2Panel = setup2ColumnLayout(managedForm, 60, 40); managedForm.addPart(typeSection = new TypeSection(editor, form2Panel.left)); managedForm.addPart(typeImportSection = new TypeImportSection(editor, form2Panel.right)); createToolBarActions(managedForm); } public TypeSection getTypeSection() { return typeSection; } public TypeImportSection getTypeImportSection() { return typeImportSection; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Parameter0000644000175000017500000000402111665471220033452 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; public class ParameterPage extends HeaderPageWithSash { private ParameterSection parameterSection; private ParameterDelegatesSection parameterDelegatesSection; public ParameterPage(MultiPageEditor editor) { super(editor, "Configuration Parameters"); } /** * Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { managedForm.getForm().setText("Parameter Definitions"); Form2Panel form2Panel = setup2ColumnLayout(managedForm, 55, 45); managedForm.addPart(parameterSection = new ParameterSection(editor, form2Panel.left)); managedForm.addPart(parameterDelegatesSection = new ParameterDelegatesSection(editor, form2Panel.right)); createToolBarActions(managedForm); } public ParameterDelegatesSection getParameterDelegatesSection() { return parameterDelegatesSection; } public ParameterSection getParameterSection() { return parameterSection; } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Utility.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Utility.j0000644000175000017500000001735511665471220033443 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.lang.reflect.Array; import java.util.Comparator; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Widget; // MessageDialog extended only to enable resize public class Utility extends MessageDialog { /** * @param parentShell * @param dialogTitle * @param dialogTitleImage * @param dialogMessage * @param dialogImageType * @param dialogButtonLabels * @param defaultIndex */ public Utility(Shell parentShell, String dialogTitle, Image dialogTitleImage, String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex) { super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType, dialogButtonLabels, defaultIndex); // TODO Auto-generated constructor stub } final private static String[] OK_CANCEL = { "OK", "Cancel" }; final private static String[] OKstring = { "OK" }; /** * Pops up a warning message with an "OK" and "Cancel" button * * @param title * of the warning * @param message * @param type * one of MessageDialog.NONE for a dialog with no image MessageDialog.ERROR for a dialog * with an error image MessageDialog.INFORMATION for a dialog with an information image * MessageDialog.QUESTION for a dialog with a question image MessageDialog.WARNING for a * dialog with a warning image */ public static int popOkCancel(String title, String message, int type) { return popMessage(title, message, type, OK_CANCEL); } /** * Pops up a warning message with an "OK" button * * @param title * of the warning * @param message * @param type * one of MessageDialog.NONE for a dialog with no image MessageDialog.ERROR for a dialog * with an error image MessageDialog.INFORMATION for a dialog with an information image * MessageDialog.QUESTION for a dialog with a question image MessageDialog.WARNING for a * dialog with a warning image * @return Window.OK or Window.CANCEL. If window is closed, Window.CANCEL is returned. */ public static void popMessage(String title, String message, int type) { popMessage(title, message, type, OKstring); } public static void popMessage(Widget w, String title, String message, int type) { popMessage(w, title, message, type, OKstring); } public static int popMessage(String title, String message, int type, String[] buttons) { return popMessage(new Shell(), title,message, type, buttons); // Utility dialog = new Utility(new Shell(), title, null, message, type, buttons, 0); // dialog.setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); // dialog.getShell().forceActive(); // int returnCode = dialog.open(); // if (returnCode == -1) // returnCode = Window.CANCEL; // Cancel code // return returnCode; } public static int popMessage(Shell parent, String title, String message, int type, String[] buttons) { Utility dialog = new Utility(parent, title, null, message, type, buttons, 0); dialog.setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE); int returnCode = dialog.open(); if (returnCode == -1) returnCode = Window.CANCEL; // Cancel code return returnCode; } // https://issues.apache.org/jira/browse/UIMA-2114 public static int popMessage(Widget w, String title, String message, int type, String[] buttons) { return popMessage(w.getDisplay().getActiveShell(), title, message, type, buttons); } /** * remove 1 element (must be present) use == test * * @param source * @param element * @param componentClass * @return */ public static Object[] removeElementFromArray(Object[] source, Object element, Class componentClass) { Object[] result = (Object[]) Array.newInstance(componentClass, source.length - 1); for (int i = 0, j = 0; i < source.length; i++) { if (element != source[i]) result[j++] = source[i]; } return result; } /** * remove 1 element (must be present) use == test * * @param source * @param element * @param componentClass * @return */ public static Object[] removeEqualElementFromArray(Object[] source, Object element, Class componentClass) { Object[] result = (Object[]) Array.newInstance(componentClass, source.length - 1); for (int i = 0, j = 0; i < source.length; i++) { if (element == null && source[i] == null) continue; if (null != element && element.equals(source[i])) continue; result[j++] = source[i]; } return result; } public static Object[] removeElementsFromArray(Object[] source, Object element, Class componentClass) { if (null == source) return null; int count = 0; for (int i = 0; i < source.length; i++) { if (!element.equals(source[i])) count++; } if (count == source.length) return source; Object[] result = (Object[]) Array.newInstance(componentClass, count); for (int i = 0, j = 0; i < source.length; i++) { if (!element.equals(source[i])) result[j++] = source[i]; } return result; } public static Object[] removeElementsFromArray(Object[] source, Object element, Class componentClass, Comparator comp) { if (null == source) return null; int count = 0; for (int i = 0; i < source.length; i++) { if (0 != comp.compare(element, source[i])) count++; } if (count == source.length) return source; Object[] result = (Object[]) Array.newInstance(componentClass, count); for (int i = 0, j = 0; i < source.length; i++) { if (0 != comp.compare(element, source[i])) result[j++] = source[i]; } return result; } public static Object[] addElementToArray(Object[] source, Object element, Class componentClass) { final int newLength = (null == source) ? 1 : source.length + 1; Object[] result = (Object[]) Array.newInstance(componentClass, newLength); System.arraycopy(source, 0, result, 0, newLength - 1); result[newLength - 1] = element; return result; } public static boolean arrayContains(Object[] array, Object element) { if (null == element) throw new InternalErrorCDE("null not allowed as an argument"); if (null == array) return false; for (int i = 0; i < array.length; i++) { if (null == array[i]) continue; if (array[i].equals(element)) return true; } return false; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/MetaDataSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/MetaDataS0000644000175000017500000000733711665471220033352 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.model.DescriptorMetaData; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.forms.IManagedForm; public class MetaDataSection extends AbstractSection { public void enable() { } private Text nameText; private Text descriptionText; private Text versionText; private Text vendorText; private DescriptorMetaData dmd = null; /** * Creates a section to enter meta data. Including a text field for name, description, version and * vendor. * * @param editor * the referenced multipage editor */ public MetaDataSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Overall Identification Information", "This section specifies the basic identification information for this descriptor"); } public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(this.getSection()); nameText = newLabeledTextField(sectionClient, "Name", "NameTextToolTip", SWT.NULL); versionText = newLabeledTextField(sectionClient, "Version", "VersionTextToolTip", SWT.NULL); vendorText = newLabeledTextField(sectionClient, "Vendor", "VendorTextToolTip", SWT.NULL); // description enter field descriptionText = newDescriptionTextBox(sectionClient, "Enter a description of this component here."); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { if (null == dmd) dmd = new DescriptorMetaData(editor); super.refresh(); String name = null; String version = null; String description = null; String vendor = null; name = dmd.getName(); version = dmd.getVersion(); description = dmd.getDescription(); vendor = dmd.getVendor(); nameText.setText(convertNull(name)); versionText.setText(convertNull(version)); vendorText.setText(convertNull(vendor)); descriptionText.setText(convertNull(description)); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { valueChanged = false; dmd.setName(setValueChanged(nameText.getText(), dmd.getName())); dmd.setVersion(setValueChanged(versionText.getText(), dmd.getVersion())); dmd.setVendor(setValueChanged(vendorText.getText(), dmd.getVendor())); dmd.setDescription(setValueChanged(multiLineFix(descriptionText.getText()), dmd .getDescription())); if (valueChanged) setFileDirty(); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterDelegatesSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Parameter0000644000175000017500000004150511665471220033462 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.model.ConfigGroup; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.IManagedForm; public class ParameterDelegatesSection extends AbstractSectionParm { private Composite sectionClient; private ParameterSection parmSection; private boolean createNonSharedOverride; private Button createOverrideButton; private Button createNonSharedOverrideButton; public ParameterDelegatesSection(MultiPageEditor editor, Composite parent) { super( editor, parent, "Delegate Component Parameters", "This section shows all delegate components by their Key names, and what parameters they have.\nDouble-click a parameter or a group if you want to specify overrides for these parameters in this aggregate; this will add a default Configuration Parameter in this Aggregate for that parameter, and set the overrides."); } /* * Called by the page constructor after all sections are created, to initialize them. * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { parmSection = editor.getParameterPage().getParameterSection(); super.initialize(form); sectionClient = newComposite(getSection()); tree = newTree(sectionClient); Composite buttonContainer = new2ColumnComposite(sectionClient); ((GridData) buttonContainer.getLayoutData()).grabExcessVerticalSpace = false; createOverrideButton = newPushButton(buttonContainer, "Create Override", "Click here to create a new override for this parameter"); createNonSharedOverrideButton = newPushButton(buttonContainer, "Create non-shared Override", "Click here to create a non-shared override for this parameter"); tree.addListener(SWT.MouseDoubleClick, this); // edit gesture tree.addListener(SWT.MouseHover, this); // hover enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); parmSection = editor.getParameterPage().getParameterSection(); tree.removeAll(); if (!isAggregate()) { getSection().setText("Not Used"); getSection().setDescription("This part is only used for Aggregate Descriptors"); } else { getSection().setText("Delegate Component Parameters"); getSection() .setDescription( "This section shows all delegate components by their Key names, and what parameters they have.\nDouble-click a parameter or a group if you want to specify overrides for these parameters in this aggregate; this will add a default Configuration Parameter in this Aggregate for that parameter, and set the overrides."); cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations(); for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) { addDelegateToGUI((Map.Entry) it.next()); } FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration(); if (null != fcd) { addDelegateToGUI(fcd.getKey(), fcd.getSpecifier()); } TreeItem[] items = tree.getItems(); if (items.length > 0) // scrolls to top, also tree.setSelection(new TreeItem[] { items[0] }); } enable(); } private void addDelegateToGUI(Map.Entry entry) { addDelegateToGUI((String) entry.getKey(), (ResourceSpecifier) entry.getValue()); // String key = (String) entry.getKey(); // ResourceSpecifier delegate = (ResourceSpecifier)entry.getValue(); // if (delegate instanceof AnalysisEngineDescription || delegate instanceof // CasConsumerDescription) { // TreeItem d = new TreeItem(tree, SWT.NONE); // d.setText(DELEGATE_HEADER + key); // d.setData(key); // addDelegateGroupsToGUI(d, (ResourceCreationSpecifier)delegate); // d.setExpanded(true); // } } private void addDelegateToGUI(String key, ResourceSpecifier delegate) { if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription || delegate instanceof FlowControllerDescription) { TreeItem d = new TreeItem(tree, SWT.NONE); d.setText(((delegate instanceof FlowControllerDescription) ? FLOWCTLR_HEADER : DELEGATE_HEADER) + key); d.setData(key); addDelegateGroupsToGUI(d, (ResourceCreationSpecifier) delegate); d.setExpanded(true); } } private void addDelegateGroupsToGUI(TreeItem parent, ResourceCreationSpecifier delegate) { ConfigurationParameterDeclarations cpd1 = delegate.getMetaData() .getConfigurationParameterDeclarations(); // if (delegate instanceof AnalysisEngineDescription) // cpd1 = ((AnalysisEngineDescription)delegate) // .getAnalysisEngineMetaData().getConfigurationParameterDeclarations(); // else if (delegate instanceof CasConsumerDescription) // cpd1 = ((CasConsumerDescription)delegate) // .getMetaData().getConfigurationParameterDeclarations(); // else // throw new InternalErrorCDE("Invalid state"); ConfigGroup noGroup = new ConfigGroup(cpd1, ConfigGroup.NOT_IN_ANY_GROUP); ConfigGroup commonGroup = new ConfigGroup(cpd1, ConfigGroup.COMMON); addDelegateGroupToGUI(parent, noGroup); addDelegateGroupToGUI(parent, commonGroup); ConfigurationGroup[] cgs = cpd1.getConfigurationGroups(); if (cgs != null) { for (int i = 0; i < cgs.length; i++) { addDelegateGroupToGUI(parent, new ConfigGroup(cpd1, cgs[i])); } } } private void addDelegateGroupToGUI(TreeItem parent, ConfigGroup cg) { ConfigurationParameter[] cps = cg.getConfigParms(); if (null != cps && cps.length > 0) { TreeItem d = new TreeItem(parent, SWT.NONE); d.setData(cg); setGroupText(d, cg.getName()); addDelegateParmsToGUI(d, cps); d.setExpanded(true); } } private void addDelegateParmsToGUI(TreeItem parent, ConfigurationParameter[] cps) { if (null != cps) { for (int i = 0; i < cps.length; i++) { TreeItem d = new TreeItem(parent, SWT.NONE); d.setData(cps[i]); d.setText(parmGuiString(cps[i])); String[] overrides = cps[i].getOverrides(); if (null != overrides && overrides.length > 0) { addDelegateParmOverridesToGUI(d, overrides); d.setExpanded(true); } } } } private void addDelegateParmOverridesToGUI(TreeItem parent, String[] overrides) { for (int i = 0; i < overrides.length; i++) { TreeItem d = new TreeItem(parent, SWT.NONE); d.setText(OVERRIDE_HEADER + overrides[i]); } } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.type == SWT.MouseHover) { showDescriptionAsToolTip(event); } else if (event.type == SWT.MouseDoubleClick) { addOverrides(0 != (event.stateMask & SWT.SHIFT)); } else if (event.widget == createOverrideButton) { addOverrides(false); } else if (event.widget == createNonSharedOverrideButton) { addOverrides(true); } } private void addOverrides(boolean nonShared) { TreeItem item = tree.getSelection()[0]; createNonSharedOverride = nonShared; if (isParameter(item)) addNewParameter(item); else if (isGroup(item)) addAllParameters(item.getItems()); else if (isDelegate(item)) addAllGroups(item.getItems()); } public ConfigurationParameter getConfigurationParameterFromTreeItem(TreeItem item) { return (ConfigurationParameter) item.getData(); } public ConfigGroup getConfigGroupFromTreeItem(TreeItem item) { return (ConfigGroup) item.getData(); } private String getKeyNameFromTreeItem(TreeItem item) { return (String) item.getData(); } private void addNewParameter(TreeItem item) { addNewParameter(getConfigurationParameterFromTreeItem(item), getConfigGroupFromTreeItem(item .getParentItem()), getKeyNameFromTreeItem(item.getParentItem().getParentItem())); } private void addAllParameters(TreeItem[] items) { for (int i = 0; i < items.length; i++) { addNewParameter(items[i]); } } private void addAllGroups(TreeItem[] items) { for (int i = 0; i < items.length; i++) { addAllParameters(items[i].getItems()); } } private void addNewParameter(ConfigurationParameter parm, ConfigGroup delegateGroup, String key) { ConfigGroup group = getCorrespondingModelGroup(delegateGroup); if (null == group) { group = parmSection.addGroup(delegateGroup); } ConfigurationParameter parmInGroup; String override = key + "/" + parm.getName(); String overrideParmName; if (null != (overrideParmName = getOverridingParmName(override, cpd))) { Utility.popMessage("Only one override allowed", "This delegate parameter already is being overridden by '" + overrideParmName + "'. To override " + "with a different parameter, first remove this override", MessageDialog.ERROR); return; } if (null != (parmInGroup = getSameNamedParmInGroup(parm, group))) { if ((!createNonSharedOverride) && parmSpecMatches(parm, parmInGroup)) { if (0 <= getOverrideIndex(parmInGroup, override)) { return; // trying to add existing override } else { parmSection.addOverride(parmInGroup, override); } } else { String newName = generateUniqueName(parm.getName()); parmSection.addParm(newName, parm, group, override); } } else { if (ParameterSection.parameterNameAlreadyDefinedNoMsg(parm.getName(), getConfigurationParameterDeclarations())) { // parm names must be unique across this descriptor, even among different groups String newName = generateUniqueName(parm.getName()); parmSection.addParm(newName, parm, group, override); } else { parmSection.addParm(parm.getName(), parm, group, override); } } } public static String getOverridingParmName(String override, ConfigurationParameterDeclarations cpd) { String result; if (null != (result = getOverridingParmName(override, cpd.getConfigurationParameters()))) return result; if (null != (result = getOverridingParmName(override, cpd.getCommonParameters()))) return result; ConfigurationGroup[] groups = cpd.getConfigurationGroups(); if (null != groups) for (int i = 0; i < groups.length; i++) { if (null != (result = getOverridingParmName(override, groups[i] .getConfigurationParameters()))) return result; } return null; } private static String getOverridingParmName(String override, ConfigurationParameter[] cps) { if (null != cps) for (int i = 0; i < cps.length; i++) { String[] overrides = cps[i].getOverrides(); if (null != overrides) for (int j = 0; j < overrides.length; j++) { if (override.equals(overrides[j])) return cps[i].getName(); } } return null; } /** * Add a suffix to the name to make it unique within all parameters defined for the cpd * * @param name * @return */ private String generateUniqueName(String name) { List allNames = new ArrayList(); addParmNames(allNames, cpd.getConfigurationParameters()); addParmNames(allNames, cpd.getCommonParameters()); ConfigurationGroup[] cgs = cpd.getConfigurationGroups(); if (null != cgs) { for (int i = 0; i < cgs.length; i++) { addParmNames(allNames, cgs[i].getConfigurationParameters()); } } int suffix = 1; String nameTry = name + suffix; while (allNames.contains(nameTry)) nameTry = name + ++suffix; return nameTry; } private void addParmNames(List list, ConfigurationParameter[] parms) { if (null != parms) { for (int i = 0; i < parms.length; i++) { list.add(parms[i].getName()); } } } private int getOverrideIndex(ConfigurationParameter parm, String override) { String[] overrides = parm.getOverrides(); if (null == overrides) return -1; for (int i = 0; i < overrides.length; i++) { if (overrides[i].equals(override)) return i; } return -1; } private ConfigurationParameter getSameNamedParmInGroup(ConfigurationParameter parm, ConfigGroup group) { ConfigurationParameter[] cps = group.getConfigParms(); String parmName = parm.getName(); for (int i = 0; i < cps.length; i++) { if (cps[i].getName().equals(parmName)) return cps[i]; } return null; } private boolean parmSpecMatches(ConfigurationParameter p, ConfigurationParameter q) { if (!p.getType().equals(q.getType())) return false; if (p.isMandatory() != q.isMandatory()) return false; if (p.isMultiValued() != q.isMultiValued()) return false; return true; } private ConfigGroup getCorrespondingModelGroup(ConfigGroup delegateGroup) { switch (delegateGroup.getKind()) { case ConfigGroup.NOT_IN_ANY_GROUP: return new ConfigGroup(cpd, ConfigGroup.NOT_IN_ANY_GROUP); case ConfigGroup.COMMON: return getCorrespondingModelGroup(getAllGroupNames(delegateGroup.getCPD())); case ConfigGroup.NAMED_GROUP: return getCorrespondingModelGroup(delegateGroup.getNameArray()); } throw new InternalErrorCDE("invalid state"); } private ConfigGroup getCorrespondingModelGroup(String[] nameArray) { ConfigurationGroup[] cgs = cpd.getConfigurationGroups(); for (int i = 0; i < cgs.length; i++) { if (setEquals(cgs[i].getNames(), nameArray)) { return new ConfigGroup(cpd, cgs[i]); } } return null; } /** * Compare for set equals, assuming sets have no duplicates * * @param a * @param b * @return */ private boolean setEquals(Object[] a, Object[] b) { if (null == a && null == b) return true; if (null == a || null == b) return false; if (a.length != b.length) return false; for (int i = 0; i < a.length; i++) { boolean foundB = false; for (int j = 0; j < b.length; j++) { if (a[i].equals(b[j])) { foundB = true; break; } } if (!foundB) return false; } return true; } public void enable() { createOverrideButton.setEnabled(tree.getSelectionCount() == 1); createNonSharedOverrideButton.setEnabled(tree.getSelectionCount() == 1); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexesPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexesPa0000644000175000017500000000522511665471220033421 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; /** */ public class IndexesPage extends HeaderPageWithSash { private IndexSection indexSection; private IndexImportSection indexImportSection; private TypePriorityImportSection typePriorityImportSection; private PriorityListSection priorityListSection; public IndexesPage(MultiPageEditor editor) { super(editor, "Indexes"); } /** * Called by the 3.0 framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { final Form2Panel form2Panel = setup2ColumnLayout(managedForm, EQUAL_WIDTH); managedForm.getForm().setText( (isLocalProcessingDescriptor() || isIndexDescriptor()) ? "Indexes" : "Type Priorities"); if (!isTypePriorityDescriptor()) { managedForm.addPart(indexSection = new IndexSection(editor, form2Panel.left)); managedForm.addPart(indexImportSection = new IndexImportSection(editor, form2Panel.right)); } if (!isIndexDescriptor()) { managedForm.addPart(priorityListSection = new PriorityListSection(editor, form2Panel.left)); managedForm.addPart(typePriorityImportSection = new TypePriorityImportSection(editor, form2Panel.right)); } createToolBarActions(managedForm); } public IndexSection getIndexSection() { return indexSection; } public PriorityListSection getPriorityListSection() { return priorityListSection; } public IndexImportSection getIndexImportSection() { return indexImportSection; } public TypePriorityImportSection getTypePriorityImportSection() { return typePriorityImportSection; } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourceDependencySection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourceD0000644000175000017500000003167111665471220033440 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.text.MessageFormat; import java.util.Iterator; import java.util.Map; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.impl.ExternalResourceDependency_impl; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddExternalResourceDependencyDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.forms.IManagedForm; /** * Declaration of primitive external resource dependencies A 4 col table: bound/unbound, keys, opt * flag, and interface name */ public class ResourceDependencySection extends AbstractSection { public final static int KEY_COL = 2; public final static int OPT_COL = 1; private final static String BOUND = "Bound"; public Table table; // accessed by inner class private Button addButton; private Button editButton; private Button removeButton; public ResourceDependencySection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Resource Dependencies", "Primitives declare what resources they need. A primitive can only bind to one external resource."); } public void initialize(IManagedForm form) { super.initialize(form); // set up Composite to hold widgets in the section Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); table = newTable(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION, 50, 0); table.setHeaderVisible(true); newTableColumn(table).setText(BOUND); newTableColumn(table).setText("Optional?"); newTableColumn(table).setText("Keys"); newTableColumn(table).setText("Interface Name"); if (isPrimitive()) { final Composite buttonContainer = newButtonContainer(sectionClient); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a dependency."); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); } // in addition to normal keyup and mouse up: table.addListener(SWT.MouseHover, this); if (isPrimitive()) // only primitives can edit table.addListener(SWT.MouseDoubleClick, this); toolkit.paintBordersFor(sectionClient); } public void refresh() { super.refresh(); table.getParent().setRedraw(false); table.removeAll(); if (isPrimitive()) addPrimitiveToGUI("", editor.getAeDescription()); else { // is aggregate for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) { Map.Entry item = (Map.Entry) it.next(); addDelegateToGUI("", (String) item.getKey(), (ResourceSpecifier) item.getValue()); } FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration(); if (null != fcd) { addDelegateToGUI("", fcd.getKey(), fcd.getSpecifier()); } } enable(); table.getParent().setRedraw(true); } private void addDelegateToGUI(String keys, String newKey, ResourceSpecifier o) { if (o instanceof AnalysisEngineDescription) { AnalysisEngineDescription aeDescription = (AnalysisEngineDescription) o; if (aeDescription.isPrimitive()) addPrimitiveToGUI(keys + newKey + "/", aeDescription); else { for (Iterator it = editor.getDelegateAEdescriptions(aeDescription).entrySet().iterator(); it .hasNext();) { Map.Entry item = (Map.Entry) it.next(); addDelegateToGUI(keys + newKey + "/", (String) item.getKey(), (ResourceSpecifier) item .getValue()); } FlowControllerDeclaration fcd = getFlowControllerDeclaration(); if (null != fcd) { addPrimitiveToGUI(keys + fcd.getKey() + "/", ((ResourceCreationSpecifier) editor .getResolvedFlowControllerDeclaration().getSpecifier())); } } } } private void addPrimitiveToGUI(String keys, ResourceCreationSpecifier aeDescription) { ExternalResourceDependency[] xrd = aeDescription.getExternalResourceDependencies(); if (null != xrd) { for (int i = 0; i < xrd.length; i++) { addXrdToGUI(keys, xrd[i]); } } } private void updateXrdToGUI(TableItem item, ExternalResourceDependency xrd, String keys) { String key = keys + xrd.getKey(); item.setText(0, isBound(key) ? BOUND : ""); item.setText(KEY_COL, key); item.setText(OPT_COL, (xrd.isOptional()) ? "optional" : "required"); item.setText(3, convertNull(xrd.getInterfaceName())); item.setData(xrd); } private boolean isBound(String key) { ResourceManagerConfiguration rmc = editor.getResolvedExternalResourcesAndBindings(); if (null == rmc) { // happens if there is no such xml element in the descriptor return false; } ExternalResourceBinding[] xrb = rmc.getExternalResourceBindings(); if (null != xrb) for (int i = 0; i < xrb.length; i++) { if (key.equals(xrb[i].getKey())) return true; } return false; } private void propagateKeyChange(String newKey, String oldKey) { ExternalResourceBinding[] xrb = getExternalResourceBindings(); if (null != xrb) for (int i = 0; i < xrb.length; i++) { if (oldKey.equals(xrb[i].getKey())) { xrb[i].setKey(newKey); editor.getResourcesPage().getResourceBindingsSection().markStale(); return; // only 1 binding at most } } } /** * * @param keys * either "" or key/key/ * @param xrd */ private void addXrdToGUI(String keys, ExternalResourceDependency xrd) { TableItem item = new TableItem(table, SWT.NONE); updateXrdToGUI(item, xrd, keys); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addButton) { handleAdd(); } else if (event.widget == removeButton || (event.type == SWT.KeyUp && event.character == SWT.DEL)) { handleRemove(); } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) { handleEdit(); } // else if (event.type == SWT.MouseDown && event.button == 3) { // handleTableContextMenuRequest(event); // } else if (event.type == SWT.MouseHover) { handleTableHoverHelp(event); } else if (event.type == SWT.Selection) { editor.getResourcesPage().getResourceBindingsSection().enable(); } enable(); } public ExternalResourceDependency getXRDependencyFromTableItem(TableItem item) { return (ExternalResourceDependency) item.getData(); } // ***************************************************** // * When hovering over an item in the table, show the // * description // ***************************************************** private void handleTableHoverHelp(Event event) { TableItem item = table.getItem(new Point(event.x, event.y)); if (null != item) { ExternalResourceDependency xrd = getXRDependencyFromTableItem(item); setToolTipText(table, xrd.getDescription()); } else { table.setToolTipText(""); // not needed? - tool tip goes away by itself } } private void handleEdit() { TableItem item = table.getSelection()[0]; ExternalResourceDependency xrd = getXRDependencyFromTableItem(item); AddExternalResourceDependencyDialog dialog = new AddExternalResourceDependencyDialog(this, xrd); if (dialog.open() == Window.CANCEL) return; alterExistingExternalResourceDependency(xrd, dialog); updateXrdToGUI(item, xrd, ""); } private void finishAction() { packChangingColumns(); setFileDirty(); } private void packChangingColumns() { table.getColumn(KEY_COL).pack(); table.getColumn(3).pack(); } private void handleRemove() { TableItem item = table.getSelection()[0]; editor.getAeDescription().setExternalResourceDependencies( (ExternalResourceDependency[]) Utility.removeElementFromArray( getExternalResourceDependencies(), getXRDependencyFromTableItem(item), ExternalResourceDependency.class)); table.setSelection(table.getSelectionIndices()[0] - 1); item.dispose(); finishAction(); } /** * add a external resource dependency to the model * */ private void handleAdd() { AddExternalResourceDependencyDialog dialog = new AddExternalResourceDependencyDialog(this); if (dialog.open() == Window.CANCEL) return; ExternalResourceDependency xrd = addNewExternalResourceDependency(dialog); addXrdToGUI("", xrd); } private void alterExistingExternalResourceDependency(ExternalResourceDependency xrd, AddExternalResourceDependencyDialog dialog) { valueChanged = false; String oldKey = xrd.getKey(); xrd.setKey(setValueChanged(dialog.keyName, xrd.getKey())); if (valueChanged) propagateKeyChange(dialog.keyName, oldKey); xrd.setDescription(setValueChanged(multiLineFix(dialog.description), xrd.getDescription())); xrd.setInterfaceName(setValueChanged(dialog.interfaceName, xrd.getInterfaceName())); if (dialog.optional != xrd.isOptional()) { xrd.setOptional(dialog.optional); valueChanged = true; } if (valueChanged) finishAction(); } private ExternalResourceDependency addNewExternalResourceDependency( AddExternalResourceDependencyDialog dialog) { ExternalResourceDependency[] xrds = getExternalResourceDependencies(); ExternalResourceDependency xrd = new ExternalResourceDependency_impl(); alterExistingExternalResourceDependency(xrd, dialog); if (null == xrds) editor.getAeDescription().setExternalResourceDependencies( new ExternalResourceDependency[] { xrd }); else { ExternalResourceDependency[] newXrds = new ExternalResourceDependency[xrds.length + 1]; System.arraycopy(xrds, 0, newXrds, 0, xrds.length); newXrds[newXrds.length - 1] = xrd; editor.getAeDescription().setExternalResourceDependencies(newXrds); } return xrd; } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractSection#enable() */ public void enable() { packTable(table); if (isPrimitive()) { addButton.setEnabled(true); editButton.setEnabled(table.getSelectionCount() == 1); removeButton.setEnabled(table.getSelectionCount() > 0); } } public boolean keyNameAlreadyDefined(String key) { ExternalResourceDependency[] xrds = getExternalResourceDependencies(); if (null != xrds) { for (int i = 0; i < xrds.length; i++) { if (key.equals(xrds[i].getKey())) { Utility .popMessage( "Key Already Defined", MessageFormat .format( "The key name you specified, ''{0}'', is already defined. Please pick a different key name.", new String[] { key }), MessageDialog.ERROR); return true; } } } return false; } public Table getTable() { return table; } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSectionParm.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractS0000644000175000017500000006733611665471220033442 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.util.AbstractList; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.resource.metadata.ConfigurationParameterSettings; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.model.ConfigGroup; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; /** */ public abstract class AbstractSectionParm extends AbstractSection { public final static String NOT_IN_ANY_GROUP = Messages .getString("AbstractSectionParm.notInAnyGroup"); //$NON-NLS-1$ public final static String COMMON_GROUP = Messages.getString("AbstractSectionParm.common"); //$NON-NLS-1$ // maintainers note: names below have extra trailing blanks to get them to approximately line up // where possible protected final static String DELEGATE_HEADER = Messages .getString("AbstractSectionParm.delegateKeyName"); //$NON-NLS-1$ protected final static String FLOWCTLR_HEADER = "Flow Controller Key Name: "; protected final static String GROUP_HEADER = Messages .getString("AbstractSectionParm.headerGroupNames"); //$NON-NLS-1$ protected final static String COMMON_GROUP_HEADER = Messages .getString("AbstractSectionParm.headerCommon"); //$NON-NLS-1$ protected final static String NOT_IN_ANY_GROUP_HEADER = Messages .getString("AbstractSectionParm.headerNotInAnyGroup"); //$NON-NLS-1$ protected final String OVERRIDE_HEADER = Messages.getString("AbstractSectionParm.overrides"); // nonstatic // for // easy // ref // in // subclass // //$NON-NLS-1$ protected final static String MULTI_VALUE_INDICATOR = "Multi "; //$NON-NLS-1$ protected final static String SINGLE_VALUE_INDICATOR = "Single "; //$NON-NLS-1$ protected final static String OPTIONAL_INDICATOR = "Opt "; //$NON-NLS-1$ protected final static String REQUIRED_INDICATOR = "Req "; //$NON-NLS-1$ protected final String nameHeader = " Name: "; //$NON-NLS-1$ protected final static Map typeNamesW = new HashMap(4); static { // map extra spaces to get these to take the same typeNamesW.put("Boolean", "Boolean"); //$NON-NLS-1$ //$NON-NLS-2$ typeNamesW.put("Float", "Float "); //$NON-NLS-1$ //$NON-NLS-2$ typeNamesW.put(Messages.getString("AbstractSectionParm.16"), "Integer "); //$NON-NLS-1$ //$NON-NLS-2$ typeNamesW.put("String", "String "); //$NON-NLS-1$ //$NON-NLS-2$ } protected Tree tree; protected Tree parameterSectionTree = null; protected boolean showOverrides; protected boolean splitGroupNames; protected ConfigurationParameter[] commonParms; protected Map groupParms; protected ConfigurationParameterDeclarations cpd; // settings set by other page when it is created protected ParameterSettingsSection settings = null; protected Tree settingsTree = null; public void setSettings(ParameterSettingsSection v) { settings = v; settingsTree = v.getTree(); } /** * @param editor * @param parent * @param hasDescription */ public AbstractSectionParm(MultiPageEditor aEditor, Composite parent, String header, String description) { super(aEditor, parent, header, description); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractSection#enable() */ public void enable() { } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public abstract void handleEvent(Event event); /************************************************************************************************* * methods shared with multiple param pages **************************************** */ /** * Two modes: settingsDisplayMode - if true, shows groups one name at a time, and puts all * parms in other groups */ protected void clearAndRefillTree(boolean usingGroups) { cpd = getConfigurationParameterDeclarations(); tree.removeAll(); // when filling ParameterSection, it might or might not have // settings tree set, depending on which panel is shown first // Filling parmaterSection on initial refresh should not update, in any case, the // the settings page; it has its own refresh. // To prevent this, we turn off the settingsTree reference while filling // and restore it at the end Tree savedSettingsTree = settingsTree; settingsTree = null; groupParms = new TreeMap(); try { // tree has 2 dummy groups // first is the , 2nd is the if (null == cpd.getConfigurationParameters()) cpd.setConfigurationParameters(configurationParameterArray0); fillGroup(cpd.getConfigurationParameters(), NOT_IN_ANY_GROUP, null); if (null == cpd.getCommonParameters()) cpd.setCommonParameters(configurationParameterArray0); if (usingGroups) { fillGroup(cpd.getCommonParameters(), COMMON_GROUP, null); } ConfigurationGroup[] groups = cpd.getConfigurationGroups(); for (int i = 0; i < groups.length; i++) { ConfigurationParameter[] cps = groups[i].getConfigurationParameters(); if (null == cps) groups[i].setConfigurationParameters(cps = configurationParameterArray0); fillGroup(groups[i].getConfigurationParameters(), groups[i].getNames(), groups[i]); } if (splitGroupNames) fillGroupsFromGroupParms(); expandAllItems(tree.getItems()); // expand for overrides or groups } finally { settingsTree = savedSettingsTree; groupParms = null; } } private void expandAllItems(TreeItem[] items) { TreeItem[] containedItems; for (int i = 0; i < items.length; i++) { items[i].setExpanded(true); containedItems = items[i].getItems(); if (null != containedItems) expandAllItems(containedItems); } } /** * Called by refresh; add a normal named group and a set of parmaters */ private void fillGroup(ConfigurationParameter[] parms, String[] names, ConfigurationGroup modelCG) { fillGroup(parms, groupNameArrayToString(names), modelCG); } /** * called by refresh() for and refresh() for named, via another path with names as array * first converted to concatenated string. * * @param parms * @param names */ private void fillGroup(ConfigurationParameter[] parms, String names, ConfigurationGroup modelCG) { if (splitGroupNames) { if (names.equals(COMMON_GROUP)) { commonParms = parms; } else { String[] nameArray = groupNamesToArray(names); if (nameArray.length == 1 && nameArray[0].equals(NOT_IN_ANY_GROUP)) { TreeItem groupItem = addGroupToGUI(nameArray[0], modelCG); fill(parms, groupItem); } else for (int i = 0; i < nameArray.length; i++) { List g = (List) groupParms.get(nameArray[i]); if (null == g) { g = new ArrayList(); groupParms.put(nameArray[i], g); } g.add(new Object[] { modelCG, parms }); } } } else { if (names.equals(COMMON_GROUP)) commonParms = parms; TreeItem groupItem = addGroupToGUI(names, modelCG); fill(parms, groupItem); } } private void fillGroupsFromGroupParms() { for (Iterator grpInfo = groupParms.entrySet().iterator(); grpInfo.hasNext();) { Map.Entry entry = (Map.Entry) grpInfo.next(); String key = (String) entry.getKey(); List pairs = (List) entry.getValue(); TreeItem groupItem = addGroupToGUI(key, null); // modelCG not available, but not used for (Iterator pi = pairs.iterator(); pi.hasNext();) { Object[] v = (Object[]) pi.next(); ConfigurationParameter[] parms = (ConfigurationParameter[]) v[1]; fill(parms, groupItem); } fill(commonParms, groupItem); } } /** * called by refresh() when no groups, just plain parm sets, also for group case * * @param parms * @param group * if not in a group, otherwise the group tree item */ protected void fill(ConfigurationParameter[] parms, TreeItem group) { if (parms == null) return; for (int i = 0; i < parms.length; i++) { addNewConfigurationParameterToGUI(parms[i], group); } } public static String groupNameArrayToString(String[] strings) { StringBuffer b = new StringBuffer(); for (int i = 0; i < strings.length; i++) { if (i > 0) b.append(" "); //$NON-NLS-1$ b.append(strings[i]); } return b.toString(); } protected String[] groupNamesToArray(String names) { if (names.equals(NOT_IN_ANY_GROUP)) return new String[] { names }; AbstractList items = new ArrayList(); int start = 0; int end; while (start < names.length() && (names.charAt(start) == ' ')) start++; for (; start < names.length();) { end = names.indexOf(' ', start); if (end == -1) { items.add(names.substring(start)); break; } items.add(names.substring(start, end)); start = end; while (start < names.length() && names.charAt(start) == ' ') start++; } return (String[]) items.toArray(stringArray0); } /** * Takes an existing model parm and fills a pre-allocated treeItem. 3 callers: * addNewConfigurationParameter, alterExistingConfigurationParamater (editing), fill (bulk update * from refresh) * * @param item * @param parm */ protected void fillParmItem(TreeItem item, ConfigurationParameter parm) { item.setText(parmGuiString(parm)); // // set data if tree == parmsection tree // if (item.getParent() == parameterSectionTree) // back link used to find corresponding model parm decl from tree item item.setData(parm); } protected String parmGuiString(ConfigurationParameter parm) { return ((parm.isMultiValued()) ? MULTI_VALUE_INDICATOR : SINGLE_VALUE_INDICATOR) + ((parm.isMandatory()) ? REQUIRED_INDICATOR : OPTIONAL_INDICATOR) + typeNamesW.get(parm.getType()) + " " + nameHeader + //$NON-NLS-1$ (parm.getName()); } protected void setGroupText(TreeItem groupItem, String names) { if (names.equals(COMMON_GROUP)) groupItem.setText(COMMON_GROUP_HEADER); else if (names.equals(NOT_IN_ANY_GROUP)) groupItem.setText(NOT_IN_ANY_GROUP_HEADER); else // next line formats the names with the right number of spaces and makes it // possible to do future equal compares groupItem.setText(GROUP_HEADER + groupNameArrayToString(groupNamesToArray(names))); } protected TreeItem addGroupToGUI(String names, ConfigurationGroup cg) { TreeItem groupItem = new TreeItem(tree, SWT.NONE); setGroupText(groupItem, names); ConfigGroup mcg; if (names.equals(COMMON_GROUP)) mcg = new ConfigGroup(cpd, ConfigGroup.COMMON); else if (names.equals(NOT_IN_ANY_GROUP)) mcg = new ConfigGroup(cpd, ConfigGroup.NOT_IN_ANY_GROUP); else mcg = new ConfigGroup(cpd, cg); groupItem.setData(mcg); String[] nameArray = groupNamesToArray(names); if (null != settingsTree) { for (int i = 0; i < nameArray.length; i++) { TreeItem[] settingsItems = settingsTree.getItems(); if (!containsGroup(nameArray[i], settingsItems)) { TreeItem settingsItem = new TreeItem(settingsTree, SWT.NONE); setGroupText(settingsItem, nameArray[i]); settingsItem.setData(null); fill(commonParms, settingsItem); } } } return groupItem; } private boolean containsGroup(String groupName, final TreeItem[] settingsItems) { for (int i = 0; i < settingsItems.length; i++) { if (groupName.equals(getName(settingsItems[i]))) return true; } return false; } /** * This is called sometimes with Settings group * * @param newCP * @param group - * is never null. May be , indicate no groups; may be the "" * group; or may be a regular group with a set of group names */ protected void addNewConfigurationParameterToGUI(ConfigurationParameter newCP, TreeItem group) { if (null == group) throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$ // is part of group but could be NOT_IN_ANY_GROUP if (null != settingsTree) { boolean isCommonOrNotInAnyGrp = COMMON_GROUP.equals(getName(group)) || NOT_IN_ANY_GROUP.equals(getName(group)); TreeItem[] groups = getSettingsGroups(group); for (int i = 0; i < groups.length; i++) { // this next test tries to add parms so that common ones come at the end, // and non-common ones come before the start of common ones. TreeItem newParmGuiItem = (isCommonOrNotInAnyGrp) ? new TreeItem(groups[i], SWT.NONE) : new TreeItem(groups[i], SWT.NONE, 0); fillParmItem(newParmGuiItem, newCP); } } // next only done for non-setting page if (group.getParent() != settingsTree) { TreeItem newItem; fillParmItem(newItem = new TreeItem(group, SWT.NONE), newCP); if (showOverrides) { fillOverrides(newItem, newCP); } } } // this is overriden where needed // here just make above fn compile OK protected void fillOverrides(TreeItem parent, ConfigurationParameter modelCP) { } protected boolean isOverride(TreeItem item) { return (item.getText().startsWith(OVERRIDE_HEADER)); } protected boolean isParameter(TreeItem item) { String s = item.getText(); return (!isGroup(item) && !s.startsWith(DELEGATE_HEADER) && !s.startsWith(FLOWCTLR_HEADER) && !item .getText().startsWith(OVERRIDE_HEADER)); } // Note: rest of code considers NOT_IN_ANY_GROUP to be a kind of group protected boolean isGroup(TreeItem item) { String s = item.getText(); return s.startsWith(GROUP_HEADER) || s.startsWith(COMMON_GROUP_HEADER) || s.startsWith(NOT_IN_ANY_GROUP_HEADER); } protected boolean isNOT_IN_ANY_GROUP(TreeItem item) { return item.getText().startsWith(NOT_IN_ANY_GROUP_HEADER); } protected boolean isCommonGroup(TreeItem item) { return item.getText().startsWith(COMMON_GROUP_HEADER); } protected boolean isDelegate(TreeItem item) { return item.getText().startsWith(DELEGATE_HEADER) || item.getText().startsWith(FLOWCTLR_HEADER); } protected boolean isGroupSelection() { return isGroup(tree.getSelection()[0]); } protected boolean isCommonGroupSelection() { return isCommonGroup(tree.getSelection()[0]); } protected boolean isOverrideSelection() { return isOverride(tree.getSelection()[0]); } protected boolean isParmSelection() { return isParameter(tree.getSelection()[0]); } protected String getName(TreeItem item) { return getName(item.getText()); } protected String getName(String s) { if (s.startsWith(NOT_IN_ANY_GROUP_HEADER)) return NOT_IN_ANY_GROUP; if (s.startsWith(COMMON_GROUP_HEADER)) return COMMON_GROUP; if (s.startsWith(GROUP_HEADER)) return s.substring(GROUP_HEADER.length()); if (s.startsWith(OVERRIDE_HEADER)) return s.substring(OVERRIDE_HEADER.length()); // parameter return s.substring(s.indexOf(nameHeader) + nameHeader.length()); } protected int getItemIndex(TreeItem parent, TreeItem child) { return getItemIndex(parent.getItems(), child); } protected int getItemIndex(Tree parent, TreeItem child) { return getItemIndex(parent.getItems(), child); } /** * Works between parameter tree and settings tree We don't use any relative index offsets. * Instead, we search for the item with the same parameter name. * * * @param containingGroup * in parm section; if null = means all groups (common parms) * @return */ protected TreeItem[] getSettingsParameter(TreeItem containingGroup, String sourceItemName) { if (null == settingsTree) return null; if (null != containingGroup && isNOT_IN_ANY_GROUP(containingGroup)) return new TreeItem[] { findMatchingParm(settingsTree.getItems()[0], sourceItemName) }; TreeItem[] groups = getSettingsGroups((null == containingGroup) ? tree.getItems()[1] // use // common // group, // will // return // all // groups // in // settings // pg : containingGroup); TreeItem[] results = new TreeItem[groups.length]; for (int i = 0; i < groups.length; i++) { results[i] = findMatchingParm(groups[i], sourceItemName); } return results; } private TreeItem findMatchingParm(TreeItem group, String name) { final TreeItem[] items = group.getItems(); for (int i = 0; i < items.length; i++) { if (name.equals(getName(items[i]))) return items[i]; } throw new InternalErrorCDE("invalid state"); } /** * get set of settings group from settingsTree that correspond to parmsection group * * @param group * @return */ protected TreeItem[] getSettingsGroups(TreeItem group) { if (null == settingsTree) return null; if (isNOT_IN_ANY_GROUP(group)) return new TreeItem[] { settingsTree.getItems()[0] }; AbstractList results = new ArrayList(); String[] groupNamesArray = groupNamesToArray(getName(group.getText())); TreeItem[] items = settingsTree.getItems(); if (groupNamesArray.length == 1 && groupNamesArray[0].equals(COMMON_GROUP)) { // add parm to all groups except TreeItem[] result = new TreeItem[items.length - 1]; System.arraycopy(items, 1, result, 0, result.length); return result; } for (int itemIndex = 0; itemIndex < items.length; itemIndex++) { String name = getName(items[itemIndex].getText()); for (int i = 0; i < groupNamesArray.length; i++) { if (name.equals(groupNamesArray[i])) results.add(items[itemIndex]); } } return (TreeItem[]) results.toArray(treeItemArray0); } /** * find settings tree item for group name * * @param name * @return */ protected TreeItem getSettingsGroupTreeItemByName(String name) { TreeItem[] items = settingsTree.getItems(); for (int i = 0; i < items.length; i++) { if (name.equals(getName(items[i].getText()))) return items[i]; } throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$ } protected ConfigurationParameter getCorrespondingModelParm(TreeItem item) { if (!isParameter(item)) throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$ return (ConfigurationParameter) item.getData(); } protected ConfigGroup getCorrespondingModelGroup(TreeItem item) { if (!isGroup(item)) throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$ return (ConfigGroup) item.getData(); } public ConfigurationParameterSettings getConfigurationParameterSettings() { return editor.getAeDescription().getMetaData().getConfigurationParameterSettings(); } /************************************************************************************************* * * methods affecting the parameter settings. * These run whether or not the settings page has * been instantiated. * If the settings page is instantiated, that GUI is also updated. * ******************************************************************* */ public ConfigurationParameterSettings getModelSettings() { return getAnalysisEngineMetaData().getConfigurationParameterSettings(); } /** * Remove a parameter from all groups it lives in the Settings. If settings page is shown, also * update the GUI. * * @param treeItem * in ParameterSection of parameter belonging to (multiple) groups */ public void removeParmSettingFromMultipleGroups(TreeItem parmItem, boolean removeFromGUI) { if (!isParameter(parmItem)) throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$ ConfigurationParameterSettings modelSettings = getModelSettings(); String parmName = getName(parmItem); TreeItem parent = parmItem.getParentItem(); String groupName = getName(parent.getText()); if (!groupName.equals(NOT_IN_ANY_GROUP)) { String[] groupNames = (getName(parent.getText()).equals(COMMON_GROUP)) ? getAllGroupNames() : getCorrespondingModelGroup(parent).getNameArray(); for (int i = 0; i < groupNames.length; i++) { modelSettings.setParameterValue(groupNames[i], parmName, null); } } else { modelSettings.setParameterValue(parmName, null); } if (null != settings) { if (removeFromGUI) { TreeItem[] settingsTreeParms = getSettingsParameter(parent, parmName); for (int i = 0; i < settingsTreeParms.length; i++) { settingsTreeParms[i].dispose(); } } else { // leave parm but remove value editor.getSettingsPage().getValueSection().refresh(); } } } public void updateParmInSettingsGUI(ConfigurationParameter existingCP, TreeItem existingTreeItem, String prevName) { if (null != settings) { TreeItem[] settingsTreeParms = getSettingsParameter(existingTreeItem.getParentItem(), prevName); for (int i = 0; i < settingsTreeParms.length; i++) { fillParmItem(settingsTreeParms[i], existingCP); } } } protected String[] getAllGroupNames() { return getAllGroupNames(cpd); } /** * * @param aCpd * @return all named groups, excludes and */ protected String[] getAllGroupNames(ConfigurationParameterDeclarations aCpd) { ConfigurationGroup[] cgs = aCpd.getConfigurationGroups(); Set results = new TreeSet(); for (int i = 0; i < cgs.length; i++) { String[] names = cgs[i].getNames(); for (int j = 0; j < names.length; j++) { results.add(names[j]); } } return (String[]) results.toArray(stringArray0); } public void removeCommonParmSettingsFromMultipleGroups() { ConfigurationParameterSettings modelSettings = getModelSettings(); String[] allGroupNames = getAllGroupNames(); // TreeItem [] items = new TreeItem[0]; // done to avoid may not have been initialized msg // int offset = 0; commonParms = cpd.getCommonParameters(); for (int i = 0; i < allGroupNames.length; i++) { // if (null != settings) { // items = getSettingsGroupTreeItemByName(allGroupNames[i]).getItems(); // offset = items.length - commonParms.length; // } for (int j = 0; j < commonParms.length; j++) { modelSettings.setParameterValue(allGroupNames[i], commonParms[j].getName(), null); } } if (null != settings) { for (int j = 0; j < commonParms.length; j++) { TreeItem[] settingsParms = getSettingsParameter(null, commonParms[j].getName()); for (int k = 0; k < settingsParms.length; k++) { settingsParms[k].dispose(); } } } } /** * Remove some of the parameter settings associated with this particular group, not all the * parameters for that group name (some parameters may be associated with other instances of a * particular group name.) If no other group-set contains a particular individual group name, in * the Settings: remove the common parameters, and remove the individual group itself. Remove the * particular group-set definition. Note that a group may be defined in more than one group-set. * * Method: for the group-set, get the parms. Remove just those parms from all groups. Remove the * group on the settings page (together with common parms for it) if no other group-set has this * group name Remove the group-set. * * @param groupNames * @param cps */ public void removeIncludedParmSettingsFromMultipleGroups(String[] groupNames, ConfigurationParameter[] cps) { for (int j = 0; j < groupNames.length; j++) { removeIncludedParmSettingsFromSingleGroup(groupNames[j], cps); } } /** * * @param treeItem * in ParameterSection of items an array of tree items to remove Can be all items under a * particular group, or a set of items from different groups */ public void removeIncludedParmSettingsFromSingleGroup(String groupName, ConfigurationParameter[] cps) { ConfigurationParameterSettings modelSettings = getModelSettings(); // modelSettings.setParameterValue() if (groupName.equals(COMMON_GROUP)) throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$ if (groupName.equals(NOT_IN_ANY_GROUP)) { modelSettings.setParameterSettings(nameValuePairArray0); } else { for (int i = 0; i < cps.length; i++) modelSettings.setParameterValue(groupName, cps[i].getName(), null); } if (null != settings) { TreeItem settingGroup = getSettingsGroupTreeItemByName(groupName); if (groupName.equals(COMMON_GROUP) || groupName.equals(NOT_IN_ANY_GROUP)) { disposeAllChildItems(settingGroup); } else { if (getConfigurationParameterDeclarations().getConfigurationGroupDeclarations(groupName).length == 1) { settingGroup.dispose(); } else { for (int i = 0; i < cps.length; i++) { findMatchingParm(settingGroup, cps[i].getName()).dispose(); } } } } } public void disposeAllChildItems(TreeItem parent) { TreeItem[] items = parent.getItems(); for (int j = 0; j < items.length; j++) { items[j].dispose(); } } protected void showDescriptionAsToolTip(Event event) { TreeItem item = tree.getItem(new Point(event.x, event.y)); if (null != item && isParameter(item)) { setToolTipText(tree, getCorrespondingModelParm(item).getDescription()); } else tree.setToolTipText(""); //$NON-NLS-1$ } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSettingsSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Parameter0000644000175000017500000001205711665471220033462 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.IManagedForm; /** * display parameters on the settings page. If groups, show by groups (using Tree metaphor) Note: * The tree displayed here is an expanded version of the ParameterSection Tree. It differs in 3 * ways, when Groups are being used: 1) no "overrides" info 2) Groups with multiple names are split; * each group name has a different setting * */ public class ParameterSettingsSection extends AbstractSectionParm { public ParameterSettingsSection(MultiPageEditor editor, Composite parent) { super( editor, parent, "Configuration Parameters", "This section list all configuration parameters, either as plain parameters, or as part of one or more groups. Select one to show, or set the value in the right hand panel."); } /* * Called by the page constructor after all sections are created, to initialize them. * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(this.getSection()); enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); tree = newTree(sectionClient); ParameterSection ps = editor.getParameterPage().getParameterSection(); if (null != ps) ps.setSettings(this); tree.addListener(SWT.MouseHover, this); // for Description } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); // only called at beginning. // Subsequently, incrementally updated as parameters and groups // change. // showOverrides = false; splitGroupNames = true; clearAndRefillTree(isParmGroup()); } // public void enable() {} /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.type == SWT.MouseHover) { showDescriptionAsToolTip(event); } else if (event.widget == tree && event.type == SWT.Selection) { editor.getSettingsPage().getValueSection().refresh(); } } public Tree getTree() { return tree; } /** * called by the Values section * * @return */ public String getSelectedParamName() { TreeItem[] items = tree.getSelection(); if (items.length == 0) return null; TreeItem item = items[0]; if (isParameter(item)) return getName(item.getText()); return null; } public String getSelectedParamGroupName() { TreeItem[] items = tree.getSelection(); if (items.length == 0) return null; TreeItem item = items[0]; if (isParameter(item)) { TreeItem parent = item.getParentItem(); if (null == parent) throw new InternalErrorCDE("invalid state"); return getName(parent.getText()); } return null; } /** * * @return */ public ConfigurationParameter getSelectedModelParameter() { TreeItem[] items = tree.getSelection(); if (items.length == 0) return null; TreeItem item = items[0]; if (isParameter(item)) { TreeItem group = item.getParentItem(); ConfigurationParameterDeclarations cpds = getConfigurationParameterDeclarations(); String groupName = (null == group) ? null : getName(group.getText()); if (NOT_IN_ANY_GROUP.equals(groupName)) return cpds.getConfigurationParameter(null, getName(item.getText())); return cpds.getConfigurationParameter(groupName, getName(item.getText())); } return null; } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeImportSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeImpor0000644000175000017500000001150211665471220033464 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.IOException; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Composite; /** */ public class TypeImportSection extends ImportSection { private CAS savedCAS; private boolean importWasRemoved; public TypeImportSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Imported Type Systems", "The following type systems are included as part of this one."); } // ************************************** // * Code to support type import section // ************************************** protected boolean isAppropriate() { if (isAggregate()) { getSection().setText("Not Used"); getSection().setDescription("Types can't be imported in an Aggregate Descriptor"); return false; } getSection().setText("Imported Type Systems"); getSection().setDescription("The following type systems are included as part of this one."); return true; } protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException { TypeSystemDescription parsedImportItem = UIMAFramework.getXMLParser() .parseTypeSystemDescription(new XMLInputSource(source)); return parsedImportItem.getDescription(); } protected Import[] getModelImportArray() { return getTypeSystemDescription().getImports(); } protected void setModelImportArray(Import[] imports) { savedCAS = editor.getCurrentView(); Import[] oldImports = getTypeSystemDescription().getImports(); importWasRemoved = (null != oldImports) && (oldImports.length > imports.length); getTypeSystemDescription().setImports(imports); } protected void clearModelBaseValue() { getTypeSystemDescription().setTypes(typeDescription0); } protected boolean isValidImport(String title, String msg) { TypeSystemDescription savedTSD = getMergedTypeSystemDescription(); TypeSystemDescription savedITSD = editor.getImportedTypeSystemDesription(); try { editor.setMergedTypeSystemDescription(); editor.descriptorCAS.validate(); } catch (ResourceInitializationException e1) { revertMsg(title, msg, editor.getMessagesToRootCause(e1)); editor.setMergedTypeSystemDescription(savedTSD); editor.setImportedTypeSystemDescription(savedITSD); editor.descriptorCAS.set(savedCAS); return false; } if (importWasRemoved) if (Window.CANCEL == Utility.popOkCancel("May need to remove dependencies", "A type import is being removed. If this would removed some types or features in the" + " merged type system, which are referenced in the Capabilities or Indexes " + "section, you will need to update those sections as appropriate.", MessageDialog.INFORMATION)) { revertMsg(title, msg, "Cancelled by user."); editor.setMergedTypeSystemDescription(savedTSD); editor.setImportedTypeSystemDescription(savedITSD); editor.descriptorCAS.set(savedCAS); return false; } return true; } /** * At this point, the basic type system description is updated. and validated. Validation has * updated the merged type system description, and updated the CAS. */ protected void finishImportChangeAction() { // at this point, the tsd validation has updated the resolved version editor.getTypePage().getTypeSection().refresh(); editor.addDirtyTypeName(""); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeSecti0000644000175000017500000017036011665471220033455 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; /* * The types shown are those that are explicitly defined; in other words, built-in types are not * shown, unless there is an explicit extending of some built-in type. In this case, the "merged" * type system is updated to include the features from the built-in type. * * Redesign 2/17/05 Two panels: This one and an "Import" panel This panel: A TreeTable with buttons * Items (top level) are Types Nested 1 down: Features col 0 = Type or Feature name col 1 = * SuperType or Range Name or allowed value * * Hover shows Description * * Types that are imported are shown in grey font color Hover shows type system they were imported * from, plus description, right click to open it * * Types for aggregates are "read-only". No right-click on hover - is ambiguous where type came * from. * * Double-click or press Edit button to edit * */ import java.util.ArrayList; import java.util.Comparator; import java.util.List; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.impl.UIMAFramework_impl; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.AllowedValue; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddAllowedValueDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddFeatureDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddTypeDialog; import org.apache.uima.taeconfigurator.wizards.TypeSystemNewWizard; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableTree; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.forms.IManagedForm; public class TypeSection extends AbstractImportablePartSection { public static final String CASCADE_MESSAGE = "This will cause a cascading deletion of an associated " + "input, output, index, or type priority, unless this deletion exposes a " + "built-in or imported type or feature of the same name. Ok to continue?"; public static final String CASCADE_DELETE_WARNING = "Cascade Delete Warning"; public static final int NAME_COL = 0; public static final int SUPER_COL = 1; public static final int RANGE_COL = 1; public static final int MULTIPLE_REF_OK_COL = 2; public static final int ELEMENT_TYPE_COL = 3; public static final int AV_COL = 1; public static final String HEADER_ALLOWED_VALUE = "Allowed Value:"; private TableTree tt; private Button addTypeButton; private Button addButton; private Button editButton; private Button removeButton; private Button jcasGenButton; private Button exportButton; // private TypeSystemDescription tsdLocal; // for this descriptor, no imports private static final boolean ALLOWED = true; public TypeSection(MultiPageEditor editor, Composite parent) { super( editor, parent, "Types (or Classes)", "The following types (classes) are defined in this analysis engine descriptor.\nThe grayed out items are imported or merged from other descriptors, and cannot be edited here. (To edit them, edit their source files)."); } // ********************************************************************** // * Called by the page constructor after all sections are created, to // initialize them. // * (non-Javadoc) // * @see // org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) // **********************************************************************/ public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); tt = newTableTree(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION); new TableColumn(tt.getTable(), SWT.NONE).setText("Type Name or Feature Name"); new TableColumn(tt.getTable(), SWT.NONE).setText("SuperType or Range"); new TableColumn(tt.getTable(), SWT.NONE).setText(" "); // space for icon new TableColumn(tt.getTable(), SWT.NONE).setText("Element Type"); tt.getTable().setHeaderVisible(true); tt.getTable().addListener(SWT.MouseHover, this); // to show description and more Composite buttonContainer = newButtonContainer(sectionClient); addTypeButton = newPushButton(buttonContainer, "Add Type", "Click here to add a new type."); addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a feature or allowed-value to the selected type."); editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP); removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP); exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP); spacer(buttonContainer); jcasGenButton = newPushButton(buttonContainer, "JCasGen", "Click here to run JCasGen on this type system."); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#update() */ public void refresh() { super.refresh(); tt.removeAll(); TypeSystemDescription tsdFull = getMergedTypeSystemDescription(); TypeDescription[] tdsFull = tsdFull.getTypes(); if (null != tdsFull) { for (int i = 0; i < tdsFull.length; i++) { addTypeToGUI(tdsFull[i]); } } if (tt.getItemCount() > 0) tt.setSelection(new TableTreeItem[] { tt.getItems()[0] }); packTable(tt.getTable()); enable(); } private FeatureDescription[] setDifference(FeatureDescription[] all, FeatureDescription[] subset) { if (null == all) return featureDescriptionArray0; if (null == subset) return all; List result = new ArrayList(); outer: for (int i = 0; i < all.length; i++) { String name = all[i].getName(); for (int j = 0; j < subset.length; j++) { if (subset[j].getName().equals(name)) continue outer; } result.add(all[i]); } return (FeatureDescription[]) result.toArray(new FeatureDescription[result.size()]); } private void addTypeToGUI(TypeDescription td) { TableTreeItem item = new TableTreeItem(tt, SWT.NONE); item.setText(NAME_COL, formatName(td.getName())); item.setText(SUPER_COL, formatName(td.getSupertypeName())); item.setData(td); setItemColor(item, isLocalType(td)); FeatureDescription[] features = td.getFeatures(); addFeaturesToGui(td, item, features); TypeDescription builtInTd = getBuiltInTypeDescription(td); if (null != builtInTd) { FeatureDescription[] additionalBuiltInFeatures = setDifference(builtInTd.getFeatures(), td .getFeatures()); addFeaturesToGui(td, item, additionalBuiltInFeatures); } AllowedValue[] avs = td.getAllowedValues(); if (null != avs) { for (int i = 0; i < avs.length; i++) { TableTreeItem avItem = new TableTreeItem(item, SWT.NONE); avItem.setText(NAME_COL, HEADER_ALLOWED_VALUE); avItem.setText(AV_COL, convertNull(avs[i].getString())); avItem.setData(avs[i]); setItemColor(avItem, null != getLocalAllowedValue(td, avs[i])); } } // No built-ins have "allowed values" so we don't have to add any item.setExpanded(true); } private void addFeaturesToGui(TypeDescription td, TableTreeItem item, FeatureDescription[] features) { if (null != features) { for (int i = 0; i < features.length; i++) { TableTreeItem fItem = new TableTreeItem(item, SWT.NONE); updateGuiFeature(fItem, features[i], td); } } } private void updateGuiFeature(TableTreeItem fItem, FeatureDescription fd, TypeDescription td) { String rangeType; fItem.setText(NAME_COL, fd.getName()); fItem.setText(RANGE_COL, formatName(rangeType = fd.getRangeTypeName())); fItem.setData(fd); setItemColor(fItem, null != getLocalFeatureDefinition(td, fd)); if (isArrayOrListType(rangeType)) { Boolean mra = fd.getMultipleReferencesAllowed(); fItem.setImage(MULTIPLE_REF_OK_COL, (null != mra && mra.booleanValue()) ? TAEConfiguratorPlugin .getImage(TAEConfiguratorPlugin.IMAGE_MREFOK) : TAEConfiguratorPlugin .getImage(TAEConfiguratorPlugin.IMAGE_NOMREF)); } else { fItem.setImage(MULTIPLE_REF_OK_COL, null); } String ert = fd.getElementType(); fItem.setText(ELEMENT_TYPE_COL, (isFSArrayOrListType(rangeType) && ert != null) ? formatName(ert) : ""); } private void setItemColor(TableTreeItem item, boolean isLocal) { if (isLocal) return; item.setForeground(editor.getFadeColor()); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addTypeButton) { handleAddType(); } else if (event.widget == addButton) { TableTreeItem parent = tt.getSelection()[0]; if (null != parent.getParentItem()) parent = parent.getParentItem(); if (isSubtypeOfString(parent)) handleAddAllowedValue(parent); else handleAddFeature(parent); } else if (event.widget == editButton) { handleEdit(); } else if (event.type == SWT.MouseDoubleClick && (!isAggregate()) && // can't edit aggregates isLocalItem(tt.getSelection()[0])) { handleEdit(); } else if (event.widget == removeButton) { handleRemove(); } else if (event.widget == exportButton) { editor.getTypePage().getTypeImportSection().exportImportablePart("", TypeSystemNewWizard.TYPESYSTEM_TEMPLATE); refresh(); } else if (event.widget == jcasGenButton) { editor.doJCasGenChkSrc(null); } else if (event.type == SWT.MouseHover) { handleHover(event); } enable(); } public void handleHover(Event event) { // next getItem call requires that table have SWT.FULL_SELECTION Style TableTreeItem item = tt.getItem(new Point(event.x, event.y)); if (null != item) { Object o = item.getData(); if (null == o) throw new InternalErrorCDE("invalid state"); if (o instanceof TypeDescription) { setToolTipText(tt, ((TypeDescription) o).getDescription()); } else if (o instanceof FeatureDescription) { FeatureDescription fd = (FeatureDescription) o; if (item.getBounds(MULTIPLE_REF_OK_COL).contains(event.x, event.y) && isArrayOrListType(fd.getRangeTypeName())) { Boolean mra = fd.getMultipleReferencesAllowed(); setToolTipText(tt, (mra != null && mra.booleanValue()) ? "Multiple References Allowed" : "Multiple References Not Allowed"); } else setToolTipText(tt, fd.getDescription()); } else if (o instanceof AllowedValue) { setToolTipText(tt, ((AllowedValue) o).getDescription()); } } else tt.setToolTipText(""); } public TypeDescription getTypeDescriptionFromTableTreeItem(TableTreeItem item) { return (TypeDescription) item.getData(); } // disabled unless type having String as supertype is selected public void handleAddAllowedValue(TableTreeItem parent) { boolean refreshNeeded = false; TypeDescription td = getTypeDescriptionFromTableTreeItem(parent); // guaranteed non-null - otherwise can't add an allowed value TypeDescription localTd = getLocalTypeDefinition(td); AddAllowedValueDialog dialog = new AddAllowedValueDialog(this, null); if (dialog.open() == Window.CANCEL) { return; } AllowedValue av = UIMAFramework_impl.getResourceSpecifierFactory().createAllowedValue(); allowedValueUpdate(av, dialog); addAllowedValue(localTd, av); if (!Utility.arrayContains(td.getAllowedValues(), av)) addAllowedValue(td, (AllowedValue) av.clone()); else refreshNeeded = true; // update the GUI if (refreshNeeded) refresh(); else { TableTreeItem item = new TableTreeItem(parent, SWT.NONE); item.setText(NAME_COL, HEADER_ALLOWED_VALUE); item.setText(AV_COL, convertNull(av.getString())); item.setData(av); parent.setExpanded(true); } editor.addDirtyTypeName(td.getName()); finishActionPack(); } private void addAllowedValue(TypeDescription td, AllowedValue av) { td.setAllowedValues((AllowedValue[]) Utility.addElementToArray(td.getAllowedValues(), av, AllowedValue.class)); } /** * * @param td - * local or merged (2 callers) * @param av */ private void removeAllowedValue(TypeDescription td, AllowedValue av) { td.setAllowedValues((AllowedValue[]) Utility.removeEqualElementFromArray(td.getAllowedValues(), av, AllowedValue.class)); } // disabled unless type is selected public void handleAddFeature(TableTreeItem parent) { TypeDescription td = getTypeDescriptionFromTableTreeItem(parent); // guaranteed non-null - otherwise add button disabled TypeDescription localTd = getLocalTypeDefinition(td); // AddFeatureDialog dialog = new AddFeatureDialog(this, td, null); if (dialog.open() == Window.CANCEL) { return; } FeatureDescription fd = localTd.addFeature(null, null, null); featureUpdate(fd, dialog); editor.addDirtyTypeName(td.getName()); // update the GUI // if this type is merged with an import or with a built-in, // need to "refresh" if (isImportedType(td) || isBuiltInType(td)) { if (!isImportedFeature(dialog.featureName, td)) { // don't need to check builtin Feature because gui doesn't let you // define a built-in feature again fd = td.addFeature(null, null, null); featureUpdate(fd, dialog); } refresh(); selectTypeInGui(td); finishAction(); } else { fd = td.addFeature(null, null, null); featureUpdate(fd, dialog); TableTreeItem item = new TableTreeItem(parent, SWT.NONE); updateGuiFeature(item, fd, td); parent.setExpanded(true); finishActionPack(); } } private void selectTypeInGui(TypeDescription td) { TableTreeItem[] items = tt.getItems(); for (int i = 0; i < items.length; i++) { if (td.getName().equals(((TypeDescription) items[i].getData()).getName())) { tt.setSelection(new TableTreeItem[] { items[i] }); return; } } } public void allowedValueUpdate(AllowedValue av, AddAllowedValueDialog dialog) { valueChanged = false; av.setString(setValueChanged(dialog.allowedValue, av.getString())); av.setDescription(setValueChanged(dialog.description, av.getDescription())); } public void featureUpdate(FeatureDescription fd, AddFeatureDialog dialog) { valueChanged = false; String v = setValueChanged(dialog.featureName, fd.getName()); fd.setName(v); v = setValueChanged(multiLineFix(dialog.description), fd.getDescription()); fd.setDescription(v); String range = setValueChanged(dialog.featureRangeName, fd.getRangeTypeName()); fd.setRangeTypeName(range); if (isArrayOrListType(range)) { Boolean b = setValueChangedCapitalBoolean(dialog.multiRef, fd.getMultipleReferencesAllowed()); fd.setMultipleReferencesAllowed(b); if (isFSArrayOrListType(range)) { v = setValueChanged(dialog.elementRangeName, fd.getElementType()); fd.setElementType(v); } else { fd.setElementType(null); } } else { fd.setMultipleReferencesAllowed(null); fd.setElementType(null); } } public void handleAddType() { AddTypeDialog dialog = new AddTypeDialog(this); if (dialog.open() == Window.CANCEL) return; TypeSystemDescription tsd = getMergedTypeSystemDescription(); TypeSystemDescription localTsd = getTypeSystemDescription(); TypeDescription td = localTsd.addType(dialog.typeName, multiLineFix(dialog.description), dialog.supertypeName); if (!isImportedType(dialog.typeName)) { td = tsd.addType(dialog.typeName, multiLineFix(dialog.description), dialog.supertypeName); addTypeToGUI(td); } else { rebuildMergedTypeSystem(); } if (isImportedType(dialog.typeName) || isBuiltInType(dialog.typeName)) { refresh(); selectTypeInGui(td); } editor.addDirtyTypeName(dialog.typeName); finishActionPack(); } private void finishActionPack() { packTable(tt.getTable()); finishAction(); } private void finishAction() { if (isLocalProcessingDescriptor()) { editor.getIndexesPage().markStale(); editor.getCapabilityPage().markStale(); } setFileDirty(); } private void handleEdit() { TableTreeItem item = tt.getSelection()[0]; TableTreeItem parentType = item.getParentItem(); if (null == parentType) { // editing a type, not a feature editType(item); } else if (item.getText(NAME_COL).equals(HEADER_ALLOWED_VALUE)) { editAllowedValue(item, parentType); } else { editFeature(item, parentType); } } public FeatureDescription getFeatureDescriptionFromTableTreeItem(TableTreeItem item) { return (FeatureDescription) item.getData(); } private void editFeature(TableTreeItem item, TableTreeItem parent) { boolean remergeNeeded = false; boolean refreshNeeded = false; TypeDescription td = getTypeDescriptionFromTableTreeItem(parent); FeatureDescription fd = getFeatureDescriptionFromTableTreeItem(item); FeatureDescription localFd = getLocalFeatureDefinition(td, fd); String oldFeatureName = fd.getName(); AddFeatureDialog dialog = new AddFeatureDialog(this, td, fd); if (dialog.open() == Window.CANCEL) return; featureUpdate(localFd, dialog); if (!valueChanged) return; if (!dialog.featureName.equals(oldFeatureName)) { if (isImportedFeature(oldFeatureName, td)) { Utility .popMessage( "Imported Feature not changed", "Changing the feature name from '" + oldFeatureName + "' to '" + dialog.featureName + "' will not affect the corresponding imported type with the previous feature name. " + "Both features will be included in the type.", MessageDialog.INFORMATION); remergeNeeded = true; refreshNeeded = true; } if (isBuiltInFeature(oldFeatureName, td)) { Utility .popMessage( "BuiltIn Feature not changed", "Changing the feature name from '" + oldFeatureName + "' to '" + dialog.featureName + "' will not affect the corresponding built-in type with the previous feature name. " + "Both features will be included in the type.", MessageDialog.INFORMATION); refreshNeeded = true; // no remerge needed - builtins not merged } } if (remergeNeeded) rebuildMergedTypeSystem(); else featureUpdate(fd, dialog); if (refreshNeeded) refresh(); else { // update the GUI updateGuiFeature(item, fd, td); } alterFeatureMentions(oldFeatureName, fd.getName(), td.getName()); editor.addDirtyTypeName(td.getName()); finishActionPack(); } public AllowedValue getAllowedValueFromTableTreeItem(TableTreeItem item) { return (AllowedValue) item.getData(); } private void editAllowedValue(TableTreeItem item, TableTreeItem parent) { TypeDescription td = getTypeDescriptionFromTableTreeItem(parent); AllowedValue av = getAllowedValueFromTableTreeItem(item); AllowedValue localAv = getLocalAllowedValue(td, av); // must use unmodified value of "av" AddAllowedValueDialog dialog = new AddAllowedValueDialog(this, av); if (dialog.open() == Window.CANCEL) return; allowedValueUpdate(av, dialog); allowedValueUpdate(localAv, dialog); if (!valueChanged) return; // update the GUI item.setText(AV_COL, av.getString()); editor.addDirtyTypeName(td.getName()); finishActionPack(); } /** * New Feature test: return null if OK, error message otherwise * * @param td * @param dialog * @return */ private String newFeatureTests(TypeDescription td, AddFeatureDialog dialog) { FeatureDescription fd; if (isLocalFeature(dialog.featureName, td)) return "Duplicate Feature Name in this Descriptor"; if (isBuiltInFeature(dialog.featureName, td)) return "Feature Name duplicates built-in feature for this type"; if (null != (fd = getFeature(td, dialog.featureName))) // verify the range is the same if (!fd.getRangeTypeName().equals(dialog.featureRangeName)) return "Range Name not the same as the range from an imported type/feature description"; return null; } /** * verify a new or edited feature is valid. For new features: The name must be unique locally. It * may duplicate a non-local feature that isn't also built-in. (We presume built-in features are * fixed). (We allow dupl non-local feature in case this type system is used without the import, * in some other context?) We don't use the TCas because it isn't necessarily being updated * * For edited features: If the name changed, do "new" test above on new name If the name changed, * do "remove" test on old name: If used in an index or capability, but merged/built-in name not * still there, warn about index being invalidated (not done here - done during feature update * itself). If name used in index, and range is not indexable - error * * @param dialog * @return */ public String checkFeature(AddFeatureDialog dialog, TypeDescription td, FeatureDescription oldFd) { if (null == oldFd) { // adding new feature return newFeatureTests(td, dialog); } String errMsg = null; // modifying existing feature if (!oldFd.getName().equals(dialog.featureName)) { // name changed errMsg = newFeatureTests(td, dialog); if (null != errMsg) return errMsg; return null; } // Note: this test is different from above: it tests current name, not old name if (isFeatureUsedInIndex(td, dialog.featureName)) if (!isIndexableRange(dialog.featureRangeName)) return ("This feature is used in an index - it must have an indexable Range"); return null; } public String checkAllowedValue(AddAllowedValueDialog dialog, TypeDescription td, AllowedValue av) { if (isLocalAllowedValue(dialog.allowedValue, td)) { return "Duplicate Allowed Value in this Descriptor"; } return null; } // type is always local; could be merging with import(s) or built-in private void editType(TableTreeItem item) { boolean mergeAndRefreshNeeded = false; boolean refreshNeeded = false; TypeDescription td = getTypeDescriptionFromTableTreeItem(item); AddTypeDialog dialog = new AddTypeDialog(this, td); if (dialog.open() == Window.CANCEL) return; // dialog disallows supertype specs inconsistent with existing features or allowed values // dialog has already checked for dup type name String newTypeName = dialog.typeName; String oldTypeName = td.getName(); String[] typesRequiringThisOne = stringArray0; if (!oldTypeName.equals(newTypeName)) { typesRequiringThisOne = showTypesRequiringThisOneMessage(oldTypeName, ALLOWED); if (null == typesRequiringThisOne) // null is cancel signal return; if (isImportedType(oldTypeName) && MessageDialog.CANCEL == Utility .popOkCancel( "Type define via Import", "The type '" + oldTypeName + "' is also defined in 1 or more imports. Changing the type name here will not change it in the imported type file, causing both types to be in the type system, together. Please confirm this is what you intend.", MessageDialog.WARNING)) return; if (isBuiltInType(oldTypeName) && MessageDialog.CANCEL == Utility .popOkCancel( "Type was extending a built-in", "The type '" + oldTypeName + "' was extending a builtin type of the same name. Changing the type name here will not change the built-in type, causing both types to be in the type system, together. Please confirm this is what you intend.", MessageDialog.WARNING)) return; if (isImportedType(oldTypeName) || isImportedType(newTypeName) || isBuiltInType(oldTypeName) || isBuiltInType(newTypeName)) mergeAndRefreshNeeded = true; } valueChanged = false; // guaranteed non-null because otherwise edit not allowed TypeDescription localTd = getLocalTypeDefinition(td); typeUpdate(localTd, dialog); if (!valueChanged) return; if (mergeAndRefreshNeeded) { rebuildMergedTypeSystem(); td = getMergedTypeSystemDescription().getType(newTypeName); } else { typeUpdate(td, dialog); updateGuiType(item, td); } editor.removeDirtyTypeName(oldTypeName); editor.addDirtyTypeName(td.getName()); // interesting case: renaming a type causes another type // which has a shadow to get a new super (should cause merge error) // or which has a shadow to get a new range (should cause merge error) // or which has a shadow of a built-in to get new range or super // (should cause error) (but only if that feature is defined in the // non-local version) refreshNeeded |= alterTypeMentionsInOtherTypes(oldTypeName, td.getName()); if (refreshNeeded || mergeAndRefreshNeeded) refresh(); alterTypeMentions(oldTypeName, td.getName()); finishActionPack(); } private void updateGuiType(TableTreeItem item, TypeDescription td) { item.setText(NAME_COL, formatName(td.getName())); item.setText(SUPER_COL, formatName(td.getSupertypeName())); } private void rebuildMergedTypeSystem() { try { editor.setMergedTypeSystemDescription(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE(e); } } private void typeUpdate(TypeDescription td, AddTypeDialog dialog) { td.setName(setValueChanged(dialog.typeName, td.getName())); td.setDescription(setValueChanged(multiLineFix(dialog.description), td.getDescription())); td.setSupertypeName(setValueChanged(dialog.supertypeName, td.getSupertypeName())); } /** * returns null or error message about a duplicate type name Cases: Dupl type in local descriptor * not allowed. Type that duplicates imported type is OK. Type that duplicates built-in type is * OK. */ public String checkDuplTypeName(String newTypeName) { if (isLocalType(newTypeName)) { return "The type '" + newTypeName + "' is already defined locally in this descriptor."; } return null; } /* * Note that the Remove action is disabled if the item selected is imported only */ private void handleRemove() { TableTreeItem item = tt.getSelection()[0]; TableTreeItem parent = item.getParentItem(); if (null == parent) handleRemoveType(item); else if (item.getText(NAME_COL).equals(HEADER_ALLOWED_VALUE)) handleRemoveAllowedValue(item); else handleRemoveFeature(item); } private void handleRemoveAllowedValue(TableTreeItem item) { TypeDescription td = getTypeDescriptionFromTableTreeItem(item.getParentItem()); AllowedValue av = getAllowedValueFromTableTreeItem(item); // guaranteed non-null -otherwise remove button disabled removeAllowedValue(getLocalTypeDefinition(td), av); if (!isImportedAllowedValue(td, av)) { removeAllowedValue(td, av); // update GUI tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1); item.dispose(); } else { refresh(); } editor.addDirtyTypeName(td.getName()); finishAction(); } // cases: removing a feature which is merged with an identical named imported feature // same - for built-in private void handleRemoveFeature(TableTreeItem item) { TypeDescription td = getTypeDescriptionFromTableTreeItem(item.getParentItem()); FeatureDescription fd = getFeatureDescriptionFromTableTreeItem(item); String featureName = fd.getName(); boolean bFeatureInUseElsewhere = isFeatureInUseElsewhere(td, featureName); if (bFeatureInUseElsewhere) { String sCascadeDeleteTitle = CASCADE_DELETE_WARNING; String sCascadeDeleteMessage = CASCADE_MESSAGE; boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle, sCascadeDeleteMessage); if (!bContinue) return; } TypeDescription localTd = getLocalTypeDefinition(td); FeatureDescription localFd = getLocalFeatureDefinition(td, fd); removeFeature(localTd, localFd); if (isImportedFeature(featureName, td)) refresh(); // don't remove from merged set else { removeFeature(td, fd); if (isBuiltInFeature(featureName, td)) refresh(); else { // update GUI tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1); item.dispose(); } } if (bFeatureInUseElsewhere && !isImportedFeature(featureName, td) && !isBuiltInFeature(featureName, td)) { deleteTypeOrFeatureMentions(featureName, FEATURES, localTd.getName()); } editor.addDirtyTypeName(td.getName()); finishAction(); } private static class TypeFeature { String typeName; String featureName; // short feature name TypeFeature(String type, String feat) { typeName = type; featureName = feat; } } private static final TypeFeature[] typeFeature0 = new TypeFeature[0]; /** * CALL THIS FN after removing and remerging. Assuming the localTd is removed, it may result in * the mergedTd having fewer features. Compute the features that would be removed. Do it not just * for this type, but for all subtypes of this type. NOTE: if mergeTd is null, it means the type * is removed completely (no shadowing of built-in or imported types), so no special feature * removal is needed. * * @param localTd * @param mergedTd * The "remerged" value of the type. * @return array of string names of features to be removed */ private TypeFeature[] computeFeaturesToRemove(TypeDescription localTd, TypeDescription mergedTd) { if (null == mergedTd) return typeFeature0; FeatureDescription[] locallyDefinedFeatures = localTd.getFeatures(); if (null == locallyDefinedFeatures || locallyDefinedFeatures.length == 0) return typeFeature0; FeatureDescription[] remainingFeatures = mergedTd.getFeatures(); ArrayList deletedFeatures = new ArrayList(); outer: for (int i = 0; i < locallyDefinedFeatures.length; i++) { String fname = locallyDefinedFeatures[i].getName(); if (null != remainingFeatures) for (int j = 0; j < remainingFeatures.length; j++) { if (fname.equals(remainingFeatures[j].getName())) continue outer; } deletedFeatures.add(fname); } // have list of features really disappearing (not kept present by imports or built-ins) // return all types/features of these for types which are subtypes of the passed-in type CAS tcas = editor.getCurrentView(); TypeSystem typeSystem = tcas.getTypeSystem(); Type thisType = typeSystem.getType(localTd.getName()); List subsumedTypesList = typeSystem.getProperlySubsumedTypes(thisType); subsumedTypesList.add(thisType); Type[] subsumedTypes = (Type[]) subsumedTypesList.toArray(new Type[0]); String[] featNameArray = (String[]) deletedFeatures.toArray(new String[deletedFeatures.size()]); ArrayList result = new ArrayList(); for (int i = 0; i < subsumedTypes.length; i++) { Type t = subsumedTypes[i]; for (int j = 0; j < featNameArray.length; j++) { if (null != t.getFeatureByBaseName(featNameArray[j])) result.add(new TypeFeature(t.getName(), featNameArray[j])); } } return (TypeFeature[]) result.toArray(typeFeature0); } private void handleRemoveType(TableTreeItem item) { TypeDescription td = getTypeDescriptionFromTableTreeItem(item); String sTypeNameToRemove = td.getName(); // pop a dialog mentioning typesRequiringThisOne, saying that others must be // deleted first.... if (null == showTypesRequiringThisOneMessage(sTypeNameToRemove, !ALLOWED)) return; boolean bTypeInUseElsewhere = isTypeInUseElsewhere(sTypeNameToRemove); if (bTypeInUseElsewhere) { String sCascadeDeleteTitle = CASCADE_DELETE_WARNING; String sCascadeDeleteMessage = CASCADE_MESSAGE; boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle, sCascadeDeleteMessage); if (!bContinue) { return; } } TypeDescription localTd = getLocalTypeDefinition(td); removeType(localTd, getTypeSystemDescription()); if (isImportedType(td)) { // although the type itself still remains in the merged type system, // features may be removed by this action, so // a remerge is needed rebuildMergedTypeSystem(); refresh(); } else { removeType(td, getMergedTypeSystemDescription()); // update GUI tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1); item.dispose(); } TypeFeature[] featuresToRemove = computeFeaturesToRemove(localTd, getMergedTypeSystemDescription().getType(td.getName())); if (bTypeInUseElsewhere && !isImportedType(td) && !isBuiltInType(td)) { deleteTypeOrFeatureMentions(sTypeNameToRemove, TYPES, null); } // if removing a type which is also imported or built-in, which is a supertype of something // this action can change the feature set. if (null != featuresToRemove) for (int i = 0; i < featuresToRemove.length; i++) { deleteTypeOrFeatureMentions(featuresToRemove[i].featureName, FEATURES, featuresToRemove[i].typeName); } editor.removeDirtyTypeName(sTypeNameToRemove); finishAction(); } /** * Called when removing a type (or renaming a type - treating old value like remove) * * @param existingTypeName * @param allowed * @return null means "cancel", stringArray0 means no problem, stringArrayN = dependent types */ private String[] showTypesRequiringThisOneMessage(String existingTypeName, boolean allowed) { // if type is imported or built-in, in addition to being defined in this // descriptor, removing it won't make the type unavailable. if (isImportedType(existingTypeName) || isBuiltInType(existingTypeName)) return stringArray0; // imported or built-in type will remain String[] typesRequiringThisOne = getTypesRequiringThisOne(existingTypeName); if (typesRequiringThisOne != null && typesRequiringThisOne.length > 0) { String sMsg = existingTypeName + " has the following dependent type(s): "; for (int i = 0; i < typesRequiringThisOne.length; i++) { if (i > 0) { sMsg += ", "; } sMsg += typesRequiringThisOne[i]; } if (!allowed) { sMsg += ". Please delete dependent types first."; Utility.popMessage("Can''t Remove Needed Type", sMsg, MessageDialog.WARNING); return null; } sMsg += ". If you proceed, the dependent types which are updatable will be updated." + " Non-updatable types (imported, etc.) you will have to update manually. Please confirm."; if (MessageDialog.OK == Utility.popOkCancel("Confirm renaming type update actions", sMsg, MessageDialog.WARNING)) return typesRequiringThisOne; return null; } return stringArray0; } private void removeType(TypeDescription td, TypeSystemDescription tsd) { tsd.setTypes((TypeDescription[]) Utility.removeElementFromArray(tsd.getTypes(), td, TypeDescription.class)); } private void removeFeature(TypeDescription td, FeatureDescription fd) { td.setFeatures((FeatureDescription[]) Utility.removeElementFromArray(td.getFeatures(), fd, FeatureDescription.class)); } private String[] getTypesRequiringThisOne(String typeName) { List upstreamTypeNames = new ArrayList(); TypeSystemDescription typeSystem = getMergedTypeSystemDescription(); TypeDescription[] types = typeSystem.getTypes(); for (int i = 0; i < types.length; i++) { if (!types[i].getName().equals(typeName)) { if (typeRequiresType(types[i], typeName)) { upstreamTypeNames.add(types[i].getName()); } } } return (String[]) upstreamTypeNames.toArray(new String[upstreamTypeNames.size()]); } private boolean typeRequiresType(TypeDescription upstreamType, String typeName) { if (null == typeName) return false; if (typeName.equals(upstreamType.getSupertypeName())) { return true; } FeatureDescription[] features = upstreamType.getFeatures(); if (features == null) { return false; } for (int i = 0; i < features.length; i++) { if (typeName.equals(features[i].getRangeTypeName())) { return true; } } return false; } public void enable() { jcasGenButton.setEnabled(tt.getItemCount() > 0); TypeSystemDescription tsd = getTypeSystemDescription(); exportButton.setEnabled(false); if (null != tsd) { TypeDescription[] tsa = tsd.getTypes(); if (null != tsa) exportButton.setEnabled(tsa.length > 0); } if (isAggregate()) { addTypeButton.setEnabled(false); addButton.setEnabled(false); editButton.setEnabled(false); removeButton.setEnabled(false); } else { addTypeButton.setEnabled(true); boolean editable = tt.getSelectionCount() == 1 && isLocalItem(tt.getSelection()[0]); addButton.setEnabled(editable); editButton.setEnabled(editable); removeButton.setEnabled(editable); } } private boolean isSubtypeOfString(TableTreeItem item) { TypeDescription td = getTypeDescriptionFromTableTreeItem(item); return CAS.TYPE_NAME_STRING.equals(td.getSupertypeName()); } private boolean isTypeInUseElsewhere(final String sTypeName) { if (!isLocalProcessingDescriptor()) { return false; } final String sTypeName_Colon = sTypeName + ":"; CapabilityVisitor cv = new CapabilityVisitor() { boolean visit(TypeOrFeature i_o) { if (i_o.isType() && i_o.getName().equals(sTypeName)) return true; else if (i_o.getName().startsWith(sTypeName_Colon)) return true; return false; } }; if (capabilityVisit(cv)) return true; FsIndexDescription[] indexes = getAnalysisEngineMetaData().getFsIndexes(); if (indexes != null) { for (int i = 0; i < indexes.length; i++) { if (indexes[i].getTypeName().equals(sTypeName)) { return true; } } } return typePriorityListsVisit(FIND_EQUAL_TYPE, sTypeName); } private final static int FIND_EQUAL_TYPE = 1; private final static int REMOVE_EQUAL_TYPE = 2; private final static int UPDATE_TYPE_NAME = 4; private boolean typePriorityListsVisit(int kind, String typeName) { return typePriorityListsVisit(kind, typeName, null); } /** * * @param kind * @param typeName * @param newTypeName * @return FIND_EQUAL_TYPE: true if found, false otherwise REMOVE_EQUAL_TYPE: true if found, false * if nothing done UPDATE_TYPE_NAME: true if found & updated, false if nothing done */ private boolean typePriorityListsVisit(int kind, String typeName, String newTypeName) { boolean returnValue = false; TypePriorities priorities = getAnalysisEngineMetaData().getTypePriorities(); if (priorities != null) { TypePriorityList[] priorityLists = priorities.getPriorityLists(); if (priorityLists != null) { for (int i = 0; i < priorityLists.length; i++) { String[] typeNames = priorityLists[i].getTypes(); if (typeNames != null) { if (kind == FIND_EQUAL_TYPE) { for (int j = 0; j < typeNames.length; j++) { if (typeNames[j].equals(typeName)) return true; } } else if (kind == UPDATE_TYPE_NAME) { boolean bChanged = false; for (int j = 0; j < typeNames.length; j++) { if (typeNames[j].equals(typeName)) { typeNames[j] = newTypeName; bChanged = true; break; } } if (bChanged) { priorityLists[i].setTypes(typeNames); returnValue = true; } } else if (kind == REMOVE_EQUAL_TYPE) { Object[] newTypeNames = Utility.removeElementsFromArray(typeNames, typeName, String.class); if (newTypeNames != typeNames) { priorityLists[i].setTypes((String[]) newTypeNames); returnValue = true; } } else throw new InternalErrorCDE("invalid argument"); } } } } return returnValue; } private TypeOrFeature[] deleteTypeOrFeatureFromCapability(TypeOrFeature[] io_s, final boolean isType, String name, String typeName) { if (!isType) // is feature name = typeName + ':' + name; return (TypeOrFeature[]) Utility.removeElementsFromArray(io_s, name, TypeOrFeature.class, isType ? capabilityTypeCompare : capabilityFeatureCompare); } private final static boolean TYPES = true; private final static boolean FEATURES = false; private static final Comparator fsIndexDescCompare = new Comparator() { public int compare(Object o1, Object o2) { return ((FsIndexDescription) o2).getTypeName().equals(o1) ? 0 : 1; } }; private static final Comparator fsIndexKeyDescCompare = new Comparator() { public int compare(Object o1, Object o2) { return (o1.equals(((FsIndexKeyDescription) o2).getFeatureName())) ? 0 : 1; } }; private static final Comparator capabilityTypeCompare = new Comparator() { public int compare(Object o1, Object o2) { TypeOrFeature tf = (TypeOrFeature) o2; return ((tf.isType() == true && tf.getName().equals(o1)) || // remove features belong to type if type is removed tf.getName().startsWith(((String) o1) + ':')) ? 0 : 1; } }; private static final Comparator capabilityFeatureCompare = new Comparator() { public int compare(Object o1, Object o2) { TypeOrFeature tf = (TypeOrFeature) o2; return (tf.isType() == false && tf.getName().equals(o1)) ? 0 : 1; } }; /** * feature name if used, is short-name * * @param typeOrFeatureName - * if feature is short feature name * @param isType * @param String * type name (used when feature name passed above */ private void deleteTypeOrFeatureMentions(final String typeOrFeatureName, boolean isType, final String typeName) { if (!isLocalProcessingDescriptor()) { return; } Capability[] c = getCapabilities(); for (int ic = 0; ic < c.length; ic++) { c[ic].setInputs(deleteTypeOrFeatureFromCapability(c[ic].getInputs(), isType, typeOrFeatureName, typeName)); c[ic].setOutputs(deleteTypeOrFeatureFromCapability(c[ic].getOutputs(), isType, typeOrFeatureName, typeName)); } CapabilityPage p = editor.getCapabilityPage(); if (null != p) p.markStale(); final FsIndexCollection indexCollection = editor.getFsIndexCollection(); FsIndexDescription[] indexes = (null == indexCollection) ? null : indexCollection .getFsIndexes(); boolean somethingChanged = false; if (indexes != null) { if (isType) { FsIndexDescription[] newFsid = (FsIndexDescription[]) Utility.removeElementsFromArray( indexes, typeOrFeatureName, FsIndexDescription.class, fsIndexDescCompare); if (newFsid != indexes) { somethingChanged = true; indexCollection.setFsIndexes(newFsid); } } else { // is feature for (int i = 0; i < indexes.length; i++) { if (typeName.equals(indexes[i].getTypeName())) { FsIndexKeyDescription[] newFsKeys = (FsIndexKeyDescription[]) Utility .removeElementsFromArray(indexes[i].getKeys(), typeOrFeatureName, FsIndexKeyDescription.class, fsIndexKeyDescCompare); if (newFsKeys != indexes[i].getKeys()) { somethingChanged = true; indexes[i].setKeys(newFsKeys); } } } } if (somethingChanged) { try { editor.setMergedFsIndexCollection(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("unexpected exception", e); } if (null != editor.getIndexesPage()) editor.getIndexesPage().markStale(); } } if (isType) { if (typePriorityListsVisit(REMOVE_EQUAL_TYPE, typeOrFeatureName)) { try { editor.setMergedTypePriorities(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("unexpected exception"); } if (null != editor.getIndexesPage()) editor.getIndexesPage().markStale(); } } } /** * return true if refresh is needed * * @param oldTypeName * @param newTypeName * @return */ private boolean alterTypeMentionsInOtherTypes(String oldTypeName, String newTypeName) { // only modify locally modifiable types, but scan all types to give appropriate error msgs TypeSystemDescription typeSystem = getMergedTypeSystemDescription(); boolean refreshNeeded = false; boolean remergeNeeded = false; TypeDescription[] types = typeSystem.getTypes(); for (int i = 0; i < types.length; i++) { TypeDescription td = types[i]; TypeDescription localTd = getLocalTypeDefinition(td); String typeName = td.getName(); if (td.getSupertypeName().equals(oldTypeName)) { if (null != localTd) { // is a local type if (isImportedType(typeName)) { Utility .popMessage( "Imported type won't be changed", "There is both a local and imported version of type, '" + typeName + "', which has a supertype which is the item being renamed. Although the local version will be updated, but the imported one won't." + "This may cause an error when you save.", MessageDialog.WARNING); } if (isBuiltInType(typeName)) { // invalid: changed some type name which was a supertype of a built in - but // all the supertypes of built-ins are unchangable. throw new InternalErrorCDE("invalid state"); } } else { // is not a local type // can't be a built-in type because all the supertypes of built-ins are unchangeable Utility .popMessage( "Imported type not changed", "There is an imported type, '" + typeName + "', which has a supertype which is the item being renamed. It won't be updated - this may cause an error when you save this descriptor." + " If it does, you will need to edit the imported type to change it.", MessageDialog.WARNING); continue; } // guaranteed to have local type def here localTd.setSupertypeName(newTypeName); if (isImportedType(typeName)) { remergeNeeded = true; refreshNeeded = true; } else { td.setSupertypeName(newTypeName); updateGuiType(tt.getItems()[i], td); } } FeatureDescription fds[] = td.getFeatures(); FeatureDescription localFds[] = (null == localTd) ? null : localTd.getFeatures(); if (null != fds) { for (int j = 0; j < fds.length; j++) { FeatureDescription fd = fds[j]; if (oldTypeName.equals(fd.getRangeTypeName())) { if (warnAndSkipIfImported(typeName)) continue; // skipped if feature not present in local td, or no local td. setNamedFeatureDescriptionRange(localFds, fd.getName(), newTypeName); if (isImportedType(typeName)) { remergeNeeded = true; refreshNeeded = true; } else { fd.setRangeTypeName(newTypeName); updateGuiFeature(tt.getItems()[i].getItems()[j], fd, td); } } } } } if (remergeNeeded) rebuildMergedTypeSystem(); return refreshNeeded; } // this function to set the corresponding feature in the "local" type's fd array private void setNamedFeatureDescriptionRange(FeatureDescription[] localFds, String featureName, final String rangeName) { if (null != localFds) { for (int i = 0; i < localFds.length; i++) { FeatureDescription fd = localFds[i]; if (fd.getName().equals(featureName)) { fd.setRangeTypeName(rangeName); return; } } } } private boolean warnAndSkipIfImported(String typeName) { if (isLocalType(typeName)) { if (isImportedType(typeName)) { Utility .popMessage( "Imported type won't be changed", "There is both a local and imported version of type, '" + typeName + "', which has a feature whose range type is the item being renamed. Although the local version will be updated, but the imported one won't." + "This may cause an error when you save.", MessageDialog.WARNING); } return false; } else { // is not a local type Utility .popMessage( "Imported feature range not changed", "There is an imported type, '" + typeName + "', which has a a feature whose range which is the item being renamed. It won't be updated - this may cause an error when you save this descriptor." + " If it does, you will need to edit the imported type to change it.", MessageDialog.WARNING); return true; } } private void alterTypeMentions(final String sOldTypeName, final String sNewTypeName) { if (sOldTypeName.equals(sNewTypeName) || (!isLocalProcessingDescriptor())) return; // update types (which are locally editable) // that reference the old type name, either as // ranges of features or // supertype final boolean[] capabilityChanged = new boolean[1]; capabilityChanged[0] = false; final String oldTypeName_colon = sOldTypeName + ':'; CapabilityVisitor cv = new CapabilityVisitor() { boolean visit(TypeOrFeature i_o) { if (i_o.isType() && i_o.getName().equals(sOldTypeName)) { capabilityChanged[0] = true; i_o.setName(sNewTypeName); } else if (!i_o.isType() && i_o.getName().startsWith(oldTypeName_colon)) { capabilityChanged[0] = true; i_o.setName(sNewTypeName + ':' + i_o.getName().substring(oldTypeName_colon.length())); } return false; } }; capabilityVisit(cv); if (capabilityChanged[0]) if (null != editor.getCapabilityPage()) editor.getCapabilityPage().markStale(); FsIndexCollection indexCollection = getAnalysisEngineMetaData().getFsIndexCollection(); FsIndexDescription[] indexes = (null == indexCollection) ? null : indexCollection .getFsIndexes(); boolean somethingChanged = false; boolean markStale = false; if (indexes != null) { for (int i = 0; i < indexes.length; i++) { if (indexes[i].getTypeName().equals(sOldTypeName)) { indexes[i].setTypeName(sNewTypeName); somethingChanged = true; } } } if (somethingChanged) { markStale = true; try { editor.setMergedFsIndexCollection(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("unexpected exception"); } } // interesting use case not handled: // changing a type name to another type name which // already exists (in an import). if (typePriorityListsVisit(UPDATE_TYPE_NAME, sOldTypeName, sNewTypeName)) { markStale = true; try { editor.setMergedTypePriorities(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("unexpected exception"); } } if (markStale) { editor.getIndexesPage().markStale(); } } private boolean isFeatureUsedInIndex(TypeDescription td, String featureName) { return isFeatureUsedInIndex(td.getName() + ":" + featureName); } private boolean isFeatureUsedInIndex(String fullFeatureName) { if (!isLocalProcessingDescriptor()) { return false; } FsIndexCollection indexCollection = editor.getMergedFsIndexCollection(); FsIndexDescription[] fsid = (null == indexCollection) ? null : indexCollection.getFsIndexes(); if (null != fsid) { for (int i = 0; i < fsid.length; i++) { FsIndexKeyDescription[] keys = fsid[i].getKeys(); if (null != keys) { for (int j = 0; j < keys.length; j++) { if (keys[j].getFeatureName().equals(fullFeatureName)) return true; } } } } return false; } private boolean isFeatureInUseElsewhere(TypeDescription td, String featureName) { return isFeatureInUseElsewhere(td.getName() + ':' + featureName); } private boolean isFeatureInUseElsewhere(final String typePlusFeature) { if (!isLocalProcessingDescriptor()) { // not strictly true for imports.... return false; } CapabilityVisitor v = new CapabilityVisitor() { boolean visit(TypeOrFeature i_o) { if ((!i_o.isType()) && i_o.getName().equals(typePlusFeature)) { return true; } return false; } }; if (capabilityVisit(v)) return true; return isFeatureUsedInIndex(typePlusFeature); } private abstract class CapabilityVisitor { abstract boolean visit(TypeOrFeature i_o); } private boolean capabilityVisit(CapabilityVisitor v) { Capability[] c = getCapabilities(); for (int ic = 0; ic < c.length; ic++) { TypeOrFeature[] inputs = c[ic].getInputs(); for (int i = 0; i < inputs.length; i++) { if (v.visit(inputs[i])) return true; } TypeOrFeature[] outputs = c[ic].getOutputs(); for (int i = 0; i < outputs.length; i++) { if (v.visit(outputs[i])) return true; } } return false; } private void alterFeatureMentions(final String sOldFeatureName, final String sNewFeatureName, final String typeName) { final boolean[] somethingChanged = new boolean[1]; somethingChanged[0] = false; if (sOldFeatureName.equals(sNewFeatureName) || (!isLocalProcessingDescriptor())) return; final String oldFullFeatureName = typeName + ':' + sOldFeatureName; final String newFullFeatureName = typeName + ':' + sNewFeatureName; CapabilityVisitor v = new CapabilityVisitor() { boolean visit(TypeOrFeature i_o) { if (!i_o.isType() && i_o.getName().equals(oldFullFeatureName)) { somethingChanged[0] = true; i_o.setName(newFullFeatureName); } return false; } }; capabilityVisit(v); if (somethingChanged[0]) if (null != editor.getCapabilityPage()) editor.getCapabilityPage().markStale(); somethingChanged[0] = false; FsIndexDescription[] fsid = getAnalysisEngineMetaData().getFsIndexes(); if (null != fsid) { for (int i = 0; i < fsid.length; i++) { if (typeName.equals(fsid[i].getTypeName())) { FsIndexKeyDescription[] keys = fsid[i].getKeys(); if (null != keys) { for (int j = 0; j < keys.length; j++) { if (keys[j].getFeatureName().equals(sOldFeatureName)) { somethingChanged[0] = true; keys[j].setFeatureName(sNewFeatureName); } } } } } } if (somethingChanged[0]) { try { editor.setMergedFsIndexCollection(); // overkill } catch (ResourceInitializationException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (null != editor.getIndexesPage()) editor.getIndexesPage().markStale(); } } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SettingsPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SettingsP0000644000175000017500000000406011665471220033455 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; public class SettingsPage extends HeaderPageWithSash { private ParameterSettingsSection parameterSettingsSection; private ValueSection valueSection; public SettingsPage(MultiPageEditor editor) { super(editor, "Parameter Value Settings"); } /** * Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { final Form2Panel form2Panel = setup2ColumnLayout(managedForm, EQUAL_WIDTH); managedForm.getForm().setText("Parameter Settings"); managedForm.addPart(parameterSettingsSection = new ParameterSettingsSection(editor, form2Panel.left)); managedForm.addPart(valueSection = new ValueSection(editor, form2Panel.right)); createToolBarActions(managedForm); } /** * @return */ public ParameterSettingsSection getParameterSettingsSection() { return parameterSettingsSection; } /** * @return */ public ValueSection getValueSection() { return valueSection; } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPag0000644000175000017500000002512411665471220033361 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.forms.AbstractFormPart; import org.eclipse.ui.forms.IFormPart; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.ManagedForm; import org.eclipse.ui.forms.editor.FormPage; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; /** * Common part of most pages */ public abstract class HeaderPage extends FormPage { final public static boolean EQUAL_WIDTH = true; protected SashForm sashForm; protected MultiPageEditor editor; protected FormToolkit toolkit; protected Composite leftPanel; protected Composite rightPanel; protected int sashFormWidth; protected float leftPanelPercent; protected float rightPanelPercent; protected int leftPanelWidth; protected int rightPanelWidth; public HeaderPage(MultiPageEditor formEditor, String id, String keyPageTitle) { super(formEditor, id, keyPageTitle); editor = formEditor; toolkit = editor.getToolkit(); } public HeaderPage(MultiPageEditor formEditor, String pageTitle) { this(formEditor, "UID_" + pageTitle, pageTitle); } protected void maybeInitialize(IManagedForm managedForm) { if (TAEConfiguratorPlugin.is30version) ((ManagedForm) managedForm).initialize(); } /* * General methods to create sub areas on pages */ public Composite newComposite(Composite parent) { return newnColumnSection(parent, 1); } // this composite spans col 1 & 2, out of a 4 column (0, 1, 2, 3) grid layout public Composite newCentered2SpanComposite(Composite parent) { spacer(parent); // skip over col 0 Composite composite = newComposite(parent); ((GridData) composite.getLayoutData()).horizontalSpan = 2; return composite; } public Composite newnColumnSection(Composite parent, int cols) { Composite section = toolkit.createComposite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = cols; layout.marginHeight = 0; layout.marginWidth = 0; section.setLayout(layout); section.setLayoutData(new GridData(GridData.FILL_BOTH)); return section; } public Composite setup1ColumnLayout(IManagedForm managedForm) { final ScrolledForm sform = managedForm.getForm(); final Composite form = sform.getBody(); form.setLayout(new GridLayout(1, false)); // this is required ! Composite xtra = toolkit.createComposite(form); xtra.setLayout(new GridLayout(1, false)); xtra.setLayoutData(new GridData(GridData.FILL_BOTH)); Control c = form.getParent(); while (!(c instanceof ScrolledComposite)) c = c.getParent(); ((GridData) xtra.getLayoutData()).widthHint = c.getSize().x; return xtra; } // this method creates no new composites. public Composite setup2ColumnGrid(IManagedForm managedForm, boolean equalWidth) { final ScrolledForm sform = managedForm.getForm(); final Composite form = sform.getBody(); GridLayout layout = new GridLayout(2, equalWidth); form.setLayout(layout); form.setLayoutData(new GridData(GridData.FILL_BOTH)); return form; } public Form2Panel setup2ColumnLayout(IManagedForm managedForm, int w1, int w2) { final ScrolledForm sform = managedForm.getForm(); final Composite form = sform.getBody(); form.setLayout(new GridLayout(1, false)); // this is required ! Composite xtra = toolkit.createComposite(form); xtra.setLayout(new GridLayout(1, false)); xtra.setLayoutData(new GridData(GridData.FILL_BOTH)); Control c = xtra.getParent(); while (!(c instanceof ScrolledComposite)) c = c.getParent(); ((GridData) xtra.getLayoutData()).widthHint = c.getSize().x; ((GridData) xtra.getLayoutData()).heightHint = c.getSize().y; sashForm = new SashForm(xtra, SWT.HORIZONTAL); sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); // needed leftPanel = newComposite(sashForm); ((GridLayout) leftPanel.getLayout()).marginHeight = 5; ((GridLayout) leftPanel.getLayout()).marginWidth = 5; rightPanel = newComposite(sashForm); ((GridLayout) rightPanel.getLayout()).marginHeight = 5; ((GridLayout) rightPanel.getLayout()).marginWidth = 5; sashForm.setWeights(new int[] { w1, w2 }); leftPanelPercent = (float) w1 / (float) (w1 + w2); rightPanelPercent = (float) w2 / (float) (w1 + w2); rightPanel.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent e) { setSashFormWidths(); } }); return new Form2Panel(form, leftPanel, rightPanel); } void setSashFormWidths() { sashFormWidth = sashForm.getSize().x; int[] ws = sashForm.getWeights(); leftPanelWidth = (int) (((float) ws[0] / (float) (ws[0] + ws[1])) * sashFormWidth); rightPanelWidth = (int) (((float) ws[1] / (float) (ws[0] + ws[1])) * sashFormWidth); } /** * Sash impl * * @param managedForm * @param equalWidth * @return */ public Form2Panel setup2ColumnLayout(IManagedForm managedForm, boolean equalWidth) { if (equalWidth) return setup2ColumnLayout(managedForm, 50, 50); else // a hack - based on first column more likely being wider return setup2ColumnLayout(managedForm, 60, 40); } public Form2Panel setup2ColumnLayoutNotSash(IManagedForm managedForm, boolean equalWidth) { final ScrolledForm sform = managedForm.getForm(); final Composite form = sform.getBody(); GridLayout layout = new GridLayout(2, equalWidth); form.setLayout(layout); form.setLayoutData(new GridData(GridData.FILL_BOTH)); leftPanel = newComposite(form); rightPanel = newComposite(form); // strategy for setting size hints of right and left panels // Why set hints? Because they make the inner containing things // scroll horiz. if they're too wide (useful for aggregates having // long names). // What hint to set? The hint should be the smallest size you want // with child scrolling, before the tabbed page container itself // gets a scroll bar. // When in the life cycle to do this? Only need to do it once, but // after the Grid Layout has happened. This can be the first resizing // event (learned this by debugging) sform.addListener(SWT.Resize, new Listener() { public void handleEvent(Event event) { float col1CurrentWidth = leftPanel.getSize().x; float col2CurrentWidth = rightPanel.getSize().x; final int minLeftPanelWidth = 250; // in pels final int minRightPanelWidth = (int) (col2CurrentWidth * minLeftPanelWidth / col1CurrentWidth); ((GridData) leftPanel.getLayoutData()).widthHint = minLeftPanelWidth; ((GridData) rightPanel.getLayoutData()).widthHint = minRightPanelWidth; sform.removeListener(SWT.Resize, this); // only do this one time } }); return new Form2Panel(form, leftPanel, rightPanel); } public Form2Panel setup2ColumnLayoutOn4Grid(IManagedForm managedForm, boolean equalWidth) { Form2Panel f = setup2ColumnLayoutNotSash(managedForm, equalWidth); ((GridLayout) f.form.getLayout()).numColumns = 4; ((GridData) f.left.getLayoutData()).horizontalSpan = 2; ((GridData) f.right.getLayoutData()).horizontalSpan = 2; return f; } protected void spacer(Composite container) { toolkit.createLabel(container, " "); } public void markStale() { if (getManagedForm() != null) { IFormPart[] parts = getManagedForm().getParts(); for (int i = 0; i < parts.length; i++) { ((AbstractFormPart) parts[i]).markStale(); } } } // ************************************************** // * Model Access // ************************************************** protected boolean isPrimitive() { return editor.getAeDescription().isPrimitive(); } protected boolean isAeDescriptor() { return editor.isAeDescriptor(); } public boolean isTypeSystemDescriptor() { return editor.isTypeSystemDescriptor(); } public boolean isIndexDescriptor() { return editor.isFsIndexCollection(); } public boolean isTypePriorityDescriptor() { return editor.isTypePriorityDescriptor(); } public boolean isExtResAndBindingsDescriptor() { return editor.isExtResAndBindingsDescriptor(); } public boolean isCollectionReaderDescriptor() { return editor.isCollectionReaderDescriptor(); } public boolean isCasInitializerDescriptor() { return editor.isCasInitializerDescriptor(); } public boolean isCasConsumerDescriptor() { return editor.isCasConsumerDescriptor(); } public boolean isLocalProcessingDescriptor() { return editor.isLocalProcessingDescriptor(); } protected AnalysisEngineMetaData getAnalysisEngineMetaData() { return editor.getAeDescription().getAnalysisEngineMetaData(); } // ************************************************** // * Common Actions in Handlers // ************************************************** } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourcesPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Resources0000644000175000017500000000534411665471220033515 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; public class ResourcesPage extends HeaderPageWithSash { private ResourceDependencySection resourceDependencySection; // private ExternalResourceSection externalResourceSection; private ExtnlResBindSection extnlResBindSection; private ImportResBindSection resBindImportSection; public ResourcesPage(MultiPageEditor editor) { super(editor, "Resource Definitions and Bindings"); } /** * Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { // Only primitive engines can declare Resource Dependencies // Both Primitive and aggregates can delcare External Resources and their bindings // Bindings always refer to a primitive, if needed via // annotatorkey / key / key ... / declaredDependencyName // Bindings for same dependencyName at multiple levels: // outer ones override inner ones. managedForm.getForm().setText("Resources"); Form2Panel form2panel = setup2ColumnLayout(managedForm, 50, 50); managedForm.addPart(extnlResBindSection = new ExtnlResBindSection(editor, form2panel.left)); managedForm.addPart(resBindImportSection = new ImportResBindSection(editor, form2panel.left)); managedForm.addPart(resourceDependencySection = new ResourceDependencySection(editor, form2panel.right)); createToolBarActions(managedForm); } public ResourceDependencySection getResourceDependencySection() { return resourceDependencySection; } public ExtnlResBindSection getResourceBindingsSection() { return extnlResBindSection; } public ImportResBindSection getResBindImportSection() { return resBindImportSection; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractS0000644000175000017500000016076611665471220033443 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.TreeSet; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngine; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.analysis_engine.metadata.SofaMapping; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ExternalResourceDependency; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.PearSpecifier; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.FsIndexKeyDescription; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.resource.metadata.OperationalProperties; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.Import_impl; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.StandardStrings; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor; import org.apache.uima.taeconfigurator.model.BuiltInTypes; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLParser; import org.apache.uima.util.XMLizable; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.custom.PopupList; import org.eclipse.swt.custom.TableTree; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.swt.widgets.Widget; import org.eclipse.ui.forms.AbstractFormPart; import org.eclipse.ui.forms.IFormPart; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.SectionPart; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; public abstract class AbstractSection extends SectionPart /* extends FormSection */ implements Listener, StandardStrings { protected FormToolkit toolkit; public MultiPageEditor editor; public FormToolkit getToolkit() { return toolkit; } public final static String IMPORTABLE_PART_CONTEXT = "ipc"; public final static String PLUGIN_ID = "org.apache.uima.desceditor"; public final static boolean SELECTED = true; public final static boolean NOT_SELECTED = false; public final static boolean ENABLED = true; public final static boolean EQUAL_WIDTH = true; public final static TreeItem[] treeItemArray0 = new TreeItem[0]; public final static ConfigurationGroup[] configurationGroup0 = new ConfigurationGroup[0]; public final static ConfigurationParameter[] configurationParameter0 = new ConfigurationParameter[0]; public final static Capability[] capabilityArray0 = new Capability[0]; public final static FeatureDescription[] featureDescriptionArray0 = new FeatureDescription[0]; public final static SofaMapping[] sofaMapping0 = new SofaMapping[0]; public final static FsIndexDescription[] fsIndexDescription0 = new FsIndexDescription[0]; public final static ExternalResourceBinding[] externalResourceBinding0 = new ExternalResourceBinding[0]; public final static ExternalResourceDescription[] externalResourceDescription0 = new ExternalResourceDescription[0]; public final static TypeDescription[] typeDescription0 = new TypeDescription[0]; public final static TypePriorityList[] typePriorityList0 = new TypePriorityList[0]; protected int initialFormWidth; // width of the form before putting controls in it public AbstractSection(MultiPageEditor aEditor, Composite parent, String headerText, String description) { super(parent, aEditor.getToolkit(), ((null != description) ? Section.DESCRIPTION : 0) | Section.TWISTIE | Section.EXPANDED); toolkit = aEditor.getToolkit(); getSection().setText(headerText); getSection().setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); toolkit.createCompositeSeparator(getSection()); if (null != description) getSection().setDescription(description); editor = aEditor; } public void initialize(IManagedForm form) { super.initialize(form); getSection().setLayoutData(new GridData(GridData.FILL_BOTH)); } // ************************************************** // * Subclasses need to implement these methods // ************************************************** public abstract void enable(); // ************************************************** // * convenience methods // ************************************************** protected void setFileDirty() { editor.setFileDirty(); } // ************************************************** // * Creating Composites // ************************************************** public Composite newComposite(Composite parent) { return newNcolumnComposite(parent, 1); } public Composite new2ColumnComposite(Composite parent) { return newNcolumnComposite(parent, 2); } public Composite new3ColumnComposite(Composite parent) { return newNcolumnComposite(parent, 3); } public Composite new4ColumnComposite(Composite parent) { return newNcolumnComposite(parent, 4); } public Composite newNcolumnComposite(Composite parent, int cols) { Composite composite = toolkit.createComposite(parent); if (parent instanceof ExpandableComposite) ((ExpandableComposite) parent).setClient(composite); GridLayout layout = new GridLayout(cols, !EQUAL_WIDTH); layout.marginHeight = 0; layout.marginWidth = 0; composite.setLayout(layout); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); return composite; } public void setMargins(Composite composite, int height, int width) { GridLayout g = (GridLayout) composite.getLayout(); g.marginHeight = height; g.marginWidth = width; } public void enableBorders(Composite composite) { GridLayout g = (GridLayout) composite.getLayout(); if (g.marginHeight < 2) g.marginHeight = 2; if (g.marginWidth < 1) g.marginWidth = 1; } // ************************************************** // * Special Composites to hold buttons // ************************************************** final static public int VERTICAL_BUTTONS = 1; final static public int HORIZONTAL_BUTTONS = 2; public Composite newButtonContainer(Composite parent) { return newButtonContainer(parent, VERTICAL_BUTTONS, 0); } public Composite newButtonContainer(Composite parent, int style, int widthMin) { Composite buttonContainer = toolkit.createComposite(parent); GridLayout gl = new GridLayout(); GridData gd = null; switch (style) { case VERTICAL_BUTTONS: gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); gd.horizontalAlignment = SWT.FILL; // gd.widthHint = widthMin; // 70, 100 break; case HORIZONTAL_BUTTONS: gl.marginWidth = 20; gl.numColumns = 2; gl.makeColumnsEqualWidth = true; gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER); gd.widthHint = widthMin; // 180 } buttonContainer.setLayout(gl); buttonContainer.setLayoutData(gd); return buttonContainer; } // public Composite newLabeledButtonContainer(Composite parent, int cellsToSpan, int nbrCols) { // Composite buttonContainer = toolkit.createComposite(parent); // GridLayout gl = new GridLayout(); // GridData gd = null; // gl.marginWidth = 0; // gl.numColumns = nbrCols; // gl.makeColumnsEqualWidth = false; // gd = new GridData(); // gd.horizontalSpan = cellsToSpan; // buttonContainer.setLayout(gl); // buttonContainer.setLayoutData(gd); // return buttonContainer; // } // ************************************************** // * Getting internationalized text // ************************************************** // ************************************************** // * Widgets // ************************************************** protected Text newLabeledTextField(Composite parent, String label, String tip) { return newLabeledTextField(parent, label, tip, SWT.NONE); } protected Text newLabeledTextField(Composite parent, String labelKey, String textToolTip, int style) { enableBorders(parent); Label label = toolkit.createLabel(parent, labelKey); label.setToolTipText(textToolTip); if ((style & SWT.V_SCROLL) == SWT.V_SCROLL) { label.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); } return newTextWithTip(parent, "", style, textToolTip); //$NON-NLS-1$ } protected Text newTextWithTip(Composite parent, String initialTxt, String tip) { return newTextWithTip(parent, initialTxt, SWT.NONE, tip); } protected Text newTextWithTip(Composite parent, String text, int style, String tip) { Text t = toolkit.createText(parent, text, style); t.setToolTipText(tip); if ((style & SWT.V_SCROLL) == SWT.V_SCROLL) { t.setLayoutData(new GridData(GridData.FILL_BOTH)); } else { t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); } addListenerForPastableWidget(t); return t; } public Label newLabelWithData(Composite parent, String text) { return newLabelWithTip(parent, text, ""); //$NON-NLS-1$ } public Label newLabelWithTip(Composite parent, String text, String tip) { return newLabelWithTip(parent, text, tip, SWT.NULL); } public Label newUnUpdatableTextWithTip(Composite parent, String text, String tip) { Label label = newLabelWithTip(parent, text, tip, SWT.BORDER); label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); return label; } public Label newLabelWithTip(Composite parent, String text, String tip, int style) { Label t = toolkit.createLabel(parent, text, style); if ((tip != null) && (tip.length()) > 0) t.setToolTipText(tip); return t; } protected CCombo newLabeledCComboWithTip(Composite parent, String labelKey, String tip) { newLabelWithTip(parent, labelKey, tip); return newCComboWithTip(parent, tip); } protected CCombo newCComboWithTip(Composite parent, String tip) { CCombo ccombo = new CCombo(parent, SWT.FLAT | SWT.READ_ONLY); toolkit.adapt(ccombo, false, false); ccombo.setToolTipText(tip); ccombo.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); ccombo.addListener(SWT.Selection, this); // Make the CCombo's border visible since CCombo is NOT a widget supported // by FormToolkit. // needed apparently by RedHat Linux ccombo.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); return ccombo; } protected Text newDescriptionTextBox(Composite parent, String tip) { return newLabeledTextField(parent, S_DESCRIPTION, tip, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL); } // ************************************************** // * Widgets Buttons // ************************************************** public Button newRadioButton(Composite parent, String label, String toolTip, boolean selected) { Button button = toolkit.createButton(parent, label, SWT.RADIO); button.setToolTipText(toolTip); button.setSelection(selected); button.addListener(SWT.Selection, this); return button; } /** * add pushbutton to container, set enabled, add listener for it * * @param parent * @param root * @return */ public Button newPushButton(Composite parent, String label, String tip) { return newPushButton(parent, label, tip, true); // set enabled by default } /** * Add a push button to a container, add a listener for it too * * @param parent * @param root * @param enabled * @return */ public Button newPushButton(Composite parent, String label, String tip, boolean enabled) { return newPushButton(parent, label, tip, enabled, 0); } public Button newPushButton(Composite parent, String label, String tip, boolean enabled, int style) { Button button = toolkit.createButton(parent, label, SWT.PUSH | style); GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL); button.setLayoutData(gd); button.pack(false); button.setToolTipText(tip); button.setEnabled(enabled); button.addListener(SWT.Selection, this); Point buttonSize = button.getSize(); gd.heightHint = buttonSize.y - 2; gd.widthHint = buttonSize.x - 2; return button; } public Button newCheckBox(Composite parent, String label, String tip) { Button button = toolkit.createButton(parent, label, SWT.CHECK); button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL)); button.pack(); button.setToolTipText(tip); button.addListener(SWT.Selection, this); return button; } public static void spacer(Composite container) { Label label = new Label(container, SWT.NONE); label.setVisible(false); // toolkit.createLabel(container, " "); } // ************************************************** // * Tables // ************************************************** final public static int NO_MIN_HEIGHT = -1; final public static int NOTHING_SELECTED = -1; // these flags can be or-ed together final public static int LINES_VISIBLE = 1; final public static int HEADER_VISIBLE = 2; final public static int WIDTH_NOT_SPECIFIED = 0; protected Table newTable(Composite parent) { return newTable(parent, SWT.FULL_SELECTION, NO_MIN_HEIGHT, 0); } protected Table newTable(Composite parent, int style, int minHeight) { return newTable(parent, style, minHeight, 0); } protected Table newTable(Composite parent, int style, int minHeight, int flags) { Table table = toolkit.createTable(parent, style); GridData gd = new GridData(GridData.FILL_BOTH); if (minHeight != NO_MIN_HEIGHT) gd.heightHint = minHeight; table.setLayoutData(gd); table.setLinesVisible(0 != (flags & LINES_VISIBLE)); table.setHeaderVisible(0 != (flags & HEADER_VISIBLE)); table.addListener(SWT.Selection, this); table.addListener(SWT.KeyUp, this); // delete key return table; } protected Tree newTree(Composite parent) { Tree tree = toolkit.createTree(parent, SWT.SINGLE); tree.setLayoutData(new GridData(GridData.FILL_BOTH)); tree.addListener(SWT.Selection, this); tree.addListener(SWT.KeyUp, this); return tree; } protected TreeItem getPreviousSelection(TreeItem[] items, TreeItem nextItem) { TreeItem prevItem = nextItem.getParentItem(); for (int i = 0; i < items.length; i++) { if (nextItem == items[i]) return prevItem; prevItem = items[i]; } return prevItem; } protected int getItemIndex(TreeItem[] items, TreeItem item) { for (int i = 0; i < items.length; i++) { if (items[i] == item) return i; } return -1; } /** * @param parent * @param style * SWT.SINGLE SWT.MULTI SWT.CHECK SWT.FULL_SELECTION * @return */ protected TableTree newTableTree(Composite parent, int style) { TableTree tt = new TableTree(parent, style); tt.setLayoutData(new GridData(GridData.FILL_BOTH)); toolkit.adapt(tt, true, true); tt.addListener(SWT.Selection, this); tt.getTable().addListener(SWT.KeyUp, this); // for delete key tt.getTable().addListener(SWT.MouseDoubleClick, this); // for edit tt.addListener(SWT.Expand, this); tt.addListener(SWT.Collapse, this); // Make the TableTree's border visible since TableTree is NOT a widget supported // by FormToolkit. Needed by RedHat Linux tt.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); return tt; } public void packTable(Table table) { TableColumn[] columns = table.getColumns(); for (int i = 0; i < columns.length; i++) { columns[i].pack(); } } public static int getIndex(TableItem item) { Table parent = item.getParent(); TableItem[] items = parent.getItems(); for (int i = items.length - 1; i >= 0; i--) { if (items[i] == item) return i; } throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$ } public static int getIndex(TableTreeItem item) { TableTreeItem parent = item.getParentItem(); TableTreeItem[] items = (null == parent) ? item.getParent().getItems() : parent.getItems(); for (int i = items.length - 1; i >= 0; i--) { if (items[i] == item) return i; } throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$ } protected void removeChildren(TableTreeItem item) { TableTreeItem[] items = item.getItems(); if (null != items) for (int i = 0; i < items.length; i++) { items[i].dispose(); } } protected void removeChildren(TreeItem item) { TreeItem[] items = item.getItems(); if (null != items) for (int i = 0; i < items.length; i++) { items[i].dispose(); } } // ********************************** // * Table Column with header setting // ********************************** protected TableColumn newTableColumn(Table table) { return newTableColumn(table, ""); //$NON-NLS-1$ } protected TableColumn newTableColumn(Table container, String header) { return newTableColumn(container, 50, SWT.LEFT, header); } protected TableColumn newTableColumn(Table container, int width, int alignment, String header) { TableColumn tc = new TableColumn(container, alignment); if (header != null && (!header.equals(""))) { //$NON-NLS-1$ tc.setText(header); } tc.setWidth(width); return tc; } protected TableColumn newTableColumn(Table container, int width) { return newTableColumn(container, width, SWT.LEFT, Messages.getString("AbstractSection.0")); //$NON-NLS-1$ } // ************************************************** // * Model Access // ************************************************** public boolean isPrimitive() { return editor.isPrimitive(); } public boolean isAggregate() { return editor.isAggregate(); } public boolean isAeDescriptor() { return editor.isAeDescriptor(); } public boolean isTypeSystemDescriptor() { return editor.isTypeSystemDescriptor(); } public boolean isIndexDescriptor() { return editor.isFsIndexCollection(); } public boolean isTypePriorityDescriptor() { return editor.isTypePriorityDescriptor(); } public boolean isExtResAndBindingsDescriptor() { return editor.isExtResAndBindingsDescriptor(); } public boolean isCollectionReaderDescriptor() { return editor.isCollectionReaderDescriptor(); } public boolean isCasInitializerDescriptor() { return editor.isCasInitializerDescriptor(); } public boolean isCasConsumerDescriptor() { return editor.isCasConsumerDescriptor(); } public boolean isFlowControllerDescriptor() { return editor.isFlowControllerDescriptor(); } public boolean isLocalProcessingDescriptor() { return editor.isLocalProcessingDescriptor(); } public AnalysisEngineMetaData getAnalysisEngineMetaData() { return editor.getAeDescription().getAnalysisEngineMetaData(); } public FlowControllerDeclaration getFlowControllerDeclaration() { return editor.getAeDescription().getFlowControllerDeclaration(); } public void setFlowControllerDeclaration(FlowControllerDeclaration fcd) { editor.getAeDescription().setFlowControllerDeclaration(fcd); } public OperationalProperties getOperationalProperties() { return editor.getAeDescription().getAnalysisEngineMetaData().getOperationalProperties(); } public SofaMapping[] getSofaMappings() { SofaMapping[] sofaMappings = editor.getAeDescription().getSofaMappings(); return null == sofaMappings ? sofaMapping0 : sofaMappings; } public static SofaMapping[] getSofaMappings(MultiPageEditor pEditor) { SofaMapping[] sofaMappings = pEditor.getAeDescription().getSofaMappings(); return null == sofaMappings ? sofaMapping0 : sofaMappings; } public Map getDelegateAnalysisEngineSpecifiersWithImports() { return editor.getAeDescription().getDelegateAnalysisEngineSpecifiersWithImports(); } public Capability[] getCapabilities() { Capability[] c = getAnalysisEngineMetaData().getCapabilities(); if (null == c) return capabilityArray0; return c; } protected TypeSystemDescription getMergedTypeSystemDescription() { return editor.getMergedTypeSystemDescription(); } protected TypeSystemDescription getTypeSystemDescription() { return editor.getTypeSystemDescription(); } protected TypePriorities getTypePriorities() { TypePriorities tps = getAnalysisEngineMetaData().getTypePriorities(); if (null == tps) { getAnalysisEngineMetaData().setTypePriorities( tps = UIMAFramework.getResourceSpecifierFactory().createTypePriorities()); } return tps; } public final static String[] stringArray0 = new String[0]; public final static ConfigurationParameter[] configurationParameterArray0 = new ConfigurationParameter[0]; public final static ConfigurationGroup[] configurationGroupArray0 = new ConfigurationGroup[0]; public final static NameValuePair[] nameValuePairArray0 = new NameValuePair[0]; public String[] getAvailableTypeNames(Set excluded) { Map allTypes = editor.allTypes.get(); Collection availableTypes = new ArrayList(); Iterator it = allTypes.keySet().iterator(); while (it.hasNext()) { String item = (String) it.next(); if (!excluded.contains(item)) availableTypes.add(item); } return (String[]) availableTypes.toArray(stringArray0); } // ************ // * Parameters // ************ public boolean isParmGroup() { ConfigurationParameterDeclarations lcpd = getAnalysisEngineMetaData() .getConfigurationParameterDeclarations(); return (lcpd.getCommonParameters() != null && lcpd.getCommonParameters().length > 0) || (lcpd.getConfigurationGroups() != null && lcpd.getConfigurationGroups().length > 0); } public ConfigurationParameterDeclarations getConfigurationParameterDeclarations() { return editor.getAeDescription().getAnalysisEngineMetaData() .getConfigurationParameterDeclarations(); } // ************************************************** // * Common GUI state access // ************************************************** public ResourceManagerConfiguration getResourceManagerConfiguration() { ResourceManagerConfiguration rmc = editor.getAeDescription().getResourceManagerConfiguration(); if (null == rmc) { rmc = UIMAFramework.getResourceSpecifierFactory().createResourceManagerConfiguration(); editor.getAeDescription().setResourceManagerConfiguration(rmc); } return rmc; } public ExternalResourceDependency[] getExternalResourceDependencies() { ExternalResourceDependency[] erd = editor.getAeDescription().getExternalResourceDependencies(); if (null == erd) { return new ExternalResourceDependency[0]; } return erd; } public ExternalResourceBinding[] getExternalResourceBindings() { ExternalResourceBinding[] erb = getResourceManagerConfiguration().getExternalResourceBindings(); if (null == erb) getResourceManagerConfiguration().setExternalResourceBindings( erb = new ExternalResourceBinding[0]); return erb; } public ExternalResourceDescription[] getExternalResources() { ExternalResourceDescription[] erd = getResourceManagerConfiguration().getExternalResources(); if (null == erd) getResourceManagerConfiguration().setExternalResources( erd = new ExternalResourceDescription[0]); return erd; } // ************************************************** // * Common Listener things // ************************************************** protected void addListenerForPastableWidget(Widget w) { w.addListener(SWT.KeyUp, this); w.addListener(SWT.MouseUp, this); // for paste operation } // ************************************************** // * Common Actions in Handlers // ************************************************** protected boolean valueChanged; protected String setValueChanged(String newValue, String oldValue) { if (null == newValue) valueChanged = valueChanged || (null == oldValue); else if (!newValue.equals(oldValue)) valueChanged = true; return newValue; } protected int setValueChangedInt(int newValue, int oldValue) { if (newValue != oldValue) valueChanged = true; return newValue; } protected boolean setValueChangedBoolean(boolean newValue, boolean oldValue) { if (newValue != oldValue) valueChanged = true; return newValue; } protected Boolean setValueChangedCapitalBoolean(Boolean newValue, Boolean oldValue) { if (null == newValue) { valueChanged |= null != oldValue; } else if (null == oldValue) { valueChanged = true; } else if (newValue.booleanValue() != oldValue.booleanValue()) valueChanged = true; return newValue; } protected FsIndexKeyDescription[] setValueChangedKeys(FsIndexKeyDescription[] newKeys, FsIndexKeyDescription[] oldKeys) { if (valueChanged) { } else if (oldKeys == null && newKeys == null) { } else if (oldKeys != null && Arrays.equals(oldKeys, newKeys)) { } else if (Arrays.equals(newKeys, oldKeys)) // newKeys must be non-null here { } else valueChanged = true; return newKeys; } protected boolean isValidAe() { if (editor.isValidAE(editor.getAeDescription())) return true; return false; } protected void revertTypeSystem(TypeSystemDescription tsd) { try { editor.setTypeSystemDescription(tsd); } catch (ResourceInitializationException e) { } } protected void revertMsg(String msgTitle, String msgTxt, String exceptionMessage) { Utility.popMessage(msgTitle, msgTxt + "\r\n" + exceptionMessage, //$NON-NLS-1$ MessageDialog.ERROR); return; } /** * * @param msg * @param msgDetails * @return true to revert, false to continue */ public static boolean revertOrContinue(String msg, String msgDetails) { if (Window.CANCEL == Utility.popMessage(msg, msgDetails + "\nDo you want to continue, or Abort the last action?", MessageDialog.QUESTION, new String[] { "Continue", "Abort" })) return true; // for closing the window or hitting Undo return false; } public void markStale(IFormPart section) { if (section != null) ((AbstractFormPart) section).markStale(); } protected void markRestOfPageStale(IManagedForm mform, AbstractSection section) { if (null == mform) return; IFormPart[] parts = mform.getParts(); for (int i = 0; i < parts.length; i++) { markStaleIfDifferent(section, parts[i]); } } protected void markStaleIfDifferent(IFormPart thisOne, IFormPart otherOne) { if (thisOne != otherOne) markStale(otherOne); } protected String multiLineFix(String s) { if (null == s) return null; return s.replaceAll("\\r\\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ } /************************************************************************************************* * Augment arrays (make new array, add one item to it at end * ********************************************************* */ public String[] stringArrayAdd(String[] a, String s) { if (a == null) return new String[] { s }; String[] newA = new String[a.length + 1]; System.arraycopy(a, 0, newA, 0, a.length); newA[newA.length - 1] = s; return newA; } public String[] stringArrayRemove(String[] a, String s) { String[] result = new String[a.length - 1]; for (int i = 0, j = 0; i < a.length; i++) { if (!a[i].equals(s)) result[j++] = a[i]; } return result; } public TypeOrFeature[] typeOrFeatureArrayAdd(TypeOrFeature[] a, TypeOrFeature item) { if (null == a) return new TypeOrFeature[] { item }; TypeOrFeature[] result = new TypeOrFeature[a.length + 1]; System.arraycopy(a, 0, result, 0, a.length); result[result.length - 1] = item; return result; } public TypeOrFeature[] typeOrFeatureArrayRemove(TypeOrFeature[] a, TypeOrFeature item) { TypeOrFeature[] result = new TypeOrFeature[a.length - 1]; for (int i = 0, j = 0; i < a.length; i++) { if (a[i] != item) result[j++] = a[i]; } return result; } public TypeOrFeature[] typeOrFeatureArrayRemove(TypeOrFeature[] a, String s) { TypeOrFeature[] result = new TypeOrFeature[a.length - 1]; for (int i = 0, j = 0; i < a.length; i++) { if (!a[i].getName().equals(s)) { // debug if (j == a.length - 1) throw new InternalErrorCDE("feature or type not found: looking for " + s); result[j++] = a[i]; } } return result; } public static TypeOrFeature getTypeOrFeature(TypeOrFeature[] a, String name) { if (null == a) return null; for (int i = 0; i < a.length; i++) { if (a[i].getName().equals(name)) return a[i]; } return null; } // tool tips seem to require no blanks following /n on Windows. protected static String parseToFitInToolTips(String text) { if (null == text) return ""; StringBuffer buffer = new StringBuffer(); final int MAGIC_LENGTH = 65; StringTokenizer tokenizer = new StringTokenizer(text); int lengthAccumulator = 0; while (tokenizer.hasMoreTokens()) { if (lengthAccumulator > 0) { buffer.append(' '); } String nextToken = tokenizer.nextToken(); buffer.append(nextToken); lengthAccumulator += (nextToken.length() + 1); if (lengthAccumulator > MAGIC_LENGTH && tokenizer.hasMoreTokens()) { // this is to avoid a final blank line buffer.append("\n"); //$NON-NLS-1$ lengthAccumulator = 0; } } return new String(buffer); } public String formatName(String name) { if (null == name) return ""; //$NON-NLS-1$ if (MultiPageEditorContributor.getUseQualifiedTypes()) return name; return getShortName(name); } public static String getShortName(String name) { if (null == name) return ""; //$NON-NLS-1$ int i = name.lastIndexOf('.'); if (i < 0) return name; return name.substring(i + 1); } public static String getShortFeatureName(String name) { return (name.substring(name.indexOf(':') + 1)); } public static String getTypeFromFullFeatureName(String name) { return (name.substring(0, name.indexOf(':'))); } public static String getNameSpace(String name) { int i = name.lastIndexOf('.'); if (i < 0) return ""; return (name.substring(0, i)); } /** * gets a feature description for a type, including supertypes. * * @param td * @param featureName * @return */ public FeatureDescription getFeature(TypeDescription td, String featureName) { FeatureDescription[] features = td.getFeatures(); String supertypeName; if (null != features) for (int i = 0; i < features.length; i++) { if (featureName.equals(features[i].getName())) return features[i]; } if (null != (supertypeName = td.getSupertypeName())) if (!CAS.TYPE_NAME_TOP.equals(supertypeName)) { //$NON-NLS-1$ TypeDescription supertype = getMergedTypeSystemDescription().getType(supertypeName); if (null == supertype) supertype = (TypeDescription) BuiltInTypes.typeDescriptions.get(supertypeName); return getFeature(supertype, featureName); } return null; } // means is this range allowed in the UIMA Index Spec as a Key public static boolean isIndexableRange(String rangeName) { return CAS.TYPE_NAME_BYTE.equals(rangeName) || CAS.TYPE_NAME_SHORT.equals(rangeName) || CAS.TYPE_NAME_INTEGER.equals(rangeName) || CAS.TYPE_NAME_LONG.equals(rangeName) || CAS.TYPE_NAME_FLOAT.equals(rangeName) || CAS.TYPE_NAME_DOUBLE.equals(rangeName) || CAS.TYPE_NAME_STRING.equals(rangeName); } public static void setToolTipText(Control w, String text) { if (null != text) w.setToolTipText(parseToFitInToolTips(text)); } public static String maybeShortenFileName(String filePathName) { if (filePathName.length() > 65) { String pathName = filePathName.replace('\\', '/'); int nLoc = pathName.lastIndexOf('/'); return filePathName.substring(0, 61 - (pathName.length() - nLoc)) + ".../" + filePathName.substring(nLoc + 1); } return filePathName; } public static void swapTableTreeItems(TableTreeItem itemBelow, int newSelection) { TableTreeItem parent = itemBelow.getParentItem(); if (null == parent) throw new InternalErrorCDE("invalid arg"); int i = getIndex(itemBelow); TableTreeItem itemAbove = parent.getItems()[i - 1]; TableTreeItem newItemAbove = new TableTreeItem(parent, SWT.NONE, i - 1); copyTableTreeItem(newItemAbove, itemBelow); TableTreeItem newItemBelow = new TableTreeItem(parent, SWT.NONE, i); copyTableTreeItem(newItemBelow, itemAbove); itemAbove.dispose(); itemBelow.dispose(); parent.getParent().setSelection(new TableTreeItem[] { parent.getItems()[newSelection] }); } public static void copyTableTreeItem(TableTreeItem target, TableTreeItem source) { int columnCount = target.getParent().getTable().getColumnCount(); for (int i = 0; i < columnCount; i++) { String text = source.getText(i); if (null != text) target.setText(i, text); } target.setData(source.getData()); } public static void swapIndexKeys(TableTreeItem itemBelow, int newSelection) { TableTreeItem parent = itemBelow.getParentItem(); FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent); int i = getIndex(itemBelow); FsIndexKeyDescription[] keys = fsid.getKeys(); FsIndexKeyDescription temp = keys[i]; keys[i] = keys[i - 1]; keys[i - 1] = temp; // swap items in the GUI swapTableTreeItems(itemBelow, newSelection); } public static void swapTableItems(TableItem itemBelow, int newSelection) { Table parent = itemBelow.getParent(); int i = getIndex(itemBelow); TableItem itemAbove = parent.getItems()[i - 1]; TableItem newItemAbove = new TableItem(parent, SWT.NONE, i - 1); copyTableItem(newItemAbove, itemBelow); TableItem newItemBelow = new TableItem(parent, SWT.NONE, i); copyTableItem(newItemBelow, itemAbove); itemAbove.dispose(); itemBelow.dispose(); parent.setSelection(newSelection); } public static void copyTableItem(TableItem target, TableItem source) { int columnCount = target.getParent().getColumnCount(); for (int i = 0; i < columnCount; i++) { String text = source.getText(i); if (null != text) target.setText(i, text); } target.setData(source.getData()); } public static FsIndexDescription getFsIndexDescriptionFromTableTreeItem(TableTreeItem item) { return (FsIndexDescription) item.getData(); } public String[][] getCapabilitySofaNames() { Set[] inOut = getCapabilitySofaNames(editor.getAeDescription(), null); String[] inputSofas = (String[]) inOut[0].toArray(stringArray0); String[] outputSofas = (String[]) inOut[1].toArray(stringArray0); Arrays.sort(inputSofas); Arrays.sort(outputSofas); return new String[][] { inputSofas, outputSofas }; } public static Capability[] getCapabilities(ResourceSpecifier rs) { if (rs instanceof ResourceCreationSpecifier) return ((ProcessingResourceMetaData) ((ResourceCreationSpecifier) rs).getMetaData()) .getCapabilities(); return null; } protected static Set[] getCapabilitySofaNames(ResourceCreationSpecifier rs, String componentKey) { Capability[] cs = getCapabilities(rs); Set inputSofasSet = new TreeSet(); Set outputSofasSet = new TreeSet(); for (int i = 0; i < cs.length; i++) { Capability c = cs[i]; mergeSofaNames(inputSofasSet, c.getInputSofas(), componentKey); mergeSofaNames(outputSofasSet, c.getOutputSofas(), componentKey); } return new Set[] { inputSofasSet, outputSofasSet }; } private static void mergeSofaNames(Set set, String[] items, String componentKey) { if (null != items) { for (int i = 0; i < items.length; i++) { if (null != componentKey) set.add(componentKey + '/' + items[i]); else set.add(items[i]); } } else if (null != componentKey) set.add(componentKey); } protected Capability addCapabilitySet() { Capability newCset = UIMAFramework.getResourceSpecifierFactory().createCapability(); // update the model AnalysisEngineMetaData md = getAnalysisEngineMetaData(); Capability[] c = getCapabilities(); if (c == null) md.setCapabilities(new Capability[] { newCset }); else { Capability[] newC = new Capability[c.length + 1]; System.arraycopy(c, 0, newC, 0, c.length); newC[c.length] = newCset; md.setCapabilities(newC); } return newCset; } /** * Get the metadata for a local or remote descriptor. If the descriptor is remote, but cannot be * currently connected to, return null. Note that this make take some time to determine. * * @param r * is the AnalysisEngineDescription or the URISpecifier for remotes. * @return AnalysisEngineMetaData or null */ public ResourceMetaData getMetaDataFromDescription(ResourceSpecifier o) { if (o instanceof ResourceCreationSpecifier) { return ((ResourceCreationSpecifier) o).getMetaData(); } if (o instanceof URISpecifier) { URISpecifier uriSpec = ((URISpecifier) o); AnalysisEngine ae = null; try { setVnsHostAndPort(o); ae = UIMAFramework.produceAnalysisEngine(uriSpec); } catch (ResourceInitializationException e) { return null; } AnalysisEngineMetaData aemd = ae.getAnalysisEngineMetaData(); ae.destroy(); return aemd; } throw new InternalErrorCDE("invalid call"); } public static void setVnsHostAndPort(String vnsHost, String vnsPort) { MultiPageEditorContributor.setVnsHost(vnsHost); MultiPageEditorContributor.setVnsPort(vnsPort); } public static void setVnsHostAndPort(Object descriptor) { String vnsHost = MultiPageEditorContributor.getCDEVnsHost(); String vnsPort = MultiPageEditorContributor.getCDEVnsPort(); // don't need this next part - the framework does it itself // if (null != descriptor) { // if (descriptor instanceof URISpecifier) { // URISpecifier rd = (URISpecifier) descriptor; // Parameter[] parms = rd.getParameters(); // if (null != parms) { // for (int i = 0; i < parms.length; i++) { // if ("VNS_HOST".equals(parms[i].getName())) // vnsHost = parms[i].getValue(); // else if ("VNS_PORT".equals(parms[i].getName())) // vnsPort = parms[i].getValue(); // } // } // } // } setVnsHostAndPort(vnsHost, vnsPort); } protected void requestPopUpOverImport(Import importItem, Control control, Event event) { String path = editor.getAbsolutePathFromImport(importItem); IPath iPath = new Path(path); IFile[] files = editor.getProject().getWorkspace().getRoot().findFilesForLocation(iPath); if (null == files || files.length != 1) return; String filePathName = files[0].getLocation().toOSString(); XMLizable inputDescription; try { inputDescription = parseDescriptor(new XMLInputSource(filePathName)); } catch (InvalidXMLException e) { return; } catch (IOException e) { return; } PopupList popupList = new PopupList(control.getShell()); String[] items = { "Open in new window..." }; popupList.setItems(items); int HACK_MARGIN = 30; Point absPoint = getAbsoluteLocation(control, event.x, event.y + HACK_MARGIN); Rectangle rect = new Rectangle(absPoint.x, absPoint.y, 150, 25); control.setToolTipText(""); String res = popupList.open(rect); // code to open selected file, by location or by name if (null != res) { if (inputDescription instanceof URISpecifier) editor.openTextEditor(path); else editor.open(path); } } private Point getAbsoluteLocation(Control control, int x, int y) { Point point = new Point(x, y); Composite composite = control.getParent(); while (composite != null) { point.x += composite.getLocation().x; point.y += composite.getLocation().y; composite = composite.getParent(); } return point; } public static String convertNull(String s) { if (null == s) return ""; return s; } public Import createImport(String fileName, boolean isByName) { if (isByName) { return createByNameImport(fileName); } else try { return createLocationImport(fileName); } catch (MalformedURLException e1) { throw new InternalErrorCDE("unhandled exception", e1); } } /** * @param location * @return * @throws MalformedURLException */ public Import createLocationImport(String location) throws MalformedURLException { String sDescriptorRelativePath = editor.getDescriptorRelativePath(location); // If relative path is not "relative", on Windows might get back // an absolute path starting with C: or something like it. // If a path starts with "C:", it must be preceeded by // file:/ so the C: is not interpreted as a "scheme". if (sDescriptorRelativePath.indexOf("file:/") == -1 //$NON-NLS-1$ && sDescriptorRelativePath.indexOf(":/") > -1) { //$NON-NLS-1$ sDescriptorRelativePath = "file:/" + sDescriptorRelativePath; //$NON-NLS-1$ } Import imp = new Import_impl(); // fails on unix? URL url = new URL("file:/" + getDescriptorDirectory()); // Set relative Path Base // a version that might work on all platforms URL url = new File(editor.getDescriptorDirectory()).toURL(); ((Import_impl) imp).setSourceUrl(url); imp.setLocation(sDescriptorRelativePath); return imp; } public Import createByNameImport(String fileName) { if (fileName.endsWith(".xml")) fileName = fileName.substring(0, fileName.length() - 4); fileName = fileName.replace('\\', '/'); fileName = fileName.replace('/', '.'); int i = fileName.indexOf(":"); if (i >= 0) fileName = fileName.substring(i + 1); if (fileName.charAt(0) == '.') fileName = fileName.substring(1); int partStart = 0; Import imp = UIMAFramework.getResourceSpecifierFactory().createImport(); ResourceManager rm = editor.createResourceManager(); for (;;) { imp.setName(fileName.substring(partStart)); try { imp.findAbsoluteUrl(rm); } catch (InvalidXMLException e) { partStart = fileName.indexOf('.', partStart) + 1; if (0 == partStart) return imp; // not found -outer code will catch error later continue; } return imp; } } // subtype of FSLists should not match public static boolean isFSArrayOrListType(String type) { return (null != type) && (type.equals(CAS.TYPE_NAME_FS_ARRAY) || type.equals(CAS.TYPE_NAME_FS_LIST)); } public static boolean isArrayOrListType(String type) { return (null != type) && (type.equals(CAS.TYPE_NAME_FS_ARRAY) || type.equals(CAS.TYPE_NAME_FS_LIST) || type.equals(CAS.TYPE_NAME_STRING_LIST) || type.equals(CAS.TYPE_NAME_FLOAT_LIST) || type.equals(CAS.TYPE_NAME_INTEGER_LIST) || type.equals(CAS.TYPE_NAME_STRING_ARRAY) || type.equals(CAS.TYPE_NAME_FLOAT_ARRAY) || type.equals(CAS.TYPE_NAME_BOOLEAN_ARRAY) || type.equals(CAS.TYPE_NAME_BYTE_ARRAY) || type.equals(CAS.TYPE_NAME_SHORT_ARRAY) || type.equals(CAS.TYPE_NAME_INTEGER_ARRAY) || type.equals(CAS.TYPE_NAME_LONG_ARRAY) || type .equals(CAS.TYPE_NAME_DOUBLE_ARRAY)); } private final static int RIDICULOUSLY_LARGE = 10000; /** * Produce Unique key for a newly added descriptor file * * @param fileName * @return */ protected String produceUniqueComponentKey(String fileName) { // get existing set of delegates from model, with imports Set existingKeyNames = new HashSet(getDelegateAnalysisEngineSpecifiersWithImports().keySet()); FlowControllerDeclaration fcd = getFlowControllerDeclaration(); if (null != fcd && null != fcd.getKey() && !"".equals(fcd.getKey())) existingKeyNames.add(fcd.getKey()); String keyName = fileName; String keyNameLowerCase = keyName.toLowerCase(); keyName = keyName.substring(0, keyNameLowerCase.indexOf(".xml")); if (!existingKeyNames.contains(keyName)) { return keyName; } for (int i = 2; i < RIDICULOUSLY_LARGE; i++) { String sKeyName = keyName + i; if (!existingKeyNames.contains(sKeyName)) { return sKeyName; } } Utility.popMessage("Failed to create unique key", "The Flow Controller name, '" + fileName + "', could not be " + "converted to a unique key name -- tried with 10000 different suffixes", MessageDialog.ERROR); return null; } private static URL urlForResourceSpecifierSchema; static { try { urlForResourceSpecifierSchema = new URL("file:resourceSpecifierSchema.xsd"); } catch (MalformedURLException e) { urlForResourceSpecifierSchema = null; } } public static XMLizable parseDescriptor(XMLInputSource input) throws InvalidXMLException { // turn off environment variable expansion XMLParser.ParsingOptions parsingOptions = new XMLParser.ParsingOptions(false); XMLParser parser = UIMAFramework.getXMLParser(); // disabled - error messages from XML validation not very helpful // parser.enableSchemaValidation(true); return parser.parse(input, "http://uima.apache.org/resourceSpecifier", urlForResourceSpecifierSchema, parsingOptions); } protected void showExceptionReadingImportedDescriptor(Exception e) { StringBuffer msg = new StringBuffer(1000); msg .append("There was an exception raised while reading and parsing an imported descriptor. " + "If this is a ''not found'' message for a remote descriptor imported by name, insure that the class path or data path includes an entry where this file should be found.\n"); msg.append(editor.getMessagesToRootCause(e)); Utility.popMessage("Exception reading Imported File", msg.toString(), MessageDialog.ERROR); } /** * Update the model while checking for validity If invalid - ask if want to continue or not * * @return */ protected boolean isValidAggregateChange() { // doing this check here is expensive, but gives the best error location information if (!editor.isValidAE(editor.getAeDescription())) if (revertOrContinue("Continue or Abort", "Because of errors in validating the resulting Analysis Engine:\n")) return false; // want to revert try { editor.setMergedTypeSystemDescription(); } catch (ResourceInitializationException e) { // no error here - continue if possible } try { editor.setResolvedExternalResourcesAndBindings(); } catch (InvalidXMLException e3) { // no error here - continue if possible } try { editor.setResolvedFlowControllerDeclaration(); } catch (InvalidXMLException e3) { // no error here - continue if possible } try { editor.setMergedFsIndexCollection(); } catch (ResourceInitializationException e1) { // no error here - continue if possible } try { editor.setMergedTypePriorities(); } catch (ResourceInitializationException e2) { // no error here - continue if possible } return true; } protected void finishAggregateChangeAction() { editor.setFileDirty(); editor.getTypePage().markStale(); editor.getIndexesPage().markStale(); editor.getCapabilityPage().markStale(); SectionPart s = editor.getParameterPage().getParameterDelegatesSection(); if (null != s) s.markStale(); editor.getResourcesPage().markStale(); } protected XMLizable readImport(Import imp, String fileName, boolean isImportByName) { URL byNameURL; XMLInputSource input; if (isImportByName) { try { byNameURL = imp.findAbsoluteUrl(editor.createResourceManager()); } catch (InvalidXMLException e) { showExceptionReadingImportedDescriptor(e); return null; } try { input = new XMLInputSource(byNameURL.openStream(), new File(byNameURL.getFile()) .getParentFile()); } catch (IOException e) { showExceptionReadingImportedDescriptor(e); return null; } } else { try { input = new XMLInputSource(new File(fileName)); } catch (IOException e) { throw new InternalErrorCDE("invalid state"); } } // read the content and merge into our model XMLizable inputDescription; try { inputDescription = parseDescriptor(input); } catch (InvalidXMLException e1) { showExceptionReadingImportedDescriptor(e1); return null; } return inputDescription; } protected static void enableCtrl(Control c, boolean enabled) { if (null != c) c.setEnabled(enabled); } protected static void setButtonSelection(Button c, boolean selected) { if (null != c) c.setSelection(selected); } /** * Return a String made from the description of a given resource specifier. If the specifier is * for a remote, try and connect to the remote and get its info. * * @param fileRef * @param rs */ private ResourceSpecifier lastResourceForDescription = null; private String lastDescriptionFromDescriptor = ""; private long lastTimeDescriptionRequested = 0; private static final long TABLE_HOVER_REQUERY_TIME = 15000; protected String getDescriptionForDescriptor(String fileRef, ResourceSpecifier rs) { if (null == fileRef || "".equals(fileRef) || null == rs) return ""; String sDesc; long lCurrentTimeInMillis = System.currentTimeMillis(); if (rs == lastResourceForDescription && ((lCurrentTimeInMillis - lastTimeDescriptionRequested) < TABLE_HOVER_REQUERY_TIME)) { return lastDescriptionFromDescriptor; } else { sDesc = fileRef + ":\n"; if (rs instanceof PearSpecifier) { sDesc += " (Pear descriptor)"; } else { ResourceMetaData resourceMetaData = getMetaDataFromDescription(rs); if (null == resourceMetaData) { sDesc += "(Remote service is not responding)"; } else { String description = resourceMetaData.getDescription(); if (null != description && !description.equals("")) { sDesc += parseToFitInToolTips(description); } else sDesc += "(No Description)"; } } lastResourceForDescription = rs; lastTimeDescriptionRequested = System.currentTimeMillis(); lastDescriptionFromDescriptor = sDesc; } return sDesc; } protected PrintWriter setupToPrintFile(String filePath) { if (new File(filePath).exists()) if (Window.CANCEL == Utility.popOkCancel("File exists, OK to replace?", MessageFormat.format( "The file ''{0}'' exists. Press OK if it can be replaced; otherwise press Cancel.", new Object[] { filePath }), MessageDialog.WARNING)) return null; FileOutputStream fos = null; try { fos = new FileOutputStream(filePath); return new PrintWriter(fos); } catch (FileNotFoundException ex) { ex.printStackTrace(); return null; } } protected FsIndexCollection getFsIndexCollection() { FsIndexCollection fsic = getAnalysisEngineMetaData().getFsIndexCollection(); if (null == fsic) getAnalysisEngineMetaData().setFsIndexCollection( fsic = UIMAFramework.getResourceSpecifierFactory().createFsIndexCollection()); return fsic; } public static String handleDefaultIndexKind(String indexKind) { if (null == indexKind) return "sorted"; return indexKind; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportSec0000644000175000017500000003703511665471220033452 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.IOException; import java.io.PrintWriter; import java.text.MessageFormat; import org.apache.uima.resource.metadata.Import; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.ExportImportablePartDialog; import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialog; import org.apache.uima.util.InvalidXMLException; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.forms.IManagedForm; /** * Imports - used by aggregates types type priorities indexes external resource specifications */ public abstract class ImportSection extends AbstractSection { protected abstract Import[] getModelImportArray(); protected abstract void setModelImportArray(Import[] newImports); protected abstract boolean isValidImport(String title, String message); protected abstract void finishImportChangeAction(); protected abstract String getDescriptionFromImport(String source) throws InvalidXMLException, IOException; protected abstract boolean isAppropriate(); // if false, don't show section protected abstract void clearModelBaseValue(); // used to clear exported value protected static final long TABLE_HOVER_REQUERY_TIME = 15000; protected TableItem lastTableHoverItem = null; protected long lLastTableHoverMillis = -1; protected String sLastTableHoverHelp = ""; protected boolean bDisableToolTipHelp = false; private static final String TABLE_INDICATOR_BY_NAME = "By Name"; private static final String TABLE_INDICATOR_BY_LOCATION = "By Location"; protected Button addButton; private Button removeButton; private Button setDataPathButton; Table importTable; public ImportSection(MultiPageEditor aEditor, Composite parent, String title, String description) { super(aEditor, parent, title, description); } public void initialize(IManagedForm form) { super.initialize(form); // set up Composite to hold widgets in the section Composite sectionClient = newComposite(getSection()); enableBorders(sectionClient); Composite buttonContainer = new2ColumnComposite(sectionClient); ((GridData) buttonContainer.getLayoutData()).grabExcessVerticalSpace = false; ((GridData) buttonContainer.getLayoutData()).grabExcessHorizontalSpace = false; ((GridData) buttonContainer.getLayoutData()).horizontalAlignment = SWT.RIGHT; addButton = newPushButton(buttonContainer, "Add...", "Click here to add an import"); removeButton = newPushButton(buttonContainer, "Remove", "Click here to remove the selected import."); setDataPathButton = newPushButton(buttonContainer, "Set DataPath", "Click here to view or set the data path to use when resolving imports by name."); importTable = newTable(sectionClient, SWT.FULL_SELECTION, NO_MIN_HEIGHT); newTableColumn(importTable).setText("Kind"); newTableColumn(importTable).setText("Location/Name"); importTable.setHeaderVisible(true); packTable(importTable); // in addition to normal keyup and mouse up: importTable.addListener(SWT.MouseHover, this); importTable.addListener(SWT.MouseDown, this); toolkit.paintBordersFor(sectionClient); } public void refresh() { super.refresh(); importTable.removeAll(); if (isAppropriate()) { Import[] importItems = getModelImportArray(); if (importItems != null) { for (int i = 0; i < importItems.length; i++) { if (importItems[i] != null) { TableItem tableItem = new TableItem(importTable, SWT.NONE); if (importItems[i].getLocation() != null) { tableItem.setText(0, TABLE_INDICATOR_BY_LOCATION); tableItem.setText(1, importItems[i].getLocation()); } else { tableItem.setText(0, TABLE_INDICATOR_BY_NAME); tableItem.setText(1, importItems[i].getName()); } } } packTable(importTable); } } enable(); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addButton) { handleAdd(); } else if (event.widget == removeButton) { handleRemove(); } else if (event.widget == setDataPathButton) { handleSetDataPath(); } else if (event.type == SWT.MouseDown && event.button == 3) { handleTableContextMenuRequest(event); } else if (event.type == SWT.MouseHover && !bDisableToolTipHelp) { handleTableHoverHelp(event); } else if (event.type == SWT.KeyUp) { if (event.character == SWT.DEL) { handleRemove(); } } else if (event.widget == importTable && event.type == SWT.Selection) { enable(); } } public void handleRemove() { int nSelectedIndex = importTable.getSelectionIndex(); Import[] oldImports = getModelImportArray(); setModelImportArray((Import[]) Utility.removeElementFromArray(oldImports, oldImports[nSelectedIndex], Import.class)); if (!isValidImport("Error Removing Import", "An error was caused by removing an import.")) { setModelImportArray(oldImports); // no refresh here: the remove action didn't happen, so leave the GUI alone return; } refresh(); importTable.setSelection(nSelectedIndex - 1); enable(); finishImportChangeAction(); setFileDirty(); } private void handleSetDataPath() { CommonInputDialog dialog = new CommonInputDialog( this, "Set DataPath", "The DataPath is a series of locations which will be used when looking up imports and external resources.\nEnter a series of absolute path names, separated by the character used to separate classpath names on this platform.", CommonInputDialog.ALLOK, CDEpropertyPage.getDataPath(editor.getProject())); if (dialog.open() == Window.CANCEL) return; CDEpropertyPage.setDataPath(editor.getProject(), dialog.getValue()); } private void handleAdd() { Shell shell = getSection().getShell(); MultiResourceSelectionDialog dialog = new MultiResourceSelectionDialog(shell, editor.getFile() .getProject().getParent(), "Select one or more descriptor files to import:", editor .getFile().getLocation(), editor); dialog.setTitle("Import File(s) Selection"); if (dialog.open() == Window.CANCEL) return; // results is an array of either IFile or File objects // depending on if the file was from the Eclipse Workspace or from the file system Object[] results = dialog.getResult(); if (results == null || results.length == 0) return; if (!addImports(results, dialog.isImportByName)) return; refresh(); finishImportChangeAction(); setFileDirty(); } /** * Called with either byLocation non-null or byName non-null Adds multiple (by location) or one * (by name) * * @param location * objects returned from dialog * @param true * if imports should be done by name * @return false if any import caused an error, true of all OK */ public boolean addImports(Object[] locations, boolean isByName) { Import[] currentImports = getModelImportArray(); Import imp; int nCountCurrentImports = (currentImports == null) ? 0 : currentImports.length; int numberToAdd = locations.length; Import[] newImports = new Import[nCountCurrentImports + numberToAdd]; if (null != currentImports) System.arraycopy(currentImports, 0, newImports, 0, nCountCurrentImports); for (int i = 0; i < locations.length; i++) { FileAndShortName fsn = new FileAndShortName(locations[i]); imp = createImport(fsn.fileName, isByName); if (alreadyImported(imp)) return false; newImports[nCountCurrentImports + i] = imp; } setModelImportArray(newImports); if (!isValidImport( "Error Adding Import(s)", "An error was caused by adding Import(s); operation cancelled. Please correct the error and retry.")) { setModelImportArray(currentImports); return false; } return true; } private boolean alreadyImported(Import imp) { String currentFileBeingEdited = editor.getFile().getLocation().toString(); currentFileBeingEdited = editor.getDescriptorRelativePath(currentFileBeingEdited); if (currentFileBeingEdited.equals(imp.getLocation())) { Utility .popMessage( "Error - importing self", MessageFormat .format( "The import {0} is the same as the current file being edited. A file can''t be imported into itself.", new Object[] { imp.getLocation() }), MessageDialog.ERROR); return true; } Import[] currentImports = getModelImportArray(); if (null == currentImports) return false; for (int i = 0; i < currentImports.length; i++) { if (currentImports[i].equals(imp)) { Utility.popMessage("Error - duplicate import", MessageFormat.format( "The import {0} is already present", new Object[] { null != imp.getName() ? imp .getName() : imp.getLocation() }), MessageDialog.ERROR); return true; } } return false; } public void enable() { int nSelectionIndex = importTable.getSelectionIndex(); boolean addEnable = (this instanceof TypeImportSection) ? (!isAggregate()) : true; addButton.setEnabled(addEnable); removeButton.setEnabled(nSelectionIndex > -1); } private void handleTableContextMenuRequest(Event event) { TableItem item = importTable.getItem(new Point(event.x, event.y)); int nSelectedIndex = getIndex(item); bDisableToolTipHelp = true; requestPopUpOverImport(getModelImportArray()[nSelectedIndex], importTable, event); bDisableToolTipHelp = false; } private void handleTableHoverHelp(Event event) { TableItem item = importTable.getItem(new Point(event.x, event.y)); if (null != item) { String sDesc; long lCurrentTimeInMillis = System.currentTimeMillis(); if (item == lastTableHoverItem && lCurrentTimeInMillis - lLastTableHoverMillis < TABLE_HOVER_REQUERY_TIME) { sDesc = sLastTableHoverHelp; } else { int itemIndex = (event.y - importTable.getHeaderHeight()) / importTable.getItemHeight(); String thisFile = item.getText(1); sDesc = thisFile + ' '; Import[] importItems = getModelImportArray(); if (itemIndex < 0 || itemIndex >= importItems.length) { System.err.println("***ERROR Item index hover out of range" + itemIndex + ", size of array = " + importItems.length); System.err.println(this.getClass().getName()); return; } Import importItem = getModelImportArray()[itemIndex]; // if by location, it's relative to the descriptor. String absolutePath = editor.getAbsolutePathFromImport(importItem); String description = null; try { description = getDescriptionFromImport(absolutePath); } catch (InvalidXMLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } if ((null != description) && (!description.equals(""))) { sDesc += "\n\n" + parseToFitInToolTips(description); } lastTableHoverItem = item; lLastTableHoverMillis = System.currentTimeMillis(); sLastTableHoverHelp = sDesc; } importTable.setToolTipText(sDesc); } else { importTable.setToolTipText(""); } } /** * * @param xmlStartElement * first element exported * @param partTemplate */ protected void exportImportablePart(String xmlStartElement, String partTemplate) { String xmlEndElement = xmlStartElement.replaceFirst("<", " Arrays.binarySearch(inputCapabilityNames, sofaName) && 0 > Arrays.binarySearch(outputCapabilityNames, sofaName)) undeclaredNames.add(sofaName); } } // It is an error to have a mapping without having the aggregate name // declared as either an input our output. If the name is not // declared, (silently) consider it to have been an input. if (undeclaredNames.size() > 0) names.addAll(undeclaredNames); return (String[]) names.toArray(stringArray0); } private void fillMap(String[] aggrKeys, boolean isInput) { TreeItem d = new TreeItem(tree, SWT.NONE); d.setText(isInput ? INPUTS : OUTPUTS); for (int i = 0; i < aggrKeys.length; i++) { TreeItem a = new TreeItem(d, SWT.NONE); a.setText(aggrKeys[i]); fillBindings(a, aggrKeys[i]); a.setExpanded(true); } d.setExpanded(true); } private void fillBindings(TreeItem parent, String aggrSofa) { // bindings are a string of key-name / sofa-name or "" String[] bindings = getSofaBindingsForAggrSofa(aggrSofa); for (int j = 0; j < bindings.length; j++) { TreeItem b = new TreeItem(parent, SWT.NONE); b.setText(bindings[j]); } } private String[] getSofaBindingsForAggrSofa(String aggrSofa) { SofaMapping[] sofaMappings = getSofaMappings(); if (null == sofaMappings) return stringArray0; Set bindings = new TreeSet(); for (int i = 0; i < sofaMappings.length; i++) { SofaMapping sofaMapping = sofaMappings[i]; if (sofaMapping.getAggregateSofaName().equals(aggrSofa)) if (null != sofaMapping.getComponentSofaName() && !"".equals(sofaMapping.getComponentSofaName())) bindings.add(sofaMapping.getComponentKey() + '/' + sofaMapping.getComponentSofaName()); else bindings.add(sofaMapping.getComponentKey()); } String[] results = (String[]) bindings.toArray(stringArray0); Arrays.sort(results); return results; } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { // Note: to add aggrSofa names, use capabilitySection. // Updates there are propagated here. // only enabled when one existing AggrSofa // or its child is selected if (event.widget == editButton || event.type == SWT.MouseDoubleClick) { if (!editButton.getEnabled()) return; // Edit a map: a new aggr capability + a delegate sofa, or // a delegate sofa to an existing map. TreeItem selected = tree.getSelection()[0]; TreeItem parent = selected.getParentItem(); if (null != parent.getParentItem()) { selected = parent; } editAggrMap(selected); } else if (event.widget == addButton) { // Add one or more new mappings TreeItem selected = tree.getSelection()[0]; TreeItem parent = selected.getParentItem(); if (null != parent.getParentItem()) { selected = parent; } addAggrMap(selected); } else if (event.widget == removeButton) { // only enabled for aggr or component TreeItem selected = tree.getSelection()[0]; TreeItem parent = selected.getParentItem(); if (null == parent.getParentItem()) removeAggr(selected); else removeComponentFromAggr(selected); } enable(); } private static final boolean AVAIL_ONLY = true; private void editAggrMap(TreeItem selected) { // pop up window: shows all available component mappings // plus current mappings for this aggrSofa // Available: a) not mapped // User selects mappings to update // update model: add (multiple) mappings // Remove all under item // update model. String aggrSofa = selected.getText(); Map availAndBoundSofas = getAvailAndBoundSofas(aggrSofa, !AVAIL_ONLY); if (availAndBoundSofas.size() == 0) { Utility .popMessage( "No available sofas", "Because there are no sofas in the delegates that are not already bound, no sofa mapping can be created.", MessageDialog.WARNING); return; } EditSofaBindingsDialog dialog = new EditSofaBindingsDialog(this, aggrSofa, availAndBoundSofas); if (dialog.open() == Window.CANCEL) return; removeAggr(aggrSofa); addAggr(aggrSofa, dialog.selectedSofaNames); removeChildren(selected); fillBindings(selected, aggrSofa); selected.setExpanded(true); setFileDirty(); } private void addAggrMap(TreeItem selected) { // pop up window: shows all available component mappings // minus current mappings for this aggrSofa // Available: a) not mapped, // User selects mappings to add String aggrSofa = selected.getText(); Map availAndBoundSofas = getAvailAndBoundSofas(aggrSofa, AVAIL_ONLY); if (availAndBoundSofas.size() == 0) { Utility .popMessage( "No available sofas", "Because there are no sofas in the delegates that are not already bound, no sofa mapping can be created.", MessageDialog.WARNING); return; } EditSofaBindingsDialog dialog = new EditSofaBindingsDialog(this, aggrSofa, availAndBoundSofas); if (dialog.open() == Window.CANCEL) return; addAggr(aggrSofa, dialog.selectedSofaNames); removeChildren(selected); fillBindings(selected, aggrSofa); selected.setExpanded(true); setFileDirty(); } private void addSofasToAllComponentSofaMap(Map allComponentSofas, String key, ResourceSpecifier delegate, boolean isInput) { // delegates can be AnalysisEngines, CasConsmers, flowControllers, or remotes if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription || delegate instanceof FlowControllerDescription) { Set[] inAndOut = getCapabilitySofaNames((ResourceCreationSpecifier) delegate, key); Set inOut = inAndOut[isInput ? 0 : 1]; if (!isInput) { // Aggr "output" can be mapped to delegate "input" inOut.addAll(inAndOut[0]); } if (inOut.size() == 0) { // no sofas defined in this delegate // create default sofa allComponentSofas.put(key, null); } for (Iterator i2 = inOut.iterator(); i2.hasNext();) { allComponentSofas.put(i2.next(), null); } } } /** * * @param aggrSofa * @return a Map, keys = component/sofaname, value = aggrsofa or null */ private Map getAvailAndBoundSofas(String aggrSofa, boolean availOnly) { boolean isInput = isInput(aggrSofa); Map allComponentSofas = new TreeMap(); // key = component/sofa, value = AggrSofa bound to // put all delegate component/sofa items in a Map for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); addSofasToAllComponentSofaMap(allComponentSofas, (String) entry.getKey(), (ResourceSpecifier) entry.getValue(), isInput); } // pick up any sofa info from flow controller FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration(); if (null != fcd) { addSofasToAllComponentSofaMap(allComponentSofas, fcd.getKey(), fcd.getSpecifier(), isInput); } // mark the bound ones with a value which is the aggr sofa they're bound to // also, add any that were not spec'd in the delegates (because // for instance, they were remote) SofaMapping[] sofaMappings = getSofaMappings(); for (int i = 0; i < sofaMappings.length; i++) { SofaMapping sm = sofaMappings[i]; String key = sm.getComponentKey(); if (null != sm.getComponentSofaName()) key = key + '/' + sm.getComponentSofaName(); if (availOnly) allComponentSofas.remove(key); else allComponentSofas.put(key, sm.getAggregateSofaName()); } // remove all that are bound to other Aggr sofa names // because although an Aggr sofa can be bound to many delegate sofas, // a delegate sofa can only be bound to one aggr one. for (Iterator i3 = allComponentSofas.entrySet().iterator(); i3.hasNext();) { Map.Entry entry = (Map.Entry) i3.next(); String boundAggrSofa = (String) entry.getValue(); if (null != boundAggrSofa && !boundAggrSofa.equals(aggrSofa)) i3.remove(); } return allComponentSofas; } private boolean isInput(String sofaName) { String[][] sns = getCapabilitySofaNames(); for (int i = 0; i < sns[0].length; i++) { if (sofaName.equals(sns[0][i])) return true; } return false; } private void addAggr(String aggrSofa, String[] sofaNames) { SofaMapping[] newSofas = new SofaMapping[sofaNames.length]; for (int i = 0; i < sofaNames.length; i++) { newSofas[i] = UIMAFramework.getResourceSpecifierFactory().createSofaMapping(); newSofas[i].setAggregateSofaName(aggrSofa); newSofas[i].setComponentKey(getComponentOnly(sofaNames[i])); newSofas[i].setComponentSofaName(getSofaOnly(sofaNames[i])); } SofaMapping[] oldSofas = getSofaMappings(); SofaMapping[] result = new SofaMapping[oldSofas.length + newSofas.length]; System.arraycopy(oldSofas, 0, result, 0, oldSofas.length); System.arraycopy(newSofas, 0, result, oldSofas.length, newSofas.length); editor.getAeDescription().setSofaMappings(result); } private void removeAggr(String aggrSofa) { Comparator comparator = new Comparator() { public int compare(Object aggrSofaName, Object o2) { SofaMapping sofaMapping = (SofaMapping) o2; if (sofaMapping.getAggregateSofaName().equals(aggrSofaName)) return 0; else return -1; } }; editor.getAeDescription().setSofaMappings( (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), aggrSofa, SofaMapping.class, comparator)); } private void removeAggr(TreeItem selected) { if (Window.CANCEL == Utility .popOkCancel( "Confirm delete of sofa mappings", "Please confirm deletion of all sofa mappings for this Aggregate Sofa name. Note this will not delete the Sofa name. To do that, remove the name from the Component Capabilities panel (the other panel on this page).", MessageDialog.WARNING)) return; removeAggr(selected.getText()); removeChildren(selected); setFileDirty(); } /** * Removes a delegate map from a particular aggr sofa mapping. * * @param selected */ private void removeComponentFromAggr(TreeItem selected) { final String aggrName = selected.getParentItem().getText(); Comparator comparator = new Comparator() { public int compare(Object componentAndSofa, Object o2) { SofaMapping sofaMapping = (SofaMapping) o2; if (!sofaMapping.getAggregateSofaName().equals(aggrName)) return -1; String component = getComponentOnly((String) componentAndSofa); if (!sofaMapping.getComponentKey().equals(component)) return -1; String sofa = getSofaOnly((String) componentAndSofa); if (null == sofa || sofa.equals("")) if (null == sofaMapping.getComponentSofaName() || "".equals(sofaMapping.getComponentSofaName())) return 0; else return -1; else if (sofa.equals(sofaMapping.getComponentSofaName())) return 0; else return -1; } }; editor.getAeDescription().setSofaMappings( (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), selected.getText(), SofaMapping.class, comparator)); selected.dispose(); setFileDirty(); } /** * Called when removing a delegate from the aggr. Removes from the sofaMappings, any and all * mappings associated with the delegate. * * @param componentSofa */ public static void removeSofaMappings(String componentKey, ResourceSpecifier delegate, MultiPageEditor pEditor) { if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription) { Set[] inOut = getCapabilitySofaNames((ResourceCreationSpecifier) delegate, componentKey); inOut[0].addAll(inOut[1]); final Set allDelegateComponentSofas = inOut[0]; Comparator comparator = new Comparator() { public int compare(Object ignore, Object elementOfArray) { SofaMapping sofaMapping = (SofaMapping) elementOfArray; String key = sofaMapping.getComponentKey(); if (null != sofaMapping.getComponentSofaName()) key = key + '/' + sofaMapping.getComponentSofaName(); if (allDelegateComponentSofas.contains(key)) { return 0; } return -1; } }; pEditor.getAeDescription().setSofaMappings( (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(pEditor), null, SofaMapping.class, comparator)); } } private String getSofaOnly(String componentAndSofa) { int locOfSlash = componentAndSofa.indexOf('/'); if (locOfSlash < 0) return null; return componentAndSofa.substring(locOfSlash + 1); } private String getComponentOnly(String componentAndSofa) { int locOfSlash = componentAndSofa.indexOf('/'); if (locOfSlash < 0) return componentAndSofa; return componentAndSofa.substring(0, locOfSlash); } public void enable() { boolean oneSelected = tree.getSelectionCount() == 1; boolean topLevelSelected = false; if (oneSelected) { TreeItem selected = tree.getSelection()[0]; topLevelSelected = (null == selected.getParentItem()); } addButton.setEnabled(oneSelected && !topLevelSelected); editButton.setEnabled(oneSelected && !topLevelSelected); removeButton.setEnabled(oneSelected && !topLevelSelected); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ExtnlResBindSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ExtnlResB0000644000175000017500000003527411665471220033416 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.resource.ExternalResourceDescription; import org.apache.uima.resource.FileLanguageResourceSpecifier; import org.apache.uima.resource.FileResourceSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.impl.ExternalResourceDescription_impl; import org.apache.uima.resource.impl.FileLanguageResourceSpecifier_impl; import org.apache.uima.resource.impl.FileResourceSpecifier_impl; import org.apache.uima.resource.metadata.ExternalResourceBinding; import org.apache.uima.resource.metadata.impl.ExternalResourceBinding_impl; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddExternalResourceDialog; import org.apache.uima.taeconfigurator.wizards.ResourceManagerConfigurationNewWizard; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.IManagedForm; /** */ public class ExtnlResBindSection extends AbstractSection { private final static String boundHeader = "Bound to: "; private Composite sectionClient; private Tree tree; private Button addButton; private Button editButton; private Button removeButton; private Button bindButton; private Button exportButton; private ResourceDependencySection resourceDependencySection; private ImportResBindSection resBindImportSection; public ExtnlResBindSection(MultiPageEditor aEditor, Composite parent) { super( aEditor, parent, "Resources Needs, Definitions and Bindings", "Specify External Resources; Bind them to dependencies on the right panel by selecting the corresponding dependency and clicking Bind."); } public void initialize(IManagedForm form) { super.initialize(form); // set up Composite to hold widgets in the section sectionClient = new2ColumnComposite(getSection()); tree = newTree(sectionClient); // Buttons Composite buttonContainer = newButtonContainer(sectionClient); addButton = newPushButton(buttonContainer, S_ADD, "Click to add a new External Resource definition"); editButton = newPushButton(buttonContainer, S_EDIT, "Click to edit an External Resource definition"); removeButton = newPushButton(buttonContainer, "Remove", "Click to remove selected binding or External Resource"); bindButton = newPushButton(buttonContainer, "Bind", "Click to bind selected dependency with selected Resource"); exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP); buttonContainer.pack(); getSection().getParent().getParent().pack(); getSection().getParent().getParent().layout(); initialFormWidth = getSection().getSize().x; ((GridData) tree.getLayoutData()).widthHint = initialFormWidth - buttonContainer.getSize().x; enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); tree.addListener(SWT.MouseDoubleClick, this); } public void refresh() { if (null == resBindImportSection) resBindImportSection = editor.getResourcesPage().getResBindImportSection(); super.refresh(); resourceDependencySection = editor.getResourcesPage().getResourceDependencySection(); ExternalResourceDescription[] xrds = getExternalResources(); ExternalResourceBinding[] bindings = getExternalResourceBindings(); tree.removeAll(); if (null != xrds) { for (int i = 0; i < xrds.length; i++) { addExternalResourceDescriptionToGUI(xrds[i], bindings); } } enable(); } private void addExternalResourceDescriptionToGUI(ExternalResourceDescription xrd, ExternalResourceBinding[] bindings) { TreeItem item = new TreeItem(tree, SWT.NONE); fillXrdItem(item, xrd); fillBindings(item, xrd, bindings); item.setExpanded(true); } private void fillXrdItem(TreeItem item, ExternalResourceDescription xrd) { StringBuffer text = new StringBuffer(); text.append(xrd.getName()); ResourceSpecifier rs = xrd.getResourceSpecifier(); if (rs instanceof FileLanguageResourceSpecifier) { FileLanguageResourceSpecifier flrs = (FileLanguageResourceSpecifier) rs; text.append(" URL_Prefix: ").append(flrs.getFileUrlPrefix()).append(" URL_Suffix: ") .append(flrs.getFileUrlSuffix()); } else if (rs instanceof FileResourceSpecifier) { FileResourceSpecifier frs = (FileResourceSpecifier) rs; text.append(" URL: ").append(frs.getFileUrl()); } else { text.append(" Custom Resource Specifier"); } String implName = xrd.getImplementationName(); if (null != implName && !implName.equals("")) { text.append(" Implementation: ").append(implName); } item.setText(text.toString()); item.setData(xrd); } private void fillBindings(TreeItem parent, ExternalResourceDescription xrd, ExternalResourceBinding[] bindings) { if (null != bindings) { for (int i = 0; i < bindings.length; i++) { if (bindings[i].getResourceName().equals(xrd.getName())) { addBindingToGUI(parent, bindings[i].getKey(), bindings[i]); } } } } private void addBindingToGUI(TreeItem parent, String key, ExternalResourceBinding xrb) { TreeItem item = new TreeItem(parent, SWT.NONE); item.setText(boundHeader + key); item.setData(xrb); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addButton) handleAdd(); else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) handleEdit(); else if (event.widget == removeButton || (event.widget == tree && event.type == SWT.KeyUp && event.character == SWT.DEL)) handleRemove(); else if (event.widget == bindButton) handleBind(); else if (event.widget == exportButton) { try { resBindImportSection.exportImportablePart("", ResourceManagerConfigurationNewWizard.RESOURCEMANGERCONFIGURATION_TEMPLATE); } finally { refresh(); // update in case of throw, even } } enable(); } public ExternalResourceDescription getXRDescriptionFromTreeItem(TreeItem item) { return (ExternalResourceDescription) item.getData(); } /** * Bindings can't be edited. They can be removed or new ones bound. External resources can be * edited. Edit button is disabled unles an editable thing is selected. But user could double * click an illegal entry * */ private void handleEdit() { TreeItem item = tree.getSelection()[0]; if (isBoundSpec(item)) return; ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(item); ResourceSpecifier rs = xrd.getResourceSpecifier(); if (!((rs instanceof FileResourceSpecifier) || (rs instanceof FileLanguageResourceSpecifier))) { Utility.popMessage("Can''t edit custom resource", "This resource is a '" + rs.getClass().getName() + "', and any edits have to be done directly in the XML in the Source view.", MessageDialog.INFORMATION); return; } AddExternalResourceDialog dialog = new AddExternalResourceDialog(this, xrd); if (dialog.open() == Window.CANCEL) return; alterExistingXRD(dialog, xrd, item); } /** * Add new external resource, with no bindings * */ private void handleAdd() { AddExternalResourceDialog dialog = new AddExternalResourceDialog(this); if (dialog.open() == Window.CANCEL) return; ExternalResourceDescription xrd = new ExternalResourceDescription_impl(); TreeItem item = new TreeItem(tree, SWT.NONE); alterExistingXRD(dialog, xrd, item); getResourceManagerConfiguration().addExternalResource(xrd); } private void alterExistingXRD(AddExternalResourceDialog dialog, ExternalResourceDescription xrd, TreeItem item) { valueChanged = false; xrd.setName(setValueChanged(dialog.xrName, xrd.getName())); xrd.setDescription(setValueChanged(dialog.xrDescription, xrd.getDescription())); xrd .setImplementationName(setValueChanged(dialog.xrImplementation, xrd .getImplementationName())); ResourceSpecifier rs = xrd.getResourceSpecifier(); if (null == dialog.xrUrlSuffix || "".equals(dialog.xrUrlSuffix)) { FileResourceSpecifier frs; if (null != rs && rs instanceof FileResourceSpecifier) { frs = (FileResourceSpecifier) rs; } else { frs = new FileResourceSpecifier_impl(); } frs.setFileUrl(setValueChanged(dialog.xrUrl, frs.getFileUrl())); xrd.setResourceSpecifier(frs); } else { FileLanguageResourceSpecifier flrs; if (null != rs && rs instanceof FileLanguageResourceSpecifier) { flrs = (FileLanguageResourceSpecifier) rs; } else { flrs = new FileLanguageResourceSpecifier_impl(); } flrs.setFileUrlPrefix(setValueChanged(dialog.xrUrl, flrs.getFileUrlPrefix())); flrs.setFileUrlSuffix(setValueChanged(dialog.xrUrlSuffix, flrs.getFileUrlSuffix())); xrd.setResourceSpecifier(flrs); } fillXrdItem(item, xrd); if (valueChanged) setFileDirty(); } /** * Bind button - enabled only when one dependency is selected, and one External Resource, not * already bound to this key, is selected */ private void handleBind() { TreeItem xrItem = tree.getSelection()[0]; if (null != xrItem.getParentItem()) xrItem = xrItem.getParentItem(); ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(xrItem); TableItem keyItem = resourceDependencySection.getTable().getSelection()[0]; ExternalResourceBinding xrb = new ExternalResourceBinding_impl(); String key = keyItem.getText(ResourceDependencySection.KEY_COL); xrb.setKey(key); xrb.setResourceName(xrd.getName()); getResourceManagerConfiguration().addExternalResourceBinding(xrb); addBindingToGUI(xrItem, key, xrb); xrItem.setExpanded(true); keyItem.setText(0, "Bound"); keyItem.getParent().getColumn(0).pack(); setFileDirty(); } /** * remove either a binding or an external resource. Removing the resource removes all bindings * associated with it * */ private void handleRemove() { int selectionCount = tree.getSelectionCount(); if (1 != selectionCount) return; TreeItem item = tree.getSelection()[0]; if (null == item.getParentItem()) { // case of removing a resource if (Window.CANCEL == Utility .popOkCancel("Removing Resource", "Removing an External Resource and all its bindings. Resource name:" + item.getText(), MessageDialog.WARNING)) return; removeAllBindings(item); removeResource(item); } else { // case of removing a binding removeBinding(item); } } public ExternalResourceBinding getXRBindingFromTreeItem(TreeItem item) { return (ExternalResourceBinding) item.getData(); } private void removeBinding(TreeItem item) { ExternalResourceBinding xrb = getXRBindingFromTreeItem(item); getResourceManagerConfiguration().removeExternalResourceBinding(xrb); removeBoundFlagInDependencySection(xrb); item.dispose(); setFileDirty(); } private void removeBoundFlagInDependencySection(ExternalResourceBinding xrb) { String key = xrb.getKey(); TableItem[] items = resourceDependencySection.getTable().getItems(); for (int i = 0; i < items.length; i++) { if (key.equals(items[i].getText(ResourceDependencySection.KEY_COL))) items[i].setText(0, ""); // reset bound } } private void removeAllBindings(TreeItem item) { TreeItem[] items = item.getItems(); for (int i = items.length - 1; i >= 0; i--) { removeBinding(items[i]); } } private void removeResource(TreeItem item) { ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(item); getResourceManagerConfiguration().removeExternalResource(xrd); item.dispose(); setFileDirty(); } public void enable() { // bind enabled when one item in tree and one in table is selected bindButton.setEnabled(tree.getSelectionCount() == 1 && resourceDependencySection.getTable().getSelectionCount() == 1 && "".equals(resourceDependencySection.getTable().getSelection()[0].getText(0))); // not // bound removeButton.setEnabled(tree.getSelectionCount() > 0); editButton.setEnabled(tree.getSelectionCount() == 1 && !isBoundSpec(tree.getSelection()[0])); exportButton.setEnabled(tree.getItemCount() > 0); } private boolean isBoundSpec(TreeItem item) { return item.getText().startsWith(boundHeader); } public boolean resourceNameAlreadyDefined(String name) { ExternalResourceDescription[] xrds = getExternalResources(); if (xrds != null) { for (int i = 0; i < xrds.length; i++) { if (xrds[i].getName().equals(name)) { Utility.popMessage("Name Already Defined", "The External Resource Name specified is already defined", MessageDialog.ERROR); return true; } } } return false; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregateSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Aggregate0000644000175000017500000006546611665471220033444 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.PrintWriter; import java.text.MessageFormat; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Vector; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.resource.PearSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.URISpecifier; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.NameValuePair; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddRemoteServiceDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.FindComponentDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.PickTaeForTypesDialog; import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialogWithFlowOption; import org.apache.uima.taeconfigurator.model.FlowNodes; import org.apache.uima.util.XMLizable; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.forms.IManagedForm; public class AggregateSection extends AbstractSection { private Table filesTable; private Button addButton; private Button addRemoteButton; private Button findAnalysisEngineButton; private Button removeButton; private Button addToFlowButton; private Button removeFromFlowButton; public Button getRemoveFromFlowButton() { return removeFromFlowButton; } private boolean bDisableToolTipHelp = false; /** * Creates a section for aggregate specifiers to add their delegates * * @param editor * backpointer to the main multipage editor * @param parent * the Composite where this section lives */ public AggregateSection(MultiPageEditor aEditor, Composite parent) { super(aEditor, parent, "Component Engines", "The following engines are included in this aggregate."); } /* * Called by the page constructor after all sections are created, to initialize them. * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(this.getSection()); // Table Container has table and buttons on bottom Composite tableContainer = newComposite(sectionClient); enableBorders(tableContainer); toolkit.paintBordersFor(tableContainer); filesTable = newTable(tableContainer, SWT.FULL_SELECTION, 150); filesTable.setHeaderVisible(true); newTableColumn(filesTable, 50, SWT.LEFT, "Delegate"); newTableColumn(filesTable, 75, SWT.LEFT, "Key Name"); // This little code fragment is an attempt to get the right sizing for the buttons // Was wrong on Mac platforms // Word below is the longer of the two words in the button container Button tempForSize = toolkit.createButton(tableContainer, "Remove", SWT.PUSH); Point p = tempForSize.computeSize(SWT.DEFAULT, SWT.DEFAULT); tempForSize.dispose(); Composite bottomButtonContainer = newButtonContainer(tableContainer, HORIZONTAL_BUTTONS, 3* p.x); addButton = newPushButton(bottomButtonContainer, S_ADD, "Click here to add a locally defined AE or CAS Consumer delegate", ENABLED); removeButton = newPushButton(bottomButtonContainer, "Remove", "Click here to remove the selected item", ENABLED); Composite sideButtonContainer = newButtonContainer(sectionClient, VERTICAL_BUTTONS, 80); // this next just serves as a spacer spacer(sideButtonContainer); spacer(sideButtonContainer); addToFlowButton = newPushButton(sideButtonContainer, ">>", "Click here to add the selected item to the flow", !ENABLED); removeFromFlowButton = newPushButton(sideButtonContainer, "<<", "Click here to remove the selected item from the flow", !ENABLED); spacer(sideButtonContainer); addRemoteButton = newPushButton(sideButtonContainer, "AddRemote", "Click here to add a Remote Analysis Engine", ENABLED); findAnalysisEngineButton = newPushButton(sideButtonContainer, "Find AE", "Click here to search for an Analysis Engine", ENABLED); addButton.setSize(removeButton.getSize()); filesTable.addListener(SWT.MouseDown, this); filesTable.addListener(SWT.MouseHover, this); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); // if annotator is primitive - page should be disabled if (!isAggregate()) { filesTable.removeAll(); getSection().setText("Not Used"); getSection().setDescription("This section is only applicable for Aggregate descriptors."); } else { getSection().setText("Component Engines"); getSection().setDescription("The following engines are included in this aggregate."); // these can be changed by direct editing of source Map delegates = getDelegateAnalysisEngineSpecifiersWithImports(); // first clear list // (we do this carefully to preserve order) String[] priorOrderedKeys = new String[filesTable.getItemCount()]; for (int i = 0; i < priorOrderedKeys.length; i++) { priorOrderedKeys[i] = filesTable.getItem(i).getText(1); } filesTable.removeAll(); // get delegate keys HashSet keys = new HashSet(); if (delegates != null) { keys.addAll(delegates.keySet()); } // first add keys that we know about in order as we knew it for (int i = 0; i < priorOrderedKeys.length; i++) { if (keys.contains(priorOrderedKeys[i])) { Object o = delegates.get(priorOrderedKeys[i]); if (o instanceof Import) addFile(o, priorOrderedKeys[i]); keys.remove(priorOrderedKeys[i]); } } Iterator itKeys = keys.iterator(); // add what's left to list while (itKeys.hasNext()) { String key = (String) itKeys.next(); Object o = delegates.get(key); if (o instanceof Import) addFile(o, key); } packTable(filesTable); } enable(); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == addButton) handleAdd(); else if (event.widget == removeButton || (event.type == SWT.KeyUp && event.character == SWT.DEL)) handleRemove(); else if (event.widget == addToFlowButton) handleAddToFlow(); else if (event.widget == removeFromFlowButton) handleRemoveFromFlow(); else if (event.widget == addRemoteButton) handleAddRemote(); else if (event.widget == findAnalysisEngineButton) handleFindAnalysisEngine(); // actions on table else if (event.widget == filesTable) { if (event.type == SWT.Selection) { // if no delegate is selected disable edit and remove boolean bEnableButtons = (filesTable.getSelectionCount() > 0); removeButton.setEnabled(bEnableButtons); addToFlowButton.setEnabled(bEnableButtons); } else if (event.type == SWT.MouseDown && (event.button == 3 || // this is for Macintosh - they just have one button (event.button == 1 && (0 != (event.stateMask & SWT.CTRL))))) { handleTableContextMenuRequest(event); } else if (event.type == SWT.MouseHover && !bDisableToolTipHelp) { handleTableHoverHelp(event); } // Don't need this. Next mouse hover kills tool tip anyway // else if (event.type == SWT.MouseMove) { // filesTable.setToolTipText(""); // } } } private void handleAdd() { MultiResourceSelectionDialogWithFlowOption dialog = new MultiResourceSelectionDialogWithFlowOption( getSection().getShell(), editor.getFile().getProject().getParent(), "Component Engine Selection", editor.getFile().getLocation(), editor); dialog.setTitle("Component Engine Selection"); dialog.setMessage("Select one or more component engines from the workspace:"); if (Window.CANCEL == dialog.open()) { return; } Object[] files = dialog.getResult(); if (files != null && files.length > 0) { for (int i = 0; i < files.length; i++) { FileAndShortName fsn = new FileAndShortName(files[i]); produceKeyAddDelegate(fsn.shortName, fsn.fileName, dialog.getAutoAddToFlow(), dialog.isImportByName); } } } private void produceKeyAddDelegate(String shortName, String fullPathFileName, boolean addToFlow, boolean isImportByName) { boolean bSuccess = false; // key is shortName plus a suffix if needed to make it unique. // The set of existing keys is obtained from the model, // not from the GUI table (as was the case in earlier design) String keyName = produceUniqueComponentKey(shortName); if (null != keyName) { bSuccess = addDelegate(fullPathFileName, shortName, keyName, isImportByName); if (bSuccess) { editor.addDirtyTypeName(""); // force running jcasgen refresh(); // refresh every time to capture the order of items added if (addToFlow) { addNodeToFlow(keyName); } } } } private void handleRemove() { // get the keyName to remove int nSelectionIndex = filesTable.getSelectionIndex(); String key = filesTable.getItem(nSelectionIndex).getText(1); // if delegate is still on flow list warn that it may be removed if (editor.getAggregatePage().getFlowSection().containsNode(key)) { String sCascadeDeleteTitle = "Cascade delete warning"; String sCascadeDeleteMessage = "This will cause a cascading deletion of an associated input, output, index, or type priority. Ok to continue?"; boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle, sCascadeDeleteMessage); if (!bContinue) { return; } } ResourceSpecifier delegate = (ResourceSpecifier) editor.getResolvedDelegates().get(key); // remove the selected delegate from delegate list Map delegatesWithImport = editor.getAeDescription() .getDelegateAnalysisEngineSpecifiersWithImports(); Object savedDelegate1 = delegatesWithImport.get(key); delegatesWithImport.remove(key); Object savedDelegate2 = getDelegateAnalysisEngineSpecifiersWithImports().get(key); getDelegateAnalysisEngineSpecifiersWithImports().remove(key); // update the model: flow lists: remove the item from the flow list // This has to be done before validation - otherwise get validation error. // Support undo FlowNodes flow = new FlowNodes(getAnalysisEngineMetaData().getFlowConstraints()); String[] savedFlowNodes = flow.getFlow(); if (null == savedFlowNodes) savedFlowNodes = stringArray0; // item may be in the flow 0, 1 or more times List nodes = new ArrayList(savedFlowNodes.length); for (int i = 0; i < savedFlowNodes.length; i++) { String flowNode = savedFlowNodes[i]; if (!flowNode.equals(key)) { nodes.add(flowNode); } } flow.setFlow((String[]) nodes.toArray(stringArray0)); if (!isValidAggregateChange()) { getDelegateAnalysisEngineSpecifiersWithImports().put(key, savedDelegate2); delegatesWithImport.put(key, savedDelegate1); flow.setFlow(savedFlowNodes); return; } Map typeNameHash = editor.allTypes.get(); boolean bInputsChanged = !editor.validateInputs(typeNameHash); boolean bOutputsChanged = !editor.validateOutputs(typeNameHash); if (bInputsChanged || bOutputsChanged) { String msg = "Some of the following are no longer valid and have been deleted (or appropriately altered): \n\n"; if (bInputsChanged) { msg += "Inputs \n"; } if (bOutputsChanged) { msg += "Outputs \n"; } Utility.popMessage("Capabilities Changed", msg, MessageDialog.INFORMATION); } SofaMapSection.removeSofaMappings(key, delegate, editor); editor.getAggregatePage().getFlowSection().refresh(); if (filesTable.getItemCount() > nSelectionIndex) { filesTable.setSelection(nSelectionIndex); filesTable.setFocus(); enable(); } refresh(); finishAggregateChangeAction(); // remove still must handle removal of parameters and param settings // removed delegate (if params dont appear elsewhere) } private void handleAddToFlow() { String node = filesTable.getSelection()[0].getText(1); addNodeToFlow(node); getTable().setSelection(-1); enable(); Table flowList = editor.getAggregatePage().getFlowSection().getFlowList(); flowList.setSelection(flowList.getItemCount() - 1); editor.getAggregatePage().getFlowSection().enable(); flowList.setFocus(); } /** * @param node */ private void addNodeToFlow(String node) { FlowSection fs = editor.getAggregatePage().getFlowSection(); fs.addNode(node); // fs.refresh(); // the fs.addNode does a refresh } private void handleRemoveFromFlow() { FlowSection fs = editor.getAggregatePage().getFlowSection(); String selectedKey = fs.getFlowList().getSelection()[0].getText(); fs.handleRemove(); for (int i = 0; i < getTable().getItemCount(); i++) { String thisKey = getTable().getItem(i).getText(1); if (selectedKey.equals(thisKey)) { getTable().setSelection(i); enable(); getTable().setFocus(); break; } } } private final static String REMOTE_TEMPLATE = "\n" + "\n" + " {0}\n" + // AnalysisEngine CasConsumer " {1} \n" + // sURI " {2}\n" + // SOAP or Vinci " {3}" + " {4}" + // for VNS "\n"; private void handleAddRemote() { String sDescriptorPath = editor.getFile().getParent().getLocation().toString() + '/'; AddRemoteServiceDialog dialog = new AddRemoteServiceDialog(this, sDescriptorPath); dialog.open(); if (dialog.getReturnCode() == InputDialog.CANCEL) return; String sServiceType = dialog.getSelectedServiceTypeName(); if (sServiceType != null && !sServiceType.equals("SOAP") && !sServiceType.equals("Vinci")) { return; } String sURI = dialog.getSelectedUri(); String sKey = dialog.getSelectedKey(); if (!isNewKey(sKey)) { Utility.popMessage("Duplicate Key", "You have specified a duplicate key. Please try again.", MessageDialog.ERROR); return; } PrintWriter printWriter = setupToPrintFile(dialog.genFilePath); if (null != printWriter) { String vnsHostPort = ""; if (dialog.vnsHost.length() > 0) { vnsHostPort = MessageFormat.format(" \n", new Object[] { dialog.vnsHost }); } if (dialog.vnsPort.length() > 0) { vnsHostPort += MessageFormat.format(" \n", new Object[] { dialog.vnsPort }); } if (vnsHostPort.length() > 0) vnsHostPort = "\n " + vnsHostPort + " "; printWriter.println(MessageFormat.format(REMOTE_TEMPLATE, new Object[] { dialog.aeOrCc, sURI, sServiceType, dialog.timeout, vnsHostPort })); printWriter.close(); boolean bSuccess = addDelegate(dialog.genFilePath, sKey, sKey, dialog.isImportByName); if (bSuccess) { boolean bAutoAddToFlow = dialog.getAutoAddToFlow(); if (bAutoAddToFlow) { addNodeToFlow(sKey); } refresh(); } } } private static final String[] delegateComponentStringHeadersLC = new String[] { " -1); addButton.setEnabled(!isPrimitive); addRemoteButton.setEnabled(!isPrimitive); findAnalysisEngineButton.setEnabled(!isPrimitive); removeButton.setEnabled(bEnable); addToFlowButton.setEnabled(bEnable); } /** * adds a tableItem to the table * * @param fileName * @param keyName */ private void addFile(Object o, String keyName) { Import impItem = (Import) o; String fileName = impItem.getLocation(); if (null == fileName || (0 == fileName.length())) fileName = impItem.getName(); // create new TableItem TableItem item = new TableItem(filesTable, SWT.NONE); item.setImage(TAEConfiguratorPlugin.getImage(TAEConfiguratorPlugin.IMAGE_ANNOTATOR)); item.setText(0, fileName); item.setText(1, keyName); } public Table getTable() { return filesTable; } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilitySection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Capabilit0000644000175000017500000012047111665471220033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.analysis_engine.impl.TypeOrFeature_impl; import org.apache.uima.analysis_engine.metadata.SofaMapping; import org.apache.uima.cas.Type; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddCapabilityFeatureDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddCapabilityTypeDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddSofaDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.TableTree; import org.eclipse.swt.custom.TableTreeItem; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.forms.IManagedForm; public class CapabilitySection extends AbstractSection { private final static String CAPABILITY_SET = "Set"; private final static String INPUT = "Input"; private final static String OUTPUT = "Output"; public final static String ALL_FEATURES = ""; private final static String TYPE_TITLE = "Type:"; private final static String FEAT_TITLE = "F:"; // not shown, in data field private final static String NAME_TITLE = "Name "; private final static String NAMESPACE_TITLE = "Name Space"; private final static String LANGS_TITLE = "Languages"; private final static String LANG_TITLE = "L:"; // not shown, in datafield private final static String SOFAS_TITLE = "Sofas"; private final static String SOFA_TITLE = "S:"; // not shown, in data field private final static int CS = 1; private final static int TYPE = 1 << 1; private final static int FEAT = 1 << 2; private final static int LANG = 1 << 3; private final static int LANG_ITEM = 1 << 4; private final static int SOFA = 1 << 5; private final static int SOFA_ITEM = 1 << 6; public final static int TITLE_COL = 0; public final static int NAME_COL = 1; public final static int INPUT_COL = 2; public final static int OUTPUT_COL = 3; public final static int NAMESPACE_COL = 4; TableTree tt; // for inner class access private Button addCapabilityButton; private Button addLangButton; private Button addTypeButton; private Button addSofaButton; private Button addEditFeatureButton; private Button editButton; private Button removeButton; private Map typeInfo; private SofaMapSection sofaMapSection; public CapabilitySection(MultiPageEditor aEditor, Composite parent) { super( aEditor, parent, "Component Capabilities", "This section describes the languages handled, and the inputs needed and outputs provided in terms of the Types and Features."); } public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); tt = newTableTree(sectionClient, SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION); Table table = tt.getTable(); // work around for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=65865 new TableColumn(table, SWT.NONE).setText(" "); newTableColumn(table, SWT.NONE).setText(NAME_TITLE); // type or feat name newTableColumn(table, SWT.NONE).setText(INPUT); newTableColumn(table, SWT.NONE).setText(OUTPUT); newTableColumn(table, SWT.NONE).setText(NAMESPACE_TITLE); // rest of typename table.setHeaderVisible(true); table.setLinesVisible(true); tt.addListener(SWT.MouseHover, this); // to show description final Composite buttonContainer = newButtonContainer(sectionClient); addCapabilityButton = newPushButton( buttonContainer, "Add Capability Set", "Analysis Engines can have one or more sets of capabilities; each one describes a set of outputs that are produced, given a particular set of inputs. Click here to add a capability set."); addLangButton = newPushButton(buttonContainer, "Add Language", "Click here to add a Language Capability to the selected set."); addTypeButton = newPushButton(buttonContainer, "Add Type", "Click here to add a Type to the selected capability set."); addSofaButton = newPushButton(buttonContainer, "Add Sofa", "Click here to add a Subject of Analysis (Sofa) to the selected capability set."); addEditFeatureButton = newPushButton(buttonContainer, "Add/Edit Features", "Click here to specify the features of a selected type as input or output"); editButton = newPushButton(buttonContainer, S_EDIT, "Edit the selected item. You can also double-click the item to edit it."); removeButton = newPushButton(buttonContainer, "Remove", "Remove the selected item. You can also press the Delete key to remove an item."); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); sofaMapSection = editor.getCapabilityPage().getSofaMapSection(); tt.getParent().setRedraw(false); tt.removeAll(); Capability[] cs = getCapabilities(); if (null != cs) { for (int i = 0; i < cs.length; i++) { TableTreeItem item = new TableTreeItem(tt, SWT.NONE); item.setText(TITLE_COL, CAPABILITY_SET); item.setData(cs[i]); tt.setSelection(new TableTreeItem[] { item }); // set default selection fillCapability(item, cs[i]); // if (0 == i) { item.setExpanded(true); TableTreeItem[] types = item.getItems(); if (types != null) for (int j = 0; j < types.length; j++) { types[j].setExpanded(true); } // } } } packTable(tt.getTable()); enable(); tt.getParent().setRedraw(true); } /** * value of hash table keyed on type name */ private static class TypeCapability { boolean isInputType; // true if mentioned in boolean isOutputType; // true if mentioned in Map features = new TreeMap(); } private static class FeatureCapability { boolean isInputFeature = false; boolean isOutputType = false; boolean isOutputUpdate = false; } private TableTreeItem createLanguageHeaderGui(TableTreeItem parent) { TableTreeItem langHdr = new TableTreeItem(parent, SWT.NONE); langHdr.setText(TITLE_COL, LANGS_TITLE); langHdr.setData(LANGS_TITLE); return langHdr; } private TableTreeItem createSofaHeaderGui(TableTreeItem parent) { TableTreeItem sofaHdr = new TableTreeItem(parent, SWT.NONE); sofaHdr.setText(TITLE_COL, SOFAS_TITLE); sofaHdr.setData(SOFAS_TITLE); return sofaHdr; } private void fillCapability(TableTreeItem parent, Capability c) { // first output language capabilities TableTreeItem langHdr = createLanguageHeaderGui(parent); String[] languages = c.getLanguagesSupported(); if (null != languages) { for (int i = 0; i < languages.length; i++) { TableTreeItem lItem = new TableTreeItem(langHdr, SWT.NONE); lItem.setData(LANG_TITLE); lItem.setText(NAME_COL, languages[i]); } } // second, output Sofas TableTreeItem sofaHdr = createSofaHeaderGui(parent); String[] inputSofaNames = c.getInputSofas(); String[] outputSofaNames = c.getOutputSofas(); Arrays.sort(inputSofaNames); Arrays.sort(outputSofaNames); for (int i = 0; i < inputSofaNames.length; i++) { TableTreeItem item = new TableTreeItem(sofaHdr, SWT.NONE); setGuiSofaName(item, inputSofaNames[i], true); } for (int i = 0; i < outputSofaNames.length; i++) { TableTreeItem item = new TableTreeItem(sofaHdr, SWT.NONE); setGuiSofaName(item, outputSofaNames[i], false); } // scan capability, collecting for each type: // inputs, outputs, updatesToInputs(features) // (updatesToInputs are output features without corresponding output type) // , or or feature set // For each item, generate minimal number of Type items: TypeCapability tc = null; FeatureCapability fc; TypeOrFeature[] inputs = c.getInputs(); TypeOrFeature[] outputs = c.getOutputs(); typeInfo = new TreeMap(); if (null != inputs) { for (int i = 0; i < inputs.length; i++) { String name = inputs[i].getName(); if (inputs[i].isType()) { tc = getTypeCapability(name); tc.isInputType = true; if (inputs[i].isAllAnnotatorFeatures()) { fc = getFeatureCapability(tc, ALL_FEATURES); fc.isInputFeature = true; } } else { tc = getTypeCapability(getTypeNameFromFullFeatureName(name)); // create a typecapability // if one doesn't exist fc = getFeatureCapability(tc, getShortFeatureName(name)); fc.isInputFeature = true; } } } if (null != outputs) { for (int i = 0; i < outputs.length; i++) { String name = outputs[i].getName(); if (outputs[i].isType()) { tc = getTypeCapability(name); tc.isOutputType = true; if (outputs[i].isAllAnnotatorFeatures()) { fc = getFeatureCapability(tc, ALL_FEATURES); fc.isOutputType = true; } } else { tc = getTypeCapability(getTypeNameFromFullFeatureName(name)); fc = getFeatureCapability(tc, getShortFeatureName(name)); fc.isOutputUpdate = true; } } } for (Iterator it = typeInfo.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String typeName = (String) entry.getKey(); tc = (TypeCapability) entry.getValue(); TableTreeItem item = new TableTreeItem(parent, SWT.NONE); setGuiTypeName(item, typeName); if (tc.isInputType) item.setText(INPUT_COL, INPUT); if (tc.isOutputType) item.setText(OUTPUT_COL, OUTPUT); for (Iterator fit = tc.features.entrySet().iterator(); fit.hasNext();) { Map.Entry fEntry = (Map.Entry) fit.next(); String featName = (String) fEntry.getKey(); fc = (FeatureCapability) fEntry.getValue(); TableTreeItem fItem = new TableTreeItem(item, SWT.NONE); fItem.setData(FEAT_TITLE); fItem.setText(NAME_COL, featName); if (fc.isInputFeature) fItem.setText(INPUT_COL, INPUT); if (fc.isOutputUpdate || fc.isOutputType) { fItem.setText(OUTPUT_COL, OUTPUT); } } } } private void setGuiTypeName(TableTreeItem item, String typeName) { item.setText(TITLE_COL, TYPE_TITLE); item.setText(NAME_COL, getShortName(typeName)); item.setText(NAMESPACE_COL, getNameSpace(typeName)); } private void setGuiSofaName(TableTreeItem item, String sofaName, boolean isInput) { item.setData(SOFA_TITLE); item.setText(NAME_COL, sofaName); if (isInput) { item.setText(INPUT_COL, INPUT); item.setText(OUTPUT_COL, ""); } else { item.setText(OUTPUT_COL, OUTPUT); item.setText(INPUT_COL, ""); } } private TypeCapability getTypeCapability(String typeName) { TypeCapability typeCapability = (TypeCapability) typeInfo.get(typeName); if (null == typeCapability) { typeInfo.put(typeName, typeCapability = new TypeCapability()); } return typeCapability; } private FeatureCapability getFeatureCapability(TypeCapability tc, String featureShortName) { FeatureCapability fc = (FeatureCapability) tc.features.get(featureShortName); if (null == fc) { tc.features.put(featureShortName, fc = new FeatureCapability()); } return fc; } public String getTypeNameFromFullFeatureName(String name) { return (name.substring(0, name.indexOf(":"))); } /* * (non-Javadoc) * * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.type == SWT.Expand || event.type == SWT.Collapse) { pack04(); return; } if (event.widget == addCapabilityButton) { handleAddCapability(); enable(); return; } TableTreeItem selItem = tt.getSelection()[0]; int itemKind = getItemKind(selItem); if (event.widget == addLangButton) { handleAddLang(selItem, itemKind); } else if (event.widget == addTypeButton) { handleAddType(selItem, itemKind); } else if (event.widget == addSofaButton) { handleAddSofa(selItem, itemKind); } else if (event.widget == addEditFeatureButton) { handleAddEditFeature(selItem, itemKind); } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) { handleEdit(selItem, itemKind); } else if (event.widget == removeButton || (event.widget == tt.getTable() && event.type == SWT.KeyUp && event.character == SWT.DEL)) { handleRemove(selItem, itemKind); } enable(); } private void handleAddCapability() { Capability newCset = addCapabilitySet(); // update the GUI TableTreeItem item = new TableTreeItem(tt, SWT.NONE); item.setText(CAPABILITY_SET); item.setData(newCset); createLanguageHeaderGui(item); createSofaHeaderGui(item); item.setExpanded(true); tt.setSelection(new TableTreeItem[] { item }); if (tt.getItemCount() == 1) tt.getTable().getColumn(TITLE_COL).pack(); finishAction(); } private void getOrCreateAllFeatItem(TableTreeItem editItem, int column, String inOrOut) { TableTreeItem allFeatItem = getAllFeatItem(editItem); if (null == allFeatItem) { allFeatItem = new TableTreeItem(editItem, SWT.NONE, 0); allFeatItem.setData(FEAT_TITLE); allFeatItem.setText(NAME_COL, ALL_FEATURES); } allFeatItem.setText(column, inOrOut); } private TableTreeItem getAllFeatItem(TableTreeItem editItem) { TableTreeItem[] subItems = editItem.getItems(); if (null == subItems || subItems.length == 0) return null; TableTreeItem item = subItems[0]; if (ALL_FEATURES.equals(item.getText(NAME_COL))) return item; return null; } private void removeAllFeatItemGui(TableTreeItem editItem, int column) { TableTreeItem allFeatItem = getAllFeatItem(editItem); if (null == allFeatItem) // throw new InternalErrorCDE("invalid state"); return; // happens when no allfeat is set allFeatItem.setText(column, ""); String otherCol = allFeatItem.getText((column == INPUT_COL) ? OUTPUT_COL : INPUT_COL); if (null == otherCol || "".equals(otherCol)) allFeatItem.dispose(); } private void handleEdit(TableTreeItem editItem, int itemKind) { Capability c = getCapability(editItem); switch (itemKind) { case SOFA_ITEM: { boolean existingIsInput = INPUT.equals(editItem.getText(INPUT_COL)); String existingSofaName = editItem.getText(NAME_COL); AddSofaDialog dialog = new AddSofaDialog(this, c, existingSofaName, existingIsInput); if (dialog.open() == Window.CANCEL) return; if (dialog.isInput == existingIsInput && dialog.sofaName.equals(existingSofaName)) return; // MODEL UPDATING // if rename, // update entry or remove / add entry // DO FOR ALL INSTANCES IN ALL CAPABILITY SETS. // change name in all mappings // if switch from input to output, delete from one array, add to other, // mappings: no change (maybe the user switches the other items too). if (Window.CANCEL == Utility .popOkCancel( "Confirm Change to all Capability Sets", "This edit operation will change the Sofa in all Capability Sets in which it is defined. Please confirm.", MessageDialog.WARNING)) return; final Capability[] cSets = getCapabilities(); for (int i = 0; i < cSets.length; i++) { boolean wasRemoved; String[] prevSofas; if (existingIsInput) { cSets[i].setInputSofas((String[]) Utility.removeElementsFromArray(prevSofas = cSets[i] .getInputSofas(), existingSofaName, String.class)); wasRemoved = prevSofas != cSets[i].getInputSofas(); } else { cSets[i].setOutputSofas((String[]) Utility.removeElementsFromArray(prevSofas = cSets[i] .getOutputSofas(), existingSofaName, String.class)); wasRemoved = prevSofas != cSets[i].getOutputSofas(); } if (wasRemoved) { if (dialog.isInput) { cSets[i].setInputSofas(stringArrayAdd(cSets[i].getInputSofas(), dialog.sofaName)); } else { cSets[i].setOutputSofas(stringArrayAdd(cSets[i].getOutputSofas(), dialog.sofaName)); } } } if (!dialog.sofaName.equals(existingSofaName)) { // rename in mappings SofaMapping[] mappings = getSofaMappings(); for (int i = 0; i < mappings.length; i++) { if (existingSofaName.equals(mappings[i].getAggregateSofaName())) { mappings[i].setAggregateSofaName(dialog.sofaName); } } } // GUI updating: // setGuiSofaName(editItem, dialog.sofaName, dialog.isInput); refresh(); // because multiple capability sets may have changed sofaMapSection.markStale(); finishAction(); pack04(); break; } case TYPE: { AddCapabilityTypeDialog dialog = new AddCapabilityTypeDialog(this, c, editItem); if (dialog.open() == Window.CANCEL) return; TypeOrFeature typeInput = getTypeOrFeature(c.getInputs(), getFullyQualifiedName(editItem)); if (dialog.inputs[0]) { if (null == typeInput) { c.addInputType(dialog.types[0], true); // add all-features getOrCreateAllFeatItem(editItem, INPUT_COL, INPUT); } } else if (null != typeInput) { // check for any input features done in dialog c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), typeInput)); removeAllFeatItemGui(editItem, INPUT_COL); } TypeOrFeature typeOutput = getTypeOrFeature(c.getOutputs(), getFullyQualifiedName(editItem)); if (dialog.outputs[0]) { if (null == typeOutput) { c.addOutputType(dialog.types[0], true); getOrCreateAllFeatItem(editItem, OUTPUT_COL, OUTPUT); } } else if (null != typeOutput) { c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), typeOutput)); removeAllFeatItemGui(editItem, OUTPUT_COL); } if (dialog.inputs[0] || dialog.outputs[0]) { editItem.setText(INPUT_COL, dialog.inputs[0] ? INPUT : ""); editItem.setText(OUTPUT_COL, dialog.outputs[0] ? OUTPUT : ""); } else { editItem.dispose(); pack04(); } finishAction(); break; } case LANG_ITEM: { CommonInputDialog dialog = new CommonInputDialog( this, "Edit Language", "Enter a two letter ISO-639 language code, followed optionally by a two-letter ISO-3166 country code (Examples: fr or fr-CA)", CommonInputDialog.LANGUAGE, editItem.getText(NAME_COL)); if (dialogForLanguage(c, dialog) == Window.CANCEL) return; c.getLanguagesSupported()[getIndex(editItem)] = dialog.getValue(); // update GUI editItem.setText(NAME_COL, dialog.getValue()); finishAction(); break; } case FEAT: { TableTreeItem typeItem = editItem.getParentItem(); String typeName = getFullyQualifiedName(typeItem); // using the CAS to get all the inherited features Type type = editor.getCurrentView().getTypeSystem().getType(typeName); AddCapabilityFeatureDialog dialog = new AddCapabilityFeatureDialog(this, type, c); if (dialog.open() == Window.CANCEL) return; addOrEditFeature(dialog, typeName, typeItem, c); break; } default: break; // happens when mouse double click on non-editable item - ignore } } private boolean anyCapabilitySetDeclaresSofa(String name, boolean isInput) { final Capability[] cSets = getAnalysisEngineMetaData().getCapabilities(); for (int i = 0; i < cSets.length; i++) { final String[] sofaNames = isInput ? cSets[i].getInputSofas() : cSets[i].getOutputSofas(); for (int j = 0; j < sofaNames.length; j++) { if (name.equals(sofaNames[j])) return true; } } return false; } private void handleRemove(TableTreeItem removeItem, int itemKind) { Table table = tt.getTable(); int previousSelection = table.getSelectionIndex() - 1; Capability c = getCapability(removeItem); switch (itemKind) { case CS: { if (Window.CANCEL == Utility.popOkCancel("Confirm Remove", "This action will remove an entire capability set. Please confirm.", MessageDialog.WARNING)) { table.setSelection(table.getSelectionIndex() + 1); return; } removeCapabilitySet(c); removeItem.dispose(); break; } case LANG_ITEM: { c.setLanguagesSupported(stringArrayRemove(c.getLanguagesSupported(), removeItem .getText(NAME_COL))); removeItem.dispose(); break; } case SOFA_ITEM: { if (Window.CANCEL == Utility .popOkCancel( "Confirm Removal of Sofa", "This action will remove this Sofa as a capability, and delete its mappings if no other capability set declares this Sofa." + " Please confirm.", MessageDialog.WARNING)) { table.setSelection(table.getSelectionIndex() + 1); return; } String sofaName = removeItem.getText(NAME_COL); boolean isInput = INPUT.equals(removeItem.getText(INPUT_COL)); if (isInput) c.setInputSofas((String[]) Utility.removeElementFromArray(c.getInputSofas(), sofaName, String.class)); else c.setOutputSofas((String[]) Utility.removeElementFromArray(c.getOutputSofas(), sofaName, String.class)); removeItem.dispose(); if (!anyCapabilitySetDeclaresSofa(sofaName, isInput)) { Comparator comparator = new Comparator() { public int compare(Object o1, Object o2) { String name = (String) o1; SofaMapping sofaMapping = (SofaMapping) o2; if (name.equals(sofaMapping.getAggregateSofaName())) return 0; return 1; } }; editor.getAeDescription().setSofaMappings( (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), sofaName, SofaMapping.class, comparator)); sofaMapSection.markStale(); } break; } case TYPE: { if (Window.CANCEL == Utility.popOkCancel("Confirm Removal of Type", "This action will remove this type as a capability. Please confirm.", MessageDialog.WARNING)) { table.setSelection(table.getSelectionIndex() + 1); return; } TableTreeItem[] features = removeItem.getItems(); if (null != features) for (int i = 0; i < features.length; i++) { removeFeature(c, features[i]); } String typeNameToRemove = getFullyQualifiedName(removeItem); if (isInput(removeItem)) c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), typeNameToRemove)); if (isOutput(removeItem) /* || isUpdate(removeItem) */) c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), typeNameToRemove)); removeItem.dispose(); break; } case FEAT: { removeFeature(c, removeItem); break; } default: throw new InternalErrorCDE("invalid state"); } table.setSelection(previousSelection); finishAction(); } private void removeCapabilitySet(Capability c) { Capability[] cs = getAnalysisEngineMetaData().getCapabilities(); Capability[] newCs = new Capability[cs.length - 1]; for (int i = 0, j = 0; i < newCs.length; i++) { if (cs[i] != c) newCs[j++] = cs[i]; } getAnalysisEngineMetaData().setCapabilities(newCs); } private boolean isInput(TableTreeItem item) { return INPUT.equals(item.getText(INPUT_COL)); // works if getText() returns null } private boolean isOutput(TableTreeItem item) { return OUTPUT.equals(item.getText(OUTPUT_COL)); } public static boolean isInput(String fullFeatureName, Capability c) { return null != getTypeOrFeature(c.getInputs(), fullFeatureName); } public static boolean isOutput(String fullFeatureName, Capability c) { return null != getTypeOrFeature(c.getOutputs(), fullFeatureName); } private void removeFeature(Capability c, TableTreeItem removeItem) { String shortFeatureName = removeItem.getText(NAME_COL); if (shortFeatureName.equals(ALL_FEATURES)) { if (isInput(removeItem)) { TypeOrFeature tfItem = getTypeOrFeature(c.getInputs(), getFullyQualifiedName(removeItem .getParentItem())); tfItem.setAllAnnotatorFeatures(false); } if (isOutput(removeItem) /* || isUpdate(removeItem) */) { TypeOrFeature tfItem = getTypeOrFeature(c.getOutputs(), getFullyQualifiedName(removeItem .getParentItem())); tfItem.setAllAnnotatorFeatures(false); } } else { String featureNameToRemove = getFullyQualifiedName(removeItem.getParentItem()) + ":" + removeItem.getText(NAME_COL); if (isInput(removeItem)) c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), featureNameToRemove)); if (isOutput(removeItem) /* || isUpdate(removeItem) */) c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), featureNameToRemove)); } removeItem.dispose(); } public Capability getCapabilityFromTableTreeItem(TableTreeItem item) { return (Capability) item.getData(); } private void handleAddLang(TableTreeItem selItem, int itemKind) { if (itemKind == CS) selItem = selItem.getItems()[0]; // lang is 1st item in capability set else if (itemKind == LANG_ITEM) selItem = selItem.getParentItem(); else if (itemKind == TYPE || itemKind == SOFA) selItem = selItem.getParentItem().getItems()[0]; else if (itemKind == FEAT || itemKind == SOFA_ITEM) selItem = selItem.getParentItem().getParentItem().getItems()[0]; Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem()); CommonInputDialog dialog = new CommonInputDialog( this, "Add Language", "Enter a two letter ISO-639 language code, followed optionally by a two-letter ISO-3166 country code (Examples: fr or fr-CA)", CommonInputDialog.LANGUAGE); if (dialogForLanguage(c, dialog) == Window.CANCEL) return; c.setLanguagesSupported(stringArrayAdd(c.getLanguagesSupported(), dialog.getValue())); // update GUI TableTreeItem lItem = new TableTreeItem(selItem, SWT.NONE); lItem.setData(LANG_TITLE); lItem.setText(NAME_COL, dialog.getValue()); selItem.setExpanded(true); pack04(); finishAction(); } private void handleAddType(TableTreeItem selItem, int itemKind) { if (itemKind == LANG || itemKind == TYPE || itemKind == SOFA) selItem = selItem.getParentItem(); else if (itemKind == LANG_ITEM || itemKind == FEAT || itemKind == SOFA_ITEM) selItem = selItem.getParentItem().getParentItem(); Capability c = getCapabilityFromTableTreeItem(selItem); AddCapabilityTypeDialog dialog = new AddCapabilityTypeDialog(this, c); if (dialog.open() == Window.CANCEL) return; for (int i = 0; i < dialog.types.length; i++) { if (dialog.inputs[i]) c.addInputType(dialog.types[i], dialog.inputs[i]); if (dialog.outputs[i]) c.addOutputType(dialog.types[i], dialog.outputs[i]); TableTreeItem item = new TableTreeItem(selItem, SWT.NONE); setGuiTypeName(item, dialog.types[i]); item.setText(INPUT_COL, dialog.inputs[i] ? INPUT : ""); item.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : ""); TableTreeItem fItem = new TableTreeItem(item, SWT.NONE); fItem.setData(FEAT_TITLE); fItem.setText(NAME_COL, ALL_FEATURES); fItem.setText(INPUT_COL, dialog.inputs[i] ? INPUT : ""); fItem.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : ""); item.setExpanded(true); } pack04(); selItem.setExpanded(true); finishAction(); } private void handleAddSofa(TableTreeItem selItem, int itemKind) { if (itemKind == CS) selItem = selItem.getItems()[1]; else if (itemKind == LANG || itemKind == TYPE) selItem = selItem.getParentItem().getItems()[1]; else if (itemKind == LANG_ITEM || itemKind == FEAT || itemKind == SOFA_ITEM) selItem = selItem.getParentItem().getParentItem().getItems()[1]; Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem()); AddSofaDialog dialog = new AddSofaDialog(this, c); if (dialog.open() == Window.CANCEL) return; // dialog.isInput, dialog.sofaName if (dialog.isInput) c.setInputSofas(stringArrayAdd(c.getInputSofas(), dialog.sofaName)); else c.setOutputSofas(stringArrayAdd(c.getOutputSofas(), dialog.sofaName)); TableTreeItem item = new TableTreeItem(selItem, SWT.NONE); setGuiSofaName(item, dialog.sofaName, dialog.isInput); selItem.setExpanded(true); pack04(); sofaMapSection.markStale(); finishAction(); } private void handleAddEditFeature(TableTreeItem selItem, int itemKind) { if (itemKind == FEAT) selItem = selItem.getParentItem(); Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem()); String typeName = getFullyQualifiedName(selItem); // using the CAS to get all the inherited features Type type = editor.getCurrentView().getTypeSystem().getType(typeName); AddCapabilityFeatureDialog dialog = new AddCapabilityFeatureDialog(this, type, c); if (dialog.open() == Window.CANCEL) return; addOrEditFeature(dialog, typeName, selItem, c); } private void addOrEditFeature(AddCapabilityFeatureDialog dialog, String typeName, // fully // qualified TableTreeItem parentItem, Capability c) { // set the flag on the type in the model, for input and output c.setInputs(setAllFeatures(c.getInputs(), typeName, dialog.allFeaturesInput)); // The logic for output features is complicated. Output features are always listed in the // outputs section of the capability. // Their type must be in either the output section or the input section. // When a feature is added here as an output, and the input section has a type, // we don't require that there be a type capability with output marked. // If the user wants to have an output type, // they can add one explicitly. // There must be either an input or an output Type in order for a feature to be added. // // For the "all features" case, we can't set an output state for all features on an input type. if (dialog.allFeaturesOutput && (null == getTypeOrFeature(c.getOutputs(), typeName))) { Utility .popMessage( "Unable to set AllFeatures", "Skipping setting of for output, because you must have the type specified itself" + " as an output in order to set the . You can individually set all the features, instead.", MessageDialog.WARNING); dialog.allFeaturesOutput = false; } else c.setOutputs(setAllFeatures(c.getOutputs(), typeName, dialog.allFeaturesOutput)); TableTreeItem[] prevFeatGUI = parentItem.getItems(); for (int i = 0; i < prevFeatGUI.length; i++) { prevFeatGUI[i].dispose(); } // update GUI for - add element if needed if (dialog.allFeaturesInput || dialog.allFeaturesOutput) { TableTreeItem item = new TableTreeItem(parentItem, SWT.NONE); item.setData(FEAT_TITLE); item.setText(NAME_COL, ALL_FEATURES); item.setText(INPUT_COL, dialog.allFeaturesInput ? INPUT : ""); item.setText(OUTPUT_COL, dialog.allFeaturesOutput ? OUTPUT : ""); } List inputsL = new ArrayList(); List outputsL = new ArrayList(); for (int i = 0; i < dialog.features.length; i++) { String fullName = typeName + ":" + dialog.features[i]; if (dialog.inputs[i]) inputsL.add(newFeature(fullName)); if (dialog.outputs[i]) outputsL.add(newFeature(fullName)); // update the GUI TableTreeItem item = new TableTreeItem(parentItem, SWT.NONE); item.setData(FEAT_TITLE); item.setText(NAME_COL, dialog.features[i]); item.setText(INPUT_COL, dialog.inputs[i] ? INPUT : ""); item.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : ""); } parentItem.setExpanded(true); tt.getTable().getColumn(NAME_COL).pack(); tt.setSelection(new TableTreeItem[] { parentItem }); c.setInputs(replaceFeaturesKeepingTypes(c.getInputs(), typeName, inputsL)); c.setOutputs(replaceFeaturesKeepingTypes(c.getOutputs(), typeName, outputsL)); finishAction(); } private TypeOrFeature newFeature(String name) { TypeOrFeature result = new TypeOrFeature_impl(); result.setType(false); result.setName(name); return result; } public String getFullyQualifiedName(TableTreeItem item) { String namespace = item.getText(NAMESPACE_COL); String name = item.getText(NAME_COL); return "".equals(namespace) ? name : namespace + "." + name; } // used by dialog table -has different columns public String getFullyQualifiedName(String namespace, String name) { return (null == namespace || "".equals(namespace)) ? name : namespace + "." + name; } /** * Given a current list of inputs/ outputs, made up of "Types" and "features", make a new list * keeping all the types, and keeping all the features that belong to other types, and adding the * features that are passed in for one particular type in the "features" parameter * * @param items * @param type * A string representing the fully qualified type name * @param features - * associated with the type * @return */ private TypeOrFeature[] replaceFeaturesKeepingTypes(TypeOrFeature[] items, String typeName, List features) { List newItems = new ArrayList(); typeName = typeName + ':'; if (null != items) for (int i = 0; i < items.length; i++) { if (items[i].isType() || !items[i].getName().startsWith(typeName)) newItems.add(items[i]); } for (Iterator it = features.iterator(); it.hasNext();) { newItems.add(it.next()); } return (TypeOrFeature[]) newItems.toArray(new TypeOrFeature[newItems.size()]); } /** * * @param items * Existing array of TypeOrFeature items (input or output) * @param typeName * @param isAllFeatures * AllFeatures value * @return */ private TypeOrFeature[] setAllFeatures(TypeOrFeature[] items, String typeName, boolean isAllFeatures) { TypeOrFeature type = getTypeOrFeature(items, typeName); if (null != type) { type.setAllAnnotatorFeatures(isAllFeatures); return items; } // If get here, case = Type declared as Output(input) or not at all while all Features // declared as Input (output) // Need to add the Type and set the all annotator features value if (isAllFeatures) throw new InternalErrorCDE("invalid state"); return items; } private void finishAction() { setFileDirty(); } private void pack04() { tt.getTable().getColumn(TITLE_COL).pack(); tt.getTable().getColumn(NAME_COL).pack(); tt.getTable().getColumn(NAMESPACE_COL).pack(); } private int getItemKind(TableTreeItem item) { String itemID = item.getText(TITLE_COL); if (CAPABILITY_SET.equals(itemID)) return CS; if (TYPE_TITLE.equals(itemID)) return TYPE; itemID = (String) item.getData(); if (LANGS_TITLE.equals(itemID)) return LANG; if (FEAT_TITLE.equals(itemID)) return FEAT; if (LANG_TITLE.equals(itemID)) return LANG_ITEM; if (SOFAS_TITLE.equals(itemID)) return SOFA; if (SOFA_TITLE.equals(itemID)) return SOFA_ITEM; throw new InternalErrorCDE("invalid state"); } public void enable() { addCapabilityButton.setEnabled(true); boolean selectOK = tt.getSelectionCount() == 1; TableTreeItem item = selectOK ? tt.getSelection()[0] : null; int kind = selectOK ? getItemKind(item) : 0; addLangButton.setEnabled(selectOK); addTypeButton.setEnabled(selectOK); addSofaButton.setEnabled(selectOK); addEditFeatureButton.setEnabled((kind & (FEAT + TYPE)) > 0); editButton.setEnabled((kind & (SOFA_ITEM + LANG_ITEM + FEAT + TYPE)) > 0); removeButton.setEnabled((kind & (CS + SOFA_ITEM + LANG_ITEM + FEAT + TYPE)) > 0); } private int dialogForLanguage(Capability c, CommonInputDialog dialog) { for (;;) { if (dialog.open() == Window.CANCEL) return Window.CANCEL; String[] languages = c.getLanguagesSupported(); boolean alreadySpecified = false; for (int i = 0; i < languages.length; i++) { if (languages[i].equals(dialog.getValue())) { Utility .popMessage( "Language spec already defined", "The language specification you entered is already specified.\nPlease enter a different specification, or Cancel this operation." + "\n\nLanguage: " + dialog.getValue(), MessageDialog.ERROR); alreadySpecified = true; break; } } if (!alreadySpecified) break; } return Window.OK; } private Capability getCapability(TableTreeItem item) { while (null != item.getParentItem()) item = item.getParentItem(); return getCapabilityFromTableTreeItem(item); } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PrimitiveSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Primitive0000644000175000017500000002145511665471220033514 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.text.MessageFormat; import org.apache.uima.Constants; import org.apache.uima.resource.metadata.OperationalProperties; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.core.runtime.Platform; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.ui.IJavaElementSearchConstants; import org.eclipse.jdt.ui.JavaUI; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.SelectionDialog; import org.eclipse.ui.forms.IManagedForm; /** * This class is misnamed - refers really to Runtime Information * */ public class PrimitiveSection extends AbstractSection { public void enable() { } private Label implNameLabel; private Text implName; private Button findButton; private Button multipleDeploymentAllowed; private Button modifiesCas; private Button outputsNewCASes; /** * Creates a section with a text field for the name of the annotator. Only enabled if annotator is * primitive Also has the operational parameters */ public PrimitiveSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Runtime Information", "This section describes information about how to run this component"); } public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(getSection()); enableBorders(sectionClient); modifiesCas = newCheckBox(sectionClient, "updates the CAS", "check this if this component updates the CAS"); spacer(sectionClient); if (isAeDescriptor() || isCasConsumerDescriptor() || isFlowControllerDescriptor()) { multipleDeploymentAllowed = newCheckBox(sectionClient, "multiple deployment allowed", "check this to allow multiple instances of this engine to be deployed that can run in parallel"); spacer(sectionClient); } if (isAeDescriptor()) { outputsNewCASes = newCheckBox(sectionClient, "Outputs new CASes", "check this for primitive components that output new CASes, " + "or for aggregates which contain a CAS Multiplier, " + "where the new CASes are returned out of the aggregate."); spacer(sectionClient); } implNameLabel = newLabelWithData(sectionClient, ""); implName = newTextWithTip(sectionClient, "", ""); spacer(sectionClient); // skip first column findButton = newPushButton(sectionClient, "Browse", "", true, SWT.RIGHT); // next line makes the browse button just big enough for the text, // otherwise it's very long... findButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END)); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); // set description for enter field (either .class or .dll file) String implKind = editor.getAeDescription().getFrameworkImplementation(); if (Constants.CPP_FRAMEWORK_NAME.equals(implKind)) { implNameLabel.setText("Name of the .dll file"); implName.setToolTipText("Enter the name of the .dll file here."); findButton.setToolTipText("Browse the file system for the .dll file."); } else { implNameLabel.setText("Name of the Java class file"); implName.setToolTipText("Enter the name of the Java class that implements this component."); findButton.setToolTipText("Browse for the Java class that implmenets this component."); } if (isPrimitive()) { setEnabled(true); // AnnotatorImplementationName may be null // due to change from aggregate to primitive String modelImplName = editor.getAeDescription().getAnnotatorImplementationName(); implName.setText(convertNull(modelImplName)); this.getSection().layout(); } else { implName.setText(""); setEnabled(false); } OperationalProperties ops = getOperationalProperties(); if (null != ops) { setButtonSelection(modifiesCas, ops.getModifiesCas()); setButtonSelection(multipleDeploymentAllowed, ops.isMultipleDeploymentAllowed()); setButtonSelection(outputsNewCASes, ops.getOutputsNewCASes()); } else { setButtonSelection(modifiesCas, true); setButtonSelection(multipleDeploymentAllowed, false); setButtonSelection(outputsNewCASes, false); } } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { valueChanged = false; OperationalProperties ops = getOperationalProperties(); if (event.widget == findButton) { String className = null; try { String implKind = editor.getAeDescription().getFrameworkImplementation(); if (Constants.CPP_FRAMEWORK_NAME.equals(implKind)) { FileDialog dialog = new FileDialog(getSection().getShell(), SWT.NONE); String[] extensions = { "*.dll" }; dialog.setFilterExtensions(extensions); String sStartDir = Platform.getLocation().toString(); dialog.setFilterPath(sStartDir); className = dialog.open(); } else { SelectionDialog typeDialog = JavaUI.createTypeDialog(getSection().getShell(), editor .getEditorSite().getWorkbenchWindow(), editor.getSearchScopeForDescriptorType(), IJavaElementSearchConstants.CONSIDER_CLASSES, false, "*"); typeDialog.setTitle(MessageFormat.format("Choose the {0} implementation class", new Object[] { editor.descriptorTypeString() })); typeDialog.setMessage("Filter/mask:"); if (typeDialog.open() == Window.CANCEL) return; Object[] result = typeDialog.getResult(); if (result != null && result.length > 0) className = ((IType) result[0]).getFullyQualifiedName(); } if (className == null || className.equals("")) //$NON-NLS-1$ return; implName.setText(className); editor.getAeDescription().setAnnotatorImplementationName(className); valueChanged = true; } catch (JavaModelException e) { throw new InternalErrorCDE("unexpected Exception", e); } } else if (event.widget == modifiesCas) { ops.setModifiesCas(setValueChangedBoolean(modifiesCas.getSelection(), ops.getModifiesCas())); } else if (event.widget == multipleDeploymentAllowed) { ops.setMultipleDeploymentAllowed(setValueChangedBoolean(multipleDeploymentAllowed .getSelection(), ops.isMultipleDeploymentAllowed())); } else if (event.widget == outputsNewCASes) { ops.setOutputsNewCASes(setValueChangedBoolean(outputsNewCASes.getSelection(), ops .getOutputsNewCASes())); } else if (event.widget == implName) { editor.getAeDescription().setAnnotatorImplementationName( setValueChanged(implName.getText(), editor.getAeDescription() .getAnnotatorImplementationName())); } if (valueChanged) editor.setFileDirty(); } /** * @param enabled * indicator for the section to be enabled. */ public void setEnabled(boolean enabled) { implNameLabel.setEnabled(enabled); implName.setEnabled(enabled); findButton.setEnabled(enabled); enableCtrl(modifiesCas, true); enableCtrl(multipleDeploymentAllowed, true); enableCtrl(outputsNewCASes, true); } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FlowSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FlowSecti0000644000175000017500000006130311665471220033437 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.text.MessageFormat; import java.util.List; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.metadata.CapabilityLanguageFlow; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.FlowConstraints; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.analysis_engine.metadata.impl.CapabilityLanguageFlow_impl; import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl; import org.apache.uima.analysis_engine.metadata.impl.FlowControllerDeclaration_impl; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.resource.metadata.Import; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.FindComponentDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.PickTaeForTypesDialog; import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialog; import org.apache.uima.taeconfigurator.model.FlowNodes; import org.apache.uima.util.XMLizable; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.forms.IManagedForm; public class FlowSection extends AbstractSection { public static final String FIXED_FLOW = "Fixed Flow"; //$NON-NLS-1$ public static final String CAPABILITY_LANGUAGE_FLOW = "Capability Language Flow"; //$NON-NLS-1$ public static final String USER_DEFINED_FLOW = "User-defined Flow"; private CCombo flowControllerChoice; Table flowList; // need access from inner class private Button upButton; private Button downButton; private Label flowControllerGUI; private Button specifyFlowControllerImportButton; private Button findFlowControllerDescriptorButton; private Label flowControllerLabel; private Label flowControllerKeyLabel; private Label flowControllerKeyGUI; // private Label flowControllerSpecifierLabel; private Label flowChoiceLabel; private boolean bDisableToolTipHelp; /** * creates a section only for aggregate specifiers to define the flow of their delegates * * @param editor * the referenced multipage editor */ public FlowSection(MultiPageEditor aEditor, Composite parent) { super(aEditor, parent, Messages.getString("FlowSection.ComponentEngineFlowTitle"), //$NON-NLS-1$ Messages.getString("FlowSection.ComponentEngineFlowDescription")); //$NON-NLS-1$ } /* * Called by the page constructor after all sections are created, to initialize them. * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm) */ public void initialize(IManagedForm form) { super.initialize(form); Composite sectionClient = new2ColumnComposite(this.getSection()); // sectionClient (2 col) // label / ccombo // comp2 // comp2a fcButtonContainer // label / text ((GridData) sectionClient.getLayoutData()).grabExcessHorizontalSpace = false; flowChoiceLabel = newLabelWithTip(sectionClient, Messages.getString("FlowSection.FlowKind"), //$NON-NLS-1$ Messages.getString("FlowSection.FlowKindTip")); //$NON-NLS-1$ flowControllerChoice = newCComboWithTip(sectionClient, Messages .getString("FlowSection.FlowKindTip")); //$NON-NLS-1$ flowControllerChoice.add(FIXED_FLOW); flowControllerChoice.add(CAPABILITY_LANGUAGE_FLOW); flowControllerChoice.add(USER_DEFINED_FLOW); Composite comp2 = new2ColumnComposite(sectionClient); ((GridData) comp2.getLayoutData()).horizontalSpan = 2; ((GridData) comp2.getLayoutData()).grabExcessVerticalSpace = false; Composite comp2a = new2ColumnComposite(comp2); Composite fcButtonContainer = newButtonContainer(comp2, VERTICAL_BUTTONS, 0); flowControllerLabel = newLabelWithTip(comp2a, "Flow Controller:", "The XML descriptor for the Custom Flow Controller"); flowControllerGUI = newUnUpdatableTextWithTip(comp2a, "", "The XML descriptor for the Custom Flow Controller"); flowControllerGUI.addListener(SWT.MouseDown, this); flowControllerGUI.addListener(SWT.MouseHover, this); flowControllerKeyLabel = newLabelWithTip(comp2a, "Key Name:", "A unique key name for this Flow Controller"); flowControllerKeyGUI = newUnUpdatableTextWithTip(comp2a, "", "A unique key name for this Flow Controller"); // flowControllerSpecifierLabel = newLabelWithTip(sectionClient, "Specify:", // "Click the Browse or Search button to specify a Flow Controller"); // Composite fcButtonContainer = newButtonContainer(sectionClient, HORIZONTAL_BUTTONS, 150); specifyFlowControllerImportButton = newPushButton(fcButtonContainer, "Browse...", "Click here to specify a locally defined Flow Controller", ENABLED); findFlowControllerDescriptorButton = newPushButton(fcButtonContainer, "Search", "Click here to search for a Flow Controller", ENABLED); // flow list Composite flowComposite = new2ColumnComposite(sectionClient); ((GridData) flowComposite.getLayoutData()).horizontalSpan = 2; enableBorders(flowComposite); toolkit.paintBordersFor(flowComposite); flowList = newTable(flowComposite, SWT.FULL_SELECTION, 0); // Buttons final Composite buttonContainer = newButtonContainer(flowComposite, VERTICAL_BUTTONS, 70); upButton = newPushButton(buttonContainer, S_UP, Messages.getString("FlowSection.upTip"), !ENABLED); //$NON-NLS-1$ downButton = newPushButton(buttonContainer, S_DOWN, Messages.getString("FlowSection.downTip"), !ENABLED); //$NON-NLS-1$ enableBorders(sectionClient); toolkit.paintBordersFor(sectionClient); } /* * (non-Javadoc) * * @see org.eclipse.ui.forms.IFormPart#refresh() */ public void refresh() { super.refresh(); flowList.removeAll(); if (!isAggregate()) { getSection().setText(Messages.getString("FlowSection.notUsed")); //$NON-NLS-1$ getSection().setDescription(Messages.getString("FlowSection.onlyForAggregates")); //$NON-NLS-1$ } else { getSection().setText(Messages.getString("FlowSection.ComponentEngineFlowTitle")); //$NON-NLS-1$ getSection().setDescription(Messages.getString("FlowSection.ComponentEngineFlowDescription")); //$NON-NLS-1$ FlowControllerDeclaration fcd = getFlowControllerDeclaration(); flowList.setEnabled(true); FlowConstraints flowConstraints = getModelFlow(); FlowNodes nodesModel = new FlowNodes(flowConstraints); String[] nodes = nodesModel.getFlow(); if (null == nodes) nodesModel.setFlow(nodes = stringArray0); // add them to the list for (int i = 0; i < nodes.length; i++) { TableItem item = new TableItem(flowList, SWT.NONE); item.setImage(TAEConfiguratorPlugin.getImage(TAEConfiguratorPlugin.IMAGE_ANNOTATOR) //$NON-NLS-1$ ); item.setText(0, nodes[i]); } packTable(flowList); if (null == fcd) { // Not a custom, user-defined flow FixedFlow ff; if (null == flowConstraints) { // force fixed flow if nothing is specified getAnalysisEngineMetaData().setFlowConstraints( flowConstraints = ff = new FixedFlow_impl()); ff.setFixedFlow(stringArray0); } String modelFlowType = flowConstraints.getFlowConstraintsType(); flowControllerChoice.setText(modelFlowType .equals(CapabilityLanguageFlow.FLOW_CONSTRAINTS_TYPE) ? CAPABILITY_LANGUAGE_FLOW : FIXED_FLOW); enableFlowControllerGUI(false); } else { // User-specified Flow Controller defined refreshFcd(fcd); } } enable(); } private void refreshFcd(FlowControllerDeclaration fcd) { enableFlowControllerGUI(true); String keyName; if (null == fcd.getKey() || "".equals(fcd.getKey())) { keyName = "Warning: no key name is specified"; flowControllerKeyGUI.setToolTipText( "Use Source tab below to specify a key name " + "in the element, or the imported "); } else keyName = fcd.getKey(); flowControllerKeyGUI.setText(keyName); Import fcdImport = fcd.getImport(); String fileName = null; if (null != fcdImport) { fileName = fcdImport.getLocation(); if (null == fileName || (0 == fileName.length())) fileName = fcdImport.getName(); } flowControllerGUI.setText(null == fileName ? "Warning: no in " : fileName); flowControllerChoice.setText(USER_DEFINED_FLOW); // must follow label updates // because this method also does the redraw // otherwise, label updates are not redrawn... flowControllerGUI.getParent().redraw(); } private void enableFlowControllerGUI(boolean enableState) { flowControllerLabel.setEnabled(enableState); flowControllerGUI.setEnabled(enableState); specifyFlowControllerImportButton.setEnabled(enableState); findFlowControllerDescriptorButton.setEnabled(enableState); flowControllerKeyLabel.setEnabled(enableState); // flowControllerSpecifierLabel.setEnabled(enableState); flowControllerKeyGUI.setEnabled(enableState); // if (!enableState) { // flowControllerKeyGUI.setText(""); // flowControllerGUI.setText(""); // } } /** * @return */ private FlowConstraints getModelFlow() { return getAnalysisEngineMetaData().getFlowConstraints(); } /* * (non-Javadoc) * * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == flowControllerChoice) { String flowTypeGUI = flowControllerChoice.getText(); if (null == flowTypeGUI || flowTypeGUI.equals(S_)) return; String prevFlowTypeGUI; FlowControllerDeclaration fcd = getFlowControllerDeclaration(); FlowConstraints modelFlow = getModelFlow(); if (null != fcd) prevFlowTypeGUI = USER_DEFINED_FLOW; else { if (null == modelFlow) prevFlowTypeGUI = ""; else { String prevFlowType = modelFlow.getFlowConstraintsType(); if (CapabilityLanguageFlow.FLOW_CONSTRAINTS_TYPE.equals(prevFlowType)) prevFlowTypeGUI = CAPABILITY_LANGUAGE_FLOW; else prevFlowTypeGUI = FIXED_FLOW; } } if (prevFlowTypeGUI.equals(flowTypeGUI)) return; CapabilityLanguageFlow clf = null; FixedFlow ff = null; String[] nodes = new FlowNodes(modelFlow).getFlow(); if (flowTypeGUI.equals(CAPABILITY_LANGUAGE_FLOW)) { setFlowControllerDeclaration(null); getAnalysisEngineMetaData().setFlowConstraints(clf = new CapabilityLanguageFlow_impl()); clf.setCapabilityLanguageFlow(nodes); } else if (flowTypeGUI.equals(FIXED_FLOW)) { setFlowControllerDeclaration(null); getAnalysisEngineMetaData().setFlowConstraints(ff = new FixedFlow_impl()); ff.setFixedFlow(nodes); } else if (flowTypeGUI.equals(USER_DEFINED_FLOW)) { // use case: user set user-defined-flow from some other state. // user will have to fill in the import (CDE only supports that format) // flow nodes kept, put under "Fixed Flow" arbitrarily FlowControllerDeclaration newFcd = new FlowControllerDeclaration_impl(); setFlowControllerDeclaration(newFcd); refreshFcd(newFcd); getAnalysisEngineMetaData().setFlowConstraints(ff = new FixedFlow_impl()); ff.setFixedFlow(nodes); } enable(); setFileDirty(); } else if (event.widget == upButton) { String[] nodes = new FlowNodes(getModelFlow()).getFlow(); // update both model and gui: swap nodes int selection = flowList.getSelectionIndex(); if (selection == 0) return; // can't move up 0 String temp = nodes[selection - 1]; nodes[selection - 1] = nodes[selection]; nodes[selection] = temp; finishFlowAction(); flowList.setSelection(selection - 1); enable(); // after setting selection } else if (event.widget == downButton) { String[] nodes = new FlowNodes(getModelFlow()).getFlow(); // update both model and gui: swap nodes int selection = flowList.getSelectionIndex(); if (selection == flowList.getItemCount() - 1) return; // can't move down at end of list String temp = nodes[selection + 1]; nodes[selection + 1] = nodes[selection]; nodes[selection] = temp; finishFlowAction(); flowList.setSelection(selection + 1); enable(); // after setting selection } else if (event.widget == specifyFlowControllerImportButton) { handleSpecifyFlowController(); } else if (event.widget == findFlowControllerDescriptorButton) { handleFindFlowController(); } else if (event.widget == flowControllerGUI && event.type == SWT.MouseDown && event.button == 3) { handleContextMenuRequest(event); } else if (event.widget == flowControllerGUI && event.type == SWT.MouseHover && !bDisableToolTipHelp) { handleHoverHelp(event); } // handle selection else if (event.widget == flowList) { if (event.type == SWT.Selection) { enable(); } if (event.character == SWT.DEL) { if (flowList.getSelectionIndex() > -1) { handleRemove(); } } } } private void handleHoverHelp(Event event) { String sDesc = ""; FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration(); String text = flowControllerGUI.getText(); if (null != fcd && !"".equals(text) && null != fcd.getSpecifier()) { sDesc = getDescriptionForDescriptor(flowControllerGUI.getText(), fcd.getSpecifier()); } flowControllerGUI.setToolTipText(sDesc); } private void handleContextMenuRequest(Event event) { Import imp = getFlowControllerDeclaration().getImport(); bDisableToolTipHelp = true; requestPopUpOverImport(imp, flowControllerGUI, event); bDisableToolTipHelp = false; } private void finishFlowAction() { setFileDirty(); refresh(); // calls enable } public void handleRemove() { // get node to remove int removedItemIndex = flowList.getSelectionIndex(); String[] nodes = new FlowNodes(getModelFlow()).getFlow(); int origItemCount = nodes.length; // remove node from array by copying additional items above down 1 for (int i = removedItemIndex + 1; i < origItemCount; i++) { nodes[i - 1] = nodes[i]; } // copy array in a smaller one String newNodes[] = new String[origItemCount - 1]; if (newNodes.length > 0) { System.arraycopy(nodes, 0, newNodes, 0, newNodes.length); } new FlowNodes(getModelFlow()).setFlow(newNodes); finishFlowAction(); // does also enable() and refresh() flowList.setSelection(removedItemIndex - 1); enable(); // after setting selection } /** * Adds a node to the flowList * * @param node * the key of the delegate */ public void addNode(String node) { FlowConstraints flowConstraints = getModelFlow(); if (null == flowConstraints) { // no constraints declared // set up Fix Flow style of contraints // This can happen if the style is user-defined flow flowConstraints = UIMAFramework.getResourceSpecifierFactory().createFixedFlow(); getAnalysisEngineMetaData().setFlowConstraints(flowConstraints); } FlowNodes flowNodes = new FlowNodes(flowConstraints); String[] nodes = flowNodes.getFlow(); if (nodes == null) { nodes = new String[] { node }; flowNodes.setFlow(nodes); } else { // create a new String array and copy old Strings String newNodes[] = new String[nodes.length + 1]; System.arraycopy(nodes, 0, newNodes, 0, nodes.length); newNodes[newNodes.length - 1] = node; flowNodes.setFlow(newNodes); } finishFlowAction(); // setFileDirty, enable() and setFocus() } /** * Enables and disables section, enables and disables buttons after content. * */ public void enable() { // if annotator is primitive disable whole section if (!isAggregate()) { upButton.setEnabled(false); downButton.setEnabled(false); flowChoiceLabel.setEnabled(false); flowControllerChoice.setEnabled(false); enableFlowControllerGUI(false); } else { FlowControllerDeclaration fcd = getFlowControllerDeclaration(); enableFlowControllerGUI(null != fcd); flowControllerChoice.setEnabled(true); flowChoiceLabel.setEnabled(true); int items = flowList.getItemCount(); int selection = flowList.getSelectionIndex(); if (items == 0 || selection == -1) { editor.getAggregatePage().getAggregateSection().getRemoveFromFlowButton().setEnabled(false); upButton.setEnabled(false); downButton.setEnabled(false); } else { editor.getAggregatePage().getAggregateSection().getRemoveFromFlowButton().setEnabled(true); // disable if first item is selected upButton.setEnabled(!(selection == 0)); // disable if last item is selected downButton.setEnabled(!(selection == items - 1)); } } } /** * Proofs if a node is contained in the list of nodes * * @param node * @return whether the node is in the list or not */ public boolean containsNode(String node) { String[] nodes = new FlowNodes(getModelFlow()).getFlow(); if (null == nodes) return false; for (int i = 0; i < nodes.length; i++) { if (node.equals(nodes[i])) return true; } return false; } /** * @return */ public Button getDownButton() { return downButton; } /** * @return */ public Table getFlowList() { return flowList; } /** * @return */ public Button getUpButton() { return upButton; } public void removeAll() { FlowConstraints flow = getModelFlow(); if (flow != null) { flow.setAttributeValue("fixedFlow", new String[0]); //$NON-NLS-1$ editor.setFileDirty(); editor.getAggregatePage().getAggregateSection().refresh(); } } private static final String[] flowControllerHeadersLC = new String[] { ""); // force running jcasgen refresh(); // refresh every time to capture the order of items added } private void handleSpecifyFlowController() { MultiResourceSelectionDialog dialog = new MultiResourceSelectionDialog(getSection().getShell(), editor.getFile().getProject().getParent(), "Flow Controller Selection", editor .getFile().getLocation(), editor); dialog.setTitle("Flow Controller Selection"); dialog.setMessage("Select a Flow Controller descriptor from the workspace:"); if (Window.CANCEL == dialog.open()) { return; } Object[] files = dialog.getResult(); if (files != null && checkForOneSelection(files.length)) { FileAndShortName fsn = new FileAndShortName(files[0]); produceKeyAddFlowController(fsn.shortName, fsn.fileName, dialog.isImportByName); } } private boolean checkForOneSelection(int numberSelected) { if (numberSelected > 1) { Utility.popMessage("Error - Multiple selection", "Only one Flow Controller can be selected. Please try again.", MessageDialog.ERROR); return false; } return true; } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexImportSection.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexImpo0000644000175000017500000000654511665471220033443 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import java.io.IOException; import org.apache.uima.UIMAFramework; import org.apache.uima.cas.CAS; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.Import; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.XMLInputSource; import org.eclipse.swt.widgets.Composite; /** */ public class IndexImportSection extends ImportSection { public IndexImportSection(MultiPageEditor editor, Composite parent) { super(editor, parent, "Index Imports", "The following index definitions are included as part of this one."); // or ! // DESCRIPTION } // ************************************** // * Code to support type import section // ************************************** protected boolean isAppropriate() { return true; // always show } /** * used when hovering */ protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException { FsIndexCollection parsedImportItem = UIMAFramework.getXMLParser().parseFsIndexCollection( new XMLInputSource(source)); return parsedImportItem.getDescription(); } protected Import[] getModelImportArray() { return getFsIndexCollection().getImports(); } protected void setModelImportArray(Import[] imports) { if (imports == null) throw new InternalErrorCDE("invalid state"); getFsIndexCollection().setImports(imports); } protected void clearModelBaseValue() { getAnalysisEngineMetaData().setFsIndexes(fsIndexDescription0); } // indexes are checked and merged when the CAS is built protected boolean isValidImport(String title, String message) { FsIndexCollection savedIC = editor.getMergedFsIndexCollection(); if (null != savedIC) savedIC = (FsIndexCollection) savedIC.clone(); CAS savedCAS = editor.getCurrentView(); try { editor.setMergedFsIndexCollection(); editor.descriptorCAS.validate(); } catch (ResourceInitializationException e) { revertMsg(title, message, editor.getMessagesToRootCause(e)); editor.setMergedFsIndexCollection(savedIC); editor.descriptorCAS.set(savedCAS); return false; } return true; } protected void finishImportChangeAction() { } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregatePage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Aggregate0000644000175000017500000000364411665471220033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.ui; import org.apache.uima.taeconfigurator.editors.Form2Panel; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.eclipse.ui.forms.IManagedForm; public class AggregatePage extends HeaderPageWithSash { private FlowSection flowSection; private AggregateSection aggregateSection; public AggregatePage(MultiPageEditor aEditor) { super(aEditor, "Aggregate Component Settings"); } /** Called by the framework to fill in the contents */ protected void createFormContent(IManagedForm managedForm) { final Form2Panel form = setup2ColumnLayout(managedForm, !EQUAL_WIDTH); managedForm.getForm().setText("Aggregate Delegates and Flows"); managedForm.addPart(aggregateSection = new AggregateSection(editor, form.left)); managedForm.addPart(flowSection = new FlowSection(editor, form.right)); createToolBarActions(managedForm); } public FlowSection getFlowSection() { return flowSection; } public AggregateSection getAggregateSection() { return aggregateSection; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditor.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEdi0000644000175000017500000034331411665471220033441 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.ref.SoftReference; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.Vector; import org.apache.uima.UIMAFramework; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.analysis_engine.TypeOrFeature; import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl; import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData; import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration; import org.apache.uima.cas.CAS; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.collection.CasInitializerDescription; import org.apache.uima.collection.CollectionReaderDescription; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.internal.util.UIMAClassLoader; import org.apache.uima.jcas.jcasgenp.MergerImpl; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.ResourceManager; import org.apache.uima.resource.ResourceServiceSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.impl.ResourceManager_impl; import org.apache.uima.resource.metadata.Capability; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.Import; import org.apache.uima.resource.metadata.MetaDataObject; import org.apache.uima.resource.metadata.ProcessingResourceMetaData; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.ResourceMetaData; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.resource.metadata.TypePriorityList; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.point.IUimaEditorExtension; import org.apache.uima.taeconfigurator.editors.point.IUimaMultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.AggregatePage; import org.apache.uima.taeconfigurator.editors.ui.CapabilityPage; import org.apache.uima.taeconfigurator.editors.ui.HeaderPage; import org.apache.uima.taeconfigurator.editors.ui.IndexesPage; import org.apache.uima.taeconfigurator.editors.ui.OverviewPage; import org.apache.uima.taeconfigurator.editors.ui.ParameterPage; import org.apache.uima.taeconfigurator.editors.ui.ResourcesPage; import org.apache.uima.taeconfigurator.editors.ui.SettingsPage; import org.apache.uima.taeconfigurator.editors.ui.TypePage; import org.apache.uima.taeconfigurator.editors.ui.Utility; import org.apache.uima.taeconfigurator.editors.xml.XMLEditor; import org.apache.uima.taeconfigurator.files.ContextForPartDialog; import org.apache.uima.taeconfigurator.model.AllTypes; import org.apache.uima.taeconfigurator.model.DefinedTypesWithSupers; import org.apache.uima.taeconfigurator.model.DescriptorTCAS; import org.apache.uima.tools.jcasgen.IError; import org.apache.uima.tools.jcasgen.Jg; import org.apache.uima.util.CasCreationUtils; import org.apache.uima.util.InvalidXMLException; import org.apache.uima.util.Level; import org.apache.uima.util.Logger; import org.apache.uima.util.XMLInputSource; import org.apache.uima.util.XMLSerializer; import org.apache.uima.util.XMLizable; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.search.IJavaSearchScope; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.ITextEditor; import org.osgi.framework.Bundle; import org.xml.sax.ContentHandler; import org.xml.sax.SAXException; /** * Main class implementing the multi page editor. In Eclipse 3, we extend FormEditor, which extends * in turn MultiPageEditorPart. * * Life cycle: Create: An instance of this class is created each time the editor is started on a new * resource. Base multipage editor createPartControl calls createPages; FormEditor's impl of * createPages calls createToolkit, then calls addPages. FormEditor has field holding the toolkit * This class overrides createToolkit to re-use the colors in the plugin. * Dispose: dispose is * called. FormEditor impl of dispose disposes of the toolkit. * * Superclass (FormEditor) holds vector of pages toolkit (disposed of in FormEditor dispose method) * SuperSuperclass (MultiPageEditorPart) holds array of editors (we only have 1 "editor" - the xml * source editor - the rest are views into that model / data). * * Stale = model (on disk, saved) is ahead of widgets Dirty = widgets are ahead of model <<< NOT * USED HERE * * Each page of the multipage editor has its own class. ownclass -> HeaderPage -> FormPage (impl * IFormPage) has instance of PageForm -> ManagedForm ManagedForm (impl IManagedForm): has instance * of ScrolledForm has subparts (IFormPart - which live on the scrolled form) A part can be a * section. A part can implement IPartSelectionListener to get selectionChanged(IFormPart, * ISelection) calls. initialize() call propagated to all parts. dispose() call propagated to all * parts. refresh() propagated to all parts (if part.isStale()) (Not Used) commit() propagated to * all parts (if part.isDirty()) setInput() propagated to all parts setFocus() propagated to 1st * part (not used) isDirty() propagated to all parts, is true if any are true isStale() propagated * to all parts, is true if any are true reflow() delegated to the contained ScrolledForm (not used) * fireSelectionChanged(IFormPart, ISelection) - can be used to notify other parts that implement * IPartSelectionListener about selection changes * * Each page has one or more sections. sectionSpecific -> (AbstractTableSection) -> AbstractSection -> * SectionPart -> AbstractFormPart (impl IFormPart, see above) * * AbstractFormPart holds back ref to managed form, a dirty and stale bit. Stale = model is ahead of * widgets (Not used) Dirty = widgets are ahead of model Stale brought into sync by 'refresh' * method. Part notifies containing ManagedForm when Stale/Dirty changes in the part; Part * responsible for removing listeners from event providers. IFormPart can receive form input * SectionPart adds listeners for expansionStateChang(ed)(ing) expansionStateChanged calls reflow on * wrapped form Note: the forms framework Dirty mechanism and the "commit" methods are not used. In * its place, the handlers directly update the model, rather than marking Dirty and letting someone * call commit. */ public class MultiPageEditor extends FormEditor implements IUimaMultiPageEditor { // ****************************** // * Tuning Parameters public final int INITIAL_SIZE_TYPE_COLLECTIONS = 20; public final int INITIAL_SIZE_FEATURE_COLLECTIONS = 40; // ****************************** // *********************************************************** // M O D E L // the following are only populated based on what type // of descriptor is being edited private AnalysisEngineDescription aeDescription = null; private TypeSystemDescription typeSystemDescription = null; private TypeSystemDescription mergedTypeSystemDescription = null; private Map mergedTypesAddingFeatures = new TreeMap(); private TypeSystemDescription importedTypeSystemDescription = null; /** * Key = unique ID of included AE in aggregate Value = AnalysisEngineSpecification or URISpecifier * if remote This value is obtained from aeDescription.getDelegateAnalysisEngineSpecifiers() for * aggregates, and is cached so we don't need to repeatedly resolve it, with checks for invalid * xml exceptions. */ private Map resolvedDelegates = new HashMap(); // fully resolved (imports) and merged index collection // resolve with mergeDelegateAnalysisEngineFsIndexCollections // (This works also for primitives) private FsIndexCollection mergedFsIndexCollection; private FsIndexCollection importedFsIndexCollection; // fully resolved (imports) and merged type priorities // resolve with mergeDelegateAnalysisEngineTypePriorities // (This works also for primitives) // This collects all the type priority lists into one list, after // resolving imports. private TypePriorities mergedTypePriorities; private TypePriorities importedTypePriorities; // fully resolved (imports) ResourceManagerConfiguration // This collects all the External Resources and bindings into 2 list, // resolving imports. The resulting list may have // overridden bindings // unused external resources (not bound) private ResourceManagerConfiguration resolvedExternalResourcesAndBindings; // private ResourceManagerConfiguration importedExternalResourcesAndBindings; private FlowControllerDeclaration resolvedFlowControllerDeclaration; private CollectionReaderDescription collectionReaderDescription; private CasInitializerDescription casInitializerDescription; private CasConsumerDescription casConsumerDescription; private FlowControllerDescription flowControllerDescription; // values computed when first needed // all use common markStale() public DescriptorTCAS descriptorCAS; public AllTypes allTypes; public DefinedTypesWithSupers definedTypesWithSupers; // **************************************** // * Model parts not part of the descriptor // **************************************** private IFile file; // file being edited private IFile fileNeedingContext; // *********************************************************** // End of M O D E L // *********************************************************** /* * Each page is an instance of a particular class. These instances are created each time a new * instance of the editor opens. */ protected int sourceIndex = -1; protected int overviewIndex = -1; private int aggregateIndex = -1; private int parameterIndex = -1; private int settingsIndex = -1; protected int typeIndex = -1; protected int capabilityIndex = -1; protected int indexesIndex = -1; protected int resourcesIndex = -1; protected OverviewPage overviewPage = null; private AggregatePage aggregatePage = null; private ParameterPage parameterPage = null; private SettingsPage settingsPage = null; protected TypePage typePage = null; protected CapabilityPage capabilityPage = null; protected IndexesPage indexesPage = null; protected ResourcesPage resourcesPage = null; protected XMLEditor sourceTextEditor; private boolean m_bIsInited = false; protected boolean isBadXML = true; public boolean sourceChanged = true; private boolean fileDirty; // can only be set dirty once inited private HashSet dirtyTypeNameHash; // for generating .java // type files upon saving (this has a problem if user edited xml // directly...) public int m_nSaveAsStatus = SAVE_AS_NOT_IN_PROGRESS; public static final int SAVE_AS_NOT_IN_PROGRESS = -1; public static final int SAVE_AS_STARTED = -2; public static final int SAVE_AS_CANCELLED = -3; public static final int SAVE_AS_CONFIRMED = -4; private boolean openingContext = false; private boolean isContextLoaded = false; public boolean getIsContextLoaded() { return isContextLoaded; } /** * Descriptor Types */ private int descriptorType = 0; public int getDescriptorType() { return descriptorType; } public static final int DESCRIPTOR_AE = 1; public static final int DESCRIPTOR_TYPESYSTEM = 1 << 1; public static final int DESCRIPTOR_INDEX = 1 << 2; public static final int DESCRIPTOR_TYPEPRIORITY = 1 << 3; public static final int DESCRIPTOR_EXTRESANDBINDINGS = 1 << 4; public static final int DESCRIPTOR_COLLECTIONREADER = 1 << 5; public static final int DESCRIPTOR_CASINITIALIZER = 1 << 6; public static final int DESCRIPTOR_CASCONSUMER = 1 << 7; public static final int DESCRIPTOR_FLOWCONTROLLER = 1 << 8; public String descriptorTypeString(int pDescriptorType) { String r; switch (pDescriptorType) { case DESCRIPTOR_AE: r = Messages.getString("MultiPageEditor.0");break; //$NON-NLS-1$ case DESCRIPTOR_TYPESYSTEM: r = Messages.getString("MultiPageEditor.1");break; //$NON-NLS-1$ case DESCRIPTOR_INDEX: r = Messages.getString("MultiPageEditor.2");break; //$NON-NLS-1$ case DESCRIPTOR_TYPEPRIORITY: r = Messages.getString("MultiPageEditor.3");break; //$NON-NLS-1$ case DESCRIPTOR_EXTRESANDBINDINGS: r = Messages.getString("MultiPageEditor.4");break; //$NON-NLS-1$ case DESCRIPTOR_COLLECTIONREADER: r = Messages.getString("MultiPageEditor.5");break; //$NON-NLS-1$ case DESCRIPTOR_CASINITIALIZER: r = Messages.getString("MultiPageEditor.6");break; //$NON-NLS-1$ case DESCRIPTOR_CASCONSUMER: r = Messages.getString("MultiPageEditor.7");break; //$NON-NLS-1$ case DESCRIPTOR_FLOWCONTROLLER: r = "Flow Controller"; break; default: throw new InternalErrorCDE(Messages.getString("MultiPageEditor.8")); //$NON-NLS-1$ } return r + Messages.getString("MultiPageEditor.9"); //$NON-NLS-1$ } public String descriptorTypeString() { return descriptorTypeString(descriptorType); } public boolean isAeDescriptor() { return 0 != (descriptorType & DESCRIPTOR_AE); } public boolean isTypeSystemDescriptor() { return 0 != (descriptorType & DESCRIPTOR_TYPESYSTEM); } public boolean isFsIndexCollection() { return 0 != (descriptorType & DESCRIPTOR_INDEX); } public boolean isTypePriorityDescriptor() { return 0 != (descriptorType & DESCRIPTOR_TYPEPRIORITY); } public boolean isExtResAndBindingsDescriptor() { return 0 != (descriptorType & DESCRIPTOR_EXTRESANDBINDINGS); } public boolean isCollectionReaderDescriptor() { return 0 != (descriptorType & DESCRIPTOR_COLLECTIONREADER); } public boolean isCasInitializerDescriptor() { return 0 != (descriptorType & DESCRIPTOR_CASINITIALIZER); } public boolean isCasConsumerDescriptor() { return 0 != (descriptorType & DESCRIPTOR_CASCONSUMER); } public boolean isFlowControllerDescriptor() { return 0 != (descriptorType & DESCRIPTOR_FLOWCONTROLLER); } public boolean isLocalProcessingDescriptor() { return 0 != (descriptorType & (DESCRIPTOR_AE | DESCRIPTOR_COLLECTIONREADER | DESCRIPTOR_CASINITIALIZER | DESCRIPTOR_CASCONSUMER | DESCRIPTOR_FLOWCONTROLLER)); } public boolean isPrimitive() { return isLocalProcessingDescriptor() && aeDescription.isPrimitive(); } public boolean isAggregate() { return isAeDescriptor() && (!aeDescription.isPrimitive()); } private TypePriorities m_typePrioritiesBackup; private Color fadeColor; private boolean isRevertingIndex; protected boolean isPageChangeRecursion = false; public static final TypeDescription[] typeDescriptionArray0 = new TypeDescription[0]; private List typeSystemsToMerge; private List typePrioritiesToMerge; private List fsIndexesToMerge; private Map failedRemotes = new TreeMap(); private Set failedRemotesAlreadyKnown = new TreeSet(); private static List externalEditorConfigurations = null; private IUimaMultiPageEditor currentEditor; // can be CDE or another editor public MultiPageEditor() { super(); currentEditor = this; // default initCDE (); // specific for CDE } /** * * Note: Try to move these codes out of constructor MultiPageEditor(). * Too much of impacts. Put it back into constructor MultiPageEditor() */ private void initCDE () { // Model initialization fileDirty = false; dirtyTypeNameHash = new HashSet(); descriptorCAS = new DescriptorTCAS(this); allTypes = new AllTypes(this); definedTypesWithSupers = new DefinedTypesWithSupers(this); // reasonable initial values aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); typeSystemDescription = null; importedTypeSystemDescription = null; mergedTypeSystemDescription = null; mergedFsIndexCollection = aeDescription.getAnalysisEngineMetaData().getFsIndexCollection(); resolvedExternalResourcesAndBindings = aeDescription.getResourceManagerConfiguration(); resolvedFlowControllerDeclaration = aeDescription.getFlowControllerDeclaration(); mergedTypePriorities = aeDescription.getAnalysisEngineMetaData().getTypePriorities(); } private static final String EXTENSION_TAG_CLASS_ATTRIB = "class"; private IUimaEditorExtension getRequiredEditor(XMLizable parsedResult) { return getRequiredEditor(null, parsedResult.getClass().getName()); } private IUimaEditorExtension getRequiredEditor(String topElementName) { return getRequiredEditor(topElementName, null); } // returns null if no matching editor found // otherwise instantiates a new editor private IUimaEditorExtension getRequiredEditor(String topElementName, String parsedResultClassName) { IUimaEditorExtension editor; // load external editor configurations if not already loaded if (null == externalEditorConfigurations) { getExternalEditorConfigurations(); } for (IConfigurationElement xeditor : externalEditorConfigurations) { for (IConfigurationElement canEdit : xeditor.getChildren()) { String elementName = canEdit.getAttribute("elementName"); String parseResultName = canEdit.getAttribute("internalParseClass"); if ( ( (null != topElementName) && topElementName.equals(elementName)) || ( (null != parsedResultClassName) && parsedResultClassName.equals(parseResultName)) ) { try { editor = (IUimaEditorExtension) xeditor.createExecutableExtension(EXTENSION_TAG_CLASS_ATTRIB); } catch (CoreException e) { Utility.popMessage("Unexpected Exception", "While trying to load an editor extension" + getMessagesToRootCause(e), Utility.ERROR); return null; } editor.init(); return editor; } } } return null; } private static final String EXTENSION_POINT_ID = "externalEditor"; // load all of the external editor xml data // (but don't load the actual editors, yet) private void getExternalEditorConfigurations () { // Get extension point from Registry IExtensionPoint point = Platform.getExtensionRegistry() .getExtensionPoint(TAEConfiguratorPlugin.pluginId, EXTENSION_POINT_ID); externalEditorConfigurations = new ArrayList(); // check: Any tags for our extension-point? if (point != null) { for (IExtension extension : point.getExtensions()) { Bundle b = Platform.getBundle(extension.getContributor().getName()); if (b == null) { Utility.popMessage( "Problem with Editor Extension", "Editor '" + extension.getContributor().getName() + "' is present, but can't be loaded, probably because of unsatisfied dependencies\n", Utility.ERROR); continue; } for (IConfigurationElement ces : extension.getConfigurationElements()) { externalEditorConfigurations.add(ces); } } } else { // Error - no such extension point Utility.popMessage( "Internal Error", "CDE's extension point is missing", Utility.ERROR); } } /***************************************************************************/ /* Expose "protected" methods and methods from Super */ /***************************************************************************/ public void initSuper(IEditorSite site, IEditorInput editorInput) throws PartInitException { super.init(site, editorInput); } public int getCurrentPageSuper () { return getCurrentPage(); } public void setPartNameSuper(String partName) { super.setPartName(partName); } public void setPageTextSuper(int pageIndex, String text) { super.setPageText(pageIndex, text); } public void pageChangeSuper(int newPageIndex) { super.pageChange(newPageIndex); } public void setActivePageSuper (int pageIndex) { super.setActivePage(pageIndex); } public void firePropertyChangeSuper(final int propertyId) { super.firePropertyChange(propertyId); } public void setInputSuper(IEditorInput input) { super.setInput(input); } // XML source editor is opened by CDE when the source is "initially" invalid. // Called by DDE when the source becomes valid and it is DD. public XMLEditor getSourceEditor () { return sourceTextEditor; } /***************************************************************************/ /** * override the createToolkit method in FormEditor - to use a shared colors resource. * * This method is called by the FormEditor's createPages() method which will in turn call the * addPages method below. The toolkit ref is stored in the FormEditor object, and can be retrieved * by getToolkit(). * */ protected FormToolkit createToolkit(Display display) { return new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors(display)); } /* * Two forms of addPage - one for non-source-editors, and one for source-editor */ protected int addPageAndSetTabTitle(HeaderPage page, String keyTabTitle) throws PartInitException { int pageIndex = addPage(page); // set the text on the tab used to select the page in the multipage editor setPageText(pageIndex, keyTabTitle); return pageIndex; } protected int addPageAndSetTabTitle(IEditorPart page, IEditorInput input, String keyTabTitle) throws PartInitException { int pageIndex = addPage(page, input); // set the text on the tab used to select the page in the multipage editor setPageText(pageIndex, keyTabTitle); return pageIndex; } /* * In general, 3 kinds of pages can be added. 1) an editor (IEditorPart, IEditorInput) 2) (lazy) * an IFormPage (extends IEditorPart) - has a managedForm, can wrap an editor 3) (lazy) a SWT * Control (Not Used) * * (non-Javadoc) * * @see org.eclipse.ui.forms.editor.FormEditor#addPages() */ protected void addPages() { currentEditor.addPagesForCurrentEditor(); } public void addPagesForCurrentEditor() { boolean allPages = isLocalProcessingDescriptor(); try { overviewIndex = addPageAndSetTabTitle(overviewPage = new OverviewPage(this), Messages .getString("MultiPageEditor.overviewTab")); //$NON-NLS-1$ if (allPages) { if (isAeDescriptor()) aggregateIndex = addPageAndSetTabTitle(aggregatePage = new AggregatePage(this), Messages .getString("MultiPageEditor.aggregateTab")); //$NON-NLS-1$ parameterIndex = addPageAndSetTabTitle(parameterPage = new ParameterPage(this), Messages .getString("MultiPageEditor.parameterTab")); //$NON-NLS-1$ settingsIndex = addPageAndSetTabTitle(settingsPage = new SettingsPage(this), Messages .getString("MultiPageEditor.settingsTab")); //$NON-NLS-1$ } if (allPages || isTypeSystemDescriptor()) { typeIndex = addPageAndSetTabTitle(typePage = new TypePage(this), Messages .getString("MultiPageEditor.typeTab")); //$NON-NLS-1$ } if (allPages) { capabilityIndex = addPageAndSetTabTitle(capabilityPage = new CapabilityPage(this), Messages .getString("MultiPageEditor.capabilityTab")); //$NON-NLS-1$ } if (allPages || isTypePriorityDescriptor() || isFsIndexCollection()) { indexesIndex = addPageAndSetTabTitle(indexesPage = new IndexesPage(this), Messages .getString("MultiPageEditor.indexesTab")); //$NON-NLS-1$ } if (allPages || isExtResAndBindingsDescriptor()) { resourcesIndex = addPageAndSetTabTitle(resourcesPage = new ResourcesPage(this), Messages .getString("MultiPageEditor.resourcesTab")); //$NON-NLS-1$ } sourceIndex = addPageAndSetTabTitle(sourceTextEditor = new XMLEditor(this), getEditorInput(), Messages.getString("MultiPageEditor.sourceTab")); //$NON-NLS-1$ } catch (PartInitException e) { e.printStackTrace(); // TODO fix this } if (isBadXML) { pageChange(sourceIndex); } } /** * @param monitor */ public void jcasGen(IProgressMonitor monitor) { if (MultiPageEditorContributor.getAutoJCasGen()) { doJCasGenChkSrc(monitor); } } public void doJCasGenChkSrc(IProgressMonitor monitor) { if (isSourceFolderValid()) doJCasGen(monitor); } public boolean isSourceFolderValid() { IResource folder = getPrimarySourceFolder(); if (folder == null) { String msg = Messages.getString("MultiPageEditor.noSrcNoJCas"); //$NON-NLS-1$ Utility.popMessage(Messages.getString("MultiPageEditor.noSrcDir"), msg, MessageDialog.ERROR); //$NON-NLS-1$ return false; } return true; } private boolean syncSourceBeforeSavingToFile() { boolean modelOK = true; if (getCurrentPage() != sourceIndex) { validateIndexes(); updateSourceFromModel(); } else { // have to check if there are dirty types modelOK = validateSource(); } if (modelOK && isLocalProcessingDescriptor()) { return isValidAE(aeDescription); } return modelOK; } public boolean isValidAE(AnalysisEngineDescription aAe) { AbstractSection.setVnsHostAndPort(aAe); // copy Ae into real descriptors if needed getTrueDescriptor(); // use clones because validation modifies (imports get imported) if (isCollectionReaderDescriptor()) { CollectionReaderDescription collRdr = (CollectionReaderDescription) collectionReaderDescription .clone(); try { collRdr.doFullValidation(createResourceManager()); } catch (Throwable e) { // all these are Throwable to catch errors like // UnsupportedClassVersionError, which happens if the annotator // class is compiled for Java 5.0, but the CDE is running Java 1.4.2 Utility .popMessage( Messages.getString("MultiPageEditor.failedCollRdrValidation"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.failedCollRdrValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); return false; } } else if (isCasInitializerDescriptor()) { CasInitializerDescription casInit = (CasInitializerDescription) casInitializerDescription .clone(); try { casInit.doFullValidation(createResourceManager()); } catch (Throwable e) { Utility .popMessage( Messages.getString("MultiPageEditor.failedCasInitValidation"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.failedCasInitValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); return false; } } else if (isCasConsumerDescriptor()) { CasConsumerDescription casCons = (CasConsumerDescription) casConsumerDescription.clone(); try { casCons.doFullValidation(createResourceManager()); } catch (Throwable e) { Utility .popMessage( Messages.getString("MultiPageEditor.failedCasConsValidation"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.failedCasConsValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); return false; } } else if (isFlowControllerDescriptor()) { FlowControllerDescription fc = (FlowControllerDescription) flowControllerDescription.clone(); try { fc.doFullValidation(createResourceManager()); } catch (Throwable e) { Utility.popMessage("Error in Flow Controller Descriptor", "The Descriptor is invalid for the following reason:" + "\n" + getMessagesToRootCause(e), MessageDialog.ERROR); return false; } } else { AnalysisEngineDescription ae = (AnalysisEngineDescription) aAe.clone(); // speedup = replace typeSystem with resolved imports version if (ae.isPrimitive()) { TypeSystemDescription tsd = getMergedTypeSystemDescription(); if (null != tsd) { tsd = (TypeSystemDescription) tsd.clone(); } ae.getAnalysisEngineMetaData().setTypeSystem(tsd); } ae.getAnalysisEngineMetaData().setFsIndexCollection(getMergedFsIndexCollection()); ae.getAnalysisEngineMetaData().setTypePriorities(getMergedTypePriorities()); try { ae.doFullValidation(createResourceManager()); } catch (Throwable e) { Utility .popMessage( Messages.getString("MultiPageEditor.failedAeValidation"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.failedAeValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); return false; } } return true; } /** * Saves the multi-page editor's document. */ public void doSave(IProgressMonitor monitor) { currentEditor.doSaveForCurrentEditor(monitor); } public void doSaveForCurrentEditor(IProgressMonitor monitor) { boolean modelOK = syncSourceBeforeSavingToFile(); sourceTextEditor.doSave(monitor); finishSave(monitor, modelOK); } private void finishSave(IProgressMonitor monitor, boolean modelOK) { if (modelOK) { if (dirtyTypeNameHash.size() > 0) jcasGen(monitor); dirtyTypeNameHash.clear(); } fileDirty = false; firePropertyChange(ISaveablePart.PROP_DIRTY); } /** * Saves the multi-page editor's document as another file. Updates this multi-page editor's input * to correspond to the nested editor's. * * This is not implemented correctly: filename isn't switched to new filename, etc. */ public void doSaveAs() { currentEditor.doSaveAsForCurrentEditor(); } public void doSaveAsForCurrentEditor() { boolean modelOK = syncSourceBeforeSavingToFile(); setSaveAsStatus(SAVE_AS_STARTED); sourceTextEditor.doSaveAs(); if (m_nSaveAsStatus == SAVE_AS_CANCELLED) { m_nSaveAsStatus = SAVE_AS_NOT_IN_PROGRESS; return; } // should only do if editorInput is new FileEditorInput newEditorInput = (FileEditorInput) sourceTextEditor.getEditorInput(); // if(old) setInput(newEditorInput); firePropertyChange(PROP_INPUT); // setTitle(newEditorInput.getFile().getName()); setPartName(newEditorInput.getFile().getName()); // this next does NOT seem to change the overall page title firePropertyChange(PROP_TITLE); finishSave(null, modelOK); } public boolean isDirty() { return fileDirty; } public boolean isSaveOnCloseNeeded() { return fileDirty; } public void setFileDirty() { if (m_bIsInited) { fileDirty = true; // next is key this.firePropertyChange(ISaveablePart.PROP_DIRTY); } } // Called by External Editor extensions when doSave or doSaveAs is called public void setFileDirtyFlag(boolean value) { fileDirty = value; } /* * (non-Javadoc) * * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput) */ public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException { XMLInputSource input; if (!(editorInput instanceof IFileEditorInput)) throw new PartInitException(Messages.getString("MultiPageEditor.invalidInputClass")); //$NON-NLS-1$ fileNeedingContext = file = ((IFileEditorInput) editorInput).getFile(); String filePathName = file.getLocation().toOSString(); try { input = new XMLInputSource(filePathName); } catch (IOException e) { String m = Messages.getFormattedString("MultiPageEditor.IOError", //$NON-NLS-1$ new String[] { AbstractSection.maybeShortenFileName(filePathName) }) + Messages.getString("MultiPageEditor.10") + getMessagesToRootCause(e); //$NON-NLS-1$ // skip showing a message because the partInitException // shows it throw new PartInitException(m); } super.init(site, editorInput); // to allow other editors to get site and editorInput // leaves isBadXML set, if it can't parse but isn't throwing isContextLoaded = false; try { parseSource(input, filePathName); } catch (MultilevelCancel e) { throw new PartInitException("Operation Cancelled"); } isContextLoaded = true; // super.init(site, editorInput); setPartName(editorInput.getName()); setContentDescription(editorInput.getName()); // setContentDescription(1 line summary); TODO m_bIsInited = true; } private IUimaEditorExtension extensionEditor; private void parseSource(XMLInputSource input, String filePathName) throws PartInitException { extensionEditor = null; parseSourceInner(input, filePathName); } private void parseSourceInner(XMLInputSource input, String filePathName) throws PartInitException { XMLizable inputDescription = null; try { inputDescription = AbstractSection.parseDescriptor(input); if (inputDescription instanceof AnalysisEngineDescription) { validateDescriptorType(DESCRIPTOR_AE); setAeDescription((AnalysisEngineDescription) inputDescription); } else if (inputDescription instanceof TypeSystemDescription) { validateDescriptorType(DESCRIPTOR_TYPESYSTEM); setTypeSystemDescription((TypeSystemDescription) inputDescription); } else if (inputDescription instanceof TypePriorities) { validateDescriptorType(DESCRIPTOR_TYPEPRIORITY); setTypePriorities((TypePriorities) inputDescription); } else if (inputDescription instanceof FsIndexCollection) { validateDescriptorType(DESCRIPTOR_INDEX); setFsIndexCollection((FsIndexCollection) inputDescription); } else if (inputDescription instanceof ResourceManagerConfiguration) { validateDescriptorType(DESCRIPTOR_EXTRESANDBINDINGS); setExtResAndBindings((ResourceManagerConfiguration) inputDescription); } else if (inputDescription instanceof CollectionReaderDescription) { validateDescriptorType(DESCRIPTOR_COLLECTIONREADER); setCollectionReaderDescription((CollectionReaderDescription) inputDescription); } else if (inputDescription instanceof CasInitializerDescription) { validateDescriptorType(DESCRIPTOR_CASINITIALIZER); setCasInitializerDescription((CasInitializerDescription) inputDescription); } else if (inputDescription instanceof CasConsumerDescription) { validateDescriptorType(DESCRIPTOR_CASCONSUMER); setCasConsumerDescription((CasConsumerDescription) inputDescription); } else if (inputDescription instanceof FlowControllerDescription) { validateDescriptorType(DESCRIPTOR_FLOWCONTROLLER); setFlowControllerDescription((FlowControllerDescription) inputDescription); } else { if (null == extensionEditor) { extensionEditor = getRequiredEditor(inputDescription); } if (null == extensionEditor) { throw new PartInitException(Messages.getFormattedString( "MultiPageEditor.unrecognizedDescType", //$NON-NLS-1$ new String[] { AbstractSection.maybeShortenFileName(filePathName) }) + Messages.getString("MultiPageEditor.11")); //$NON-NLS-1$ } else { extensionEditor.activateEditor(getEditorSite(), getEditorInput(), this, inputDescription); currentEditor = (IUimaMultiPageEditor)extensionEditor; } } isBadXML = false; } catch (InvalidXMLException e) { if (InvalidXMLException.INVALID_DESCRIPTOR_FILE.equals(e.getMessageKey())) { Throwable cause = e.getCause(); if ((cause instanceof InvalidXMLException) && InvalidXMLException.UNKNOWN_ELEMENT.equals(((InvalidXMLException)cause).getMessageKey()) && (null == extensionEditor)) { // try loading extension editors and reparsing extensionEditor = getRequiredEditor((String)((InvalidXMLException)cause).getArguments()[0]); if (null != extensionEditor) { // the act of finding the right editor calls that editors init() method // which could install another parse target result, which would make this // exception go away - so try reparsing. try { parseSourceInner(new XMLInputSource(input.getURL()), filePathName); } catch (IOException e1) { Utility.popMessage( "Internal Error", "While parsing input for extension editor: " + getMessagesToRootCause(e1), Utility.ERROR); throw new InternalErrorCDE(e1); } return; } } } e.printStackTrace(); Utility.popMessage(Messages.getString("MultiPageEditor.XMLerrorInDescriptorTitle"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.XMLerrorInDescriptor") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); } catch (ResourceInitializationException e) { // occurs if bad xml // leave isBadXML flag set to true Utility.popMessage(Messages.getString("MultiPageEditor.errorInDescTitle"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.errorInDesc") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$ MessageDialog.ERROR); } } private void validateDescriptorType(int newDescriptorType) throws ResourceInitializationException { if (0 != descriptorType && !openingContext && ((descriptorType & newDescriptorType) == 0)) throw new ResourceInitializationException(Messages.getString("MultiPageEditor.12"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.13"), //$NON-NLS-1$ new String[] { descriptorTypeString(), descriptorTypeString(newDescriptorType) }); if (!openingContext) descriptorType = newDescriptorType; } /** * Create a resource manager that has a class loader that will search the compiled output of the * current project, in addition to the plug-in's classpath. * * We create a new resource manager every time it's needed to pick up any changes the user may * have made to any classes that could have been loaded. * * @return */ public ResourceManager createResourceManager() { // long time = System.currentTimeMillis(); ResourceManager rm = createResourceManager(null); // System.out.println("CreateResourceManager: " + (System.currentTimeMillis() - time)); return rm; } private String cachedRMclassPath = null; private SoftReference cachedRMcl = new SoftReference(null); public ResourceManager createResourceManager(String classPath) { ResourceManager resourceManager = UIMAFramework.newDefaultResourceManager(); try { if (null == classPath) { classPath = getProjectClassPath(); } String dataPath = CDEpropertyPage.getDataPath(getProject()); // first try to get the value of the class loader from the last (cached) // value - should succeed frequently because the class loader is only dependent // on the value of the classpath UIMAClassLoader uimaCL = null; if (cachedRMclassPath != null && cachedRMclassPath.equals(classPath)) { uimaCL = cachedRMcl.get(); } if (uimaCL != null) { ((ResourceManager_impl)resourceManager).setExtensionClassPath(uimaCL, true); } else { // first arg in next is the parent of the class loader. Make it be the // uima framework's class loader (not this class's class loader) // so the validation tests work properly (that test isAssignableFrom) resourceManager.setExtensionClassPath(UIMAFramework.class.getClassLoader(), classPath, true); cachedRMclassPath = classPath; cachedRMcl = new SoftReference((UIMAClassLoader) resourceManager.getExtensionClassLoader()); } // in any case, set the data path resourceManager.setDataPath(dataPath); } catch (MalformedURLException e1) { throw new InternalErrorCDE(Messages.getString("MultiPageEditor.14"), e1); //$NON-NLS-1$ } catch (CoreException e1) { throw new InternalErrorCDE(Messages.getString("MultiPageEditor.15"), e1); //$NON-NLS-1$ } return resourceManager; } /* * (non-Javadoc) Method declared on IEditorPart. */ public boolean isSaveAsAllowed() { return true; } protected void pageChange(int newPageIndex) { currentEditor.pageChangeForCurrentEditor(newPageIndex); } public void pageChangeForCurrentEditor(int newPageIndex) { if (isPageChangeRecursion) return; isRevertingIndex = false; int oldPageIndex = getCurrentPage(); if (oldPageIndex != -1) { if (oldPageIndex == sourceIndex) { if (!validateSource()) { setActivePageWhileBlockingRecursion(sourceIndex); return; } } else if (oldPageIndex == indexesIndex && // could be the same page if users chose to // edit current descriptor when validateIndexes detected a // bad type priorities set newPageIndex != indexesIndex) // could be the same if (!validateIndexes()) return; else if (newPageIndex != indexesIndex) { saveGoodVersionOfTypePriorities(); } } super.pageChange(newPageIndex); Object newPage = pages.get(newPageIndex); if (newPage instanceof HeaderPage) { // ((HeaderPage)newPage).getManagedForm().refresh(); //super.pageChange does this if (newPage instanceof IndexesPage && oldPageIndex != indexesIndex) { saveGoodVersionOfTypePriorities(); } } else if (newPageIndex == sourceIndex) { if (!isBadXML) updateSourceFromModel(); else setActivePageWhileBlockingRecursion(sourceIndex); // set sourceChanged if badXML to redo error notification if nothing changed // in case XML was bad sourceChanged = (isBadXML || isRevertingIndex) ? true : false; } } protected void setActivePageWhileBlockingRecursion(int sourceIndex) { try { isPageChangeRecursion = true; // next call needed to be done but wasn't prior to // Eclipse 3.2 // In Eclipse 3.2 they fixed this, but call this now // calls pageChange, and makes a recursive loop // We break that loop here. setActivePage(sourceIndex); // isn't being done otherwise? } finally { isPageChangeRecursion = false; } } private void saveGoodVersionOfTypePriorities() { TypePriorities tp = getAeDescription().getAnalysisEngineMetaData().getTypePriorities(); m_typePrioritiesBackup = (null == tp) ? null : (TypePriorities) tp.clone(); } private boolean revertToLastValid(String msg, String msgDetails) { String[] buttonLabels = new String[2]; buttonLabels[0] = Messages.getString("MultiPageEditor.revertToLastValid"); //$NON-NLS-1$ buttonLabels[1] = Messages.getString("MultiPageEditor.EditExisting"); //$NON-NLS-1$ MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), msg, null, msgDetails, MessageDialog.WARNING, buttonLabels, 0); dialog.open(); // next line depends on return code for button 1 (which is 1) // and CANCEL code both being == 1 return dialog.getReturnCode() == 0; } /** * Called when switching off of the indexes page Goal is to validate indexes by making a CAS - as * a side effect it does index validation. * * We do this without changing the typeSystemDescription * * @return */ private boolean validateIndexes() { CAS localCAS = descriptorCAS.get(); TypePriorities savedMergedTypePriorities = getMergedTypePriorities(); FsIndexCollection savedFsIndexCollection = getMergedFsIndexCollection(); try { setMergedFsIndexCollection(); setMergedTypePriorities(); descriptorCAS.validate(); } catch (Exception ex) { descriptorCAS.set(localCAS); if (!revertToLastValid(Messages.getString("MultiPageEditor.indexDefProblemTitle"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.indexDefProblem") + //$NON-NLS-1$ getMessagesToRootCause(ex))) { // currentIndex = -1; //irrelevent, but not sourceIndex super.setActivePage(indexesIndex); // currentIndex = indexesIndex; return false; } else { getAeDescription().getAnalysisEngineMetaData().setTypePriorities(m_typePrioritiesBackup); setMergedTypePriorities(savedMergedTypePriorities); setMergedFsIndexCollection(savedFsIndexCollection); isRevertingIndex = true; return true; } } return true; } public String getCharSet(String text) { final String key = Messages.getString("MultiPageEditor.16"); //$NON-NLS-1$ int i = text.indexOf(key); if (i == -1) return Messages.getString("MultiPageEditor.17"); //$NON-NLS-1$ i += key.length(); int end = text.indexOf(Messages.getString("MultiPageEditor.18"), i); //$NON-NLS-1$ return text.substring(i, end); } private boolean validateSource() { if (!sourceChanged) return true; isBadXML = true; // preset IDocument doc = sourceTextEditor.getDocumentProvider().getDocument( sourceTextEditor.getEditorInput()); String text = doc.get(); InputStream is; try { is = new ByteArrayInputStream(text.getBytes(getCharSet(text))); } catch (UnsupportedEncodingException e2) { Utility.popMessage(Messages.getString("MultiPageEditor.19"), //$NON-NLS-1$ getMessagesToRootCause(e2), MessageDialog.ERROR); super.setActivePage(sourceIndex); return false; } String filePathName = getFile().getLocation().toString(); XMLInputSource input = new XMLInputSource(is, new File(filePathName)); AnalysisEngineDescription oldAe = aeDescription; TypeSystemDescription oldTsdWithResolvedImports = mergedTypeSystemDescription; try { parseSource(input, filePathName); // sets isBadXML to false if OK } catch (PartInitException e1) { // if user switched the kind of descriptor Utility.popMessage(Messages.getString("MultiPageEditor.20"), //$NON-NLS-1$ getMessagesToRootCause(e1), MessageDialog.ERROR); super.setActivePage(sourceIndex); return false; } if (isBadXML) return false; if (isPrimitive()) checkForNewlyDirtyTypes(oldTsdWithResolvedImports); checkForNewlyStaleSections(oldAe.getAnalysisEngineMetaData(), aeDescription .getAnalysisEngineMetaData()); return true; } public void markAllPagesStale() { checkForNewlyStaleSections(null, null); } private void checkForNewlyStaleSections(MetaDataObject previous, MetaDataObject current) { // AnalysisEngineMetaData previous, // AnalysisEngineMetaData current // some day can implement code to see what's affected // for now, mark everything as stale // index tests during development - some pages not done if (overviewIndex >= 0) ((HeaderPage) pages.get(overviewIndex)).markStale(); if (aggregateIndex >= 0) ((HeaderPage) pages.get(aggregateIndex)).markStale(); if (parameterIndex >= 0) ((HeaderPage) pages.get(parameterIndex)).markStale(); if (settingsIndex >= 0) ((HeaderPage) pages.get(settingsIndex)).markStale(); if (typeIndex >= 0) ((HeaderPage) pages.get(typeIndex)).markStale(); if (capabilityIndex >= 0) ((HeaderPage) pages.get(capabilityIndex)).markStale(); if (indexesIndex >= 0) ((HeaderPage) pages.get(indexesIndex)).markStale(); if (resourcesIndex >= 0) ((HeaderPage) pages.get(resourcesIndex)).markStale(); } private void checkForNewlyDirtyTypes(TypeSystemDescription oldTsd) { // an array of TypeDescription objects (not CAS), including imported ones TypeDescription[] oldTypes = (null == oldTsd || null == oldTsd.getTypes()) ? new TypeDescription[0] : oldTsd.getTypes(); HashMap oldTypeHash = new HashMap(oldTypes.length); for (int i = 0, length = oldTypes.length; i < length; i++) { TypeDescription oldType = oldTypes[i]; oldTypeHash.put(oldType.getName(), oldType); } TypeDescription[] newTypes = mergedTypeSystemDescription.getTypes(); for (int i = 0; i < newTypes.length; i++) { TypeDescription newType = newTypes[i]; TypeDescription oldType = (TypeDescription) oldTypeHash.get(newType.getName()); if (newType.equals(oldType)) { oldTypeHash.remove(oldType.getName()); } else { addDirtyTypeName(newType.getName()); if (oldType != null) { oldTypeHash.remove(oldType.getName()); } } } Set deletedTypes = oldTypeHash.keySet(); Iterator deletedTypeIterator = deletedTypes.iterator(); while (deletedTypeIterator.hasNext()) { removeDirtyTypeName((String) deletedTypeIterator.next()); } } /* * This returns the true descriptor, accounting for the "trick" when we put CPM descriptors in the * AE descriptor. As a side effect, it updates the CPM descriptors */ private XMLizable getTrueDescriptor() { XMLizable thing; if (isAeDescriptor()) thing = aeDescription; else if (isTypeSystemDescriptor()) thing = typeSystemDescription; else if (isTypePriorityDescriptor()) thing = aeDescription.getAnalysisEngineMetaData().getTypePriorities(); else if (isExtResAndBindingsDescriptor()) thing = aeDescription.getResourceManagerConfiguration(); else if (isFsIndexCollection()) thing = aeDescription.getAnalysisEngineMetaData().getFsIndexCollection(); else if (isCollectionReaderDescriptor()) { thing = collectionReaderDescription; linkLocalProcessingDescriptorsFromAe(collectionReaderDescription); } else if (isCasInitializerDescriptor()) { thing = casInitializerDescription; linkLocalProcessingDescriptorsFromAe(casInitializerDescription); } else if (isCasConsumerDescriptor()) { thing = casConsumerDescription; linkLocalProcessingDescriptorsFromAe(casConsumerDescription); } else if (isFlowControllerDescriptor()) { thing = flowControllerDescription; linkLocalProcessingDescriptorsFromAe(flowControllerDescription); } else throw new InternalErrorCDE(Messages.getString("MultiPageEditor.21")); //$NON-NLS-1$ return thing; } public String prettyPrintModel() { StringWriter writer = new StringWriter(); String parsedText = null; try { XMLSerializer xmlSerializer = new XMLSerializer(true); xmlSerializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.valueOf( MultiPageEditorContributor.getXMLindent()).toString()); xmlSerializer.setWriter(writer); ContentHandler contentHandler = xmlSerializer.getContentHandler(); contentHandler.startDocument(); XMLizable trueDescriptor = getTrueDescriptor(); if (trueDescriptor instanceof AnalysisEngineDescription) { AnalysisEngineDescription aed = (AnalysisEngineDescription) trueDescriptor; aed.toXML(contentHandler, true, true); } else trueDescriptor.toXML(contentHandler, true); contentHandler.endDocument(); writer.close(); parsedText = writer.toString(); } catch (SAXException e) { throw new InternalErrorCDE(Messages.getString("MultiPageEditor.22"), e); //$NON-NLS-1$ } catch (IOException e) { throw new InternalErrorCDE(Messages.getString("MultiPageEditor.23"), e); //$NON-NLS-1$ } return parsedText; } public void updateSourceFromModel() { sourceTextEditor.setIgnoreTextEvent(true); IDocument doc = sourceTextEditor.getDocumentProvider().getDocument( sourceTextEditor.getEditorInput()); doc.set(prettyPrintModel()); sourceTextEditor.setIgnoreTextEvent(false); } public AnalysisEngineDescription getAeDescription() { return aeDescription; } /** * @return * @throws ResourceInitializationException */ public void setAeDescription(AnalysisEngineDescription aAnalysisEngineDescription) throws ResourceInitializationException { if (null == aAnalysisEngineDescription) throw new InternalErrorCDE(Messages.getString("MultiPageEditor.24")); //$NON-NLS-1$ aeDescription = aAnalysisEngineDescription; try { // we do this to keep resolvedDelegates update-able // The value from getDeletageAESpecs is an unmodifiable hash map resolvedDelegates.putAll(aeDescription .getDelegateAnalysisEngineSpecifiers(createResourceManager())); } catch (InvalidXMLException e) { throw new ResourceInitializationException(e); } // get the metadata once, because it can be expensive to do AnalysisEngineMetaData md = aeDescription.getAnalysisEngineMetaData(); // These come before setTypeSystemDescription call because that call // invokes tcas validate, which uses the merged values for speedup // Here we set them to values that won't cause errors. They're set to actual values below. mergedFsIndexCollection = md.getFsIndexCollection(); mergedTypePriorities = md.getTypePriorities(); resolvedExternalResourcesAndBindings = aeDescription.getResourceManagerConfiguration(); resolvedFlowControllerDeclaration = aeDescription.getFlowControllerDeclaration(); setTypeSystemDescription(aeDescription.isPrimitive() ? md.getTypeSystem() : null); // aggregates have null type system descriptors. // If passed in one that isn't null, make it null. // These come after setTypeSystemDescription call, even though // that call invokeds tcas validate, which uses the merged values for speedup // Therefore, merged values have to be set to proper ideas first. setMergedFsIndexCollection(); setImportedFsIndexCollection(); setMergedTypePriorities(); setImportedTypePriorities(); try { setResolvedExternalResourcesAndBindings(); // setImportedExternalResourcesAndBindings(); } catch (InvalidXMLException e1) { throw new ResourceInitializationException(e1); } try { setResolvedFlowControllerDeclaration(); } catch (InvalidXMLException e1) { throw new ResourceInitializationException(e1); } } // note that this also updates merged type system // Also called for aggregate TAEs public void setTypeSystemDescription(TypeSystemDescription typeSystemDescription) throws ResourceInitializationException { boolean doValidation = true; this.typeSystemDescription = typeSystemDescription; // This could be a tsd associated with a primitive TAE descriptor, or // it could be a tsd from a tsd if (typeSystemDescription == null) { if (!isAggregate()) { this.typeSystemDescription = UIMAFramework.getResourceSpecifierFactory() .createTypeSystemDescription(); doValidation = false; // speed up by 1/3 second } } setMergedTypeSystemDescription(); // setImportedTypeSystemDescription(); // done in above call if (aeDescription == null) aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); aeDescription.getAnalysisEngineMetaData().setTypeSystem(this.typeSystemDescription); if (doValidation) descriptorCAS.validate(); } // ************************************************************** // * From taeDescriptor back into the Collection part descriptors // ************************************************************** private void linkLocalProcessingDescriptorsFromAe(CollectionReaderDescription d) { d.setImplementationName(aeDescription.getAnnotatorImplementationName()); d.setFrameworkImplementation(aeDescription.getFrameworkImplementation()); linkCommonCollectionDescriptorsFromAe(d); } private void linkLocalProcessingDescriptorsFromAe(CasInitializerDescription d) { d.setImplementationName(aeDescription.getAnnotatorImplementationName()); d.setFrameworkImplementation(aeDescription.getFrameworkImplementation()); linkCommonCollectionDescriptorsFromAe(d); } private void linkLocalProcessingDescriptorsFromAe(CasConsumerDescription d) { d.setImplementationName(aeDescription.getAnnotatorImplementationName()); d.setFrameworkImplementation(aeDescription.getFrameworkImplementation()); linkCommonCollectionDescriptorsFromAe(d); } private void linkLocalProcessingDescriptorsFromAe(FlowControllerDescription d) { d.setImplementationName(aeDescription.getAnnotatorImplementationName()); d.setFrameworkImplementation(aeDescription.getFrameworkImplementation()); linkCommonCollectionDescriptorsFromAe(d); } private void linkCommonCollectionDescriptorsFromAe(ResourceCreationSpecifier r) { r.setExternalResourceDependencies(aeDescription.getExternalResourceDependencies()); r.setMetaData(convertFromAeMetaData((AnalysisEngineMetaData) aeDescription.getMetaData())); r.setResourceManagerConfiguration(aeDescription.getResourceManagerConfiguration()); } // ********************************************************* // * From Collection Part Descriptors into the taeDescriptor // ********************************************************* private void createAndLinkLocalProcessingDescriptorsToAe(CollectionReaderDescription d) throws ResourceInitializationException { aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); aeDescription.setAnnotatorImplementationName(d.getImplementationName()); aeDescription.setFrameworkImplementation(d.getFrameworkImplementation()); linkLocalProcessingDescriptorsToAe(d); } private void createAndLinkLocalProcessingDescriptorsToAe(CasInitializerDescription d) throws ResourceInitializationException { aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); aeDescription.setAnnotatorImplementationName(d.getImplementationName()); aeDescription.setFrameworkImplementation(d.getFrameworkImplementation()); linkLocalProcessingDescriptorsToAe(d); } private void createAndLinkLocalProcessingDescriptorsToAe(CasConsumerDescription d) throws ResourceInitializationException { aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); aeDescription.setAnnotatorImplementationName(d.getImplementationName()); aeDescription.setFrameworkImplementation(d.getFrameworkImplementation()); linkLocalProcessingDescriptorsToAe(d); } private void createAndLinkLocalProcessingDescriptorsToAe(FlowControllerDescription d) throws ResourceInitializationException { aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); aeDescription.setAnnotatorImplementationName(d.getImplementationName()); aeDescription.setFrameworkImplementation(d.getFrameworkImplementation()); linkLocalProcessingDescriptorsToAe(d); } private void linkLocalProcessingDescriptorsToAe(ResourceCreationSpecifier r) throws ResourceInitializationException { aeDescription.setExternalResourceDependencies(r.getExternalResourceDependencies()); aeDescription.setMetaData(convertToAeMetaData(r.getMetaData())); aeDescription.setPrimitive(true); aeDescription.setResourceManagerConfiguration(r.getResourceManagerConfiguration()); setAeDescription(aeDescription); } private AnalysisEngineMetaData convertToAeMetaData(ResourceMetaData r) { ProcessingResourceMetaData p = (ProcessingResourceMetaData) r; AnalysisEngineMetaData d = UIMAFramework.getResourceSpecifierFactory() .createAnalysisEngineMetaData(); d.setCapabilities(p.getCapabilities()); d.setConfigurationParameterDeclarations(p.getConfigurationParameterDeclarations()); d.setConfigurationParameterSettings(p.getConfigurationParameterSettings()); d.setCopyright(p.getCopyright()); d.setDescription(p.getDescription()); d.setFsIndexCollection(p.getFsIndexCollection()); d.setName(p.getName()); d.setTypePriorities(p.getTypePriorities()); d.setTypeSystem(p.getTypeSystem()); d.setVendor(p.getVendor()); d.setVersion(p.getVersion()); d.setOperationalProperties(p.getOperationalProperties()); return d; } private ProcessingResourceMetaData convertFromAeMetaData(AnalysisEngineMetaData p) { ProcessingResourceMetaData d = UIMAFramework.getResourceSpecifierFactory() .createProcessingResourceMetaData(); d.setCapabilities(p.getCapabilities()); d.setConfigurationParameterDeclarations(p.getConfigurationParameterDeclarations()); d.setConfigurationParameterSettings(p.getConfigurationParameterSettings()); d.setCopyright(p.getCopyright()); d.setDescription(p.getDescription()); d.setFsIndexCollection(p.getFsIndexCollection()); d.setName(p.getName()); d.setTypePriorities(p.getTypePriorities()); d.setTypeSystem(p.getTypeSystem()); d.setVendor(p.getVendor()); d.setVersion(p.getVersion()); d.setOperationalProperties(p.getOperationalProperties()); return d; } private void setCollectionReaderDescription(CollectionReaderDescription d) throws ResourceInitializationException { collectionReaderDescription = d; createAndLinkLocalProcessingDescriptorsToAe(d); } private void setCasInitializerDescription(CasInitializerDescription d) throws ResourceInitializationException { casInitializerDescription = d; createAndLinkLocalProcessingDescriptorsToAe(d); } private void setCasConsumerDescription(CasConsumerDescription d) throws ResourceInitializationException { casConsumerDescription = d; createAndLinkLocalProcessingDescriptorsToAe(d); } private void setFlowControllerDescription(FlowControllerDescription d) throws ResourceInitializationException { flowControllerDescription = d; createAndLinkLocalProcessingDescriptorsToAe(d); } private void setTypePriorities(TypePriorities typePriorities) throws ResourceInitializationException { loadContext(typePriorities); aeDescription.getAnalysisEngineMetaData().setTypePriorities(typePriorities); setMergedTypePriorities(); setImportedTypePriorities(); descriptorCAS.validate(); } private static class MultilevelCancel extends RuntimeException { private static final long serialVersionUID = 1L; } private void loadContext(XMLizable thing) { // try to load a context that has the types if (isContextLoaded) return; String contextFile = null; XMLInputSource input = null; aeDescription = null; openingContext = true; try { try { contextFile = fileNeedingContext.getPersistentProperty(new QualifiedName( AbstractSection.PLUGIN_ID, AbstractSection.IMPORTABLE_PART_CONTEXT)); } catch (CoreException e) { throw new InternalErrorCDE("unexpected exception", e); } ContextForPartDialog dialog = new ContextForPartDialog(PlatformUI.getWorkbench().getDisplay() .getShells()[0], // ok in Eclipse 3.0 getFile().getProject().getParent(), thing, getFile().getLocation(), this, contextFile); dialog.setTitle("File specifying context for editing importable part"); if (dialog.open() == Window.CANCEL) throw new MultilevelCancel(); contextFile = dialog.contextPath; if (null == contextFile) { Utility .popMessage( "Context Info", "A context is required to edit this part. However no context was supplied. Editing will be cancelled", Utility.INFORMATION); throw new MultilevelCancel(); } else { try { input = new XMLInputSource(contextFile); } catch (IOException e) { showContextLoadFailureMessage(e, contextFile); throw new MultilevelCancel(); } if (null != input) try { parseSource(input, contextFile); } catch (PartInitException e) { showContextLoadFailureMessage(e, contextFile); throw new MultilevelCancel(); } } } finally { openingContext = false; } if (null == aeDescription) { aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription(); } else { try { file.setPersistentProperty(new QualifiedName(AbstractSection.PLUGIN_ID, AbstractSection.IMPORTABLE_PART_CONTEXT), contextFile); } catch (CoreException e) { Utility.popMessage("Unexpected Exception", "While loading Context" + getMessagesToRootCause(e), Utility.ERROR); throw new InternalErrorCDE("Unexpected Exception:" + getMessagesToRootCause(e), e); } } } private void setFsIndexCollection(FsIndexCollection indexCollection) throws ResourceInitializationException { loadContext(indexCollection); aeDescription.getAnalysisEngineMetaData().setFsIndexCollection(indexCollection); setMergedFsIndexCollection(); setImportedFsIndexCollection(); descriptorCAS.validate(); } private void showContextLoadFailureMessage(Exception e, String contextFile) { String m = Messages.getFormattedString("MultiPageEditor.IOError", //$NON-NLS-1$ new String[] { AbstractSection.maybeShortenFileName(contextFile) }) + Messages.getString("MultiPageEditor.10") + getMessagesToRootCause(e); //$NON-NLS-1$ Utility.popMessage("Cannot load context", m + "\nCannot load the context file for this importable part due to an I/O exception" + " - proceeding without context", Utility.WARNING); } /** * Only called when editing a resources/bindings descriptor * * @param rb * @throws ResourceInitializationException */ private void setExtResAndBindings(ResourceManagerConfiguration rb) throws ResourceInitializationException { loadContext(rb); aeDescription.setResourceManagerConfiguration(rb); try { setResolvedExternalResourcesAndBindings(); // setImportedExternalResourcesAndBindings(); } catch (InvalidXMLException e) { throw new ResourceInitializationException(e); } descriptorCAS.validate(); } public String getAbsolutePathFromImport(Import importItem) { // getAbsoluteURLfromImport may return a bundleresource style url return new File(getAbsoluteURLfromImport(importItem).getPath()).getPath(); } private URL getAbsoluteURLfromImport(Import importItem) { try { // if by location, it's relative to the descriptor. return Platform.asLocalURL(importItem.findAbsoluteUrl(createResourceManager())); } catch (InvalidXMLException ex) { ex.printStackTrace(); } catch (IOException e) { } return null; } public AggregatePage getAggregatePage() { return aggregatePage; } public OverviewPage getOverviewPage() { return overviewPage; } public ParameterPage getParameterPage() { return parameterPage; } public TypePage getTypePage() { return typePage; } public CapabilityPage getCapabilityPage() { return capabilityPage; } public IndexesPage getIndexesPage() { return indexesPage; } public ResourcesPage getResourcesPage() { return resourcesPage; } public XMLEditor getXMLEditorPage() { return sourceTextEditor; } public SettingsPage getSettingsPage() { return settingsPage; } /** * @return current file being edited */ public IFile getFile() { return file; } public Map getResolvedDelegates() { return resolvedDelegates; } /** * gets the Hash Map of resolved AE delegates Clones the description first because the getting * updates it in some cases * * @param aed * @return */ public Map getDelegateAEdescriptions(AnalysisEngineDescription aed) { Map result = new HashMap(); AnalysisEngineDescription aedClone = (AnalysisEngineDescription) ((AnalysisEngineDescription_impl) aed) .clone(); try { result = aedClone.getDelegateAnalysisEngineSpecifiers(createResourceManager()); } catch (InvalidXMLException e) { } return result; } public void markTCasDirty() { descriptorCAS.markDirty(); allTypes.markDirty(); definedTypesWithSupers.markDirty(); } public CAS getCurrentView() { return descriptorCAS.get(); } public IProject getProject() { IFile iFile = getFile(); if (null == iFile) // can be null when just creating the instance of the MPE, before init() // call return null; return getFile().getProject(); } public String getDescriptorDirectory() { String sDir = file.getParent().getLocation().toString(); if (sDir.charAt(sDir.length() - 1) != '/') { sDir += '/'; } return sDir; } public String getDescriptorRelativePath(String aFullOrRelativePath) { String sEditorFileFullPath = getFile().getLocation().toString(); String sFullOrRelativePath = aFullOrRelativePath.replace('\\', '/'); // first, if not in workspace, or if a relative path, not a full path, return path String sWorkspacePath = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation().toString(); if (sFullOrRelativePath.indexOf(sWorkspacePath) == -1) { return sFullOrRelativePath; } String sFullPath = sFullOrRelativePath; // rename the var to its semantics String commonPrefix = getCommonParentFolder(sEditorFileFullPath, sFullPath); if (commonPrefix.length() < 2 || commonPrefix.indexOf(':') == commonPrefix.length() - 2) { return sFullPath; } // now count extra slashes to determine how many ..'s are needed int nCountBackDirs = 0; String sRelativePath = ""; //$NON-NLS-1$ for (int i = commonPrefix.length(); i < sEditorFileFullPath.length(); i++) { if (sEditorFileFullPath.charAt(i) == '/') { sRelativePath += "../"; //$NON-NLS-1$ nCountBackDirs++; } } sRelativePath += sFullPath.substring(commonPrefix.length()); return sRelativePath; } private static String getCommonParentFolder(String sFile1, String sFile2) { if (sFile1 == null || sFile2 == null) { return ""; //$NON-NLS-1$ } int maxLength = (sFile1.length() <= sFile2.length() ? sFile1.length() : sFile2.length()); int commonPrefixLength = 0; for (int i = 0; i < maxLength; i++) { if (sFile1.charAt(i) != sFile2.charAt(i) || (i == maxLength - 1)) { // catch files which have // same prefix for (int j = i; j >= 0; j--) { if (sFile1.charAt(j) == '/' || sFile1.charAt(j) == '\\') { commonPrefixLength = j + 1; break; } } break; } } return sFile1.substring(0, commonPrefixLength); } public boolean isFileInWorkspace(String aFileRelPath) { Object fileOrIFile = getIFileOrFile(aFileRelPath); return (fileOrIFile instanceof IFile && ((IFile) fileOrIFile).exists()); } public String getFullPathFromDescriptorRelativePath(String aDescRelPath) { if (aDescRelPath.indexOf(':') > 0) { // indicates already an absolute path on Windows, at least return aDescRelPath.replace('\\', '/'); } String sEditorFileFullPath = getFile().getLocation().toString(); String sDescRelPath = aDescRelPath.replace('\\', '/'); int nCountDirsToBackup = 0; int nNextFindLoc = -1; int nLastFindLoc = -1; while (true) { nLastFindLoc = nNextFindLoc; nNextFindLoc = sDescRelPath.indexOf("../", nNextFindLoc + 1); //$NON-NLS-1$ if (nNextFindLoc > -1) { nCountDirsToBackup++; } else { break; } } String sFinalFragment = ""; //$NON-NLS-1$ if (nCountDirsToBackup > 0) { sFinalFragment = sDescRelPath.substring(nLastFindLoc + 3); } if (nCountDirsToBackup == 0) { int nEditorFileLastSlash = sEditorFileFullPath.lastIndexOf('/'); String sEditorFileDirectory = sEditorFileFullPath.substring(0, nEditorFileLastSlash + 1); return sEditorFileDirectory + sDescRelPath; } int nSubDirCount = 0; for (int i = 0; i < sEditorFileFullPath.length(); i++) { if (sEditorFileFullPath.charAt(i) == '/') { nSubDirCount++; } } int[] subDirMarkerLocs = new int[nSubDirCount]; int j = 0; for (int i = 0; i < sEditorFileFullPath.length(); i++) { if (sEditorFileFullPath.charAt(i) == '/') { subDirMarkerLocs[j++] = i; } } if (nCountDirsToBackup > nSubDirCount) { return null; } return sEditorFileFullPath.substring(0, subDirMarkerLocs[nSubDirCount - nCountDirsToBackup - 1] + 1) + sFinalFragment; } public void open(IFile fileToOpen) { final IFile ffile = fileToOpen; Shell shell = new Shell(); shell.getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { page.openEditor(new FileEditorInput(ffile), "taeconfigurator.editors.MultiPageEditor"); //$NON-NLS-1$ } catch (PartInitException e) { throw new InternalErrorCDE("unexpected exception"); } } }); } public void openTextEditor(IFile fileToOpen) { final IFile ffile = fileToOpen; Shell shell = new Shell(); shell.getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { page.openEditor(new FileEditorInput(ffile), "org.eclipse.ui.DefaultTextEditor"); //$NON-NLS-1$ } catch (PartInitException e) { throw new InternalErrorCDE("unexpected exception"); } } }); } public Object getIFileOrFile(String relOrAbsPath) { String sFileFullPath = getFullPathFromDescriptorRelativePath(relOrAbsPath); String sWorkspacePath = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation().toString(); boolean bHasWorkspacePath = (sFileFullPath.indexOf(sWorkspacePath) > -1); if (bHasWorkspacePath) { Path path = new Path(sFileFullPath); return TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path); } return new File(sFileFullPath); } public void open(String fullPath) { Path path = new Path(fullPath); IFile fileToOpen = TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path); open(fileToOpen); } public void openTextEditor(String fullPath) { Path path = new Path(fullPath); IFile fileToOpen = TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path); openTextEditor(fileToOpen); } public void addDirtyTypeName(String typeName) { dirtyTypeNameHash.add(typeName); markTypeModelDirty(); } private void markTypeModelDirty() { allTypes.markDirty(); descriptorCAS.markDirty(); definedTypesWithSupers.markDirty(); } public void removeDirtyTypeName(String typeName) { dirtyTypeNameHash.remove(typeName); markTypeModelDirty(); } public void doJCasGen(IProgressMonitor monitor) { if (0 < mergedTypesAddingFeatures.size()) { if (Window.CANCEL == Utility.popOkCancel("Type feature merging extended features", "Before generating the JCas classes for the CAS types, please note that " + "the following types were generated by merging different type descriptors, " + "where the resulting number of features is larger than that of the components. " + "Although the resulting generated JCas classes are correct, " + "doing this kind of merging makes reuse of this component more difficult." + makeMergeMessage(mergedTypesAddingFeatures) + "\n Press OK to generate the JCas classes anyway, or cancel to skip generating the JCas classes.", MessageDialog.WARNING)) return; } final JCasGenThrower jCasGenThrower = new JCasGenThrower(); try { final IWorkspace workspace = ResourcesPlugin.getWorkspace(); final Jg jg = new Jg(); final TypeDescription[] types = mergedTypeSystemDescription.getTypes(); final String outputDirectory = getPrimarySourceFolder().getLocation().toOSString(); final String inputFile = file.getLocation().toOSString(); // path to descriptor file IWorkspaceRunnable runnable = new IWorkspaceRunnable() { public void run(IProgressMonitor progressMonitor) { try { jg.mainForCde(new MergerImpl(), new JCasGenProgressMonitor(progressMonitor), jCasGenThrower, inputFile, outputDirectory, types, (CASImpl) getCurrentView()); } catch (IOException e) { Utility.popMessage(Messages.getString("MultiPageEditor.25"), //$NON-NLS-1$ Messages.getString("MultiPageEditor.26") //$NON-NLS-1$ + getMessagesToRootCause(e), MessageDialog.ERROR); } } }; workspace.run(runnable, monitor); getPrimarySourceFolder().refreshLocal(IResource.DEPTH_INFINITE, null); String jcasMsg = jCasGenThrower.getMessage(); if (null != jcasMsg && jcasMsg.length() > 0) { Utility.popMessage(Messages.getString("MultiPageEditor.JCasGenErrorTitle"), //$NON-NLS-1$ Messages.getFormattedString("MultiPageEditor.jcasGenErr", //$NON-NLS-1$ new String[] { jcasMsg }), MessageDialog.ERROR); System.out.println(jcasMsg); } } catch (Exception ex) { Utility.popMessage(Messages.getString("MultiPageEditor.JCasGenErrorTitle"), //$NON-NLS-1$ Messages.getFormattedString("MultiPageEditor.jcasGenErr", //$NON-NLS-1$ new String[] { jCasGenThrower.getMessage() }), MessageDialog.ERROR); ex.printStackTrace(); } } // message: TypeName = ".....", URLs defining this type = "xxxx", "xxxx", .... private String makeMergeMessage(Map m) { StringBuffer sb = new StringBuffer(); for (Iterator it = m.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); String typeName =(String)entry.getKey(); sb.append("\n "); sb.append("TypeName having merged features = ").append(typeName).append("\n URLs defining this type ="); Set urls = (Set)entry.getValue(); boolean afterFirst = false; for (Iterator itUrls = urls.iterator(); itUrls.hasNext();) { if (afterFirst) sb.append(",\n "); else sb.append("\n "); afterFirst = true; String url = (String) itUrls.next(); sb.append('"').append(url).append('"'); } } return sb.toString(); } final public static String PATH_SEPARATOR = System.getProperty("path.separator"); //$NON-NLS-1$ private long cachedStamp = -1; private String cachedClassPath = null; public String getProjectClassPath() throws CoreException { return getFilteredProjectClassPath(true); } public String getFilteredProjectClassPath(boolean filterCoreResources) throws CoreException { IProject project = getProject(); if (null == project || !project.isNatureEnabled("org.eclipse.jdt.core.javanature")) { //$NON-NLS-1$ return ""; //$NON-NLS-1$ } IJavaProject javaProj = JavaCore.create(project); IProject projectRoot = javaProj.getProject(); IResource classFileResource = projectRoot.findMember(".classpath"); //$NON-NLS-1$ long stamp = classFileResource.getModificationStamp(); if (stamp == cachedStamp && filterCoreResources) // only filtered is cached return cachedClassPath; StringBuffer result = new StringBuffer(1000); String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(javaProj); for (int i = 0; i < classPaths.length; i++) { String classPath = classPaths[i]; if (filterCoreResources) { URLClassLoader checker = null; try { // ignore this entry if it is the Java JVM path checker = new URLClassLoader(new URL[] { new File(classPath).toURL() }); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (null == checker || // || null != checker.findResource("java/lang/Object.class") // //$NON-NLS-1$ null != checker.findResource("org/apache/uima/impl/UIMAFramework_impl.class")) { //$NON-NLS-1$ continue; } } if (result.length() > 0) result = result.append(PATH_SEPARATOR); result = result.append(classPath); } if (filterCoreResources) { cachedStamp = stamp; cachedClassPath = result.toString(); return cachedClassPath; } return result.toString(); } public IResource getPrimarySourceFolder() { IProject project = getProject(); try { if (!project.isNatureEnabled("org.eclipse.jdt.core.javanature")) { //$NON-NLS-1$ return null; } IJavaProject javaProj = JavaCore.create(project); IPackageFragmentRoot[] frs = javaProj.getPackageFragmentRoots(); for (int i = 0; i < frs.length; i++) { frs[i].open(null); IResource resource = frs[i].getResource(); // first folder resource will always be first // source folder if (resource instanceof IFolder || resource instanceof IProject) { return resource; } } } catch (Exception ex) { ex.printStackTrace(); } return null; } public void setSaveAsStatus(int nStatus) { m_nSaveAsStatus = nStatus; } public TypeSystemDescription getTypeSystemDescription() { return aeDescription.getAnalysisEngineMetaData().getTypeSystem(); } public TypePriorities getTypePriorities() { return aeDescription.getAnalysisEngineMetaData().getTypePriorities(); } public FsIndexCollection getFsIndexCollection() { return aeDescription.getAnalysisEngineMetaData().getFsIndexCollection(); } public ResourceManagerConfiguration getExtResAndBindings() { return aeDescription.getResourceManagerConfiguration(); } private static final boolean VALIDATE_INPUTS = true; // returns true if no inputs were removed, false otherwise public boolean validateInputs(Map typeNameHash) { return validateIOs(VALIDATE_INPUTS, typeNameHash); } // returns true if no outputs were removed, false otherwise public boolean validateOutputs(Map typeNameHash) { return validateIOs(!VALIDATE_INPUTS, typeNameHash); } public boolean validateIOs(boolean isValidateInputs, Map typeNameHash) { boolean bRes = true; if (aeDescription != null) { Capability[] capabilities = aeDescription.getAnalysisEngineMetaData().getCapabilities(); if (capabilities == null || capabilities.length == 0) { return true; } TypeOrFeature[] oldIOs = (isValidateInputs) ? capabilities[0].getInputs() : capabilities[0] .getOutputs(); Vector validIOs = new Vector(); for (int i = 0; i < oldIOs.length; i++) { String typeName; int nColonLoc = oldIOs[i].getName().indexOf(':'); if (nColonLoc == -1) { typeName = oldIOs[i].getName(); } else { typeName = oldIOs[i].getName().substring(0, nColonLoc); } if (typeNameHash.containsKey(typeName)) { validIOs.addElement(oldIOs[i]); } else { bRes = false; } } if (!bRes) { TypeOrFeature[] newIOs = new TypeOrFeature[validIOs.size()]; for (int i = 0; i < newIOs.length; i++) { newIOs[i] = (TypeOrFeature) validIOs.elementAt(i); } if (isValidateInputs) capabilities[0].setInputs(newIOs); else capabilities[0].setOutputs(newIOs); } } return bRes; } // returns true if no type priorities were modified, false otherwise public boolean validateTypePriorities(Map typeNameHash) { boolean bRes = true; TypePriorities priorities = aeDescription.getAnalysisEngineMetaData().getTypePriorities(); if (priorities != null) { TypePriorityList[] priorityLists = priorities.getPriorityLists(); if (priorityLists != null) { for (int i = 0; i < priorityLists.length; i++) { String[] typeNames = priorityLists[i].getTypes(); if (typeNames != null) { int nCountNewTypeNames = 0; for (int j = 0; j < typeNames.length; j++) { if (typeNameHash.containsKey(typeNames[j])) { nCountNewTypeNames++; } } if (nCountNewTypeNames < typeNames.length) { bRes = false; String[] newTypeNames = new String[nCountNewTypeNames]; for (int j = 0, k = 0; j < typeNames.length; j++) { if (typeNameHash.containsKey(typeNames[j])) { newTypeNames[k++] = typeNames[j]; } } priorityLists[i].setTypes(newTypeNames); } } } } } return bRes; } private static final int previewSize = 1024 * 16; /** * Used by code to get lists of delegate components by input/output type specs. */ public static ResourceSpecifier getDelegateResourceSpecifier(IFile iFile, String[] componentHeaders) { if (!iFile.getName().toLowerCase().endsWith(".xml")) { //$NON-NLS-1$ return null; } // make a quick assesment of whether file is a TAE // looking in the first part of the file, but 1024 isn't big enough // because initial comment blocks like the apache license are that big // Do 16 K char[] acBuffer = new char[previewSize]; FileReader fileReader = null; int nCharsRead = 0; try { // FileReader is FileInputStream using "default" char-encoding fileReader = new FileReader(iFile.getLocation().toString()); while (true) { int tempCharsRead = fileReader.read(acBuffer, nCharsRead, previewSize - nCharsRead); if (-1 == tempCharsRead) break; nCharsRead = nCharsRead + tempCharsRead; if (nCharsRead >= previewSize) break; } } catch (FileNotFoundException e) { return null; } catch (IOException e) { return null; } finally { if (null != fileReader) try { fileReader.close(); } catch (IOException e1) { } } if (-1 == nCharsRead) return null; String sBuffer = (new String(acBuffer, 0, nCharsRead)).toLowerCase(); for (int i = 0; i < componentHeaders.length; i++) { if (-1 != sBuffer.indexOf(componentHeaders[i])) break; if (i == (componentHeaders.length - 1)) return null; } try { XMLInputSource input = new XMLInputSource(iFile.getLocation().toFile()); XMLizable inputDescription = AbstractSection.parseDescriptor(input); if (inputDescription instanceof AnalysisEngineDescription || inputDescription instanceof CasConsumerDescription || inputDescription instanceof FlowControllerDescription) return (ResourceCreationSpecifier) inputDescription; else if (inputDescription instanceof ResourceServiceSpecifier) return (ResourceSpecifier) inputDescription; return null; } catch (IOException e) { return null; } catch (InvalidXMLException e) { return null; } } // ************************************************** // * Getting exception messages down to root // ************************************************** public String getMessagesToRootCause(Throwable e) { boolean wantStackTrace = false; StringBuffer b = new StringBuffer(200); String messagePart = e.getMessage(); // messages for noClassDef found and NPE don't say what the problem was, // so always include the exception class also formatMessageWithClass(e, b, messagePart); if (null == messagePart) { wantStackTrace = true; } // if (null == messagePart) { // b.append(e.getClass().getName()); // wantStackTrace = true; // } else // b.append(messagePart); Throwable cur = e; Throwable next; while (null != (next = cur.getCause())) { String message = next.getMessage(); wantStackTrace = false; // only do stack trace if last item has no message if (null == message) { b.append(next.getClass().getName()); wantStackTrace = true; } if (null != message && !message.equals(messagePart)) { b.append(Messages.getString("MultiPageEditor.causedBy")); formatMessageWithClass(next, b, message); messagePart = message; } cur = next; } if (wantStackTrace) { ByteArrayOutputStream ba = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(ba); cur.printStackTrace(ps); ps.flush(); b.append(ba.toString()); ps.close(); } return b.toString(); } private void formatMessageWithClass(Throwable e, StringBuffer b, String messagePart) { String name = e.getClass().getName(); //because this is a message for ordinary users, and // because the exceptions are more easily readable without their package prefixes, // remove the package prefix from the displayed name int lastDot = name.lastIndexOf('.'); if (lastDot >= 0) { name = name.substring(lastDot + 1); } b.append(name); if (null != messagePart) { b.append(": ").append(messagePart); } } public static class JCasGenProgressMonitor implements org.apache.uima.tools.jcasgen.IProgressMonitor { IProgressMonitor m_progressMonitor; public JCasGenProgressMonitor(IProgressMonitor progressMonitor) { m_progressMonitor = progressMonitor; } /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#done() */ public void done() { m_progressMonitor.done(); } /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#beginTask(java.lang.String, int) */ public void beginTask(String name, int totalWorked) { m_progressMonitor.beginTask(name, totalWorked); } /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#subTask(java.lang.String) */ public void subTask(String name) { m_progressMonitor.subTask(name); } /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#worked(int) */ public void worked(int work) { m_progressMonitor.worked(work); } } public static class JCasGenThrower implements IError { private Level logLevels[] = { Level.INFO, Level.WARNING, Level.SEVERE }; private String m_message = null; /* * (non-Javadoc) * * @see org.apache.uima.jcas.jcasgen_gen.IError#newError(int, java.lang.String) */ public void newError(int severity, String message, Exception ex) { Logger log = UIMAFramework.getLogger(); log.log(logLevels[severity], "JCasGen: " + message); //$NON-NLS-1$ System.out.println(Messages.getString("MultiPageEditor.JCasGenErr") //$NON-NLS-1$ + message); if (null != ex) ex.printStackTrace(); if (IError.WARN < severity) { m_message = message; throw new Jg.ErrorExit(); } } public String getMessage() { return m_message; } } public Color getFadeColor() { if (null == fadeColor) // COLOR_WIDGET_DARK_SHADOW is the same as black on SUSE KDE fadeColor = getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); return fadeColor; } // ********************** // * Merged type system // ********************** public void setMergedTypeSystemDescription(TypeSystemDescription saved) { mergedTypeSystemDescription = saved; } public void setImportedTypeSystemDescription(TypeSystemDescription saved) { importedTypeSystemDescription = saved; } private void setImportedTypeSystemDescription() throws ResourceInitializationException { Collection tsdc = new ArrayList(1); TypeSystemDescription tsd = typeSystemDescription; if (null != tsd) { tsd = (TypeSystemDescription) tsd.clone(); tsd.setTypes(typeDescriptionArray0); } tsdc.clear(); tsdc.add(tsd); importedTypeSystemDescription = CasCreationUtils .mergeTypeSystems(tsdc, createResourceManager()); } public void setMergedTypeSystemDescription() throws ResourceInitializationException { mergedTypesAddingFeatures.clear(); if (isAggregate()) mergedTypeSystemDescription = mergeDelegateAnalysisEngineTypeSystems( (AnalysisEngineDescription) aeDescription.clone(), createResourceManager(), mergedTypesAddingFeatures); else { if (null == typeSystemDescription) { mergedTypeSystemDescription = null; } else { ResourceManager resourceManager = createResourceManager(); Collection tsdc = new ArrayList(1); tsdc.add(typeSystemDescription.clone()); // System.out.println("mergingTypeSystem 2"); //$NON-NLS-1$ // long time = System.currentTimeMillis(); mergedTypeSystemDescription = CasCreationUtils.mergeTypeSystems(tsdc, resourceManager, mergedTypesAddingFeatures); // System.out.println("Finished mergingTypeSystem 2; time= " + //$NON-NLS-1$ // (System.currentTimeMillis() - time)); setImportedTypeSystemDescription(); } } } public TypeSystemDescription getMergedTypeSystemDescription() { return mergedTypeSystemDescription; } public TypeSystemDescription getImportedTypeSystemDesription() { return importedTypeSystemDescription; } public void setMergedFsIndexCollection() throws ResourceInitializationException { mergedFsIndexCollection = mergeDelegateAnalysisEngineFsIndexCollections( (AnalysisEngineDescription) aeDescription.clone(), createResourceManager()); } public void setMergedFsIndexCollection(FsIndexCollection saved) { mergedFsIndexCollection = saved; } public FsIndexCollection getMergedFsIndexCollection() { return mergedFsIndexCollection; } // full merge - including locally defined and imported ones public void setMergedTypePriorities() throws ResourceInitializationException { mergedTypePriorities = mergeDelegateAnalysisEngineTypePriorities( (AnalysisEngineDescription) aeDescription.clone(), createResourceManager()); } public void setMergedTypePriorities(TypePriorities saved) { mergedTypePriorities = saved; } public TypePriorities getMergedTypePriorities() { return mergedTypePriorities; } public void setResolvedFlowControllerDeclaration() throws InvalidXMLException { FlowControllerDeclaration fcDecl = aeDescription.getFlowControllerDeclaration(); if (null != fcDecl) { resolvedFlowControllerDeclaration = (FlowControllerDeclaration) fcDecl.clone(); resolvedFlowControllerDeclaration.resolveImports(createResourceManager()); } else resolvedFlowControllerDeclaration = null; } public FlowControllerDeclaration getResolvedFlowControllerDeclaration() { return resolvedFlowControllerDeclaration; } /** * A Merge method doesn't "fit". merging isn't done over aggregates for these. Instead, the * outer-most one "wins". * * But: resolving does fit. So we name this differently * * @throws InvalidXMLException */ public void setResolvedExternalResourcesAndBindings() throws InvalidXMLException { AnalysisEngineDescription clonedAe = (AnalysisEngineDescription) aeDescription.clone(); ResourceManagerConfiguration rmc = clonedAe.getResourceManagerConfiguration(); if (null != rmc) rmc.resolveImports(createResourceManager()); resolvedExternalResourcesAndBindings = rmc; } public void setResolvedExternalResourcesAndBindings(ResourceManagerConfiguration saved) { resolvedExternalResourcesAndBindings = saved; } public ResourceManagerConfiguration getResolvedExternalResourcesAndBindings() { return resolvedExternalResourcesAndBindings; } private void setImportedFsIndexCollection() throws ResourceInitializationException { AnalysisEngineDescription localAe = (AnalysisEngineDescription) aeDescription.clone(); localAe.getAnalysisEngineMetaData().setFsIndexCollection(null); importedFsIndexCollection = CasCreationUtils.mergeDelegateAnalysisEngineFsIndexCollections( localAe, createResourceManager()); } public FsIndexCollection getImportedFsIndexCollection() { return importedFsIndexCollection; } // this is all the type priorities, except those locally defined // used to distinguish between locally defined and imported ones // (only locally defined ones can be edited) private void setImportedTypePriorities() throws ResourceInitializationException { AnalysisEngineDescription localAe = (AnalysisEngineDescription) aeDescription.clone(); localAe.getAnalysisEngineMetaData().setTypePriorities(null); importedTypePriorities = mergeDelegateAnalysisEngineTypePriorities(localAe, createResourceManager()); } public TypePriorities getImportedTypePriorities() { return importedTypePriorities; } // private void setImportedExternalResourcesAndBindings() throws ResourceInitializationException { // ResourceManagerConfiguration_impl rmc = ((ResourceManagerConfiguration_impl) // aeDescription.getResourceManagerConfiguration()); // if (null != rmc) { // rmc = (ResourceManagerConfiguration_impl) rmc.clone(); // rmc.setExternalResourceBindings(null); // rmc.setExternalResources(null); // try { // rmc.resolveImports(createResourceManager()); // } catch (InvalidXMLException e) { // throw new ResourceInitializationException(e); // } // } // importedExternalResourcesAndBindings = rmc; // } // public ResourceManagerConfiguration getImportedExternalResourcesAndBindings() { // return importedExternalResourcesAndBindings; // } public ITextEditor getSourcePageEditor() { if (getCurrentPage() == sourceIndex) { return sourceTextEditor; } else return null; } private IJavaProject javaProject = null; public IJavaProject getJavaProject() { if (null == javaProject && null != file) { javaProject = JavaCore.create(file.getProject()); } return javaProject; } public IType getTypeFromProject(String typename) { IJavaProject jp = getJavaProject(); if (null != jp) try { return jp.findType(typename); } catch (JavaModelException e) { Utility.popMessage("Unexpected Exception", MessageFormat.format( "Unexpected exception while getting type information for type ''{0}''. {1}", new Object[] { typename, getMessagesToRootCause(e) }), Utility.ERROR); throw new InternalErrorCDE("unexpected exception", e); } return null; } private IType analysisComponentIType = null; private IType baseAnnotatorIType = null; private IType collectionReaderIType = null; private IType casInitializerIType = null; private IType casConsumerIType = null; private IType flowControllerIType = null; public IType getAnalysisComponentIType() { if (null == analysisComponentIType) analysisComponentIType = getTypeFromProject("org.apache.uima.analysis_component.AnalysisComponent"); return analysisComponentIType; } public IType getBaseAnnotatorIType() { if (null == baseAnnotatorIType) baseAnnotatorIType = getTypeFromProject("org.apache.uima.analysis_engine.annotator.BaseAnnotator"); return baseAnnotatorIType; } public IType getCollectionReaderIType() { if (null == collectionReaderIType) collectionReaderIType = getTypeFromProject("org.apache.uima.collection.CollectionReader"); return collectionReaderIType; } public IType getCasInitializerIType() { if (null == casInitializerIType) casInitializerIType = getTypeFromProject("org.apache.uima.collection.CasInitializer"); return casInitializerIType; } public IType getCasConsumerIType() { if (null == casConsumerIType) casConsumerIType = getTypeFromProject("org.apache.uima.collection.CasConsumer"); return casConsumerIType; } public IType getFlowControllerIType() { if (null == flowControllerIType) flowControllerIType = getTypeFromProject("org.apache.uima.flow.FlowController"); return flowControllerIType; } private static class CombinedHierarchyScope implements IJavaSearchScope { private IJavaSearchScope[] subScopes = new IJavaSearchScope[5]; private int nbrScopes = 0; public IJavaSearchScope[] getScopes() { return subScopes; } public void addScope(IJavaSearchScope newScope) { subScopes[nbrScopes++] = newScope; } public boolean encloses(String resourcePath) { for (int i = 0; i < nbrScopes; i++) { if (subScopes[i].encloses(resourcePath)) { return true; } } if (!resourcePath.startsWith("C:\\p\\j")) System.out.println(MessageFormat.format(" FALSE encloses resourcepath: ''{0}''", new Object[] { resourcePath })); return false; } public boolean encloses(IJavaElement element) { for (int i = 0; i < nbrScopes; i++) { if (subScopes[i].encloses(element)) return true; } return false; } public IPath[] enclosingProjectsAndJars() { ArrayList result = new ArrayList(10); for (int i = 0; i < nbrScopes; i++) { IPath[] pjs = subScopes[i].enclosingProjectsAndJars(); if (null != pjs) for (int j = 0; j < pjs.length; j++) { if (!result.contains(pjs[j])) result.add(pjs[j]); } } return (IPath[]) result.toArray(new IPath[result.size()]); } public boolean includesBinaries() { // TODO Auto-generated method stub return true; } public boolean includesClasspaths() { // TODO Auto-generated method stub return true; } public void setIncludesBinaries(boolean includesBinaries) { // implements interface method } public void setIncludesClasspaths(boolean includesClasspaths) { // implements interface method } } public IJavaSearchScope getSearchScopeForDescriptorType() { try { switch (descriptorType) { case DESCRIPTOR_AE: CombinedHierarchyScope scope = new CombinedHierarchyScope(); scope.addScope(SearchEngine.createHierarchyScope(getAnalysisComponentIType())); scope.addScope(SearchEngine.createHierarchyScope(getBaseAnnotatorIType())); scope.addScope(SearchEngine.createHierarchyScope(getCollectionReaderIType())); scope.addScope(SearchEngine.createHierarchyScope(getCasConsumerIType())); return scope; case DESCRIPTOR_CASCONSUMER: return SearchEngine.createHierarchyScope(getCasConsumerIType()); case DESCRIPTOR_CASINITIALIZER: return SearchEngine.createHierarchyScope(getCasInitializerIType()); case DESCRIPTOR_COLLECTIONREADER: return SearchEngine.createHierarchyScope(getCollectionReaderIType()); case DESCRIPTOR_FLOWCONTROLLER: return SearchEngine.createHierarchyScope(getFlowControllerIType()); } } catch (JavaModelException e) { throw new InternalErrorCDE("unexpected exception", e); } return null; } private TypeSystemDescription mergeDelegateAnalysisEngineTypeSystems( AnalysisEngineDescription aAeDescription, ResourceManager aResourceManager, Map aOutputMergedTypes) throws ResourceInitializationException { getMergeInput(aAeDescription, aResourceManager); return CasCreationUtils.mergeTypeSystems(typeSystemsToMerge, aResourceManager, aOutputMergedTypes); } private TypePriorities mergeDelegateAnalysisEngineTypePriorities( AnalysisEngineDescription aAeDescription, ResourceManager aResourceManager) throws ResourceInitializationException { getMergeInput(aAeDescription, aResourceManager); return CasCreationUtils.mergeTypePriorities(typePrioritiesToMerge, aResourceManager); } private FsIndexCollection mergeDelegateAnalysisEngineFsIndexCollections( AnalysisEngineDescription aAeDescription, ResourceManager aResourceManager) throws ResourceInitializationException { getMergeInput(aAeDescription, aResourceManager); return CasCreationUtils.mergeFsIndexes(fsIndexesToMerge, aResourceManager); } public CAS createCas(AnalysisEngineDescription aAeDescription, Properties aPerformanceTuningSettings, ResourceManager aResourceManager) throws ResourceInitializationException { getMergeInput(aAeDescription, aResourceManager); // merge TypeSystemDescription aggTypeDesc = CasCreationUtils.mergeTypeSystems(typeSystemsToMerge, aResourceManager); TypePriorities aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesToMerge, aResourceManager); FsIndexCollection aggIndexColl = CasCreationUtils.mergeFsIndexes(fsIndexesToMerge, aResourceManager); return CasCreationUtils.createCas(aggTypeDesc, aggTypePriorities, aggIndexColl.getFsIndexes(), aPerformanceTuningSettings, aResourceManager); } private void getMergeInput ( AnalysisEngineDescription aAggregateDescription, ResourceManager aResourceManager) throws ResourceInitializationException { // expand the aggregate AE description into the individual delegates ArrayList l = new ArrayList(); l.add(aAggregateDescription); List mdList = CasCreationUtils.getMetaDataList(l, aResourceManager, failedRemotes); maybeShowRemoteFailure(); // extract type systems and merge typeSystemsToMerge = new ArrayList(); typePrioritiesToMerge = new ArrayList(); fsIndexesToMerge = new ArrayList(); Iterator it = mdList.iterator(); while (it.hasNext()) { ProcessingResourceMetaData md = (ProcessingResourceMetaData) it.next(); if (md.getTypeSystem() != null) typeSystemsToMerge.add(md.getTypeSystem()); if (md.getTypePriorities() != null) typePrioritiesToMerge.add(md.getTypePriorities()); if (md.getFsIndexCollection() != null) fsIndexesToMerge.add(md.getFsIndexCollection()); } } private void maybeShowRemoteFailure() { if (failedRemotes.size() == 0) { return; } List names = new ArrayList(); List exceptions = new ArrayList(); for (Iterator it = failedRemotes.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); String component = (String)entry.getKey(); if (failedRemotesAlreadyKnown.contains(component)) { continue; } failedRemotesAlreadyKnown.add(component); names.add(component); exceptions.add(entry.getValue()); } if (names.size() == 0) { return; } StringBuffer sb = new StringBuffer(100); for (int i = 0; i < names.size(); i++) { sb.append("Component key-name(s): ").append(names.get(i)) .append(": ") .append(getMessagesToRootCause((Exception)exceptions.get(i))) .append("\n---------------\n"); } Utility.popMessage("Remotes Unavailable", "Note: This message is only shown once.\n\n" + "Some Remote components (see error message below) could not be accessed.\n" + "This is not an error; perhaps the remote components are not currently running.\n\n" + "WARNING: The Types, Type Priorities, and Indexes created by \"merging\"\n" + "information from the imported remote types may be incomplete\n" + "(because the editor can't read this information at the moment).\n" + "However, this doesn't affect the editing operations; you can continue\n" + "(but with perhaps less complete error checking in the editor,\n" + "and JCasGen, if used, may be missing some type information that\n" + "would have come from the remote components, had they been available.\n\n" + sb, MessageDialog.WARNING); } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/0000755000175000017500000000000011665471212031776 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017500000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/NonRuleBasedDamagerRepairer.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/NonRuleB0000644000175000017500000001175611665471212033417 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.DocumentEvent; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.ITypedRegion; import org.eclipse.jface.text.Region; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.TextPresentation; import org.eclipse.jface.text.presentation.IPresentationDamager; import org.eclipse.jface.text.presentation.IPresentationRepairer; import org.eclipse.jface.util.Assert; import org.eclipse.swt.custom.StyleRange; public class NonRuleBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer { /** The document this object works on */ protected IDocument fDocument; /** The default text attribute if non is returned as data by the current token */ protected TextAttribute fDefaultTextAttribute; /** * Constructor for NonRuleBasedDamagerRepairer. */ public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) { Assert.isNotNull(defaultTextAttribute); fDefaultTextAttribute = defaultTextAttribute; } /** * @see IPresentationRepairer#setDocument(IDocument) */ public void setDocument(IDocument document) { fDocument = document; } /** * Returns the end offset of the line that contains the specified offset or if the offset is * inside a line delimiter, the end offset of the next line. * * @param offset * the offset whose line end offset must be computed * @return the line end offset for the given offset * @exception BadLocationException * if offset is invalid in the current document */ protected int endOfLineOf(int offset) throws BadLocationException { IRegion info = fDocument.getLineInformationOfOffset(offset); if (offset <= info.getOffset() + info.getLength()) return info.getOffset() + info.getLength(); int line = fDocument.getLineOfOffset(offset); try { info = fDocument.getLineInformation(line + 1); return info.getOffset() + info.getLength(); } catch (BadLocationException x) { return fDocument.getLength(); } } /** * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean) */ public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, boolean documentPartitioningChanged) { if (!documentPartitioningChanged) { try { IRegion info = fDocument.getLineInformationOfOffset(event.getOffset()); int start = Math.max(partition.getOffset(), info.getOffset()); int end = event.getOffset() + (event.getText() == null ? event.getLength() : event.getText().length()); if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) { // optimize the case of the same line end = info.getOffset() + info.getLength(); } else end = endOfLineOf(end); end = Math.min(partition.getOffset() + partition.getLength(), end); return new Region(start, end - start); } catch (BadLocationException x) { } } return partition; } /** * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion) */ public void createPresentation(TextPresentation presentation, ITypedRegion region) { addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute); } /** * Adds style information to the given text presentation. * * @param presentation * the text presentation to be extended * @param offset * the offset of the range to be styled * @param length * the length of the range to be styled * @param attr * the attribute describing the style of the range to be styled */ protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) { if (attr != null) presentation.addStyleRange(new StyleRange(offset, length, attr.getForeground(), attr .getBackground(), attr.getStyle())); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDocumentProvider.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDocum0000644000175000017500000000323311665471212033352 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.rules.DefaultPartitioner; import org.eclipse.ui.editors.text.FileDocumentProvider; public class XMLDocumentProvider extends FileDocumentProvider { protected IDocument createDocument(Object element) throws CoreException { IDocument document = super.createDocument(element); if (document != null) { IDocumentPartitioner partitioner = new DefaultPartitioner(new XMLPartitionScanner(), new String[] { XMLPartitionScanner.XML_TAG, XMLPartitionScanner.XML_COMMENT }); partitioner.connect(document); document.setDocumentPartitioner(partitioner); } return document; } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/ColorManager.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/ColorMan0000644000175000017500000000301511665471212033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; public class ColorManager { protected Map fColorTable = new HashMap(10); public void dispose() { Iterator e = fColorTable.values().iterator(); while (e.hasNext()) ((Color) e.next()).dispose(); } public Color getColor(RGB rgb) { Color color = (Color) fColorTable.get(rgb); if (color == null) { color = new Color(Display.getCurrent(), rgb); fColorTable.put(rgb, color); } return color; } } ././@LongLink0000000000000000000000000000015400000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLScanner.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLScann0000644000175000017500000000263711665471212033354 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.rules.*; import org.eclipse.jface.text.*; public class XMLScanner extends RuleBasedScanner { public XMLScanner(ColorManager manager) { IToken procInstr = new Token(new TextAttribute(manager.getColor(IXMLColorConstants.PROC_INSTR))); IRule[] rules = new IRule[2]; // Add rule for processing instructions rules[0] = new SingleLineRule("", procInstr); // Add generic whitespace rule. rules[1] = new WhitespaceRule(new XMLWhitespaceDetector()); setRules(rules); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLPartitionScanner.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLParti0000644000175000017500000000273011665471212033363 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.rules.*; public class XMLPartitionScanner extends RuleBasedPartitionScanner { public final static String XML_DEFAULT = "__xml_default"; public final static String XML_COMMENT = "__xml_comment"; public final static String XML_TAG = "__xml_tag"; public XMLPartitionScanner() { IToken xmlComment = new Token(XML_COMMENT); IToken tag = new Token(XML_TAG); IPredicateRule[] rules = new IPredicateRule[2]; rules[0] = new MultiLineRule("", xmlComment); rules[1] = new TagRule(tag); setPredicateRules(rules); } } ././@LongLink0000000000000000000000000000015100000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/TagRule.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/TagRule.0000644000175000017500000000306611665471212033347 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.rules.*; public class TagRule extends MultiLineRule { public TagRule(IToken token) { super("<", ">", token); } protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) { int c = scanner.read(); if (sequence[0] == '<') { if (c == '?') { // processing instruction - abort scanner.unread(); return false; } if (c == '!') { scanner.unread(); // comment - abort return false; } } else if (sequence[0] == '>') { scanner.unread(); } return super.sequenceDetected(scanner, sequence, eofAllowed); } } ././@LongLink0000000000000000000000000000016400000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/IXMLColorConstants.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/IXMLColo0000644000175000017500000000221511665471212033307 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.swt.graphics.RGB; public interface IXMLColorConstants { RGB XML_COMMENT = new RGB(128, 0, 0); RGB PROC_INSTR = new RGB(128, 128, 128); RGB STRING = new RGB(0, 128, 0); RGB DEFAULT = new RGB(0, 0, 0); RGB TAG = new RGB(0, 0, 128); } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDoubleClickStrategy.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDoubl0000644000175000017500000000611011665471212033345 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.*; public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy { protected ITextViewer fText; public void doubleClicked(ITextViewer part) { int pos = part.getSelectedRange().x; if (pos < 0) return; fText = part; if (!selectComment(pos)) { selectWord(pos); } } protected boolean selectComment(int caretPos) { IDocument doc = fText.getDocument(); int startPos, endPos; try { int pos = caretPos; char c = ' '; while (pos >= 0) { c = doc.getChar(pos); if (c == '\\') { pos -= 2; continue; } if (c == '\n' || c == '\"') break; --pos; } if (c != '\"') return false; startPos = pos; pos = caretPos; int length = doc.getLength(); c = ' '; while (pos < length) { c = doc.getChar(pos); if (c == Character.LINE_SEPARATOR || c == '\"') break; ++pos; } if (c != '\"') return false; endPos = pos; int offset = startPos + 1; int len = endPos - offset; fText.setSelectedRange(offset, len); return true; } catch (BadLocationException x) { } return false; } protected boolean selectWord(int caretPos) { IDocument doc = fText.getDocument(); int startPos, endPos; try { int pos = caretPos; char c; while (pos >= 0) { c = doc.getChar(pos); if (!Character.isJavaIdentifierPart(c)) break; --pos; } startPos = pos; pos = caretPos; int length = doc.getLength(); while (pos < length) { c = doc.getChar(pos); if (!Character.isJavaIdentifierPart(c)) break; ++pos; } endPos = pos; selectRange(startPos, endPos); return true; } catch (BadLocationException x) { } return false; } private void selectRange(int startPos, int stopPos) { int offset = startPos + 1; int length = stopPos - offset; fText.setSelectedRange(offset, length); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLWhitespaceDetector.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLWhite0000644000175000017500000000215111665471212033361 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.rules.IWhitespaceDetector; public class XMLWhitespaceDetector implements IWhitespaceDetector { public boolean isWhitespace(char c) { return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLConfiguration.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLConfi0000644000175000017500000001024611665471212033343 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.ITextDoubleClickStrategy; import org.eclipse.jface.text.TextAttribute; import org.eclipse.jface.text.presentation.IPresentationReconciler; import org.eclipse.jface.text.presentation.PresentationReconciler; import org.eclipse.jface.text.rules.DefaultDamagerRepairer; import org.eclipse.jface.text.rules.Token; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewerConfiguration; import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor; public class XMLConfiguration extends SourceViewerConfiguration { private XMLDoubleClickStrategy doubleClickStrategy; private XMLTagScanner tagScanner; private XMLScanner scanner; private ColorManager colorManager; public XMLConfiguration(ColorManager colorManager) { this.colorManager = colorManager; } public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) { return new String[] { IDocument.DEFAULT_CONTENT_TYPE, XMLPartitionScanner.XML_COMMENT, XMLPartitionScanner.XML_TAG }; } public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) { if (doubleClickStrategy == null) doubleClickStrategy = new XMLDoubleClickStrategy(); return doubleClickStrategy; } protected XMLScanner getXMLScanner() { if (scanner == null) { scanner = new XMLScanner(colorManager); scanner.setDefaultReturnToken(new Token(new TextAttribute(colorManager .getColor(IXMLColorConstants.DEFAULT)))); } return scanner; } protected XMLTagScanner getXMLTagScanner() { if (tagScanner == null) { tagScanner = new XMLTagScanner(colorManager); tagScanner.setDefaultReturnToken(new Token(new TextAttribute(colorManager .getColor(IXMLColorConstants.TAG)))); } return tagScanner; } public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) { PresentationReconciler reconciler = new PresentationReconciler(); DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getXMLTagScanner()); reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG); reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG); dr = new DefaultDamagerRepairer(getXMLScanner()); reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE); reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE); NonRuleBasedDamagerRepairer ndr = new NonRuleBasedDamagerRepairer(new TextAttribute( colorManager.getColor(IXMLColorConstants.XML_COMMENT))); reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT); reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT); return reconciler; } // these 2 functions don't seem to control indent public int getTabWidth(ISourceViewer sourceViewer) { return MultiPageEditorContributor.getXMLindent(); } public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) { StringBuffer spaces = new StringBuffer(4); int indent = getTabWidth(null); for (int i = 0; i < indent; i++) spaces.append(' '); return new String[] { "\t", spaces.toString() /* , "" */}; //$NON-NLS-1$ //$NON-NLS-2$ } } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLEditor.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLEdito0000644000175000017500000001547411665471212033361 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.text.ITextListener; import org.eclipse.jface.text.TextEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.SaveAsDialog; import org.eclipse.ui.editors.text.TextEditor; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.ui.texteditor.IDocumentProvider; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; public class XMLEditor extends TextEditor { MultiPageEditor editor; private ColorManager colorManager; private EditorsTextListener m_textListener = new EditorsTextListener(); // next set to true when we are setting the text of the // editor so that just switching to source page doesn't // cause editor to think source file is dirty boolean m_bIgnoreTextEvent = false; public class EditorsTextListener implements ITextListener { /* * (non-Javadoc) * * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent) */ public void textChanged(TextEvent event) { if (!m_bIgnoreTextEvent) { editor.sourceChanged = true; editor.setFileDirty(); } } } public XMLEditor(MultiPageEditor editor) { super(); colorManager = new ColorManager(); setSourceViewerConfiguration(new XMLConfiguration(colorManager)); setDocumentProvider(new XMLDocumentProvider()); this.editor = editor; } public void createPartControl(Composite parent) { super.createPartControl(parent); getSourceViewer().addTextListener(m_textListener); } public void dispose() { colorManager.dispose(); super.dispose(); } public void doSaveAs() { IProgressMonitor progressMonitor = getProgressMonitor(); Shell shell = getSite().getShell(); IEditorInput input = getEditorInput(); SaveAsDialog dialog = new SaveAsDialog(shell); IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile() : null; if (original != null) dialog.setOriginalFile(original); dialog.create(); IDocumentProvider provider = getDocumentProvider(); if (provider == null) { // editor has programatically been closed while the dialog was open return; } if (provider.isDeleted(input) && original != null) { String message = "The original file, '" + original.getName() + "' has been deleted"; dialog.setErrorMessage(null); dialog.setMessage(message, IMessageProvider.WARNING); } if (dialog.open() == Dialog.CANCEL) { if (progressMonitor != null) progressMonitor.setCanceled(true); editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED); return; } IPath filePath = dialog.getResult(); if (filePath == null) { if (progressMonitor != null) progressMonitor.setCanceled(true); editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED); return; } IWorkspace workspace = ResourcesPlugin.getWorkspace(); IFile file = workspace.getRoot().getFile(filePath); final IEditorInput newInput = new FileEditorInput(file); WorkspaceModifyOperation op = new WorkspaceModifyOperation() { public void execute(final IProgressMonitor monitor) throws CoreException { getDocumentProvider().saveDocument(monitor, newInput, getDocumentProvider().getDocument(getEditorInput()), true); } }; boolean success = false; try { provider.aboutToChange(newInput); new ProgressMonitorDialog(shell).run(false, true, op); success = true; } catch (InterruptedException x) { } catch (InvocationTargetException x) { Throwable targetException = x.getTargetException(); String title = "Error saving"; // TextEditorMessages.getString("Editor.error.save.title"); // //$NON-NLS-1$ String msg = "Error occurred during save operation"; // MessageFormat.format(TextEditorMessages.getString("Editor.error.save.message"), // new Object[] { // targetException.getMessage()}); // //$NON-NLS-1$ if (targetException instanceof CoreException) { CoreException coreException = (CoreException) targetException; IStatus status = coreException.getStatus(); if (status != null) { switch (status.getSeverity()) { case IStatus.INFO: MessageDialog.openInformation(shell, title, msg); break; case IStatus.WARNING: MessageDialog.openWarning(shell, title, msg); break; default: MessageDialog.openError(shell, title, msg); } } else { MessageDialog.openError(shell, title, msg); } } } finally { provider.changed(newInput); if (success) { setInput(newInput); editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CONFIRMED); } else { editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED); } } if (progressMonitor != null) progressMonitor.setCanceled(!success); } public void setIgnoreTextEvent(boolean bIgnoreTextEvent) { m_bIgnoreTextEvent = bIgnoreTextEvent; } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLTagScanner.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLTagSc0000644000175000017500000000277211665471212033313 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.editors.xml; import org.eclipse.jface.text.*; import org.eclipse.jface.text.rules.*; public class XMLTagScanner extends RuleBasedScanner { public XMLTagScanner(ColorManager manager) { IToken string = new Token(new TextAttribute(manager.getColor(IXMLColorConstants.STRING))); IRule[] rules = new IRule[3]; // Add rule for double quotes rules[0] = new SingleLineRule("\"", "\"", string, '\\'); // Add a rule for single quotes rules[1] = new SingleLineRule("'", "'", string, '\\'); // Add generic whitespace rule. rules[2] = new WhitespaceRule(new XMLWhitespaceDetector()); setRules(rules); } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/StandardStrings.java0000644000175000017500000000356011665471220033505 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; /** */ public interface StandardStrings { public static final String S_ADD = "Add..."; public static final String S_EDIT = "Edit..."; public static final String S_EDIT_TIP = "Click here to edit the selected item. You can also double-click the item to edit it."; public static final String S_REMOVE = "Remove"; public static final String S_REMOVE_TIP = "Click here to remove the selected item. You can also use the delete key."; public static final String S_UP = "Up"; public static final String S_UP_TIP = "Click here to move the selected item up by one."; public static final String S_DOWN = "Down"; public static final String S_DOWN_TIP = "Click here to move the selected item down by one."; public static final String S_DESCRIPTION = "Description:"; public static final String S_ = ""; public static final String S_EXPORT = "Export..."; public static final String S_EXPORT_TIP = "Export to an importable part, and substitute an Import for that part here"; } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/CDEpropertyPage.java0000644000175000017500000001336611665471220033375 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.PropertyPage; public class CDEpropertyPage extends PropertyPage { private static final String DATAPATH_LABEL = "&Data Path:"; private static final String DATAPATH_PROPERTY_KEY = "CDEdataPath"; private static final String DEFAULT_DATAPATH = ""; private static final String BY_DEFAULT_PROPERTY_KEY = "CDEByDefault"; private static final String ADD_TO_FLOW_PROPERTY_KEY = "CDEAddToFlow"; // private static final int TEXT_FIELD_WIDTH = 50; private Text dataPathUI; public CDEpropertyPage() { super(); } /** * @see PreferencePage#createContents(Composite) */ protected Control createContents(Composite parent) { Composite composite = create2ColComposite(parent); Label instructions = new Label(composite, SWT.WRAP); instructions .setText("Enter the data path to use for finding resources by name;\n" + "This is a series of absolute paths, separated by\n" + "whatever character this platform uses for path separation (similar to class paths).\n\n"); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.horizontalSpan = 2; gd.grabExcessHorizontalSpace = true; instructions.setLayoutData(gd); new Label(composite, SWT.NONE).setText(DATAPATH_LABEL); dataPathUI = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL); gd = new GridData(GridData.FILL_BOTH); dataPathUI.setLayoutData(gd); try { String dataPath = ((IResource) getElement()).getPersistentProperty(new QualifiedName("", DATAPATH_PROPERTY_KEY)); dataPathUI.setText((dataPath != null) ? dataPath : DEFAULT_DATAPATH); } catch (CoreException e) { dataPathUI.setText(DEFAULT_DATAPATH); } return composite; } private Composite create2ColComposite(Composite parent) { Composite composite = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); layout.numColumns = 2; composite.setLayout(layout); GridData data = new GridData(); data.verticalAlignment = GridData.FILL; data.horizontalAlignment = GridData.FILL; composite.setLayoutData(data); return composite; } protected void performDefaults() { dataPathUI.setText(DEFAULT_DATAPATH); } public boolean performOk() { // store the value in the owner text field try { ((IResource) getElement()).setPersistentProperty( new QualifiedName("", DATAPATH_PROPERTY_KEY), dataPathUI.getText()); } catch (CoreException e) { return false; } return true; } public static String getDataPath(IProject project) { String dataPath; try { dataPath = project.getPersistentProperty(new QualifiedName("", DATAPATH_PROPERTY_KEY)); } catch (CoreException e) { dataPath = ""; } if (null == dataPath) dataPath = ""; return dataPath; } public static void setDataPath(IProject project, String dataPath) { try { project.setPersistentProperty(new QualifiedName("", DATAPATH_PROPERTY_KEY), dataPath); } catch (CoreException e) { throw new InternalErrorCDE("unhandled exception", e); } } public static String getImportByDefault(IProject project) { String byDefault; try { byDefault = project.getPersistentProperty(new QualifiedName("", BY_DEFAULT_PROPERTY_KEY)); } catch (CoreException e) { byDefault = ""; } if (null == byDefault) byDefault = ""; return byDefault; } public static void setImportByDefault(IProject project, String byDefault) { try { project.setPersistentProperty(new QualifiedName("", BY_DEFAULT_PROPERTY_KEY), byDefault); } catch (CoreException e) { throw new InternalErrorCDE("unhandled exception", e); } } public static String getAddToFlow(IProject project) { String byDefault; try { byDefault = project.getPersistentProperty(new QualifiedName("", ADD_TO_FLOW_PROPERTY_KEY)); } catch (CoreException e) { byDefault = ""; } if (null == byDefault) byDefault = ""; return byDefault; } public static void setAddToFlow(IProject project, String byDefault) { try { project.setPersistentProperty(new QualifiedName("", ADD_TO_FLOW_PROPERTY_KEY), byDefault); } catch (CoreException e) { throw new InternalErrorCDE("unhandled exception", e); } } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/0000755000175000017500000000000011665471210030625 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceS0000644000175000017500000003411411665471210033500 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.files; import java.io.BufferedInputStream; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.dialogs.ResourcePickerDialog; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.forms.widgets.FormToolkit; public class MultiResourceSelectionDialog extends ResourcePickerDialog { private final static String PATH_SEPARATOR = System.getProperty("path.separator"); private static class CandidateAndSource implements Comparable { String candidate; String source; CandidateAndSource(String aCandidate, String aSource) { candidate = aCandidate; source = aSource; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((candidate == null) ? 0 : candidate.hashCode()); result = prime * result + ((source == null) ? 0 : source.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; final CandidateAndSource other = (CandidateAndSource) obj; if (candidate == null) { if (other.candidate != null) return false; } else if (!candidate.equals(other.candidate)) return false; if (source == null) { if (other.source != null) return false; } else if (!source.equals(other.source)) return false; return true; } public int compareTo(CandidateAndSource o) { int r = o.candidate.compareTo(this.candidate); if (r == 0) { return o.source.compareTo(this.source); } return r; } } private Button browseButton; // for browsing the file system private Button importByNameUI; private Button importByLocationUI; public boolean isImportByName; protected MultiPageEditor editor; public MultiResourceSelectionDialog(Shell parentShell, IAdaptable rootElement, String message, IPath aExcludeDescriptor, MultiPageEditor aEditor) { super(parentShell); editor = aEditor; String importByStickySetting = CDEpropertyPage.getImportByDefault(editor.getProject()); isImportByName = (importByStickySetting.equals("name")) ? true : false; /* super(parentShell, rootElement, message); editor = aEditor; setTitle(Messages.getString("ResourceSelectionDialog.title")); //$NON-NLS-1$ if (message != null) setMessage(message); else setMessage(Messages.getString("ResourceSelectionDialog.message")); //$NON-NLS-1$ setShellStyle(getShellStyle() | SWT.RESIZE); */ } protected Control createDialogArea(Composite parent) { // page group Composite composite = (Composite) super.createDialogArea(parent); FormToolkit factory = new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors( parent.getDisplay())); Label label = new Label(composite, SWT.WRAP /* SWT.CENTER */); label.setText(Messages.getString("MultiResourceSelectionDialog.Or")); //$NON-NLS-1$ browseButton = factory.createButton(composite, Messages .getString("MultiResourceSelectionDialog.BrowseFileSys"), //$NON-NLS-1$ SWT.PUSH); browseButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING)); browseButton.pack(false); browseButton.addListener(SWT.MouseUp, new Listener() { public void handleEvent(Event event) { FileDialog dialog = new FileDialog(getShell(), /* SWT.OPEN | */ SWT.MULTI); String[] extensions = { Messages.getString("MultiResourceSelectionDialog.starDotXml") }; //$NON-NLS-1$ dialog.setFilterExtensions(extensions); String sStartDir = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation() .toOSString(); dialog.setFilterPath(sStartDir); String file = dialog.open(); if (file != null && !file.equals("")) { //$NON-NLS-1$ // close(); okPressed(); ArrayList list = new ArrayList(); IPath iPath = new Path(file); list.add(iPath); localSetResult(list); } } }); new Label(composite, SWT.NONE).setText(""); importByNameUI = new Button(composite, SWT.RADIO); importByNameUI.setText("Import by Name"); importByNameUI .setToolTipText("Importing by name looks up the name on the datapath, and if not found there, on the classpath."); importByLocationUI = new Button(composite, SWT.RADIO); importByLocationUI.setText("Import By Location"); importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL"); String importByStickySetting = CDEpropertyPage.getImportByDefault(editor.getProject()); if (importByStickySetting.equals("location")) { importByNameUI.setSelection(false); importByLocationUI.setSelection(true); isImportByName = false; } else { importByNameUI.setSelection(true); importByLocationUI.setSelection(false); isImportByName = true; } if (importByNameUI.getSelection()) { setupResourcesByName(); } importByLocationUI.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (importByLocationUI.getSelection()) { isImportByName = false; CDEpropertyPage.setImportByDefault(editor.getProject(), "location"); MultiResourceSelectionDialog.this.setupResourcesByLocation(); browseButton.setEnabled(true); } } }); importByNameUI.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { if (importByNameUI.getSelection()) { isImportByName = true; CDEpropertyPage.setImportByDefault(editor.getProject(), "name"); MultiResourceSelectionDialog.this.setupResourcesByName(); } } }); return composite; } @Override protected void setupResourcesByLocation() { if (! isImportByName) { super.setupResourcesByLocation(); } } private void setupResourcesByName() { resourcesUI.removeAll(); resourcesUI.removeListener(SWT.Expand, this); // remove to prevent // triggering while setting up resourcesUI.removeListener(SWT.Selection, this); // remove to prevent // triggering while // setting up resourcesUI.setHeaderVisible(true); resourcesUIc1.setWidth(400); resourcesUIc1.setText("by-name xml resource"); resourcesUIc2.setWidth(400); resourcesUIc2.setText("source of by-name resource"); CandidateAndSource [] candidates = computeByNameCandidates(); for (CandidateAndSource c : candidates) { TreeItem item = new TreeItem(resourcesUI, SWT.NULL, 0); item.setText(new String [] {c.candidate, c.source}); item.setData(c.candidate); } resourcesUI.addListener(SWT.Selection, this); browseButton.setEnabled(false); } public void copyValuesFromGUI() { if (resourcesUI.getSelectionCount() > 0) { if (importByLocationUI.getSelection()) { super.copyValuesFromGUI(); return; } result = new Object[] {resourcesUI.getSelection()[0].getData()}; } } // some caching - for jars with timestamps private CandidateAndSource [] computeByNameCandidates() { String cp; try { cp = editor.getFilteredProjectClassPath(false); } catch (CoreException e) { throw new InternalErrorCDE("unhandled CoreException while getting classpaths to populate by-location list", e); } String [] cps = cp.split(PATH_SEPARATOR); List candidates = new ArrayList(100); for (String jarOrDir : cps) { if (jarOrDir.toLowerCase().endsWith(".jar")) { addJarCandidates(jarOrDir, candidates, jarOrDir); } else { addClassCandidates(new File(jarOrDir), candidates, "", jarOrDir); } } CandidateAndSource [] result = candidates.toArray(new CandidateAndSource[candidates.size()]); Arrays.sort(result); /* test - verify all resources can be loaded ResourceManager rm = editor.createResourceManager(); for (String r : result) { try { Object resource = rm.getResource(r); assert resource != null; } catch (ResourceAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } */ return result; } private FilenameFilter onlyXml = new FilenameFilter() { public boolean accept(File dir, String name) { return name.endsWith(".xml"); } }; private FileFilter onlyDir = new FileFilter() { public boolean accept(File pathname) { return pathname.isDirectory(); } }; private void addClassCandidates(File dir, List candidates, String prefix, String source) { if (null == dir) { return; } String[] xmlFileNames = dir.list(onlyXml); if (null == xmlFileNames) { return; } for (String xmlFileName : xmlFileNames) { candidates.add(new CandidateAndSource(prefix + xmlFileName, source)); } File[] subdirs = dir.listFiles(onlyDir); if (null == subdirs) { return; } for (File subdir : subdirs) { String nextPrefix = prefix + subdir.getName() + "/"; addClassCandidates(subdir, candidates, nextPrefix, source); } } private static Map sawJar = new TreeMap(); private static Map> cachedCs = new TreeMap>(); private void addJarCandidates(String jarPath, List candidates, String source) { Long fileLastModified = (new File(jarPath)).lastModified(); Long lastModified = sawJar.get(jarPath); List css = cachedCs.get(jarPath); if (fileLastModified <= 0 || lastModified == null || lastModified.longValue() != fileLastModified || null == css) { JarInputStream jarIn; css = new ArrayList(); try { jarIn = new JarInputStream(new BufferedInputStream(new FileInputStream(jarPath))); } catch (FileNotFoundException e) { return; } catch (IOException e) { throw new InternalErrorCDE( "unhandled IOException while reading Jar in classpath to populate by-location list", e); } ZipEntry entry; try { while (null != (entry = jarIn.getNextEntry())) { String name = entry.getName(); if (name.startsWith("META-INF")) { continue; } if (name.endsWith(".xml")) { css.add(new CandidateAndSource(name, source)); } } } catch (IOException e) { throw new InternalErrorCDE( "unhandled IOException while getting next Jar Entry to populate by-location list", e); } sawJar.put(jarPath, fileLastModified); cachedCs.put(jarPath, css); } candidates.addAll(css); } // This is to avoid synthetic access method warning protected void localSetResult(ArrayList list) { setResult(list); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { okButton.setEnabled(false); // preset if (0 < resourcesUI.getSelectionCount()) { if (importByLocationUI.getSelection()) { if (resourcesUI.getSelection()[0].getData() instanceof IFile) { okButton.setEnabled(true); } } else { // import by name okButton.setEnabled(true); } } } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/PickOverrideKeysAndParmName.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/PickOverrideKe0000644000175000017500000003166411665471210033430 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.files; import java.util.Iterator; import java.util.Map; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.collection.CasConsumerDescription; import org.apache.uima.flow.FlowControllerDescription; import org.apache.uima.resource.ResourceCreationSpecifier; import org.apache.uima.resource.ResourceSpecifier; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.ParameterDelegatesSection; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog; import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddParameterDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; public class PickOverrideKeysAndParmName extends AbstractDialog { private AddParameterDialog parameterDialog = null; // not currently used private ConfigurationParameter cp; private ConfigurationParameterDeclarations cpd; private boolean adding; private Table paramsUI; private Table keysUI; private Map delegates; //returned values public String delegateKeyName; public String delegateParameterName; /* * Shows 2 side-by-side windows. * * Left one is a list of keys of next-level-delegates * Right one is a list of parms of those delegates that * match sufficiently to be overridden by this overriding parm * If adding to existing override - current overrides are not shown as * candidates. * If editing - all are shown (you can delete) * */ public PickOverrideKeysAndParmName(AbstractSection aSection, Map delegateMap, String message, ConfigurationParameter aCp, ConfigurationParameterDeclarations aCpd, boolean aAdding) { super(aSection, "Delegate Keys and Parameter Name Selection", message); delegates = delegateMap; cp = aCp; cpd = aCpd; adding = aAdding; // true if we're adding, not editing } protected Control createDialogArea(Composite parent) { Composite mainArea = (Composite)super.createDialogArea(parent); Composite twoCol = new2ColumnComposite(mainArea); keysUI = newTable(twoCol, SWT.SINGLE); paramsUI = newTable(twoCol, SWT.SINGLE); for (Iterator it = delegates.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); TableItem item = new TableItem(keysUI, SWT.NULL); item.setText((String)entry.getKey()); item.setData(entry); } keysUI.addListener(SWT.Selection, this); if (0 < keysUI.getItemCount()) { keysUI.setSelection(0); } return mainArea; } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { if (event.widget == keysUI && event.type == SWT.Selection) { fillParameterCandidates(); super.handleEvent(event); } else if (event.widget == paramsUI && event.type == SWT.Selection) { copyValuesFromGUI(); super.handleEvent(event); } } private void fillParameterCandidates() { paramsUI.setRedraw(false); paramsUI.removeAll(); TableItem selectedItem = keysUI.getSelection()[0]; Map.Entry entry = (Map.Entry) selectedItem.getData(); String keyName = (String) entry.getKey(); // support CasConsumers also // support Flow Controllers too // and skip remote service descriptors ResourceSpecifier rs = (ResourceSpecifier) entry.getValue(); if (rs instanceof AnalysisEngineDescription || rs instanceof CasConsumerDescription || rs instanceof FlowControllerDescription) { ConfigurationParameterDeclarations delegateCpd = ((ResourceCreationSpecifier) rs) .getMetaData().getConfigurationParameterDeclarations(); addSelectedParms(delegateCpd.getCommonParameters(), keyName); ConfigurationGroup[] groups = delegateCpd.getConfigurationGroups(); if (null != groups) { for (int i = 0; i < groups.length; i++) { addSelectedParms(groups[i].getConfigurationParameters(), keyName); } } addSelectedParms(delegateCpd.getConfigurationParameters(), keyName); } if (0 < paramsUI.getItemCount()) { paramsUI.setSelection(0); } paramsUI.setRedraw(true); } /* * Filter overridable parameters to exclude: - already overridden (can't override same parameter * twice) - those with different type or multi-valued-ness (Group match not required) */ private void addSelectedParms(ConfigurationParameter[] parms, String keyName) { boolean isMultiValued = (null != parameterDialog) ? parameterDialog.multiValueUI .getSelection() : cp.isMultiValued(); String type = (null != parameterDialog) ? parameterDialog.parmTypeUI.getText() : cp.getType(); if (null != parms) { for (int i = 0; i < parms.length; i++) { // multi-valued-ness must match if ((isMultiValued != parms[i].isMultiValued())) continue; // types must match, but we also allow if no type is spec'd - not sure if this is useful if ((null != type && !"".equals(type) && //$NON-NLS-1$ !type.equals(parms[i].getType()))) continue; // parameter must not be already overridden, unless we're editing an existing one String override = keyName + '/' + parms[i].getName(); if (adding && null != ParameterDelegatesSection.getOverridingParmName(override, cpd)) continue; TableItem tableItem = new TableItem(paramsUI, SWT.NULL); tableItem.setText(parms[i].getName()); tableItem.setData(parms[i]); } } } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI() */ public void copyValuesFromGUI() { delegateKeyName = keysUI.getSelection()[0].getText(); delegateParameterName = paramsUI.getSelection()[0].getText(); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { okButton.setEnabled( (0 < keysUI.getSelectionCount()) && (0 < paramsUI.getSelectionCount())); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid() */ public boolean isValid() { return true; } /* protected TreeGroup createTreeGroup(Composite composite, Object rootObject) { return new TreeGroup(composite, rootObject, (keyTreeProvider = new KeyTreeProvider()), new KeyTreeLabelProvider(), new ParmNameProvider(), new ParmNameLabelProvider(), SWT.NONE, -1, -1, true); // set single selection // mode } protected void okPressed() { Iterator resultEnum = selectionGroup.getAllCheckedTreeItems().iterator(); ArrayList list = new ArrayList(); while (resultEnum.hasNext()) { Map.Entry entry = (Map.Entry) resultEnum.next(); list.add(entry); while (null != (entry = (Map.Entry) keyTreeProvider.getParent(entry))) list.add(entry); } super.okPressed(); List result = new ArrayList(2); result.add(list.toArray(new Map.Entry[list.size()])); result.add(getResult()); setResult(result); } Map keyTreeParent = new HashMap(); class KeyTreeProvider implements ITreeContentProvider { */ /** * for a given map of delegates, return an array of maps representing the those delegates having * children. Not called for the top element, but called for subsequent layers */ /* public Object[] getChildren(Object parentElement) { return objectArray0; } public Object getParent(Object element) { return keyTreeParent.get(element); } public boolean hasChildren(Object element) { return false; } */ /** * returns an array of Map.Entry elements: Key and AE or flow ctlr Description. Called only for * the top element */ /* public Object[] getElements(Object inputElement) { AbstractList items = new ArrayList(); if (inputElement instanceof ArrayList) inputElement = ((ArrayList) inputElement).get(0); Map delegatesMap = (Map) inputElement; for (Iterator it = delegatesMap.entrySet().iterator(); it.hasNext();) { items.add(it.next()); } return items.toArray(); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { keyTreeParent.clear(); } */ /** * elements are Map.Entry */ /* static class KeyTreeLabelProvider implements ILabelProvider { public Image getImage(Object element) { return null; } public String getText(Object element) { return ((String) ((Map.Entry) element).getKey()); } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } */ /** * Element is: Map Entry Set ConfigurationParameterDeclarations */ /* class ParmNameProvider implements ITreeContentProvider { public Object[] getChildren(Object parentElement) { return null; } public Object getParent(Object element) { // TODO Auto-generated method stub return null; } public boolean hasChildren(Object element) { // TODO Auto-generated method stub return false; } */ /* * Get elements (which are overridable parameters) for one delegate * * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) */ /* public Object[] getElements(Object inputElement) { AbstractList items = new ArrayList(); Map.Entry entry = (Map.Entry) inputElement; String keyName = (String) entry.getKey(); // support CasConsumers also // support Flow Controllers too // and skip remote service descriptors ResourceSpecifier rs = (ResourceSpecifier) entry.getValue(); if (rs instanceof AnalysisEngineDescription || rs instanceof CasConsumerDescription || rs instanceof FlowControllerDescription) { ConfigurationParameterDeclarations delegateCpd = ((ResourceCreationSpecifier) rs) .getMetaData().getConfigurationParameterDeclarations(); addSelectedParms(delegateCpd.getCommonParameters(), items, keyName); ConfigurationGroup[] groups = delegateCpd.getConfigurationGroups(); if (null != groups) { for (int i = 0; i < groups.length; i++) { addSelectedParms(groups[i].getConfigurationParameters(), items, keyName); } } addSelectedParms(delegateCpd.getConfigurationParameters(), items, keyName); } return items.toArray(); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } static class ParmNameLabelProvider implements ILabelProvider { public Image getImage(Object element) { return null; } public String getText(Object element) { return (String) element; } public void addListener(ILabelProviderListener listener) { } public void dispose() { } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { } } */ } ././@LongLink0000000000000000000000000000020600000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialogWithFlowOption.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceS0000644000175000017500000000611011665471210033473 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.files; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.forms.widgets.FormToolkit; import org.apache.uima.taeconfigurator.CDEpropertyPage; import org.apache.uima.taeconfigurator.Messages; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; public class MultiResourceSelectionDialogWithFlowOption extends MultiResourceSelectionDialog { private Button autoAddToFlowButton; private boolean m_bAutoAddToFlow = true; /** * @param parentShell * @param rootElement * @param message * @param excludeDescriptor */ public MultiResourceSelectionDialogWithFlowOption(Shell parentShell, IAdaptable rootElement, String message, IPath excludeDescriptor, MultiPageEditor editor) { super(parentShell, rootElement, message, excludeDescriptor, editor); } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); new Label(composite, SWT.WRAP).setText(""); //$NON-NLS-1$ String sAddToFlowPrompt = Messages .getString("MultiResourceSelectionDialogWithFlowOption.addSelectedAEsToEndOfFlow"); //$NON-NLS-1$ FormToolkit factory = new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors( parent.getDisplay())); autoAddToFlowButton = factory.createButton(composite, sAddToFlowPrompt, SWT.CHECK); m_bAutoAddToFlow = "false".equals(CDEpropertyPage.getAddToFlow(editor.getProject())) ? false : true; autoAddToFlowButton.setSelection(m_bAutoAddToFlow); autoAddToFlowButton.setBackground(null); return composite; } protected void okPressed() { m_bAutoAddToFlow = autoAddToFlowButton.getSelection(); CDEpropertyPage.setAddToFlow(editor.getProject(), m_bAutoAddToFlow ? "true" : "false"); super.okPressed(); } public boolean getAutoAddToFlow() { return m_bAutoAddToFlow; } } ././@LongLink0000000000000000000000000000016000000000000011562 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/ContextForPartDialog.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/ContextForPart0000644000175000017500000001664311665471210033504 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.files; import java.text.MessageFormat; import org.apache.uima.resource.metadata.FsIndexCollection; import org.apache.uima.resource.metadata.ResourceManagerConfiguration; import org.apache.uima.resource.metadata.TypePriorities; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.dialogs.ResourcePickerDialog; import org.apache.uima.util.XMLizable; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IPath; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class ContextForPartDialog extends /*LimitedResourceSelectionDialog*/ ResourcePickerDialog /*implements ICheckStateListener*/ { // private MultiPageEditor editor; private Text contextPathGUI; public String contextPath; private String initialPath; private XMLizable tbe; public ContextForPartDialog(Shell parentShell, IAdaptable rootElement, XMLizable thingBeingEdited, IPath aExcludeDescriptor, MultiPageEditor aEditor, String aInitialPath) { super(parentShell); initialPath = aInitialPath; setTitle("Context for importable part"); tbe = thingBeingEdited; /* super(parentShell, rootElement, "Context for importable part"); // editor = aEditor; initialPath = aInitialPath; setTitle("Context for importable part"); tbe = thingBeingEdited; setShellStyle(getShellStyle() | SWT.RESIZE); */ } protected Control createDialogArea(Composite parent) { parent = new Composite(parent, SWT.NONE); parent.setLayout(new GridLayout(1, true)); parent.setLayoutData(new GridData(SWT.LEAD, SWT.BEGINNING, true, false)); ((GridLayout) parent.getLayout()).marginWidth = 15; // Show a text field with the path, allow editing // anything picked overrides the text field AbstractSection.spacer(parent); Label instructions = new Label(parent, SWT.WRAP); instructions .setText(MessageFormat .format( "You are about to edit a UIMA {0} descriptor. \n" + "In order to do this, you need to specify another UIMA descriptor, which will supply " + "the needed context for this file.\n" + "It can be any of the following kinds of descriptors:\n\n " + "{1}\n\n" + "The file below is a suggested context. \n\n" + " >>> If it is correct, just push OK. <<<\n\n" + "Otherwise you can change it by overtyping it,\n" + "or use the project explorer window below to pick the context file to use.", new Object[] { (tbe instanceof FsIndexCollection) ? "Index Definition" : (tbe instanceof TypePriorities) ? "Type Priority Definition" : (tbe instanceof ResourceManagerConfiguration) ? "Resource Manager Configuration" : "unhandled - error", (tbe instanceof FsIndexCollection) ? "A Type System or any descriptor containing or " + "importing the type system associated with this Index Definition,\n other than a Collection Processing Engine" : (tbe instanceof TypePriorities) ? "A Type System or any descriptor containing or " + "importing the type system associated with this TypePriority Definition,\n other than a Collection Processing Engine" : (tbe instanceof ResourceManagerConfiguration) ? "A descriptor (such as an Analysis Engine) containing " + "(directly or via aggregate delegates)\n " + "the External Resource Dependencies referenced by this Resource Manager Configuration" : "unhandled - error" })); AbstractSection.spacer(parent); contextPathGUI = new Text(parent, SWT.BORDER); contextPathGUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); contextPathGUI.setText(null == initialPath ? "" : initialPath); // AbstractSection.spacer(parent); Composite composite = (Composite) super.createDialogArea(parent); return composite; } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event) */ public void handleEvent(Event event) { super.handleEvent(event); if (event.widget == resourcesUI && event.type == SWT.Selection) { if (null != pickedResource) { IFile f = (IFile)getResult()[0]; contextPathGUI.setText(f.getLocation().toOSString()); } } } protected void okPressed() { contextPath = contextPathGUI.getText(); super.okPressed(); } /* (non-Javadoc) * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK() */ public void enableOK() { super.enableOK(); String path = contextPathGUI.getText(); if (null != path && !"".equals(path)) okButton.setEnabled(true); } /* public void checkStateChanged(CheckStateChangedEvent event) { // event.getChecked(); // true if checked // event.getElement(); // File with workspace-relative path if (event.getChecked() && event.getElement() instanceof IFile) { contextPathGUI.setText(((IFile) event.getElement()).getLocation().toString()); } okButton.setEnabled( selectionGroup.getCheckedElementCount() > 0 || contextPathGUI.getText().length() > 0); } protected void initializeDialog() { selectionGroup.addCheckStateListener(this); getOkButton().setEnabled(contextPathGUI.getText().length() > 0); } */ } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/PreferencePage.java0000644000175000017500000000613011665471220033242 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { public static final String P_JCAS = "org.apache.uima.cde.autojcasgen"; public static final String P_SHOW_FULLY_QUALIFIED_NAMES = "org.apache.uima.cde.qualifiedtypes"; public static final String P_XML_TAB_SPACES = "org.apache.uima.cde.xmlIndentAmount"; public static final String P_VNS_HOST = "org.apache.uima.cde.vnsHost"; public static final String P_VNS_PORT = "org.apache.uima.cde.vnsPort"; public PreferencePage() { super(GRID); setPreferenceStore(TAEConfiguratorPlugin.getDefault().getPreferenceStore()); setDescription("UIMA Component Descriptor Editor Preferences"); initializeDefaults(); } /** * Sets the default values of the preferences. */ private void initializeDefaults() { IPreferenceStore store = getPreferenceStore(); store.setDefault(P_JCAS, false); store.setDefault(P_SHOW_FULLY_QUALIFIED_NAMES, true); store.setDefault(P_XML_TAB_SPACES, 2); store.setDefault(P_VNS_HOST, "localhost"); store.setDefault(P_VNS_PORT, "9000"); // store.setDefault(P_DATA_PATH, ""); } public void createFieldEditors() { addField(new BooleanFieldEditor(P_JCAS, "&Automatically run JCasGen when Types change", getFieldEditorParent())); addField(new BooleanFieldEditor(P_SHOW_FULLY_QUALIFIED_NAMES, "&Show fully qualified names", getFieldEditorParent())); addField(new IntegerFieldEditor(P_XML_TAB_SPACES, "&XML indentation", getFieldEditorParent())); addField(new StringFieldEditor(P_VNS_HOST, "&Vinci Name Service Host IP address", getFieldEditorParent())); addField(new StringFieldEditor(P_VNS_PORT, "Vinci NameService &Port number", getFieldEditorParent())); } public void init(IWorkbench workbench) { } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/0000755000175000017500000000000011665471210031206 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializ0000644000175000017500000000267511665471210033526 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class CasInitializerNewWizardPage extends AbstractNewWizardPage { public CasInitializerNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Cas Initializer Descriptor File", "Create a new Cas Initializer Descriptor file", "casInitializerDescriptor.xml"); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControll0000644000175000017500000000603311665471210033557 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. * * Following Eclipse conventions, the new Wizard will actually create the resource in the file * system and in the Eclipse resource space, with initial contents, and then open the resource with * the CDE. */ public class FlowControllerNewWizard extends AbstractNewWizard implements INewWizard { public FlowControllerNewWizard() { super("New Flow Controller Descriptor File"); } public void addPages() { page = new FlowControllerNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return "\n" + "\n" + "org.apache.uima.java\n" + "\n" + "\n" + "" + name + "\n" + "\n" + "1.0\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + ""; } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfigura0000644000175000017500000000605711665471210033410 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. * * Following Eclipse conventions, the new Wizard will actually create the resource in the file * system and in the Eclipse resource space, with initial contents, and then open the resource with * the CDE. */ public class TAEConfiguratorNewWizard extends AbstractNewWizard implements INewWizard { public TAEConfiguratorNewWizard() { super("New Analysis Engine Descriptor File"); } public void addPages() { page = new TAEConfiguratorNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return "\n" + "org.apache.uima.java\n" + "true\n" + "\n" + "\n" + "" + name + "\n" + "\n" + "1.0\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; } } ././@LongLink0000000000000000000000000000020300000000000011560 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceMana0000644000175000017500000000444511665471210033524 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import java.text.MessageFormat; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class ResourceManagerConfigurationNewWizard extends AbstractNewWizard implements INewWizard { public static final String RESOURCEMANGERCONFIGURATION_TEMPLATE = "\n" + "{0}\n" + "\n" + "1.0\n" + "{1}" + "\n"; public ResourceManagerConfigurationNewWizard() { super("External Resource and Bindings (Resource Manager Configuration) Descriptor File"); } public void addPages() { page = new ResourceManagerConfigurationNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return MessageFormat.format(RESOURCEMANGERCONFIGURATION_TEMPLATE, new Object[] { name, "\n" + "\n" }); } } ././@LongLink0000000000000000000000000000017300000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionRe0000644000175000017500000000270711665471210033521 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class CollectionReaderNewWizardPage extends AbstractNewWizardPage { public CollectionReaderNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Collection Reader Descriptor File", "Create a new Collection Reader Descriptor file", "collectionReaderDescriptor.xml"); } } ././@LongLink0000000000000000000000000000015700000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewW0000644000175000017500000001605411665471210033503 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import java.io.ByteArrayInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. * * Following Eclipse conventions, the new Wizard will actually create the resource in the file * system and in the Eclipse resource space, with initial contents, and then open the resource with * the CDE. */ public abstract class AbstractNewWizard extends Wizard implements INewWizard { public final static String XMLNS_PART = "xmlns=\"http://uima.apache.org/resourceSpecifier\">\n"; protected AbstractNewWizardPage page; protected ISelection selection; private String windowTitle; public AbstractNewWizard(String windowTitle) { super(); setDialogSettings(TAEConfiguratorPlugin.getDefault().getDialogSettings()); setNeedsProgressMonitor(true); setForcePreviousAndNextButtons(false); this.windowTitle = windowTitle; } /* * (non-Javadoc) * * @see org.eclipse.jface.wizard.Wizard#performFinish() */ /** * Called when 'Finish' button is pressed in the wizard. Create an operation and run it using * wizard as execution context. */ public boolean performFinish() { final String containerName = page.getContainerName(); final String fileName = page.getFileName(); IRunnableWithProgress op = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException { try { doFinish(containerName, fileName, monitor); } catch (CoreException e) { throw new InvocationTargetException(e); } finally { monitor.done(); } } }; try { getContainer().run(true, false, op); } catch (InterruptedException e) { return false; } catch (InvocationTargetException e) { Throwable realException = e.getTargetException(); MessageDialog.openError(getShell(), "Error", realException.getMessage()); return false; } return true; } public abstract String getPrototypeDescriptor(String name); void doFinish(String containerName, String fileName, IProgressMonitor monitor) throws CoreException { // create a sample file monitor.beginTask("Creating " + fileName, 2); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource resource = root.findMember(new Path(containerName)); if (!resource.exists() || !(resource instanceof IContainer)) { throwCoreException("Container \"" + containerName + "\" does not exist."); } IContainer container = (IContainer) resource; final IFile file = container.getFile(new Path(fileName)); if (file.exists()) { throwCoreException("New Wizard creating file '" + fileName + "', but it already exists."); } else { int indexOfXml = file.getName().toLowerCase().indexOf(".xml"); String name = (indexOfXml > 0) ? file.getName().substring(0, indexOfXml) : file.getName(); String descriptor = getPrototypeDescriptor(name); PrintWriter printWriter = null; FileOutputStream fileOutputStream = null; InputStream stream = null; try { try { fileOutputStream = new FileOutputStream(file.getLocation().toOSString()); } catch (FileNotFoundException e) { throw new InternalErrorCDE("unexpected Exception", e); } printWriter = new PrintWriter(fileOutputStream); printWriter.println(descriptor); } finally { if (null != printWriter) printWriter.close(); if (null != fileOutputStream) try { fileOutputStream.close(); } catch (IOException e1) { } } stream = new ByteArrayInputStream(descriptor.getBytes()); file.create(stream, true, monitor); try { stream.close(); } catch (IOException e1) { } } monitor.worked(1); monitor.setTaskName("Starting editor for new descriptor..."); getShell().getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchPage page1 = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); try { page1.openEditor(new FileEditorInput(file), "taeconfigurator.editors.MultiPageEditor"); } catch (PartInitException e) { } } }); monitor.worked(2); } private void throwCoreException(String message) throws CoreException { IStatus status = new Status(IStatus.ERROR, "DescEditor", IStatus.OK, message, null); throw new CoreException(status); } public void init(IWorkbench workbench, IStructuredSelection pSelection) { selection = pSelection; setWindowTitle(windowTitle); } } ././@LongLink0000000000000000000000000000017200000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfigura0000644000175000017500000000265111665471210033404 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class TAEConfiguratorNewWizardPage extends AbstractNewWizardPage { public TAEConfiguratorNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Analysis Engine (AE) Descriptor File", "Create a new AE Descriptor File", "aeDescriptor.xml"); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNe0000644000175000017500000000265311665471210033550 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class TypeSystemNewWizardPage extends AbstractNewWizardPage { public TypeSystemNewWizardPage(ISelection selection) { super(selection, "big_t_s_.gif", "Type System Descriptor File", "Create a new Type System Descriptor file", "typeSystemDescriptor.xml"); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControll0000644000175000017500000000267311665471210033565 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class FlowControllerNewWizardPage extends AbstractNewWizardPage { public FlowControllerNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Flow Controller Descriptor File", "Create a new Flow Controller Descriptor file", "flowControllerDescriptor.xml"); } } ././@LongLink0000000000000000000000000000017400000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexColle0000644000175000017500000000270611665471210033455 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class FsIndexCollectionNewWizardPage extends AbstractNewWizardPage { public FsIndexCollectionNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Index Collection Descriptor File", "Create a new Index Collection Descriptor file", "indexCollectionDescriptor.xml"); } } ././@LongLink0000000000000000000000000000020700000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceMana0000644000175000017500000000316211665471210033517 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class ResourceManagerConfigurationNewWizardPage extends AbstractNewWizardPage { public ResourceManagerConfigurationNewWizardPage(ISelection selection) { super( selection, "big_ae.gif", "External Resources and Bindings (Resource Manager Configuration) Descriptor File", "Create a new External Resource and Bindings (Resource Manager Configuration) Descriptor file", "extResAndBindingsDescriptor.xml"); } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerN0000644000175000017500000000541011665471210033471 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class CasConsumerNewWizard extends AbstractNewWizard implements INewWizard { public CasConsumerNewWizard() { super("Cas Consumer Descriptor File"); } public void addPages() { page = new CasConsumerNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return "\n" + "org.apache.uima.java\n" + "\n" + "\n" + "" + name + "\n" + "\n" + "1.0\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; } } ././@LongLink0000000000000000000000000000016100000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNe0000644000175000017500000000400411665471210033540 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import java.text.MessageFormat; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class TypeSystemNewWizard extends AbstractNewWizard implements INewWizard { public static final String TYPESYSTEM_TEMPLATE = "\n" + "{0}\n" + "\n" + "1.0\n" + "\n" + "{1}" + "\n"; public TypeSystemNewWizard() { super("New Type System Descriptor File"); } public void addPages() { page = new TypeSystemNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return MessageFormat.format(TYPESYSTEM_TEMPLATE, new Object[] { name, "\n" }); } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioriti0000644000175000017500000000412311665471210033574 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import java.text.MessageFormat; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class TypePrioritiesNewWizard extends AbstractNewWizard implements INewWizard { public static final String TYPEPRIORITIES_TEMPLATE = "\n" + "{0}\n" + "\n" + "1.0\n" + "\n" + "{1}" + "\n"; public TypePrioritiesNewWizard() { super("New Type Priorities Descriptor File"); } public void addPages() { page = new TypePrioritiesNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return MessageFormat.format(TYPEPRIORITIES_TEMPLATE, new Object[] { name, "\n" }); } } ././@LongLink0000000000000000000000000000016600000000000011570 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerN0000644000175000017500000000265611665471210033502 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class CasConsumerNewWizardPage extends AbstractNewWizardPage { public CasConsumerNewWizardPage(ISelection selection) { super(selection, "big_ae.gif", "Cas Consumer Descriptor File", "Create a new Cas Consumer Descriptor file", "casConsumerDescriptor.xml"); } } ././@LongLink0000000000000000000000000000017000000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexColle0000644000175000017500000000416311665471210033454 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import java.text.MessageFormat; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class FsIndexCollectionNewWizard extends AbstractNewWizard implements INewWizard { public static final String FSINDEXCOLLECTION_TEMPLATE = "\n" + "{0}\n" + "\n" + "1.0\n" + "\n" + "{1}" + "\n"; public FsIndexCollectionNewWizard() { super("New Index Collection Descriptor File"); } public void addPages() { page = new FsIndexCollectionNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return MessageFormat.format(FSINDEXCOLLECTION_TEMPLATE, new Object[] { name, "\n" }); } } ././@LongLink0000000000000000000000000000017100000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioriti0000644000175000017500000000267711665471210033610 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.jface.viewers.ISelection; /** * The "New" wizard page allows setting the container for the new file as well as the file name. * Will only accept file name without the extension OR with the extension that matches the expected * one (xml). */ public class TypePrioritiesNewWizardPage extends AbstractNewWizardPage { public TypePrioritiesNewWizardPage(ISelection selection) { super(selection, "big_t_s_.gif", "Type Priorities Descriptor File", "Create a new Type Priorities Descriptor file", "typePrioritiesDescriptor.xml"); } } ././@LongLink0000000000000000000000000000016300000000000011565 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizardPage.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewW0000644000175000017500000001350311665471210033477 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.Path; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ContainerSelectionDialog; import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin; public abstract class AbstractNewWizardPage extends WizardPage { protected ISelection selection; protected Text containerText; protected Text fileText; private String defaultNewName; public AbstractNewWizardPage(ISelection pSelection, String image, String title, String description, String defaultNewName) { super("wizardPage"); setTitle(title); setDescription(description); setImageDescriptor(TAEConfiguratorPlugin.getImageDescriptor("big_t_s.gif")); selection = pSelection; this.defaultNewName = defaultNewName; } public void createControl(Composite parent) { Composite container = new Composite(parent, SWT.NULL); GridLayout layout = new GridLayout(); container.setLayout(layout); layout.numColumns = 3; layout.verticalSpacing = 9; Label label = new Label(container, SWT.NULL); label.setText("Parent &Folder:"); containerText = new Text(container, SWT.BORDER | SWT.SINGLE); GridData gd = new GridData(GridData.FILL_HORIZONTAL); containerText.setLayoutData(gd); containerText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { dialogChanged(); } }); Button button = new Button(container, SWT.PUSH); button.setText("Browse..."); button.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { handleBrowse(); } }); label = new Label(container, SWT.NULL); label.setText("&File name:"); fileText = new Text(container, SWT.BORDER | SWT.SINGLE); gd = new GridData(GridData.FILL_HORIZONTAL); fileText.setLayoutData(gd); fileText.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { dialogChanged(); } }); initialize(); dialogChanged(); setControl(container); } private void initialize() { if (selection != null && selection.isEmpty() == false && selection instanceof IStructuredSelection) { IStructuredSelection ssel = (IStructuredSelection) selection; if (ssel.size() > 1) return; Object obj = ssel.getFirstElement(); if (!(obj instanceof IResource) && obj instanceof IAdaptable) obj = ((IAdaptable) obj).getAdapter(IResource.class); if (obj instanceof IResource) { IContainer container = null; if (obj instanceof IContainer) container = (IContainer) obj; else container = ((IResource) obj).getParent(); if (container.isAccessible()) containerText.setText(container.getFullPath().toString()); } } fileText.setText(defaultNewName); } void handleBrowse() { ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin .getWorkspace().getRoot(), false, "Select a containing folder"); if (dialog.open() == ContainerSelectionDialog.OK) { Object[] result = dialog.getResult(); if (result.length == 1) { containerText.setText(((Path) result[0]).toOSString()); } } } void dialogChanged() { String container = getContainerName(); String fileName = getFileName(); if (container.length() == 0) { updateStatus("Parent folder must be specified"); return; } if (fileName.length() == 0) { updateStatus("File name must be specified"); return; } int dotLoc = fileName.lastIndexOf('.'); if (dotLoc != -1) { String ext = fileName.substring(dotLoc + 1); if (ext.equalsIgnoreCase("xml") == false) { updateStatus("File extension must be \"xml\""); return; } } updateStatus(null); } public String getContainerName() { return containerText.getText(); } public String getFileName() { return fileText.getText(); } private void updateStatus(String message) { setErrorMessage(message); setPageComplete(message == null); } } ././@LongLink0000000000000000000000000000016700000000000011571 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionRe0000644000175000017500000000544611665471210033524 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class CollectionReaderNewWizard extends AbstractNewWizard implements INewWizard { public CollectionReaderNewWizard() { super("Collection Reader Descriptor File"); } public void addPages() { page = new CollectionReaderNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return "\n" + "org.apache.uima.java\n" + "\n" + "\n" + "" + name + "\n" + "\n" + "1.0\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; } } ././@LongLink0000000000000000000000000000016500000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizard.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializ0000644000175000017500000000543211665471210033520 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.wizards; import org.eclipse.ui.INewWizard; /** * Create a new file resource in the provided container. If the container resource (a folder or a * project) is selected in the workspace when the wizard is opened, it will accept it as the target * container. If a sample multi-page editor is registered for the same extension, it will be able to * open it. */ public class CasInitializerNewWizard extends AbstractNewWizard implements INewWizard { public CasInitializerNewWizard() { super("Cas Initializer Descriptor File"); } public void addPages() { page = new CasInitializerNewWizardPage(selection); addPage(page); } public String getPrototypeDescriptor(String name) { return "\n" + "org.apache.uima.java\n" + "\n" + "\n" + "" + name + "\n" + "\n" + "1.0\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/InternalErrorCDE.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/InternalErrorCDE.jav0000644000175000017500000000303211665471220033326 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; /** */ public class InternalErrorCDE extends RuntimeException { /** * */ public InternalErrorCDE() { super(); } /** * @param message */ public InternalErrorCDE(String message) { super(message + " - Please see Eclipse Error Log for more information."); } /** * @param message * @param cause */ public InternalErrorCDE(String message, Throwable cause) { super(message + " - Please see Eclipse Error Log for more information.", cause); } /** * @param cause */ public InternalErrorCDE(Throwable cause) { super(cause); } static final long serialVersionUID = 1041388340406853782L; } ././@LongLink0000000000000000000000000000015300000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/TAEConfiguratorPlugin.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/TAEConfiguratorPlugi0000644000175000017500000002010011665471220033435 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; import java.net.MalformedURLException; import java.net.URL; import java.util.MissingResourceException; import java.util.ResourceBundle; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPluginDescriptor; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.forms.FormColors; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; /** * The main plugin class to be used in the desktop. */ /* * Plugin not yet converted to OSGi Bundle (3.0 design) - therefore will require the compatibility * interface. * * The descriptor editor is a Multi-page editor, and implements the Model View Controller pattern * (MVC). Model: Maintain data, basic logic plus one or more data sources View: Display all or a * portion of the data. Implements the GUI that displays information about the model to the user * Controller: Handle events that affect the model or view. The flow-control mechanism means by * which the user interacts with the application * * View: in packages ...editors, editors.ui, and editors.ui.dialogs Observer links: View updates * from model when update() is called on the page that is showing. This happens when which page is * showing changes, or when the model changes. * * * Life Cycle: On first activation - does almost nothing. Anything that could be done here is done * lazily, on first use/need. On shutdown: shutdown call not done (it's deprecated.) Instead, we use * the stop method. It releases SWT resources. */ public class TAEConfiguratorPlugin extends AbstractUIPlugin { // no longer include support for < 3.1 public static final boolean is30version = false; /* public static final int eclipseVersionMajor; public static final int eclipseVersionMinor; static { Bundle bundle = Platform.getBundle("org.eclipse.platform"); String versionString = (String) bundle.getHeaders().get( org.osgi.framework.Constants.BUNDLE_VERSION); PluginVersionIdentifier version = new PluginVersionIdentifier(versionString); eclipseVersionMajor = version.getMajorComponent(); eclipseVersionMinor = version.getMinorComponent(); is30version = eclipseVersionMajor == 3 && eclipseVersionMinor == 0; } */ // The shared instance. private static TAEConfiguratorPlugin plugin; // Resource bundle. private ResourceBundle resourceBundle; private static FormColors formColors; private static ImageRegistry imageRegistry = new ImageRegistry(); public final static String IMAGE_ANNOTATOR = "annotator.gif"; public final static String IMAGE_BIG_AE = "big_ae.gif"; public final static String IMAGE_BIG_T_S = "big_t_s.gif"; public final static String IMAGE_BLANK = "blank.gif"; public final static String IMAGE_COMMON = "common.gif"; public final static String IMAGE_EDITOR = "editor.gif"; public final static String IMAGE_FORM_BANNER = "form_banner.gif"; public final static String IMAGE_GELB = "gelb.gif"; public final static String IMAGE_GROUP = "group.gif"; public final static String IMAGE_PARAMETER = "parameter.gif"; public final static String IMAGE_T_S = "t_s.gif"; public final static String IMAGE_TH_HORIZONTAL = "th_horizontal.gif"; public final static String IMAGE_TH_VERTICAL = "th_vertical.gif"; public final static String IMAGE_MREFOK = "arrows.gif"; public final static String IMAGE_NOMREF = "one_arrow.gif"; private static URL installURL = null; public static String pluginId; /** * The constructor. */ public TAEConfiguratorPlugin(IPluginDescriptor descriptor) { super(descriptor); plugin = this; pluginId = descriptor.getUniqueIdentifier(); try { resourceBundle = ResourceBundle.getBundle("org.apache.uima.taeconfigurator.taeconfigurator"); } catch (MissingResourceException x) { resourceBundle = null; } imageRegistry.put(IMAGE_ANNOTATOR, getImageDescriptor("annotator.gif")); imageRegistry.put(IMAGE_BIG_AE, getImageDescriptor("big_ae.gif")); imageRegistry.put(IMAGE_BIG_T_S, getImageDescriptor("big_t_s.gif")); imageRegistry.put(IMAGE_BLANK, getImageDescriptor("blank.gif")); imageRegistry.put(IMAGE_COMMON, getImageDescriptor("common.gif")); imageRegistry.put(IMAGE_EDITOR, getImageDescriptor("editor.gif")); imageRegistry.put(IMAGE_FORM_BANNER, getImageDescriptor("form_banner.gif")); imageRegistry.put(IMAGE_GELB, getImageDescriptor("gelb.gif")); imageRegistry.put(IMAGE_GROUP, getImageDescriptor("group.gif")); imageRegistry.put(IMAGE_PARAMETER, getImageDescriptor("parameter.gif")); imageRegistry.put(IMAGE_T_S, getImageDescriptor("t_s.gif")); imageRegistry.put(IMAGE_TH_HORIZONTAL, getImageDescriptor("th_horizontal.gif")); imageRegistry.put(IMAGE_TH_VERTICAL, getImageDescriptor("th_vertical.gif")); imageRegistry.put(IMAGE_MREFOK, getImageDescriptor("arrows.gif")); imageRegistry.put(IMAGE_NOMREF, getImageDescriptor("one_arrow.gif")); } /** * Returns the shared instance. */ public static TAEConfiguratorPlugin getDefault() { return plugin; } /** * Returns the workspace instance. */ public static IWorkspace getWorkspace() { return ResourcesPlugin.getWorkspace(); } /** * Returns the string from the plugin's resource bundle, or 'key' if not found. */ public static String getResourceString(String key) { ResourceBundle bundle = TAEConfiguratorPlugin.getDefault().getResourceBundle(); try { return bundle.getString(key); } catch (MissingResourceException e) { return key; } } /** * called when the Eclipse environment is shut down */ public void stop(BundleContext context) throws Exception { try { if (null != formColors) formColors.dispose(); } finally { formColors = null; super.stop(context); } } /** * On first call, gets a formColors instance; on subsequent calls, returns that instance. * * @param display * @return */ public FormColors getFormColors(Display display) { if (null == formColors) { FormColors tempToAvoidSyncIssues = new FormColors(display); tempToAvoidSyncIssues.markShared(); // keep it from being disposed early formColors = tempToAvoidSyncIssues; } return formColors; } /** * Returns the plugin's resource bundle, */ public ResourceBundle getResourceBundle() { return resourceBundle; } public static Image getImage(String imageFile) { return imageRegistry.get(imageFile); } public static ImageDescriptor getImageDescriptor(String imageFile) { String iconPath = "icons/"; try { if (null == installURL) installURL = getDefault().getDescriptor().getInstallURL(); URL url = new URL(installURL, iconPath + imageFile); return ImageDescriptor.createFromURL(url); } catch (MalformedURLException exc) { return ImageDescriptor.getMissingImageDescriptor(); } } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/Messages.java0000644000175000017500000000310311665471220032133 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator; import java.text.MessageFormat; import java.util.MissingResourceException; import java.util.ResourceBundle; /** */ public class Messages { private static final String BUNDLE_NAME = "org.apache.uima.taeconfigurator.messages";//$NON-NLS-1$ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME); private Messages() { } public static String getString(String key) { try { return RESOURCE_BUNDLE.getString(key); } catch (MissingResourceException e) { return '!' + key + '!'; } } public static String getFormattedString(String key, String[] args) { return MessageFormat.format(RESOURCE_BUNDLE.getString(key), args); } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/0000755000175000017500000000000011665471206030630 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000015200000000000011563 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorTCAS.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorTCAS0000644000175000017500000000625011665471206033347 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import org.apache.uima.analysis_engine.AnalysisEngineDescription; import org.apache.uima.cas.CAS; import org.apache.uima.cas.admin.CASAdminException; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; /** * Model part: CAS corresponding to the descriptor being edited */ public class DescriptorTCAS extends AbstractModelPart { private CAS cachedResult; public DescriptorTCAS(MultiPageEditor modelRoot) { super(modelRoot); } public void validate() throws ResourceInitializationException { AnalysisEngineDescription ae = (AnalysisEngineDescription) modelRoot.getAeDescription().clone(); // speedup = replace typeSystem with resolved imports version if (ae.isPrimitive()) { TypeSystemDescription tsd = modelRoot.getMergedTypeSystemDescription(); if (null != tsd) tsd = (TypeSystemDescription) tsd.clone(); ae.getAnalysisEngineMetaData().setTypeSystem(tsd); } ae.getAnalysisEngineMetaData().setFsIndexCollection(modelRoot.getMergedFsIndexCollection()); ae.getAnalysisEngineMetaData().setTypePriorities(modelRoot.getMergedTypePriorities()); try { // long time = System.currentTimeMillis(); // System.out.println("Creating TCas model"); cachedResult = modelRoot.createCas(ae, casCreateProperties, modelRoot.createResourceManager()); // System.out.println("Finished Creating TCas model; time= " + // (System.currentTimeMillis() - time)); if (null == cachedResult) throw new InternalErrorCDE("null result from createTCas"); } catch (CASAdminException e) { throw new ResourceInitializationException(e); } dirty = false; modelRoot.allTypes.dirty = true; } /** * @return a CAS for the model descriptor */ public CAS get() { if (dirty) { update(); } return cachedResult; } public void set(CAS tcas) { cachedResult = tcas; dirty = false; } private void update() { try { validate(); } catch (ResourceInitializationException e) { throw new InternalErrorCDE("Unexpected Exception", e); } } } ././@LongLink0000000000000000000000000000016200000000000011564 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DefinedTypesWithSupers.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DefinedTypesWi0000644000175000017500000000542111665471206033440 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; /** * Model part: names of the defined types, augmented with their supertypes This means that some of * the built-ins (those in the super chain) will be included. */ public class DefinedTypesWithSupers extends AbstractModelPart { private Set cachedResult; public DefinedTypesWithSupers(MultiPageEditor pModelRoot) { super(pModelRoot); cachedResult = new HashSet(modelRoot.INITIAL_SIZE_TYPE_COLLECTIONS); } /** * @return a set of strings, including not only types defined in this TAE, but also supertypes of * said types. */ public Set get() { if (dirty) { update(); dirty = false; } return cachedResult; } private void update() { cachedResult.clear(); // for aggregates, this is the fully-merged type system // for all systems, it is the type system with imports resolved TypeSystemDescription typeSystemDescription = modelRoot.getMergedTypeSystemDescription(); if (typeSystemDescription == null) return; // cleared table TypeDescription[] types = typeSystemDescription.getTypes(); TypeSystem typeSystem = modelRoot.descriptorCAS.get().getTypeSystem(); String typeName; Map allTypes = modelRoot.allTypes.get(); for (int i = 0; i < types.length; i++) { cachedResult.add(typeName = types[i].getName()); Type nextType = (Type) allTypes.get(typeName); while (nextType != null) { nextType = typeSystem.getParent(nextType); if (nextType != null) cachedResult.add(nextType.getName()); } } } } ././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/ConfigGroup.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/ConfigGroup.ja0000644000175000017500000001004511665471206033366 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import org.apache.uima.resource.metadata.ConfigurationGroup; import org.apache.uima.resource.metadata.ConfigurationParameter; import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.ui.AbstractSection; import org.apache.uima.taeconfigurator.editors.ui.AbstractSectionParm; /** * Instances of this class model the 3 varients of configuration parameter sets. * */ public class ConfigGroup { private ConfigurationParameterDeclarations cpd; private int kind; private ConfigurationGroup namedCg = null; public final static int NOT_IN_ANY_GROUP = 1; public final static int COMMON = 2; public final static int NAMED_GROUP = 4; public ConfigGroup(ConfigurationParameterDeclarations aCpd, int aKind) { cpd = aCpd; kind = aKind; fixupCpd(); } public ConfigGroup(ConfigurationParameterDeclarations aCpd, ConfigurationGroup aNamedCg) { cpd = aCpd; kind = NAMED_GROUP; namedCg = aNamedCg; fixupCpd(); } private void fixupCpd() { if (null == cpd.getConfigurationParameters()) cpd.setConfigurationParameters(AbstractSection.configurationParameterArray0); if (null == cpd.getCommonParameters()) cpd.setCommonParameters(AbstractSection.configurationParameterArray0); if (null == cpd.getConfigurationGroups()) cpd.setConfigurationGroups(AbstractSection.configurationGroupArray0); ConfigurationGroup[] cgs = cpd.getConfigurationGroups(); for (int i = 0; i < cgs.length; i++) { if (null == cgs[i].getConfigurationParameters()) cgs[i].setConfigurationParameters(AbstractSection.configurationParameterArray0); } } public ConfigurationParameter[] getConfigParms() { switch (kind) { case NOT_IN_ANY_GROUP: return cpd.getConfigurationParameters(); case COMMON: return cpd.getCommonParameters(); case NAMED_GROUP: return namedCg.getConfigurationParameters(); default: throw new InternalErrorCDE("invalid state"); } } public String getName() { switch (kind) { case NOT_IN_ANY_GROUP: return AbstractSectionParm.NOT_IN_ANY_GROUP; case COMMON: return AbstractSectionParm.COMMON_GROUP; case NAMED_GROUP: return AbstractSectionParm.groupNameArrayToString(namedCg.getNames()); default: throw new InternalErrorCDE("invalid state"); } } public String[] getNameArray() { switch (kind) { case NOT_IN_ANY_GROUP: return new String[] { AbstractSectionParm.NOT_IN_ANY_GROUP }; case COMMON: return new String[] { AbstractSectionParm.COMMON_GROUP }; case NAMED_GROUP: return namedCg.getNames(); default: throw new InternalErrorCDE("invalid state"); } } public void setNameArray(String[] names) { if (kind != NAMED_GROUP) throw new InternalErrorCDE("invalid call"); namedCg.setNames(names); } public int getKind() { return kind; } public ConfigurationParameterDeclarations getCPD() { return cpd; } } ././@LongLink0000000000000000000000000000015500000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AbstractModelPart.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AbstractModelP0000644000175000017500000000267611665471206033432 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import java.util.Properties; import org.apache.uima.UIMAFramework; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; /** */ public class AbstractModelPart { public static final Properties casCreateProperties = new Properties(); static { casCreateProperties.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "200"); } protected MultiPageEditor modelRoot; protected boolean dirty; public AbstractModelPart(MultiPageEditor pMPE) { modelRoot = pMPE; dirty = true; } public void markDirty() { dirty = true; } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AllTypes.java0000644000175000017500000000467011665471206033237 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; /** * Model part: Map of all defined types Key = string = typename, fully qualified Value = CAS * TypeSystem Type object */ public class AllTypes extends AbstractModelPart { private Map cachedResult; public AllTypes(MultiPageEditor pModelRoot) { super(pModelRoot); cachedResult = new HashMap(modelRoot.INITIAL_SIZE_TYPE_COLLECTIONS); } /** * @return a map of Types, keyed by type name, including not only types defined in this TAE, but * also supertypes of said types. * @throws ResourceInitializationException */ public Map get() { if (dirty) { update(); dirty = false; } return cachedResult; } // create a hash table of all types private void update() { cachedResult.clear(); CAS tcas = modelRoot.getCurrentView(); if (null == tcas) return; TypeSystem typeSystem = tcas.getTypeSystem(); if (typeSystem == null) return; Iterator typeIterator = typeSystem.getTypeIterator(); while (typeIterator.hasNext()) { Type type = (Type) typeIterator.next(); String typeName = type.getName(); if (null != typeName && !typeName.endsWith("[]")) { cachedResult.put(type.getName(), type); } } } } uimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/FlowNodes.java0000644000175000017500000000425211665471206033376 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import org.apache.uima.analysis_engine.metadata.CapabilityLanguageFlow; import org.apache.uima.analysis_engine.metadata.FixedFlow; import org.apache.uima.analysis_engine.metadata.FlowConstraints; /** * Instances of this class model the varients of flow nodes in a uniform way. * */ public class FlowNodes { private FixedFlow fixedFlow; private CapabilityLanguageFlow capabilityLanguageFlow; public FlowNodes(FlowConstraints flow) { if (flow instanceof FixedFlow) fixedFlow = (FixedFlow) flow; else if (flow instanceof CapabilityLanguageFlow) capabilityLanguageFlow = (CapabilityLanguageFlow) flow; // can be null if omitted } public String[] getFlow() { if (fixedFlow != null) return fixedFlow.getFixedFlow(); if (capabilityLanguageFlow != null) return capabilityLanguageFlow.getCapabilityLanguageFlow(); return null; // throw new InternalErrorCDE("invalid state"); } public void setFlow(String[] newFlow) { if (fixedFlow != null) { fixedFlow.setFixedFlow(newFlow); return; } if (capabilityLanguageFlow != null) { capabilityLanguageFlow.setCapabilityLanguageFlow(newFlow); return; } // throw new InternalErrorCDE("invalid state"); return; // ignore in null case } } ././@LongLink0000000000000000000000000000015000000000000011561 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/BuiltInTypes.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/BuiltInTypes.j0000644000175000017500000000710711665471206033403 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.uima.cas.CAS; import org.apache.uima.cas.Feature; import org.apache.uima.cas.Type; import org.apache.uima.cas.TypeSystem; import org.apache.uima.cas.impl.CASImpl; import org.apache.uima.resource.ResourceInitializationException; import org.apache.uima.resource.metadata.FeatureDescription; import org.apache.uima.resource.metadata.FsIndexDescription; import org.apache.uima.resource.metadata.TypeDescription; import org.apache.uima.resource.metadata.TypeSystemDescription; import org.apache.uima.resource.metadata.impl.FeatureDescription_impl; import org.apache.uima.resource.metadata.impl.TypeDescription_impl; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.util.CasCreationUtils; /** * Gets and caches an array list of all the built-in tcas types */ public class BuiltInTypes extends AbstractModelPart { public static final TypeSystem typeSystem; public static final Map typeDescriptions = new TreeMap(); static { CAS tcas = null; try { tcas = CasCreationUtils.createCas((TypeSystemDescription) null, null, new FsIndexDescription[0], casCreateProperties); } catch (ResourceInitializationException e1) { throw new InternalErrorCDE("invalid ResourceInitializationException", e1); } ((CASImpl) tcas).commitTypeSystem(); typeSystem = tcas.getTypeSystem(); for (Iterator it = typeSystem.getTypeIterator(); it.hasNext();) { Type type = (Type) it.next(); String typeName = type.getName(); TypeDescription td = new TypeDescription_impl(); td.setName(typeName); Type parent = typeSystem.getParent(type); td.setSupertypeName(null == parent ? null : parent.getName()); List fs = type.getFeatures(); FeatureDescription[] fds = null; if (null != fs) { List validFs = new ArrayList(); for (int i = 0; i < fs.size(); i++) { Feature f = (Feature) fs.get(i); String fName = f.getName(); String fTypeName = fName.substring(0, fName.indexOf(':')); if (typeName.equals(fTypeName)) validFs.add(f); } fds = new FeatureDescription[validFs.size()]; for (int i = 0; i < fds.length; i++) { fds[i] = new FeatureDescription_impl(); Feature f = (Feature) validFs.get(i); fds[i].setName(f.getShortName()); fds[i].setRangeTypeName(f.getRange().getName()); } } td.setFeatures(fds); typeDescriptions.put(typeName, td); } } BuiltInTypes() { super(null); } } ././@LongLink0000000000000000000000000000015600000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorMetaData.javauimaj-2.4.0/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorMeta0000644000175000017500000001421511665471206033503 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.taeconfigurator.model; import org.apache.uima.taeconfigurator.InternalErrorCDE; import org.apache.uima.taeconfigurator.editors.MultiPageEditor; /** * Instances of this class model the varients of getting and setting metadata. * */ public class DescriptorMetaData { private MultiPageEditor editor; public DescriptorMetaData(MultiPageEditor editor) { this.editor = editor; } public String getName() { if (editor.isLocalProcessingDescriptor()) return editor.getAeDescription().getMetaData().getName(); if (editor.isTypeSystemDescriptor()) return editor.getTypeSystemDescription().getName(); if (editor.isTypePriorityDescriptor()) return editor.getTypePriorities().getName(); if (editor.isFsIndexCollection()) return editor.getFsIndexCollection().getName(); if (editor.isExtResAndBindingsDescriptor()) return editor.getExtResAndBindings().getName(); throw new InternalErrorCDE("invalid state"); } public void setName(String name) { if (editor.isLocalProcessingDescriptor()) editor.getAeDescription().getMetaData().setName(name); else if (editor.isTypeSystemDescriptor()) editor.getTypeSystemDescription().setName(name); else if (editor.isTypePriorityDescriptor()) editor.getTypePriorities().setName(name); else if (editor.isFsIndexCollection()) editor.getFsIndexCollection().setName(name); else if (editor.isExtResAndBindingsDescriptor()) editor.getExtResAndBindings().setName(name); else throw new InternalErrorCDE("invalid state"); } public String getVersion() { if (editor.isLocalProcessingDescriptor()) return editor.getAeDescription().getMetaData().getVersion(); if (editor.isTypeSystemDescriptor()) return editor.getTypeSystemDescription().getVersion(); if (editor.isTypePriorityDescriptor()) return editor.getTypePriorities().getVersion(); if (editor.isFsIndexCollection()) return editor.getFsIndexCollection().getVersion(); if (editor.isExtResAndBindingsDescriptor()) return editor.getExtResAndBindings().getVersion(); throw new InternalErrorCDE("invalid state"); } public void setVersion(String name) { if (editor.isLocalProcessingDescriptor()) editor.getAeDescription().getMetaData().setVersion(name); else if (editor.isTypeSystemDescriptor()) editor.getTypeSystemDescription().setVersion(name); else if (editor.isTypePriorityDescriptor()) editor.getTypePriorities().setVersion(name); else if (editor.isFsIndexCollection()) editor.getFsIndexCollection().setVersion(name); else if (editor.isExtResAndBindingsDescriptor()) editor.getExtResAndBindings().setVersion(name); else throw new InternalErrorCDE("invalid state"); } public String getVendor() { if (editor.isLocalProcessingDescriptor()) return editor.getAeDescription().getMetaData().getVendor(); if (editor.isTypeSystemDescriptor()) return editor.getTypeSystemDescription().getVendor(); if (editor.isTypePriorityDescriptor()) return editor.getTypePriorities().getVendor(); if (editor.isFsIndexCollection()) return editor.getFsIndexCollection().getVendor(); if (editor.isExtResAndBindingsDescriptor()) return editor.getExtResAndBindings().getVendor(); throw new InternalErrorCDE("invalid state"); } public void setVendor(String name) { if (editor.isLocalProcessingDescriptor()) editor.getAeDescription().getMetaData().setVendor(name); else if (editor.isTypeSystemDescriptor()) editor.getTypeSystemDescription().setVendor(name); else if (editor.isTypePriorityDescriptor()) editor.getTypePriorities().setVendor(name); else if (editor.isFsIndexCollection()) editor.getFsIndexCollection().setVendor(name); else if (editor.isExtResAndBindingsDescriptor()) editor.getExtResAndBindings().setVendor(name); else throw new InternalErrorCDE("invalid state"); } public String getDescription() { if (editor.isLocalProcessingDescriptor()) return editor.getAeDescription().getMetaData().getDescription(); if (editor.isTypeSystemDescriptor()) return editor.getTypeSystemDescription().getDescription(); if (editor.isTypePriorityDescriptor()) return editor.getTypePriorities().getDescription(); if (editor.isFsIndexCollection()) return editor.getFsIndexCollection().getDescription(); if (editor.isExtResAndBindingsDescriptor()) return editor.getExtResAndBindings().getDescription(); throw new InternalErrorCDE("invalid state"); } public void setDescription(String name) { if (editor.isAeDescriptor() || editor.isLocalProcessingDescriptor()) editor.getAeDescription().getMetaData().setDescription(name); else if (editor.isTypeSystemDescriptor()) editor.getTypeSystemDescription().setDescription(name); else if (editor.isTypePriorityDescriptor()) editor.getTypePriorities().setDescription(name); else if (editor.isFsIndexCollection()) editor.getFsIndexCollection().setDescription(name); else if (editor.isExtResAndBindingsDescriptor()) editor.getExtResAndBindings().setDescription(name); else throw new InternalErrorCDE("invalid state"); } } uimaj-2.4.0/uimaj-test-util/0000755000175000017500000000000011665471570015567 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/pom.xml0000644000175000017500000000534311665471546017114 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml org.apache.uima uimaj-test-util jar 2.4.0 Apache UIMA Base: ${project.artifactId}: JUnit utilities Utilities for testing UIMA ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/jvinci scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/jvinci http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/jvinci jvinci ${ibmNoticeText} junit junit 3.8.1 compile uimaj-2.4.0/uimaj-test-util/src/0000755000175000017500000000000011665471262016354 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/0000755000175000017500000000000011665471262017300 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/resources/0000755000175000017500000000000011665471262021312 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/0000755000175000017500000000000011665471262020221 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/org/0000755000175000017500000000000011665471262021010 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/0000755000175000017500000000000011665471262022231 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/0000755000175000017500000000000011665471262023164 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/0000755000175000017500000000000011665471262024143 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/0000755000175000017500000000000011665471262027370 5ustar drazzibdrazzib././@LongLink0000000000000000000000000000014700000000000011567 Lustar rootrootuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/ManageOutputDevice.javauimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/ManageOutputDevice.ja0000644000175000017500000000716111665471262033442 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintStream; /** * This class manupulates the output of the system. Methode output like System.out.println("blah") * may be send to something else than the console. */ public class ManageOutputDevice { private static PrintStream sysOutPS; private static PrintStream sysErrPS; static { sysOutPS = System.out; sysErrPS = System.err; } /** * sets the System.out to a file based java.io.PrintStream * * @param descriptor * a full qualified filename {@see java.io.File#File(String pathname)} * @throws FileNotFoundException */ public static void setSysOutToFile(String descriptor) throws FileNotFoundException { File f = new File(descriptor); PrintStream printStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(f)), true); System.setOut(printStream); } /** * sets the System.out to the value, which was set, when the class was loaded by * the VM. */ public static void setSysOutToDefault() { System.setOut(sysOutPS); } /** * sets the System.out to a virtual java.io.ByteArrayOutputStream */ public static void setSysOutToNirvana() { System.setOut(new PrintStream(new ByteArrayOutputStream())); } /** * sets the System.err to a file based java.io.PrintStream * * @param descriptor * @throws FileNotFoundException */ public static void setSysErrToFile(String descriptor) throws FileNotFoundException { File f = new File(descriptor); PrintStream printStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(f)), true); System.setErr(printStream); } /** * sets the System.err to the value, which was set, when this class was loaded by * the VM. */ public static void setSysErrToDefault() { System.setErr(sysErrPS); } /** * sets the System.err to a virtual java.io.ByteArrayOutputStream */ public static void setSysErrToNirvana() { System.setErr(new PrintStream(new ByteArrayOutputStream())); } /** * sets the System.err and System.out to a virtual * java.io.ByteArrayOutputStream */ public static void setAllSystemOutputToNirvana() { setSysErrToNirvana(); setSysOutToNirvana(); } /** * sets the System.err and System.out to their values, which were * set, when this class was loaded. */ public static void setAllSystemOutputToDefault() { setSysErrToDefault(); setSysOutToDefault(); } } ././@LongLink0000000000000000000000000000014600000000000011566 Lustar rootrootuimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/UIMAResultPrinter.javauimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/UIMAResultPrinter.jav0000644000175000017500000001706311665471262033377 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.PrintStream; import java.text.NumberFormat; import java.util.Enumeration; import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestFailure; import junit.framework.TestListener; import junit.framework.TestResult; import junit.runner.BaseTestRunner; import junit.textui.ResultPrinter; /** * UIMAResultPrinter is a ResultPrinter extension for the JUnit framework. */ public class UIMAResultPrinter extends ResultPrinter implements TestListener { // print stream for the output private PrintStream fWriter; // current column in line private int fColumn = 0; // test case counter private int testCounter; // name of the current test class private String currentTestClass; // success status of the current test method private boolean currentTestSuccess; // abort execution if an error occurs private boolean abortOnFail; // dublicated output stream, change output layout private boolean teeOutputStream; public UIMAResultPrinter(PrintStream writer, boolean abortOnFail, boolean teeOutputStream) { // init class members super(writer); this.fWriter = writer; this.testCounter = 0; this.currentTestClass = null; this.currentTestSuccess = true; this.abortOnFail = abortOnFail; this.teeOutputStream = teeOutputStream; } /** * @see junit.textui.ResultPrinter#printHeader(long) */ protected void printHeader(long runTime) { getWriter().println(); getWriter().println(); getWriter().println("Time: " + elapsedTimeAsString(runTime)); } /** * @see junit.textui.ResultPrinter#printErrors(junit.framework.TestResult) */ protected void printErrors(TestResult result) { printDefects(result.errors(), result.errorCount(), "error"); } /** * @see junit.textui.ResultPrinter#printFailures(junit.framework.TestResult) */ protected void printFailures(TestResult result) { printDefects(result.failures(), result.failureCount(), "failure"); } /** * @see junit.textui.ResultPrinter#printDefects(java.util.Enumeration, int, java.lang.String) */ protected void printDefects(Enumeration booBoos, int count, String type) { if (count == 0) return; if (count == 1) getWriter().println("There was " + count + " " + type + ":"); else getWriter().println("There were " + count + " " + type + "s:"); for (int i = 1; booBoos.hasMoreElements(); i++) { printDefect((TestFailure) booBoos.nextElement(), i); } } /** * @see junit.textui.ResultPrinter#printDefect(junit.framework.TestFailure, int) */ public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes printDefectHeader(booBoo, count); printDefectTrace(booBoo); } /** * @see junit.textui.ResultPrinter#printDefectHeader(junit.framework.TestFailure, int) */ protected void printDefectHeader(TestFailure booBoo, int count) { // I feel like making this a println, then adding a line giving the throwable a chance to print // something // before we get to the stack trace. getWriter().print(count + ") " + booBoo.failedTest()); } /** * @see junit.textui.ResultPrinter#printDefectTrace(junit.framework.TestFailure) */ protected void printDefectTrace(TestFailure booBoo) { getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace())); } /** * @see junit.textui.ResultPrinter#printFooter(junit.framework.TestResult) */ protected void printFooter(TestResult result) { if (result.wasSuccessful()) { getWriter().println(); getWriter().print("OK"); getWriter().println( " (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")"); } else { getWriter().println(); getWriter().println("FAILURES!!!"); getWriter().println( "Tests run: " + result.runCount() + ", Failures: " + result.failureCount() + ", Errors: " + result.errorCount()); } getWriter().println(); } /** * Returns the formatted string of the elapsed time. Duplicated from BaseTestRunner. Fix it. */ protected String elapsedTimeAsString(long runTime) { return NumberFormat.getInstance().format((double) runTime / 1000); } /** * @see junit.textui.ResultPrinter#getWriter() */ public PrintStream getWriter() { return this.fWriter; } /** * @see junit.framework.TestListener#addError(Test, Throwable) */ public void addError(Test test, Throwable t) { getWriter().print("error"); this.currentTestSuccess = false; if (this.abortOnFail) { getWriter().println(); getWriter().println(); getWriter().println("Stop executing testcases..."); getWriter().println("Print Stacktrace: "); getWriter().println(); StackTraceElement[] stackTrace = t.getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { getWriter().println(stackTrace[i].toString()); } throw new RuntimeException("Abort on error"); } } /** * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError) */ public void addFailure(Test test, AssertionFailedError t) { getWriter().print("failure"); this.currentTestSuccess = false; if (this.abortOnFail) { getWriter().println(); getWriter().println(); getWriter().println("Stop executing testcases..."); getWriter().println("Print Stacktrace: "); getWriter().println(); StackTraceElement[] stackTrace = t.getStackTrace(); for (int i = 0; i < stackTrace.length; i++) { getWriter().println(stackTrace[i].toString()); } throw new RuntimeException("Abort on failure"); } } /** * @see junit.framework.TestListener#endTest(Test) */ public void endTest(Test test) { if (this.currentTestSuccess == false) this.currentTestSuccess = true; else getWriter().print("ok"); } /** * @see junit.framework.TestListener#startTest(Test) */ public void startTest(Test test) { this.testCounter++; String name = test.toString(); String tempCurrentTestClass = name.substring(name.indexOf('(') + 1, name.lastIndexOf(')')); String testName = name.substring(0, name.indexOf('(')); if (!tempCurrentTestClass.equals(this.currentTestClass)) { this.currentTestClass = tempCurrentTestClass; getWriter().println(); getWriter().println(); getWriter().print(this.currentTestClass); getWriter().println(); for (int i = 0; i < this.currentTestClass.length(); i++) getWriter().print("="); } getWriter().println(); getWriter().print(this.testCounter + ": " + testName + ": "); if (this.fColumn++ >= 40 || this.teeOutputStream) { getWriter().println(); this.fColumn = 0; } } } uimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/JUnitTestRunner.java0000644000175000017500000002256711665471262033332 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.FileOutputStream; import java.io.PrintStream; import java.lang.reflect.Method; import java.text.DateFormat; import java.util.GregorianCalendar; import junit.framework.Test; import junit.framework.TestResult; import junit.framework.TestSuite; import junit.textui.TestRunner; /** * JUnitTestRunner is the start class for the comand line test with JUnit. */ public class JUnitTestRunner { // this mehtod name must be avaialbe at every TestSuite class private static final String SUITE_METHODNAME = "suite"; // command line parameters private static final String ABORT_ON_FAIL = "-abortonfail"; private static final String TEST_SUITE = "-suite"; private static final String TEST_CASE = "-testcase"; private static final String RESULT_OUTPUT = "-resultfile"; private static final String CONSOLE_OUTPUT = "-consolefile"; private static final String RESULT_OUTPUT_SHORT = "-rf"; private static final String CONSOLE_OUTPUT_SHORT = "-cf"; private static final String TEE_CONSOLE_OUTPUT = "-cpconsole"; private static final String TEE_RESULT_OUTPUT = "-cpresult"; // command line argument flags private static boolean abortOnFail = false; private static boolean testCase = false; private static boolean testSuite = false; private static boolean teeResult = false; private static boolean teeConsole = false; private static boolean error = false; // command line arguments private static String testName = null; private static String consoleFileName = null; private static String resultFileName = null; public static void main(String args[]) { JUnitTestRunner jRun = new JUnitTestRunner(); if (jRun.runTest(args)) { System.exit(0); } else { System.exit(1); } } public boolean runTest(String[] args) { // process command line arguments, loop over all arguments for (int i = 0; i < args.length; i++) { // get current argument String currentArg = args[i]; // if current argument starts with '-' transform to lower case if (currentArg.startsWith("-")) { currentArg = currentArg.toLowerCase(); } // check abort on failure if (currentArg.equals(ABORT_ON_FAIL)) { abortOnFail = true; } // check if testname is a TestSuite else if (currentArg.equals(TEST_SUITE)) { if ((i + 1) < args.length) { testSuite = true; testName = args[i + 1]; i++; } else { error = true; } } // check if testname is a TestCase else if (currentArg.equals(TEST_CASE)) { if ((i + 1) < args.length) { testCase = true; testName = args[i + 1]; i++; } else { error = true; } } // check if a result output filename is specified else if (currentArg.equals(RESULT_OUTPUT) || currentArg.equals(RESULT_OUTPUT_SHORT)) { if ((i + 1) < args.length) { resultFileName = args[i + 1]; i++; } else { error = true; } } // check if a console output filename is specified else if (currentArg.equals(CONSOLE_OUTPUT) || currentArg.equals(CONSOLE_OUTPUT_SHORT)) { if ((i + 1) < args.length) { consoleFileName = args[i + 1]; i++; } else { error = true; } } // check if console output should be dublicated else if (currentArg.equals(TEE_CONSOLE_OUTPUT)) { teeConsole = true; } // check if result output should be dublicated else if (currentArg.equals(TEE_RESULT_OUTPUT)) { teeResult = true; } } // check if commandline was ok if (!(testCase || testSuite) || error) { System.out .println("Usage: JUnitTestRunner [-abortOnFail] [-testcase ] " + " [-suite ]" + " [-resultFile ] [-cpConsole] [-cpResult]"); } // create new JUnitTestRunner TestRunner aTestRunner = new TestRunner(); try { // create ouput files references File resultFile = null; File consoleFile = null; // initialize standard output stream, use console as standard output PrintStream resultWriter = System.out; PrintStream consoleWriter = System.out; // check if result output filename was specifed if (resultFileName != null) { // create new result output file resultFile = new File(resultFileName); resultFile.createNewFile(); // dublicate PrintStream if neccessary if (teeResult == true) { PrintStream tempResultWriter = new PrintStream(new FileOutputStream(resultFile, false), true, "UTF-8"); resultWriter = new TeePrintStream(tempResultWriter, System.out); } else { resultWriter = new PrintStream(new FileOutputStream(resultFile, false), true, "UTF-8"); } } // check if console output filename was specified if (consoleFileName != null) { // create new console output file consoleFile = new File(consoleFileName); consoleFile.createNewFile(); // dublicate PrintStream if neccessary if (teeConsole == true) { PrintStream tempConsoleWriter = new PrintStream(new FileOutputStream(consoleFile, false), true, "UTF-8"); consoleWriter = new TeePrintStream(tempConsoleWriter, System.out); } else { consoleWriter = new PrintStream(new FileOutputStream(consoleFile, false), true, "UTF-8"); } // set new System.out PrintStream System.setOut(consoleWriter); } // set UIMAResult printer mode, if teeResult is true use another output layout UIMAResultPrinter printer = new UIMAResultPrinter(resultWriter, abortOnFail, teeResult); aTestRunner.setPrinter(printer); // get testClass for the given testname Class testClass = Class.forName(testName); // create new JUnit TestSuite TestSuite suite = new TestSuite(); suite.setName(testName.substring((testName.lastIndexOf(".") + 1), testName.length())); // add suite to current suite if (testSuite) { Method suiteMethod = testClass.getMethod(SUITE_METHODNAME, new Class[0]); Test test = (Test) suiteMethod.invoke(null, new Class[0]); // static method suite.addTest(test); } // add testcase to current suite if (testCase) { suite.addTestSuite(testClass); } // print header resultWriter .println("################################################################################################"); resultWriter.println("# TestSuite: " + suite.getName()); resultWriter.println("# Testcases: " + suite.countTestCases()); resultWriter.println("# Test candidate: " + testName); resultWriter.println("# Abort on error: " + abortOnFail); resultWriter.println("# Result output filename: " + resultFileName); resultWriter.println("# Console output filename: " + consoleFileName); resultWriter.println("# Test start directory: " + System.getProperty("user.dir")); resultWriter.println("# Test starter: " + System.getProperty("user.name")); resultWriter.println("# OS: " + System.getProperty("os.name") + " " + System.getProperty("os.version")); resultWriter.println("# Command line run: " + System.getProperty("isCommandLine", "false")); // get current date and time DateFormat dateTime; GregorianCalendar cal = new GregorianCalendar(); StringBuffer time = new StringBuffer(42); time.append("# Test started at: "); dateTime = DateFormat.getDateInstance(); time.append(dateTime.format(cal.getTime())); dateTime = DateFormat.getTimeInstance(); time.append(" "); time.append(dateTime.format(cal.getTime())); resultWriter.println(time.toString()); resultWriter.println("# Test runs with java version: " + System.getProperty("java.version")); resultWriter.println("# JUnitTestRunner version: 1.2"); resultWriter .println("################################################################################################"); // run current test TestResult results = aTestRunner.doRun(suite); // check test result if (results.wasSuccessful() == false) { return false; } return true; } catch (Exception e) { System.out.println(e.getMessage()); return false; } } } uimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/FileCompare.java0000644000175000017500000003341311665471262032425 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * FileCompare class provides a several methods, which compare two files or input streams. * Most methods are static. * * It has a facility to incorporate a regex ignore-differences filter * */ public class FileCompare { /** * TODO Currently only tags containing word characters [a-zA-Z_0-9] are recognised. */ // match "<" followed by 1 or more word_chars followed by ">" followed by "" private static final String EMPTY_TAG_REGEX = "(<([\\w]+)>[\\s]*)"; private static Pattern emptyTagPattern = Pattern.compile(EMPTY_TAG_REGEX); // matches cr if it is followed by a new-line, will be repl with just a new line private static Pattern crnlPattern = Pattern.compile("\\r(?=\\n)"); /** * compares two files and return true if the files have the same content. * * @param filename1 * filename of the first file * @param filename2 * filename of the second file * @return - true if the files have the same content * * @throws IOException */ public static boolean compare(String filename1, String filename2) throws IOException { InputStream file1 = null; InputStream file2 = null; try { // create file input stream of the two bytes file1 = new FileInputStream(filename1); file2 = new FileInputStream(filename2); return compare(file1, file2); } finally { file1.close(); file2.close(); } } /** * compares two files and return true if the files have the same content. * * @param file1 * first file * @param file2 * second file * @return - true if the files have the same content * * @throws IOException */ public static boolean compare(File file1, File file2) throws IOException { InputStream inputStream1 = null; InputStream inputStream2 = null; try { // create file input stream of the two bytes inputStream1 = new FileInputStream(file1); inputStream2 = new FileInputStream(file2); return compare(inputStream1, inputStream2); } finally { inputStream1.close(); inputStream2.close(); } } /** * compares two files and return true if the files have the same content. * * @param filename1 * filename of the first file * @param in * an input Sream * * @return - true if the content is the same * * @throws IOException */ public static boolean compare(String filename1, InputStream in) throws IOException { InputStream file1 = null; try { // create file input stream of the two bytes file1 = new FileInputStream(filename1); return compare(file1, in); } finally { file1.close(); } } public static boolean compare(InputStream in1, InputStream in2) throws IOException { int in1byte, in2byte; final int byteBufferSize = 10000; in1 = new BufferedInputStream(in1, byteBufferSize); in2 = new BufferedInputStream(in2, byteBufferSize); in1byte = 0; while (in1byte != -1) { // read one byte from file1 in1byte = in1.read(); // check if byte is whitespace or blank if ((!(Character.isWhitespace((char) in1byte))) && (in1byte != ' ') && (in1byte != '\n') && (in1byte != '\r')) { // read one byte form file2 in2byte = in2.read(); // read bytes until byte is no whitespace or blank while ((Character.isWhitespace((char) in2byte)) || (in2byte == ' ') || (in2byte == '\n') || (in2byte == '\r')) { // if byte is whitespace or blank read next byte in2byte = in2.read(); } // check if byte from file1 and file2 are the same if (in1byte != in2byte) { return false; // file content of the two files are not the same } } } return true; } /** * Compare 2 strings, ignoring whitespace characters * @param in1 * @param in2 * @return */ public static boolean compareStrings(String in1, String in2) { char c1, c2; int i1 = 0; int i2 = 0; while (i1 < in1.length()) { c1 = in1.charAt(i1 ++); // check if char is whitespace, and skip it if (Character.isWhitespace(c1)) { continue; } while (true) { if (i2 >= in2.length()) { return false; // ran off the end of string 2 } c2 = in2.charAt(i2 ++); if (!Character.isWhitespace(c2)) { break; } } if (c1 != c2) { return false; } } return true; } /** * Compares two XML files and returns true, if both have the same content. Different notations for * empty tags are considered equal. * * @param filename1 * Filename of the first XML file. * @param filename2 * Filename of the second XML file. * @return * @throws IOException */ public static boolean compareXML(String filename1, String filename2) throws IOException { File file1 = null; File file2 = null; String s1 = null; String s2 = null; ByteArrayInputStream bais1 = null; ByteArrayInputStream bais2 = null; try { file1 = new File(filename1); file2 = new File(filename2); // read files into strings s1 = file2String(file1); s2 = file2String(file2); // replace empty tags with short notation s1 = shortenEmptyTags(s1, filename1); s2 = shortenEmptyTags(s2, filename2); // create input streams from resulting XML strings bais1 = new ByteArrayInputStream(s1.getBytes()); bais2 = new ByteArrayInputStream(s2.getBytes()); // compare the two XML strings return compare(bais1, bais2); } finally { bais1.close(); bais2.close(); } } /** * Compares two files and returns true, if both have the same content, after * filtering using the supplied Pattern. * In addition, * \r\n is normalized to \n, * multiple spaces and tabs are normalized to a single space * * @param filename1 * Filename of the first XML file. * @param filename2 * Filename of the second XML file. * @param pattern * an instance of Pattern which matches all substrings which should be filtered out of the match * @return * @throws IOException */ public static boolean compareWithFilter(String filename1, String filename2, Pattern pattern) throws IOException { File file1 = null; File file2 = null; String s1 = null; String s2 = null; file1 = new File(filename1); file2 = new File(filename2); // read files into strings s1 = file2String(file1); s2 = file2String(file2); return compareStringsWithFilter(s1, s2, pattern); } // match at least 2 spaces private static final Pattern multipleWhiteSpace = Pattern.compile("[ \\t]{2,}"); // match nl space nl private static final Pattern emptyLinePattern = Pattern.compile("(?m)^ $"); // match 2 or more nl's in a row private static final Pattern multipleNlPattern = Pattern.compile("\\n{2,}"); /** * Compare 2 strings, showing where they differ in output to system.out, after * doing filtering: * normalize cr nl to nl * normalize to * normalize by applying supplied Pattern and deleting anything it matches * normalize by converting all 2 or more spaces/tabs to just 1 space * @param s1 * @param s2 * @param pattern * @return */ public static boolean compareStringsWithFilter(String s1, String s2, Pattern pattern) { // apply cr + nl --> nl s1 = crnlPattern.matcher(s1).replaceAll(""); s2 = crnlPattern.matcher(s2).replaceAll(""); // apply empty xml tag conversion s1 = emptyTagPattern.matcher(s1).replaceAll("<$2/>"); s2 = emptyTagPattern.matcher(s2).replaceAll("<$2/>"); // apply filter s1 = pattern.matcher(s1).replaceAll(""); s2 = pattern.matcher(s2).replaceAll(""); // ignore different white space outside of strings s1 = multipleWhiteSpace.matcher(s1).replaceAll(" "); s2 = multipleWhiteSpace.matcher(s2).replaceAll(" "); // apply nl + spaces + nl -> nl nl s1 = emptyLinePattern.matcher(s1).replaceAll(""); s2 = emptyLinePattern.matcher(s2).replaceAll(""); // apply nl nl -> nl s1 = multipleNlPattern.matcher(s1).replaceAll("\n"); s2 = multipleNlPattern.matcher(s2).replaceAll("\n"); // apply get rid of trailing nl s1 = removeTrailingNl(s1); s2 = removeTrailingNl(s2); return compareStringsWithMsg(s1, s2); } private static String removeTrailingNl(String s) { int i = s.length() - 1; if (i >= 0 && s.charAt(i) == '\n') { return s.substring(0, i); } return s; } /** * Compare two strings, give message indicating where they miscompare, including * approx 10 chars before and after the first miscompare, for context * @param s1 first string to compare * @param s2 second string to compare * @return true if strings have the same charactersS */ public static boolean compareStringsWithMsg(String s1, String s2) { final int maxI = Math.min(s1.length(), s2.length()); for (int i = 0; i < maxI; i++) { if (s1.charAt(i) != s2.charAt(i)) { System.out.println("Error: strings differ starting at char: " + i); System.out.println("Error: string 1 = " + s1.substring(Math.max(0, i-100), Math.min(s1.length(), i+100))); System.out.println("Error: string 2 = " + s2.substring(Math.max(0, i-100), Math.min(s2.length(), i+100))); return false; } } if (s1.length() != s2.length()) { System.out.println("Error: strings are different length"); System.out.println(" s1 length = " + s1.length() + "; s2 length = " + s2.length()); return false; } return true; } /** * Helper method that replaces empty XML tags in long notation with the corresponding short form. * * @param xml * The XML file where the empty tags are to be replaced as string. * @return The XML file with short empty tags as string. */ private static String shortenEmptyTags(String xml, String filename) { Matcher matcher = emptyTagPattern.matcher(xml); StringBuffer result = new StringBuffer(); StringBuffer sb = null; String replacement = null; boolean replaced = false; // find and replace while (matcher.find()) { sb = new StringBuffer(); sb.append("<").append(matcher.group(2)).append("/>"); replacement = sb.toString(); matcher.appendReplacement(result, replacement); replaced = true; } matcher.appendTail(result); // notify that files have been changed in memory if (replaced) { System.out.println("In file \"" + filename + "\" empty tags have been transformed from long to short notation in memory!"); } return result.toString(); } /** * Read the contents of a file into a string, using the default platform encoding. * * @param file * The file to be read in. * @return String The contents of the file. * @throws IOException * Various I/O errors. ' * * TODO: This is duplicated from org.apache.uima.internal.util.FileUtils in the uimaj-core * package. We can't have a compile dependency on uimaj-core since that introduces a cycle. Not * sure what the best way of handling this is. */ public static String file2String(File file) throws IOException { return reader2String( new FileReader(file), (int) file.length()); } /** * Read a bufferedReader into a string, using the default platform encoding. * * @param reader to be read in * @param bufSize - size of stream, in bytes. Size in chars is <= size in bytes, because * chars take 1 or more bytes to encode. * @return String The contents of the stream. * @throws IOException * Various I/O errors. * * TODO: This is duplicated from org.apache.uima.internal.util.FileUtils in the uimaj-core * package. We can't have a compile dependency on uimaj-core since that introduces a cycle. Not * sure what the best way of handling this is. */ public static String reader2String(Reader reader, int bufSize) throws IOException { char[] buf = new char[bufSize]; int read_so_far = 0; try { while (read_so_far < bufSize) { int count = reader.read(buf, read_so_far, bufSize - read_so_far); if (0 > count) { break; } read_so_far += count; } } finally { reader.close(); } return new String(buf, 0, read_so_far); } } uimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/JUnitExtension.java0000644000175000017500000000376411665471262033173 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import junit.framework.Assert; /** * Contains static convenience methods for using the UIMA JUnit extensions. * */ public class JUnitExtension { public static File getFile(String aRelativeFilePath) { URL url = JUnitExtension.class.getClassLoader().getResource(aRelativeFilePath); File file = null; if (url != null) { try { String fileURL = URLDecoder.decode(url.getFile(), "UTF-8"); file = new File(fileURL); } catch (UnsupportedEncodingException ex) { return null; } } return file; } public static URL getURL(String aRelativeFilePath) { return JUnitExtension.class.getClassLoader().getResource(aRelativeFilePath); } public static void handleException(Exception e) throws Exception { // check command line setting if (System.getProperty("isCommandLine", "false").equals("true")) { // print exception ExceptionPrinter.printException(e); Assert.fail(e.getMessage()); } else { // thow exception to the JUnit framework throw e; } } } uimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/TeePrintStream.java0000644000175000017500000001200511665471262033137 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; import java.io.PrintStream; /** * TeePrintStream duplicates a PrintStream. * */ public class TeePrintStream extends PrintStream { PrintStream original; PrintStream teeStream; /** * Initialize the two print streams. * * @param original * original stream * @param teeStream * dublicated stream */ public TeePrintStream(PrintStream original, PrintStream teeStream) { super(original); this.original = original; this.teeStream = teeStream; } /** * @see java.io.PrintStream#checkError() */ public boolean checkError() { if (this.original.checkError() && this.teeStream.checkError()) return true; else return false; } /** * @see java.io.OutputStream#close() */ public void close() { this.original.close(); this.teeStream.close(); } /** * @see java.io.OutputStream#flush() */ public void flush() { this.original.flush(); this.teeStream.flush(); } /** * @see java.io.PrintStream#print(boolean) */ public void print(boolean b) { this.original.print(b); this.teeStream.print(b); } /** * @see java.io.PrintStream#print(char) */ public void print(char c) { this.original.print(c); this.teeStream.print(c); } /** * @see java.io.PrintStream#print(char[]) */ public void print(char[] s) { this.original.print(s); this.teeStream.print(s); } /** * @see java.io.PrintStream#print(double) */ public void print(double d) { this.original.print(d); this.teeStream.print(d); } /** * @see java.io.PrintStream#print(float) */ public void print(float f) { this.original.print(f); this.teeStream.print(f); } /** * @see java.io.PrintStream#print(int) */ public void print(int i) { this.original.print(i); this.teeStream.print(i); } /** * @see java.io.PrintStream#print(long) */ public void print(long l) { this.original.print(l); this.teeStream.print(l); } /** * @see java.io.PrintStream#print(java.lang.Object) */ public void print(Object obj) { this.original.print(obj); this.teeStream.print(obj); } /** * @see java.io.PrintStream#print(java.lang.String) */ public void print(String s) { this.original.print(s); this.teeStream.print(s); } /** * @see java.io.PrintStream#println() */ public void println() { this.original.println(); this.teeStream.println(); } /** * @see java.io.PrintStream#println(boolean) */ public void println(boolean x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(char) */ public void println(char x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(char[]) */ public void println(char[] x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(double) */ public void println(double x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(float) */ public void println(float x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(int) */ public void println(int x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(long) */ public void println(long x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(java.lang.Object) */ public void println(Object x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.PrintStream#println(java.lang.String) */ public void println(String x) { this.original.println(x); this.teeStream.println(x); } /** * @see java.io.OutputStream#write(byte[], int, int) */ public void write(byte[] buf, int off, int len) { this.original.write(buf, off, len); this.teeStream.write(buf, off, len); } /** * @see java.io.OutputStream#write(int) */ public void write(int b) { this.original.write(b); this.teeStream.write(b); } } uimaj-2.4.0/uimaj-test-util/src/main/java/org/apache/uima/test/junit_extension/ExceptionPrinter.java0000644000175000017500000000607411665471262033544 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.test.junit_extension; /** * ExceptionPrinter print out an exception with the place where the exception occurs * */ public class ExceptionPrinter { /** * Print out exception stack trace and the place where the exception was thrown. * * @param stackTrace * a exception stack trace * @param message * exception message */ public static void printException(StackTraceElement[] stackTrace, String message) { Throwable ex = new Throwable(); StackTraceElement[] stackTraceElement = ex.getStackTrace(); System.out.println(); System.out.println("Exception occurred:"); /* * System.out.println(stackTraceElement[1].getClassName()+ "." + * stackTraceElement[1].getMethodName() + "(" + stackTraceElement[1].getFileName() + ")"); */ System.out.println("Test file: " + stackTraceElement[1].getFileName()); System.out.println("Test class: " + stackTraceElement[1].getClassName()); System.out.println("Test method: " + stackTraceElement[1].getMethodName() + "()"); System.out.println(); System.out.println("Exception output:"); System.out.println(message); // print stack trace for (int i = 0; i < stackTrace.length; i++) { System.out.println(stackTrace[i].toString()); } } /** * Print out the exception message and where the exception was thrown. * * @param message * exception message */ public static void printException(String message) { Throwable ex = new Throwable(); StackTraceElement[] stackTraceElement = ex.getStackTrace(); System.out.println(); System.out.println("Exception occurred:"); System.out.println("Test file: " + stackTraceElement[1].getFileName()); System.out.println("Test class: " + stackTraceElement[1].getClassName()); System.out.println("Test method: " + stackTraceElement[1].getMethodName() + "()"); System.out.println(); System.out.println("Exception output:"); // print exception message System.out.println(message); } /** * Print out exception stack trace and the place where the exception was thrown. * * @param ex * exception */ public static void printException(Exception ex) { printException(ex.getStackTrace(), ex.getMessage()); } } uimaj-2.4.0/uimaj-test-util/src/test/0000755000175000017500000000000011665471262017333 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-test-util/src/test/java/0000755000175000017500000000000011665471262020254 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/0000755000175000017500000000000011665472310016232 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/pom.xml0000644000175000017500000000507311665471546017566 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uima-docbook-tools pom 2.4.0 Apache UIMA SDK Documentation - tools ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tools scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tools http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tools ${project.artifactId} tools uimaj-2.4.0/uima-docbook-tools/src/0000755000175000017500000000000011665471326017027 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/0000755000175000017500000000000011665471336020450 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/tools.annotation_viewer.xml0000644000175000017500000000770011665471336026070 0ustar drazzibdrazzib %uimaents; ]> Annotation Viewer The Annotation Viewer is a tool for viewing analysis results that have been saved to your disk as external XML representations of the CAS. These are saved in a particular format called XMI. In the UIMA SDK, XML versions of CASes can be generated by: Running the Document Analyzer (see , which saves an XML representations of the CAS to the specified output directory. Running a Collection Processing Engine that includes the XMI Writer CAS Consumer (examples/descriptors/cas_consumer/XmiWriterCasConsumer.xml). Explicitly creating XML representations of the CAS from your own application using the org.apache.uima.cas.impl.XMISerializer class. The best way to learn how to do this is to look at the example code for the XMI Writer CAS Consumer, located in examples/src/org/apache/uima/examples/xmi/XmiWriterCasConsumer.java. An older form of a different XML format for the CAS is also provided mainly for backwards compatibility. This form is called XCAS, and you can see examples of its use in examples/src/org/apache/uima/examples/cpe/XCasWriterCasConsumer.java. The Annotation Viewer only shows CAS views where the Sofa data type is a String. You can run the Annotation Viewer by executing the annotationViewer shell script located in the bin directory of the UIMA SDK or the "UIMA Annotation Viewer" Eclipse run configuration in the uimaj-examples project. This will open the following window: Screenshot of annotationViewer Select an input directory (which must contain XMI files), and the descriptor for the AE that produced the Analysis (which is needed to get the type system for the analysis). Then press the View button. This will bring up a dialog where you can select a viewing format and double-click on a document to view it. This dialog is the same as the one that is described in . uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.pear.installer.xml0000644000175000017500000001550111665471336025256 0ustar drazzibdrazzib %uimaents; ]> PEAR Installer User's Guide PEAR (Processing Engine ARchive) is a new standard for packaging UIMA compliant components. This standard defines several service elements that should be included in the archive package to enable automated installation of the encapsulated UIMA component. The major PEAR service element is an XML Installation Descriptor that specifies installation platform, component attributes, custom installation procedures and environment variables. The installation of a UIMA compliant component includes 2 steps: (1) installation of the component code and resources in a local file system, and (2) verification of the serviceability of the installed component. Installation of the component code and resources involves extracting component files from the archive (PEAR) package in a designated directory and localizing file references in component descriptors and other configuration files. Verification of the component serviceability is accomplished with the help of standard UIMA mechanisms for instantiating analysis engines. PEAR Installer GUI There are two versions of the PEAR Installer. One is an interactive, GUI-based application which puts up a panel asking for the parameters of the installation; the other is a command line interface version where you pass the parameters needed on the command line itself. To launch the GUI version of the PEAR Installer, use the script in the UIMA bin directory: runPearInstaller.bat or runPearInstaller.sh. The command line is launched using runPearInstallerCli.cmd or runPearInstallerCli.sh. The PEAR Installer installs UIMA compliant components (analysis engines) from PEAR packages in a local file system. To install a desired UIMA component the user needs to select the appropriate PEAR file in a local file system and specify the installation directory (optional). If no installation directory is specified, the PEAR file is installed to the current working directory. By default the PEAR packages are not installed directly to the specified installation directory. For each PEAR a subdirectory with the name of the PEAR's ID is created where the PEAR package is installed to. If the PEAR installation directory already exists, the old content is automatically deleted before the new content is installed. During the component installation the user can read messages printed by the installation program in the message area of the application window. If the installation fails, appropriate error message is printed to help identifying and fixing the problem. After the desired UIMA component is successfully installed, the PEAR Installer allows testing this component in the CAS Visual Debugger (CVD) application, which is provided with the UIMA package. The CVD application will load your UIMA component using its XML descriptor file. If the component is loaded successfully, you'll be able to run it either with sample documents provided in the <UIMA_HOME>/examples/data directory, or with any other sample documents. See for more information about the CVD application. Running your component in the CVD application helps to make sure the component will run in other UIMA applications. If the CVD application fails to load or run your component, or throws an exception, you can find more information about the problem in the uima.log file in the current working directory. The log file can be viewed with the CVD. PEAR Installer creates a file named setenv.txt in the <component_root>/metadata directory. This file contains environment variables required to run your component in any UIMA application. It also creates a PEAR descriptor (see also ) file named <componentID>_pear.xml in the <component_root> directory that can be used to directly run the installed pear file in your application. The metadata/setenv.txt is not read by the UIMA framework anywhere. It's there for use by non-UIMA application code if that code wants to set environment variables. The metadata/setenv.txt is just a "convenience" file duplicating what's in the xml. The setenv.txt file has 2 special variables: the CLASSPATH and the PATH. The CLASSPATH is computed from any supplied CLASSPATH environment variable, plus the jars that are configured in the PEAR structure, including subcomponents. The PATH is similarly computed, using any supplied PATH environment variable plus it includes the "bin" subdirectory of the PEAR structure, if it exists. The command line version of the PEAR installer has one required argument: the path to the PEAR file being installed. A second argument can specify the installation directory (default is the current working directory). An optional argument, one of "-c" or "-check" or "-verify", causes verification to be done after installation, as described above. uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.cpe.xml0000644000175000017500000002507411665471336023110 0ustar drazzibdrazzib %uimaents; ]> Collection Processing Engine Configurator User's Guide CPE Configurator User's Guide A Collection Processing Engine (CPE) processes collections of artifacts (documents) through the combination of the following components: a Collection Reader, Analysis Engines, and CAS Consumers. Earlier versions of UIMA supported another component, the CAS Initializer, but this component is now deprecated in UIMA Version 2. The Collection Processing Engine Configurator(CPE Configurator) is a graphical tool that allows you to assemble and run CPEs. For an introduction to Collection Processing Engine concepts, including developing the components that make up a CPE, read . This chapter is a user's guide for using the CPE Configurator tool, and does not describe UIMA's Collection Processing Architecture itself.
Limitations of the CPE Configurator The CPE Configurator only supports basic CPE configurations. It only supports Integrated deployments (although it will connect to remotes if particular CAS Processors are specified with remote service descriptors). It doesn't support configuration of the error handling. It doesn't support Sofa Mappings; it assumes all Single-View components are operating with the _InitialView Sofa. Multi-View components will not have their names mapped. It sets up a fixed-sized CAS Pool. To set these additional options, you must edit the CPE Descriptor XML file directly. See for the syntax. You may then open the CPE Descriptor in the CPE Configurator and run it. The changes you applied to the CPE Descriptor will be respected, although you will not be able to see them or edit them from the GUI.
Starting the CPE Configurator The CPE Configurator tool can be run using the cpeGui shell script, which is located in the bin directory of the UIMA SDK. If you've installed the example Eclipse project (see , you can also run it using the UIMA CPE GUI run configuration provided in that project. If you are planning to build a CPE using components other than the examples included in the UIMA SDK, you will first need to update your CLASSPATH environment variable to include the classes needed by these components. When you first start the CPE Configurator, you will see the main window shown here: CPE Configurator main GUI window
Selecting Component Descriptors The CPE Configurator's main window is divided into three sections, one each for the Collection Reader, Analysis Engines, and CAS Consumers. There is also a fourth pane, for the CAS Initializer, but it is hidden by default. To enable it click the View → CAS Initializer Panel menu item. In each section of the CPE Configurator, you can select the component(s) you want to use by browsing to (or typing the location of) their XML descriptors. You must select a Collection Reader, and at least one Analysis Engine or CAS Consumer. When you select a descriptor, the configuration parameters that are defined in that descriptor will then be displayed in the GUI; these can be modified to override the values present in the descriptor. For example, the screen shot below shows the CPE Configurator after the following components have been chosen: examples/descriptors/collectionReader/FileSystemCollectionReader.xml examples/descriptors/analysis_engine/NamesAndPersonTitles_TAE.xml examples/descriptors/cas_consumer/XmiWriterCasConsumer.xml CPE Configurator after components chosen
Running a Collection Processing Engine After selecting each of the components and providing configuration settings, click the play (forward arrow) button at the bottom of the screen to begin processing. A progress bar should be displayed in the lower left corner. (Note that the progress bar will not begin to move until all components have completed their initialization, which may take several seconds.) Once processing has begun, the pause and stop buttons become enabled. If an error occurs, you will be informed by an error dialog. If processing completes successfully, you will be presented with a performance report.
The File Menu The CPE Configurator's File Menu has the following options: Open CPE Descriptor Save CPE Descriptor Save Options (submenu) Refresh Descriptors from File System Clear All Exit Open CPE Descriptor will allow you to select a CPE Descriptor file from disk, and will read in that CPE Descriptor and configure the GUI appropriately. Save CPE Descriptor will create a CPE Descriptor file that defines the CPE you have constructed. This CPE Descriptor will identify the components that constitute the CPE, as well as the configuration settings you have specified for each of these components. Later, you can use Open CPE Descriptor to restore the CPE Configurator to the state. Also, CPE Descriptors can be used to easily run a CPE from a Java program – see . CPE Descriptors also allow specifying operational parameters, such as error handling options that are not currently available for configuration through the CPE Configurator. For more information on manually creating a CPE Descriptor, see . The Save Options submenu has one item, "Use <import>". If this item is checked (the default), saved CPE descriptors will use the <import> syntax to refer to their component descriptors. If unchecked, the older <include> syntax will be used for new components that you add to your CPE using the GUI. (However, if you open a CPE descriptor that used <import>, these imports will not be replaced.) Refresh Descriptors from File System will reload all descriptors from disk. This is useful if you have made a change to the descriptor outside of the CPE Configurator, and want to refresh the display. Clear All will reset the CPE Configurator to its initial state, with no components selected. Exit will close the CPE Configurator. If you have unsaved changes, you will be prompted as to whether you would like to save them to a CPE Descriptor file. If you do not save them, they will be lost. When you restart the CPE Configurator, it will automatically reload the last CPE descriptor file that you were working with.
The Help Menu The CPE Configurator's Help menu provides About information and some very simple instructions on how to use the tool.
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.pear.packager.maven.xml0000644000175000017500000003537211665471336026153 0ustar drazzibdrazzib %uimaents; ]> The PEAR Packaging Maven Plugin UIMA includes a Maven plugin that supports creating PEAR packages using Maven. When configured for a project, it assumes that the project has the PEAR layout, and will copy the standard directories that are part of a PEAR structure under the project root into the PEAR, excluding files that start with a period ("."). It also will put the Jar that is built for the project into the lib/ directory and include it first on the generated classpath. The classpath that is generated for this includes the artifact's Jar first, any user specified entries second (in the order they are specified), and finally, entries for all Jars found in the lib/ directory (in some arbitrary order).
Specifying the PEAR Packaging Maven Plugin To use the PEAR Packaging Plugin within a Maven build, the plugin must be added to the plugins section of the Maven POM as shown below: ... org.apache.uima PearPackagingMavenPlugin true package $main_root/lib/sample.jar desc/${artifactId}.xml ${artifactId} $main_root/resources package ... ]]> To configure the plugin with the specific settings of a PEAR package, the <configuration> element section is used. This sections contains all parameters that are used by the PEAR Packaging Plugin to package the right content and set the specific PEAR package settings. The details about each parameter and how it is used is shown below: <classpath> - This element specifies the classpath settings for the PEAR component. The Jar artifact that is built during the current Maven build is automatically added to the PEAR classpath settings and does not have to be added manually. In addition, all Jars in the lib directory and its subdirectories will be added to the generated classpath when the PEAR is installed. Use $main_root variables to refer to libraries inside the PEAR package. For more details about PEAR packaging please refer to the Apache UIMA PEAR documentation. <mainComponentDesc> - This element specifies the relative path to the main component descriptor that should be used to run the PEAR content. The path must be relative to the project root. A good default to use is desc/${artifactId}.xml. <componentID> - This element specifies the PEAR package component ID. A good default to use is ${artifactId}. <datapath> - This element specifies the PEAR package UIMA datapath settings. If no datapath settings are necessary, this element can be omitted. Use $main_root variables to refer libraries inside the PEAR package. For more details about PEAR packaging please refer to the Apache UIMA PEAR documentation. For most Maven projects it is sufficient to specify the parameters described above. In some cases, for more complex projects, it may be necessary to specify some additional configuration parameters. These parameters are listed below with the default values that are used if they are not added to the configuration section shown above. <mainComponentDir> - This element specifies the main component directory where the UIMA nature is applied. By default this parameter points to the project root directory - ${basedir}. <targetDir> - This element specifies the target directory where the result of the plugin are written to. By default this parameters points to the default Maven output directory - ${basedir}/target
Automatically including dependencies A key concept in PEARs is that they allow specifying other Jars in the classpath. You can optionally include these Jars within the PEAR package. The PEAR Packaging Plugin does not take care of automatically adding these Jars (that the PEAR might depend on) to the PEAR archive. However, this behavior can be manually added to your Maven POM. The following two build plugins hook into the build cycle and insure that all runtime dependencies are included in the PEAR file. The dependencies will be automatically included in the PEAR file using this procedure; the pear install process also will automatically adds all files in the lib directory (and sub directories) to the classpath. The maven-dependency-plugin copies the runtime dependencies of the PEAR into the lib folder, which is where the PEAR packaging plugin expects them. ... org.apache.maven.plugins maven-dependency-plugin copy-dependencies package copy-dependencies ${basedir}/lib true runtime ... ]]> The second Maven plug-in hooks into the clean phase of the build life-cycle, and deletes the lib folder. With this approach, the lib folder is automatically created, populated, and removed during the build process. Therefore it should not go into the source control system and neither should you manually place any jars in there. ... maven-antrun-plugin CleanLib clean run ... ]]>
Installing The PEAR Packaging Plugin If you specify the Apache Incubating Repository as one of the repositories for your maven configuration, then the uima-pear-maven-plugin.jar will be automatically fetched when needed. This is typically specified in the POM, the Maven .settings file or in a parent POM, using this format: apache-incubating-repository http://people.apache.org/repo/m2-incubating-repository never ]]> Otherwise, the uima-pear-maven-plugin.jar file must be manually installed into your local repository. See . The information you need to do this is: -DgroupId=org.apache.uima -DartifactId=PearPackagingMavenPlugin -Dversion=2.3.0-incubating (change this to the version you want) -Dpackaging=jar -DgeneratePom=true
Running from the command line The pear packager can be run as a maven command. To enable this, you have to add the following to your maven settings file: ... org.apache.uima ]]> To invoke the pear packager using maven, use the command: ]]> The settings are the same ones used in the configuration above, specified as -D variables where the variable name is pear.parameterName. For example:
Building the PEAR Packaging Plugin From Source The plugin code is available in the Apache subversion repository at: . Use the following command line to build it (you will need the Maven build tool, available from Apache): mvn install]]> This maven command will build the tool and install it in your local maven repository, making it available for use by other maven POMs. The plugin version number is displayed at the end of the Maven build as shown in the example below. For this example, the plugin version number is: 2.3.0-incubating
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.caseditor.xml0000644000175000017500000005150411665471336024313 0ustar drazzibdrazzib %uimaents; ]> Cas Editor User's Guide Cas Editor User's Guide
Introduction The CAS Editor is an Eclipse based annotation tool which supports manual and automatic annotation (via running UIMA annotators) of CASes stored in files. Currently only text-based CAS are supported. The CAS Editor can visualize and edit all feature structures. Feature Structures which are annotations can additionally be viewed and edited directly on text.
Launching the Cas Editor To open a CAS in the Cas Editor it needs a compatible type system and styling information which specify how to display the types. The styling information is created automatically by the Cas Editor; but the type system file must be provided by the user. A CAS in the xmi or xcas format can simply be opened by clicking on it, like a text file is opened with the Eclipse text editor.
Specifying a type system The Cas Editor expects a type system file at the root of the project named TypeSystem.xml. If a type system cannot be found, this message is shown: No type system available for the opened CAS. If the type system file does not exist in this location you can point the Cas Editor to a specific type system file. You can also change the default type system location in the properties page of the Eclipse project. To do that right click the project, select Properties and go to the UIMA Type System tab, and specify the default location for the type system file.
After the Cas Editor is opened switch to the Cas Editor Perspective to see all the Cas Editor related views.
Annotation editor The annotation editor shows the text with annotations and provides different views to show aspects of the CAS.
Editor After the editor is open it shows the default sofa of the CAS. (Displaying another sofa is right now not possible.) The editor has an associated, changeable CAS Type. This type is called the editor "mode". By default the editor only shows annotation of this type. Actions and views are sensitive to this mode. The next screen shows the display, where the mode is set to "Person": To change the mode for the editor, use the "Mode" menu in the editor context menu. To open the context menu right click somewhere on the text. The current mode is displayed in the status line at the bottom and in the Style View. It's possible to work with more than one annotation type at a time; the mode just selects the default annotation type which can be marked with the fewest keystrokes. To show annotations of other types, use the "Show" menu in the context menu. Alternatively, you may select the annotation types to be shown in the Style View. The editor will show the additional selected types. The annotation renderer and rendering layer can be changed in the Properties dialog. After the change all editors which share the same type system will be updated. The editor automatically selects annotations of the editor mode type that are near the cursor. This selection is then synchronized or displayed in other views. To create an annotation manually using the editor, mark a piece of text and then press the enter key. This creates an annotation of the type of the editor mode, having bounds corresponding to the selection. You can also use the "Quick Annotate" action from the context menu. It is also possible to choose the annotation type; press shift + enter (smart insert) or click on "Annotate" in the context menu for this. A dialog will ask for the annotation type to create; either select the desired type or use the associated key shortcut. In the screen shot below, pressing the "p" key will create a Person annotation for "Obama". To delete an annotation, select it and press the delete key. Only annotations of the editor mode can be deleted with this method. To delete non-editor mode annotations use the Outline View. For annotation projects you can change the font size in the editor. The default font size is 13. To change this open the Eclipse preference dialog, go to "UIMA Annotation Editor".
Configure annotation styling The Cas Editor can visualize the annotations in multiple highlighting colors and with different annotation drawing styles. The annotation styling is defined per type system. When its changed, the appearance changes in all opened editors sharing a type system. The styling is initialized with a unique color for every annotation type and every annotation is drawn with Squiggles annotation style. You may adjust the annotation styles and coloring depending on the project needs. The Cas Editor offers a property page to edit the styling. To open this property page click on the "Properties" button in the Styles view. The property page can be seen below. By clicking on one of the annotation types, the color, drawing style and drawing layer can be edited on the right side. The annotations can be visualized with one the following annotation stlyes:
Style Table Style Sample Description BACKGROUND The background is drawn in the annotation color. TEXT_COLOR The text is drawn in the annotation color. TOKEN The token type assumes that token annotation are always separated by a whitespace. Only if they are not separated by a whitespace a vertical line is drawn to display the two token annotations. The image on the left actually contains three annotations, one for "Mr", "." and "Obama". SQUIGGLES Squiggles are drawen under the annotation in the annotation color. BOX A box in the annotation color is drawn around the annotation. UNDERLINE A line in the annotation color is drawen below the annotation. BRACKET An opening bracket is drawn around the first character of the annotation and a closing bracket is drawn around the last character of the annotation.
The Cas Editor can draw the annotations in different layers. If the spans of two annotations overlap the annotation which is in a higher layer is drawn over annotations in a lower layer. Depending on the drawing style it is possible to see both annotations. The drawing order is defined by the layer number, layer 0 is drawn first, then layer 1 and so on. If annotations in the same layer overlap its not defined which annotation type is drawn first.
CAS view support The Annotation Editor can only display text Sofa CAS views. Displaying CAS views with Sofas of different types is not possible and will show an editor page to switch back to another CAS view. The Edit and Feature Structure Browser views are still available and might be used to edit Feature Structures which belong to the CAS view. To switch to another CAS view, right click in the editor to open the context menu and choose "CAS Views" and the view the editor should switch to.
Outline view The outline view gives an overview of the annoations which are shown in the editor. The annotation are grouped by type. There are actions to increase or decrease the bounds of the selected annotation. There is also an action to merge selected annotations. The outline has second view mode where only annotations of the current editor mode are shown. The style can be switched in the view menu, to a style where it only shows the annotations which belong to the current editor mode.
Edit Views The Edit Views show details about the currently selected annotations or feature structures. It is possible to change primitive values in this view. Referenced feature structures can be created and deleted, including arrays. To link a feature structure with other feature structures, it can be pinned to the edit view. This means that it does not change if the selection changes.
FeatureStructure View The FeatureStructure View lists all feature structures of a specified type. The type is selected in the type combobox. It's possible to create and delete feature structures of every type.
Implementing a custom Cas Editor View Custom Cas Editor views can be added, to rapidly create, access and/or change Feature Structures in the CAS. While the Annotation Editor and its views offer support for general viewing and editing, accessing and editing things in the CAS can be streamlined using a custom Cas Editor. A custom Cas Editor view can be programmed to use a particular type system and optimized to quickly change or show something. Annotation projects often need to track the annotation status of a CAS where a user needs to mark which parts have been annotated or corrected. To do this with the Cas Editor a user would need to use the Feature Structure Browser view to select the Feature Structure and then edit it inside the Edit view. A custom Cas Editor view could directly select and show the Feature Structure and offer a tailored user interface to change the annotation status. Some features such as the name of the annotator could even be automatically filled in. The creation of Feature Structures which are linked to existing annotations or Feature Structures is usually difficult with the standard views. A custom view which can make assumptions about the type system is usually needed to do this efficiently.
Annotation Status View Sample The Cas Editor provides the CasEditorView class as a base class for views which need to access the CAS which is opened in the current editor. It shows a "view not available" message when the current editor does not show a CAS, no editor is opened at all or the current CAS view is incompatible with the view. The following snippet shows how it is usually implemented: public class AnnotationStatusView extends CasEditorView { public AnnotationStatusView() { super("The Annotation Status View is currently not available."); } @Override protected IPageBookViewPage doCreatePage(ICasEditor editor) { ICasDocument document = editor.getDocument(); if (document != null) { return new AnnotationStatusViewPage(editor); } return null; } } The doCreatePage method is called to create the actual view page. If the document is null the editor failed to load a document and is showing an error message. In the case the document is not null but the CAS view is incompatible the method should return null to indicate that it has nothing to show. In this case the "not available" message is displayed. The next step is to implement the AnnotationStatusViewPage. That is the page which gets the CAS as input and need to provide the user with a ui to change the Annotation Status Feature Structure. public class AnnotationStatusViewPage extends Page { private ICasEditor editor; AnnotationStatusViewPage(ICasEditor editor) { this.editor = editor; } ... public void createControl(Composite parent) { // create ui elements here ... ICasDocument document = editor.getDocument(); CAS cas = document.getCAS(); // Retrieve Annotation Status FS from CAS // and initalize the ui elements with it FeatureStructre statusFS; ... // Add event listeners to the ui element // to save an update to the CAS // and to advertise a change ... // Send update event document.update(statusFS); } } The above code sketches out how a typical view page is implemented. The CAS can be directly used to access any Feature Structures or annotations stored in it. When something is modified added/removed/changed that must be advertised via the ICasDocument object. It has multiple notification methods which send an event so that other views can be updated. The view itself can also register a listener to receive CAS change events.
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.cvd.xml0000644000175000017500000010322311665471336023106 0ustar drazzibdrazzib %uimaents; ]> CAS Visual Debugger
Introduction The CAS Visual Debugger is a tool to run text analysis engines in UIMA and view the results. The tool is implemented as a stand-alone GUI tool using Java's Swing library. This is a developer's tool.  It is intended to support you in writing text analysis annotators for UIMA (Unstructured Information Management Architecture).  As a development tool, the emphasis is not so much on pretty pictures, but rather on navigability.  It is intended to show you all the information you need, and show it to you quickly (at least on a fast machine ;-). The main purpose of this application is to let you browse all the data that was created when you ran an analysis engine over some text.  The display mimics the access methods you have in the CAS API in terms of indexes, types, feature structures and feature values. As in the CAS, there is special support for annotations.  Clicking on an annotation will select the corresponding text, and conversely, you can display all annotations that cover a given position in the text. This will be explained in more detail in the section on the main display area. As usual, the graphics in this manual are for illustrative purposes and may not look 100% like the actual version of CVD you are running. This depends on your operating system, your version of Java, and a variety of other factors.
Running CVD You will usually want to start CVD from the command line, or from Eclipse. To start CVD from the command line, you minimally need the uima-core and uima-tools jars. Below is a sample command line for sh and its offspring. java -cp ${UIMA_HOME}/lib/uima-core.jar:${UIMA_HOME}/lib/uima-tools.jar org.apache.uima.tools.cvd.CVD However, there is no need to type this. The ${UIMA_HOME}/bin directory contains a cvd.sh and cvd.bat file for Unix/Linux/MacOS and Windows, respectively. In Eclipse, you have a ready to use launch configuration available when you have installed the UIMA sample project (see ). Below is a screenshot of the the Eclipse Run dialog with the CVD run configuration selected. Eclipse run dialog with CVD selected
Command line parameters You can provide some command line parameters to influence the startup behavior of CVD. For example, if you want to run a certain analysis engine on a certain text over and over again (for debugging, say), you can make CVD load the annotator and text at startup and execute the annotator. Here's a list of the supported command line options. Command line options Option Description -text <textFile> Loads the text file <textFile> -desc <descriptorFile> Loads the descriptor <descriptorFile> -exec Runs the pre-loaded annotator; only allowed in conjunction with -desc -datapath <datapath> Sets the data path to <datapath> -ini <iniFile> Makes CVD use alternative ini file <textFile> (default is ~/annotViewer.pref) -lookandfeel <lnfClass> Uses alternative look-and-feel <lnfClass>
Error Handling On encountering an error, CVD will pop up an error dialog with a short, usually incomprehensible message.  Often, the error message will claim that there is more information available in the log file, and sometimes, this is actually true; so do go and check the log.  You can view the log file by selecting the appropriate item in the "Tools" menu. Sample error dialog
Preferences File The program will attempt to read on startup and save on exit a file called annotViewer.pref in your home directory.  This file contains information about choices you made while running the program: directories (such as where your data files are) and window sizes.  These settings will be used the next time you use the program. There is no user control over this process, but the file format is reasonably transparent, in case you feel like changing it.  Note, however, that the file will be overwritten every time you exit the program. If you use CVD for several projects, it may be convenient to use a different ini files for each project. You can specify the ini file CVD should use with the -ini <iniFile> parameter on the command line.
The Menus We give a brief description of the various menus. All menu items come with mnemonics (e.g., Alt-F X will exit the program). In addition, some menu items have their own keyboard accelerators that you can use anywhere in the program. For example, Ctrl-S will save the text you've been editing.
The File Menu The File menu lets you load, create and save text, load and save color settings, and import and export the XCAS format. Here's a screenshot. The File menu Below is a list of the menu items, together with an explanation. New Text... Clears the text area. Text you type is written to an anonymous buffer. You can use "Save Text As..." to save the text you typed to a file. Note: whenever you modify the text, be it through typing, loading a file or using the "New Text..." menu item, previous analysis results will be lost. Since the previous analysis is specific to the text, modifying the text invalidates the analysis. Open Text File Loads a new text file into the viewer.  The next time you run an analysis engine, it will run the text you loaded last.  Depending on the annotator you're using, the program may run slow with very large text files, so you may want to experiment. Save Text File Saves the currently open text file. If no file is currently loaded (either because you haven't loaded a file, or you've used the "New Text..." menu item), this menu item is disabled (and Ctrl-S will do nothing). Save Text As... Save the text to a file of your choosing. This can be an existing file, which is then overwritten, or it can be a new file that you're creating. Change Code Page Allows you to change the code page that is used to load and save text files. If you're sure the text you're loading is in ASCII or one of the 8-bit extensions such as ISO-8859-1 (ISO Latin1), there is probably nothing you need to do. Just load the text and look at the display. If you see no funny characters or square boxes, chances are your selected code page is compatible with your text file. Note that the code page setting is also in effect when you save files. You can observe the effects with a hex editor or by just looking at the file size. For example, if you save the default text This is where the text goes. to a file on Windows using the default code page, the size of the file will be 28 bytes. If you now change the code page to UTF-16 and save the file again, the file size will be 58 bytes: two bytes for each character, plus two bytes for the byte-order mark. Now switch the code page back to the default Windows code page and reload the UTF-16 file to see the difference in the editor. CVD will display all code pages that are available in the JVM you're running it on. The first code page in the list is the default code page of your system. This is also CVD's default if you don't make a specific choice. Your code page selection will be remembered in CVD's ini file. Load Color Settings Load previously saved color settings from a file (see Tools/Customize Annotation Display).  It is highly recommended that you only load automatically generated files.  Strange things may happen if you try to load the wrong file format. On startup, the program attempts to load the last color settings file that you loaded or saved during a previous session. If you intend to use the same color settings as the last time you ran the program, there is therefore no need to manually load a color settings file. Save Color Settings Save your customized color settings (see Tools/Customize Annotation Display).  The file is a Java properties file, and as such, reasonably transparent.  What is not transparent is the encoding of the colors (integer encoding of 24-bit RGB values), so changing the file by hand is not really recommended. Read Type System File Load a type system file. This allows you to load an XCAS file without having to have access to the corresponding annotator. Write Type System File Create a type system file from the currently loaded type definitions. In addition, you can save the current CAS as a XCAS file (see below). This allows you to later load the type system and XCAS to view the CAS without having to rerun the annotator. Read XMI CAS File Read an XMI CAS file. Important: XMI CAS is a serialization format that serializes a CAS without type system and index information. It is therefore impossible to read in a stand-alone XMI CAS file. XMI CAS files can only be interpreted in the context of an existing type system. Consequently, you need to first load the Analysis Engine that was used to create the XMI file, to be able to load that XMI file. Write XMI CAS File Writes the current analysis out as an XMI CAS file. Read XCAS File Read an XCAS file. Important: XCAS is a serialization format that serializes a CAS without type system and index information. It is therefore impossible to read in a stand-alone XCAS file. XCAS files can only be interpreted in the context of an existing type system. Consequently, you need to load the Analysis Engine that was used to create the XCAS file to be able to load it. Loading a XCAS file without loading the Analysis Engine may produce strange errors. You may get syntax errors on loading the XCAS file, or worse, everything may appear to go smoothly but in reality your CAS may be corrupted. Write XCAS File Writes the current analysis out as an XCAS file. Exit Exits the program. Your preferences will be saved.
The Edit Menu The Edit menu The "Edit" menu provides a standard text editing menu with Cut, Copy and Paste, as well as unlimited Undo. Note that standard keyboard accelerators Ctrl-X, Ctrl-C, Ctrl-V and Ctrl-Z can be used for Cut, Copy, Paste and Undo, respectively. The text area supports other standard keyboard operations such as navigation HOME, Ctrl-HOME etc., as well as marking text with Shift- <ArrowKey>.
The Run Menu The Run menu In the Run menu, you can load and run text analysis engines. Load AE Loads and initializes a text analysis engine. Choosing this menu item will display a file open dialog where you should choose an XML descriptor of a Text Analysis Engine to process the current text.  Even if the analysis engine runs fast, this will take a while, since there is a lot of setup work to do when a new TAE is created.  So be patient. When you develop a new annotator, you will often need to recompile your code. Gladis will not reload your annotator code. When you recompile your code, you need to terminate the GUI and restart it. If you only make changes to the XML descriptor, you don't need to restart the GUI. Simply reload the XML file. Run AE Before you have (successfully) loaded a TAE, this menu item will be disabled. After you have loaded a TAE, it will be enabled, and the name changes according to the name of the TAE you have loaded. For example, if you've loaded "The World's Fastest Parser", you will have a menu item called "Run The World's Fastest Parser". When you choose the item, the TAE is run on whatever text you have currently loaded. After a TAE has run successfully, the index window in the upper left-hand corner of the screen should be updated and show the indexes that were created by this run.  We will have more to say about indexes and what to do with them later. Run AE on CAS This allows you to run an analysis engine on the current CAS. This is useful if you have loaded a CAS from an XCAS file, and would like to run further analysis on it. Run collectionProcessComplete When you select this item, the analysis engine's collectionProcessComplete() method is called. Performance Report After you've run your analysis, you can view a performance report. It will show you where the time went: which component used how much of the processing time. Recently used Collects a list of recently used analysis engines as a short-cut for loading. Language Some annotators do language specific processing. For example, if you run lexical analysis, the results may be quite different depending on what the analysis engine thinks the language of the document is. With this menu item, you can manually set the document language. Alternatively, you can use an automatic language identification annotator. If the analysis engines you're working with are language agnostic, there is no need to set the language.
The tools menu The tools menu contains some assorted utilities, such as the log file viewer. Here you can also set the log level for UIMA. A more detailed description of some of the menu items follows below.
View Type System Brings up a new window that displays the type system. This menu item is disabled until the first time you have run an analysis engine, since there is no type system to display until then. An example is shown above. You can view the inheritance tree on the left by expanding and collapsing nodes.  When you select a type, the features defined on that type are displayed in the table on the right.  The feature table has three columns.  The first gives the name of the feature, the second one the type of the feature (i.e., what values it takes), and the third column displays the highest type this feature is defined on.  In this example, the features "begin" and "end" are inherited from the built-in annotation type. In the options menu, you can configure if you want to see inherited features or not (not yet implemented).
Show Selected Annotations
Annotations produced by a statistical named entity tagger
To enable this menu, you must have run an analysis engine and selected the ``AnnotationIndex'' or one of its subnodes in the upper left hand corncer of the screen.  It will bring up a new text window with all selected annotations marked up in the text.  shows the results of applying a statistical named entity tagger to a newspaper article.  Some annotation colors have been customized: countries are in reverse video, organizations have a turquois background, person names are green, and occupations have a maroon background.  The default background color is yellow.  This color is also used if there is more than one annotation spanning a certain text.  Clearly, this display is only useful if you don't have any overlapping annotations, or at least not too many. This menu item is also available as a context menu in the Index Tree area of the main window. To use it, select the annotation index or one of its subnodes, right-click to bring up a popup menu, and select the only item in the popup menu. The popup menu is actually a better way to invoke the annotation display, since it changes according to the selection in the Index Tree area, and will tell you if what you've selected can be displayed or not.
The Main Display Area The main display area has three sub-areas.  In the upper left-hand corner is the index display, which shows the indexes that were defined in the AE, as well as the types of the indexes and their subtypes.  In the lower left-hand corner, the content of indexes and sub-indexes is displayed (FS display).  Clicking on any node in the index display will show the corresponding feature structures in the FS display.  You can explore those structures by expanding the tree nodes.  When you click on a node that represents an annotation, clicking on it will cause the corresponding text span to marked in the text display.
State of GUI after running an analysis engine
shows the state after running the UIMA_Analysis_Example.xml aggregate from the uimaj-examples project.  There are two indexes in the index display, and the annotation index has been selected.  Note that the number of structures in an index is displayed in square brackets after the index name. Since displaying thousands of sister nodes is both confusing and slow, nodes are grouped in powers of 10.  As soon as there are no more than 100 sister nodes, they are displayed next to each other. In our example, a name annotation has been selected, and the corresponding token text is highlighted in the text area.  We have also expanded the token node to display its structure (not much to see in this simple example). In , we selected an annotation in the FS display to find the corresponding text.  We can also do the reverse and find out what annotations cover a certain point in the text.  Let's go back to the name recognizer for an example.
Finding annotations for a specific location in the text
We would like to know if the Michael Baessler has been recognized as a name.  So we position the cursor in the corresponding text span somewhere, then right-click to bring up the context menu telling us which annotations exist at this point. An example is shown in .
Selecting an annotation from the context menu will highlight that annotation in the FS display
At this point (), we only know that somewhere around the text cursor position (not visible in the picture), we discovered a name. When we select the corresponding entry in the context menu, the name annotation is selected in the FS display, and its covered text is highlighted. shows the display after the name node has been selected in the popup menu. We're glad to see that, indeed, Michael Baessler is considered to be a name.  Note that in the FS display, the corresponding annotation node has been selected, and the tree has been expanded to make the node visible. NB that the annotations displayed in the popup menu come from the annotations currently displayed in the FS display.  If you didn't select the annotation index or one of its sub-nodes, no annotations can be displayed and the popup menu will be empty.
The Status Bar At the bottom of the screen, some useful information is displayed in the status bar. The left-most area shows the most recent major event, with the time when the event terminated in square brackets. The next area shows the file name of the currently loaded XML descriptor. This area supports a tool tip that will show the full path to the file. The right-most area shows the current cursor position, or the extent of the selection, if a portion of the text has been selected. The numbers correspond to the character offsets that are used for annotations.
Keyboard Navigation and Shortcuts The GUI can be completely navigated and operated through the keyboard. All menus and menu items support keyboard mnemonics, and some common operations are accessible through keyboard accelerators. You can move the focus between the three main areas using Tab (clockwise) and Shift-Tab (counterclockwise). When the focus is on the text area, the Tab key will insert the corresponding character into the text, so you will need to use Ctrl-Tab and Ctrl-Shift-Tab instead. Alternatively, you can use the following key bindings to jump directly to one of the areas: Ctrl-T to focus the text area, Ctrl-I for the index repository frame and Ctrl-F for the feature structure area. Some additional keyboard shortcuts are available only in the text area, such as Ctrl-X for Cut, Ctrl-C for Copy, Ctrl-V for Paste and Ctrl-Z for Undo. The context menu in the text area can be evoke through the Alt-Enter shortcut. Text can be selected using the arrow keys while holding the Shift key. The following table shows the supported keyboard shortcuts. Keyboard shortcuts Shortcut Action Scope Ctrl-O Open text file Global Ctrl-S Save text file Global Ctrl-L Load AE descriptor Global Ctrl-R Run current AE Global Ctrl-I Switch focus to index repository Global Ctrl-T Switch focus to text area Global Ctrl-F Switch focus to FS area Global Ctrl-X Cut selection Text Ctrl-C Copy selection Text Ctrl-V Paste selection Text Ctrl-Z Undo Text Alt-Enter Show context menu Text
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.eclipse_launcher.xml0000644000175000017500000001065411665471336025644 0ustar drazzibdrazzib %uimaents; ]> Eclipse Analysis Engine Launcher's Guide Eclipse Analysis Engine Launcher's Guide The Analysis Engine Launcher is an Eclipse plug-in that provides debug and run support for Analysis Engines directly within eclipse, like a Java program can be debugged. It supports most of the descriptor formats expect CPE, UIMA AS and some remote deployment descriptors.
Creating an Analysis Engine launch configuration To debug or run an Analysis Engine a launch configuration must be created. To do this select "Run -> Run Configurations" or "Run -> Run Configurations" from the menu bar. A dialog will open where the launch configuration can be created. Select UIMA Analysis Engine and create a new configuration via pressing the New button at the top, or via the New button in the context menu. The newly created configuration will be automatically selected and the Main tab will be displayed. The Main tab defines the Analysis Engine which will be launched. First select the project which contains the descriptor, then choose a descriptor and select the input. The input can either be a folder which contains input files or just a single input file, if the recursively check box is marked the input folder will be scanned recursively for input files. The input format defines the format of the input files, if it is set to CASes the input resource must be either in the XMI or XCAS format and if it is set to plain text, plain text input files in the specified encoding are expected. The input logic filters out all files which do not have an appropriate file ending, depending on the chosen format the file ending must be one of .xcas, .xmi or .txt, all other files are ignored when the input is a folder, if a single file is selected it will be processed independent of the file ending. The output directory is optional, if set all processed input files will be written to the specified directory in the XMI CAS format, if the clear check box is marked all files inside the output folder will be deleted, usually this option is not needed because existing files will be overwritten without notice. The other tabs in the launch configuration are documented in the eclipse documentation, see the "Java development user guide -> Tasks -> Running and Debugging".
Launching an Analysis Engine To launch an Analysis Engine go to the previously created launch configuration and click on "Debug" or "Run" depending on the desired run mode. The Analysis Engine will now be launched. The output will be shown in the Console View. To debug an Analysis Engine place breakpoints inside the implementation class. If a breakpoint is hit the execution will pause like in a Java program.
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.pear.merger.xml0000644000175000017500000002064311665471336024545 0ustar drazzibdrazzib %uimaents; ]> PEAR Merger User's Guide The PEAR Merger utility takes two or more PEAR files and merges their contents, creating a new PEAR which has, in turn, a new Aggregate analysis engine whose delegates are the components from the original files being merged. It does this by (1) copying the contents of the input components into the output component, placing each component into a separate subdirectory, (2) generating a UIMA descriptor for the output Aggregate analysis engine and (3) creating an output PEAR file that encapsulates the output Aggregate. The merge logic is quite simple, and is intended to work for simple cases. More complex merging needs to be done by hand. Please see the Restrictions and Limitations section, below. To run the PearMerger command line utility you can use the runPearMerger scripts (.bat for Windows, and .sh for Unix). The usage of the tooling is shown below: runPearMerger 1st_input_pear_file ... nth_input_pear_file -n output_analysis_engine_name [-f output_pear_file ] The first group of parameters are the input PEAR files. No duplicates are allowed here. The -n parameter is the name of the generated Aggregate Analysis Engine. The optional -f parameter specifies the name of the output file. If it is omitted, the output is written to output_analysis_engine_name.pear in the current working directory. During the running of this tool, work files are written to a temporary directory created in the user's home directory.
Details of the merging process The PEARs are merged using the following steps: A temporary working directory, is created for the output aggregate component. Each input PEAR file is extracted into a separate 'input_component_name' folder under the working directory. The extracted files are processed to adjust the '$main_root' macros. This operation differs from the PEAR installation operation, because it does not replace the macros with absolute paths. The output PEAR directory structure, 'metadata' and 'desc' folders under the working directory, are created. The UIMA AE descriptor for the output aggregate component is built in the 'desc' folder. This aggregate descriptor refers to the input delegate components, specifying 'fixed flow' based on the original order of the input components in the command line. The aggregate descriptor's 'capabilities' and 'operational properties' sections are built based on the input components' specifications. A new PEAR installation descriptor is created in the 'metadata' folder, referencing the new output aggregate descriptor built in the previous step. The content of the temporary output working directory is zipped to created the output PEAR, and then the temporary working directory is deleted. The PEAR merger utility logs all the operations both to standard console output and to a log file, pm.log, which is created in the current working directory.
Testing and Modifying the resulting PEAR The output PEAR file can be installed and tested using the PEAR Installer. The output aggregate component can also be tested by using the CVD or DocAnalyzer tools. The PEAR Installer creates Eclipse project files (.classpath and .project) in the root directory of the installer PEAR, so the installed component can be imported into the Eclipse IDE as an external project. Once the component is in the Eclipse IDE, developers may use the Component Descriptor Editor and the PEAR Packager to modify the output aggregate descriptor and re-package the component.
Restrictions and Limitations The PEAR Merger utility only does basic merging operations, and is limited as follows. You can overcome these by editing the resulting PEAR file or the resulting Aggregate Descriptor. The Merge operation specifies Fixed Flow sequencing for the Aggregate. The merged aggregate does not define any parameters, so the delegate parameters cannot be overridden. No External Resource definitions are generated for the aggregate. No Sofa Mappings are generated for the aggregate. Name collisions are not checked for. Possible name collisions could occur in the fully-qualified class names of the implementing Java classes, the names of JAR files, the names of descriptor files, and the names of resource bindings or resource file paths. The input and output capabilities are generated based on merging the capabilities from the components (removing duplicates). Capability sets are ignored - only the first of the set is used in this process, and only one set is created for the generated Aggregate. There is no support for merging Sofa specifications. No Indexes or Type Priorities are created for the generated Aggregate. No checking is done to see if the Indexes or Type Priorities of the components conflict or are inconsistent. You can only merge Analysis Engines and CAS Consumers. Although PEAR file installation descriptors that are being merged can have specific XML elements describing Collection Reader and CAS Consumer descriptors, these elements are ignored during the merge, in the sense that the installation descriptor that is created by the merge does not set these elements. The merge process does not use these elements; the output PEAR's new aggregate only references the merged components' main PEAR descriptor element, as identified by the PEAR element: the_component.xml... ]]>
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.cde.xml0000644000175000017500000021535011665471336023072 0ustar drazzibdrazzib %uimaents; ]> Component Descriptor Editor User's Guide CDE User's Guide The Component Descriptor Editor is an Eclipse plug-in that provides a forms-based interface for creating and editing UIMA XML descriptors. It supports most of the descriptor formats, except the Collection Processing Engine descriptor, the PEAR package descriptor and some remote deployment descriptors.
Launching the Component Descriptor Editor Here's how to launch this tool on a descriptor contained in the examples. This presumes you have installed the examples as described in the SDK Installation and Setup chapter. Expand the uimaj-examples project in the Eclipse Navigator or Package Explorer view Within this project, browse to the file descriptors/tutorial/ex1/RoomNumberAnnotator.xml. Right-click on this file and select Open With → Component Descriptor Editor. (If this option is not present, check to make sure you installed the plug-ins as described . The EMF plugin is also required.). This should open a graphical editor and display the contents of the RoomNumberAnnotator descriptor.
Creating a New AE Descriptor A new AE descriptor file may be created by selecting the File → New → Other... menu. This brings up the following dialog: Screenshot of selecting new UIMA component in Eclipse If the user then selects UIMA and Analysis Engine Descriptor File, and clicks the Next > button, the following dialog is displayed. We will cover creating other kinds of components later in the documentation. Screenshot of selecting new UIMA component in Eclipse after pushing Next After entering the appropriate parent folder and file name, and clicking Finish, an initial AE descriptor file is created with the given name, and the descriptor is opened up within the Component Descriptor Editor. At this point, the display inside the Component Descriptor Editor is the same whether one started by creating a new AE descriptor, as in the preceding paragraph, or one merely opened a previously created AE descriptor from, say, the Package Explorer view. We show a previously created AE in the figure below: Screenshot of CDE showing overview page To see all the information shown in the main editor pane with less scrolling, double click the title tab to toggle between the full screen and normal views. It is possible to set the Component Descriptor Editor as the default editor for all .xml files by going to Window → Preferences, and then selecting File Associations on the left, and *.xml on the right, and finally by clicking on Component Descriptor Editor, the Default button and then OK. If AE and Type System descriptors are not the primary .xml files you work with within the Eclipse environment, we recommend not setting the Component Descriptor Editor as your default editor for all .xml files. To open an .xml file using the Component Descriptor Editor, if the Component Descriptor Editor is not set as your default editor, right click on the file in the Package Explorer, or other navigational view, and select Open With → Component Descriptor Editor. This choice is remembered by Eclipse for subsequent open operations.
Pages within the Editor The Component Descriptor Editor follows a standard Eclipse paradigm for these kinds of editors. There are several pages in the editor; each one can be selected, one at a time, by clicking on the bottom tabs. The last page contains the actual XML source file being edited, and is displayed as plain text. The same set of tabs appear at the bottom of each page in the Component Descriptor Editor. The Component Descriptor Editor uses this multi-page editor paradigm to give the user a view of conceptually distinct portions of the Descriptor metadata in separate pages. At any point in time the user may click on the Source tab to view the actual XML source. The Component Descriptor Editor is, in a way, just a fancy GUI for editing the XML. The tabs provide quick access to the following pages: Overview, Aggregate, Parameters, Parameter Settings, Type System, Capabilities, Indexes, Resources, and Source. We discuss each of these pages in turn.
Adjusting the display of pages Most pages in the editor have a sash bar. This is a light gray bar which separates sub-sections of the page. This bar can be dragged with the mouse to adjust how the display area is split between the two sash panes. You can also change the orientation of the Sash so it splits vertically, instead of horizontally, by clicking on the small icons at the top right of the page that look like this: Changing orientation of two window split All of the sections on a page have subtitles, with an indicator to the left which you can click to collapse or expand that particular section. Collapsing sections can sometimes be useful to free up screen area for other sections.
Overview Page Normally, the first page displayed in the Component Descriptor Editor is the Overview page (the name of the page is shown in the GUI panel at the top left). If there is an error reading and parsing the source, the Source page is shown instead, giving you the opportunity to correct the problem. For many components, the Overview page contains three sections: Implementation Details, Runtime Information and overall Identification Information.
Implementation Details In the Implementation Details section you specify the Implementation Language and Engine Type. There are two kinds of Engines: Aggregate, and non-Aggregate (also called Primitive). An Aggregate engine is one which is composed of additional component engines and contains no code, itself. Several of the pages in the Component Descriptor Editor have different formats, depending on the engine type.
Runtime Information Runtime information is only applicable for primitive engines and is disabled for aggregates and other kinds of descriptors. This is where you specify the class name of the annotator implementation, if you are doing a Java implementation, or the C++ shared object or dll name, if you are doing a C++ implementation. Most Analysis Engines will specify that they update the CAS, and that they may be replicated (for performance reasons) when deployed. If a particular Analysis Engine must see every CAS (for instance, if it is counting the number of CASes), then uncheck the multiple deployment allowed box. If the Analysis Engine doesn't update the CAS, uncheck the updates the CAS box. (Most CAS Consumers do not update the CAS, and this parameter defaults to unchecked for new CAS Consumer descriptors). Analysis engines are written using the CAS Multiplier APIs (see ) can create additional CASes for analysis. To specify that they do this, check the returns new artifacts.
Overall Identification Information The Name should be a human-readable name that describes this component. The Version, Vendor, and Description fields are optional, and are arbitrary strings.
Aggregate Page For primitive Analysis Engines, Flow Controllers or Collection Processing components, the Aggregate page is not used. For aggregate engines, the page looks like this: CDE Aggregate page On the left we see a list of component engines, and on the right information about the flow. If you hover the mouse over an item in the list of component engines, that engine's description meta data will be shown. If you right-click on one of these items, you get an option to open that delegate descriptor in another editor instance. Any changes you make, however, won't be seen until you close and reopen the editor on the importing file. Engines can be added to the list on the left by clicking the Add button at the bottom of the Component Engine section. This brings up one of the following two dialogs: Adding an Analysis Engine to an Aggregate, by location This dialog lets you select a descriptor from your workspace, or browse the file system to select a descriptor. Or, if you have selected to import by name, this dialog is shown: Adding an Analysis Engine to an Aggregate, by name You can specify that the import should be by Name (the name is looked up using both the Project's class path, and DataPath), or by location. If it is by name, the dialog shows the available xml files on the class path, to pick from. If the one you want isn't showing, this means it isn't on the enclosing Eclipse Java Project's classpath, nor on the datapath, and one of those needs to be updated to include the path to the resource. If the name picked is com/company/prod/xyz.xml, the name in the descriptor will be com.company.prod.xyz. The "Browse the file system..." button is disabled when import by name is checked, because the file system is not the source of the imports - rather, its the resources on the classpath or datapath that are. If it is by location, the file reference is converted to a relative reference if possible, in the descriptor. The final selection at the bottom tells whether or not the selected engine(s) should automatically be added to the end of the flow section (the right section on the Aggregate page). The OK button does not become activated until a descriptor file is selected. To remove an analysis engine from the component engine list simply select an engine and click the Remove button, or press the delete key. If the engine is already in the flow list you will be warned that deletion will also delete the specified engine from this list.
Adding components more than once Components may be added to the left panel more than once. Each of these components will be given a key which is unique. A typical reason this might be done is to use a component in a flow several times, but have each use be associated with different configuration parameters (different configuration parameters can be associated with each instance).
Adding or Removing components in a flow The button in-between the Component Engines and the Flow List, labeled >>, adds a chosen engine to the flow list and the button labeled << removes an engine from the flow list. To add an engine to the flow list you must first select an engine from the left hand list, and then press the >> button. Engines may appear any number of times in the flow list. To remove an engine from the flow list, select an engine from the right hand list and press the << button.
Adding remote Analysis Engines There are two ways to add remote engines: add an existing descriptor, which specifies a remote engine (just as if you were adding a non-remote engine) or use the Add Remote button which will create a remote descriptor, save it, and then import it, all in one operation. The Add Remote button enables you to easily specify the information needed to create a Service Client descriptor for a remote AE - one that runs on a different computer connected over the network. The Service Client descriptor is described in . The Add Remote button creates this descriptor, saves it as a file in the workspace, and imports it into the aggregate. Of course, if you already have a Service Client descriptor, you can add it to the set of delegates, just like adding other kinds of analysis engines. After clicking on Add Remote, the following dialog is displayed: Adding a remote client to an aggregate To define a remote service you specify the Service Kind, Protocol Service Type, URI and Key. You can also specify a Timeout in milliseconds, used by the SOAP service, and a VNS Host and Port used by the Vinci Service. Just like when one adds an engine from the file system, you have the option of adding the engine to the end of the flow. The Component Descriptor Editor currently only supports Vinci and SOAP services using this dialog. Remote engines are added to the descriptor using the <import ... > syntax. The information you specify here is saved in the Eclipse project as a file, using a generated name, <key-name>.xml, where <key-name> is the name you listed as the Key. Because of this, the key-name must be a valid file name. If you want a different name, you can change the path information in the dialog box.
Connecting to Remote Services If you are using the Vinci protocol, it requires that you specify the location of the Vinci Name Server (an IP address and a Port number). You can specify these in the service descriptor, or globally, for your Eclipse workspace, using the Eclipse menu item: Window → Preferences... → UIMA Preferences. If the remote service is available (up and running), additional operations become possible. For instance, hovering the mouse over the remote descriptor will show the description metadata from the remote service.
Finding Analysis Engines by searching The next button that appears between the component engine list and the flow list is the Find AE button. When this button is pressed the following dialog is displayed, which allows one to search for AEs by name, by input or output types, or by a combination of these criteria. This function searches the existing Eclipse workspace for matching *.xml descriptor source files; it does not look inside Jar files. Searching for an AE to add to an aggregate The search automatically adds a match any characters - style (*) wildcard at the beginning and end of anything entered. Thus, if person is specified for an output type, a *person* search is performed. Such a search would match such things as my.namespace.person and person.governmentOfficial. One can search in all projects or one particular project. The search does an implicit and on all fields which are left non-blank.
Component Engine Flow The UIMA SDK currently supports three kinds of sequencing flows: Fixed, CapabilityLanguageFlow (see ), and user-defined. The first two require specification of a linear flow sequence; this linear flow sequence can also be read by a user-defined flow controller (what use is made of it is up to the user-defined flow controller). The Component Engine Flow section allows specification of these items. The pull-down labeled Flow Kind picks between the three flow models. When the user-defined flow is selected, the Browse and Search buttons become enabled to let you pick the flow controller XML descriptor to import. Specifying flow control The key name value is set automatically from the XML descriptor being imported, and enables parameters to be overridden for that descriptor (see following sections). The Up and Down buttons to the right in the Flow section are activated when an engine in the flow is selected. The Up button moves the selected engine up one place in the execution order, and down moves the selected engine down one place in the execution order. Remember that engines can appear multiple times in the flow (or not at all).
Parameters Definition Page There are two pages for parameters: the first one is where parameters are defined, and the second one is where the parameter settings are configured. The first page is the Parameter Definition page and has two alternatives, depending on whether or not the descriptor is an Aggregate or not. We start with a description of parameter definitions for Primitive engines, CAS Consumers, Collection Readers, CAS Initializers, and Flow Controllers. Here is an example: Parameter Definitions - not Aggregate The first checkbox at the top simplifies things if you are not using Parameter Groups (see the following section for a discussion of groups). In this case, leave the check box unchecked. The main area shows a list of parameter definitions. Each parameter has a name, which must be unique for this Analysis Engine. The other three attributes specify whether the parameter can have a single or multiple values (an array of values), whether it is Optional or Mandatory, and what the value type it can hold (String, Integer, Float, and Boolean). In addition to using the buttons on the right to edit this information, you can double-click a parameter to edit it, or remove (delete) a selected parameter by pressing the delete key. Use the Add button to add a new parameter to the list. Parameters have an additional description field, which you can specify when you add or edit a parameter. To see the value of the description, hover the mouse over the item, as shown in the picture below: Parameter description shown in a hover message
Using groups The group concept for parameters arose from the observation that sets of parameters were sometimes associated with different configuration needs. As an example, you might have an Analysis Engine which needed different configuration based on the language of a document. To use groups, you check the Use Parameter Groups box. When you do this, you get the ability to add groups, and to define parameters within these groups. You also get a capability to define Common parameters, which are parameters which are defined for all groups. Here is a screen shot showing some parameter groups in use: Using parameter groups You can see the <Common> parameters as well as two different sets of groups. The Default Group is an optional specification of what Group to use if the parameter is not available for the group requested. The Search strategy specifies what to do when a parameter is not available for the group requested. It can have the values of None, language_fallback, or default_fallback. These are more fully described in the section . Groups are added using the Add Group button. Once added, they can be edited or removed, using the buttons to the right, or the standard gestures for editing (double-clicking the item) and removing (pressing the delete key after an item is selected). Removing a group removes all the parameter definitions in the group. If you try and remove the <Common> group, it just removes the parameters in the group. Each entry for a group in the table specifies one or more group names. For example, the highlighted entry above, specifies two groups: myNewGroup2 and mg3. The parameter definition underneath is considered to be in both groups.
Parameter declarations for Aggregates Aggregates declare parameters which always must override a parameter setting for a component making up the aggregate. They do this using the version of this page which is shown when the descriptor is an Aggregate; here's an example: Aggregate parameters There is an additional panel shown (on the right) which lists all of the components by their key names, and shows for each of them their defined parameters. To add a new override for one or more of these parameters to the aggregate, select the component parameter you wish to override and push the Create Override button (or, you can just double-click the component parameter). This will automatically add a parameter of the same name (by default – you can change the name if you like) to the aggregate, putting it into the same group(s) (if groups are being used in the component – this is required), and setting the properties of the parameter to match those of the component (this is required). If the name of the parameter being added already is in use in the aggregate, and the parameters are not compatible, a new parameter name is generated by suffixing the name with a number. If the parameters are compatible, the selected component parameter is added to the existing aggregate parameter, as an additional override. If you don't want this behavior, but want to have a new name generated in this case, push the Create non-shared Override button instead, or hold down the shift key when double clicking the component parameter. The required / optional setting in the aggregate parameter is set to match that of the parameter being overridden. You may want to make an optional delegate parameter required. You can do this by changing that value manually in the source editor view. In the above example, the user has just double-clicked the TypeNames parameter in the NameRecognizer component. This added that parameter to this aggregate under the <Not in any group> section – since it wasn't part of a group. Once you have added a parameter definition to the aggregate, you can use the buttons on the right side of the left panel to add additional overrides or remove parameters or their overrides. You can also remove groups; removing a group is like removing all the parameter definitions in the group. In addition to adding one parameter at a time from a component, you can also add all the parameters for a group within a component, or all the parameters in the component, by selecting those items. If you double-click (or push Create Override) the <Common> group or a parameter in the <Common> group in a component, a special group is created in the Aggregate consisting of all of the groups in that component, and the overriding parameter (or parameters) are added to that. This is done because each component can have different groups belonging to the Common group notion; the Common group for a component is just shorthand for all the groups in that component. The Aggregate's specification of the default group and search strategy override any specifications contained in the components.
Parameter Settings Page The Parameter Settings page is rather straightforward; it is where the user defines parameter settings for their engines. An example of such a page is given below: Parameter settings page For single valued attributes, the user simply types the default value into the Value box on the right hand side. For multi-valued parameters the user should use the Add, Edit and Remove buttons to manage the list of multiple parameter values. Values within groups are shown with each group separately displayed, to allow configuring different values for each group. Values are checked for validity. For Boolean values in a list, use the words true or false. If you specify a value in a single-valued parameter, and then delete all the characters in the value, the CDE will treat this as if you wanted to not specify any setting for this parameter. In order to specify a 0 length string setting for a String-valued parameter, you will have to manually edit the XML using the Source tab. For array valued parameters, if you remove all of the entries for a particular array parameter setting, the XML will reflect a 0-length array. To change this to an unspecified parameter setting, you will have to manually edit the XML using the Source tab.
Type System Page This page declares the type system used by the annotator. For aggregates it is derived by merging the type systems of all constituent AEs. The types used by the AE constitute the language in which the inputs and outputs are described in the Capabilities page and also affect the choice of indexes on the Indexes page. The Type System page looks like the following: Type System declaration page Before discussing this page in detail, it is important to note that there are two settings that affect the operation of this page. These are accessed by selecting the UIMA → Settings (or by going to the Eclipse Window → Preferences → UIMA Preferences) and checking or unchecking one of the following: Auto generate .java files when defining types and Display fully qualified type names. When the Auto generate option is checked and the development language for the AE is Java, any time a change is made to a type and the change is saved, the corresponding .java files are generated using the JCasGen tool. The results are stored in the primary source directory defined for the project. The primary source directory is that listed first when you right click on your project and select Properties → Java Build Path, click on the Source tab and look in the list box under the text that reads: Source folder on build path. If no source folders are defined, you will get a warning that you have no source folders defined and JCasGen will not be run. (For information on JCasGen see ). When JCasGen is run, you can monitor the progress of the generation by observing the status on the Eclipse status line (normally at the bottom of the Eclipse window). JCasGen runs on the fully-merged type system, consisting of the type specification plus any imported type system, plus (for aggregates) the merged type systems of all the components in an aggregate. If the components of the aggregate have different definitions for the same type name, the CDE will show a warning. It is possible to continue past this warning, in which case the CDE will produce the correct Java source files representing the merged types (that is, the type definition that contains all of the features defined on that type by all of your components). However, it is not recommended to use this feature (of having different definitions for the same type name) since it can make it difficult to combine/package your annotator with others. See for more information. In addition to running automatically, you can manually run JCasGen on the fully merged type system by clicking the JCasGen button, or by selecting Run JCasGen from the UIMA pulldown menu: Setting JCasGen options When Display fully qualified type names is left unchecked, the namespace of types is not displayed, i.e. if a fully qualified type name is my.namespace.person, only the abbreviated type name person will be displayed. In the Type page diagram shown above, Display fully qualified type names is in fact unchecked. To add, edit, or remove types the buttons on the top left section are used. When adding or editing types, fully qualified type names should of course be used, regardless of whether the Display fully qualified type names is unchecked. Removing or editing a type will have a cascading effect in that the type removal/edit will effect inputs, outputs, indexes and type priorities in the natural way. When a type is added, this dialog is shown: Adding a type Type names should be specified using a namespace. The namespace is like a Java package name, and serves to insure type names are unique. It also serves as the package name for the generated JCas classes. The namespace name is the set of names up to the last period in the string. The supertype must be picked from an existing type. The entry field for the supertype supports Eclipse-style content assist. To use it, put the cursor in the supertype field, and type a letter or two of the supertype name (lower case is fine), either starting with the name space, or just with the type name (without the name space), and hold down the Control key and then press the spacebar. When you do this, you can see a list of suitable matching types. You can then type more letters to narrow down your choices, or pick the right entry with the mouse. To see the available types and pick one, press the Browse button. This will show the available types, and as you type letters for the type name (in lower case – capitalization is ignored), the available types that match are narrowed. When you've typed enough to specify the type you want, press Enter. Or you can use the list of matching type names and pick the one you want with the mouse. Once you've added the type, you can add features to it by highlighting the type, and pressing the Add button. If the type being defined is a subtype of uima.cas.String, the Add button allows you to add allowed values for the string, instead of adding features. To edit a type or feature, you can double click the entry, or highlight the entry and press the Edit button. To delete a type or feature, you highlight the entry to be deleted, and click the delete button or push the delete key. If the range of a feature is an array or one of the built-in list types, an additional specification allows you to specify if multiple references to the object referenced by this feature are allowed. If they are not allowed then the XMI serialization of instances of this type use a more efficient format. If the range of a feature is an array of Feature Structures, then it is possible to specify an element type for the array. This information is used in the XMI serialization and also by the JCas generation routines to generate more efficient code. Specifying a Feature Structure It is also possible to import type systems for inclusion in your descriptor. To do this, use the Type Import panel's Add... button. This allows you to import a type system descriptor. When importing by name, the name is resolved using the class path for the Eclipse project containing the descriptor file being edited, or by looking up this name in the UIMA DataPath. The DataPath can be set by pushing the Set DataPath button. It will be remembered for this Eclipse project, as a project Property, so you only have to set it once (per project). The value of the DataPath setting is written just like a class path, and can include directories or JAR files, just as is true for class paths. The following dialog allows you to pick one or more files from the Eclipse workspace, or one file (at a time) from the file system: Picking files for importing This is essentially the same dialog as was used to add component engines to an aggregate. To import from a type system descriptor that is not part of your Eclipse workspace, click the Browse the file system.... button. Imported types are validated, and if OK, they are added to the list in the Imported Type Systems section of the Type System page. Any types they define are merged with the existing type system. Imported types and features which are only defined in imports are shown in the Type System section, but in a grayed-out font; these type cannot be edited here. To change them, open up the imported type system descriptor, and change them there. If you hover the mouse over an import specification, it will show more information about the import. If you right-click, it will bring up a context menu that allows opening the imported file in the Editor, if the imported file is part of the Eclipse workspace. Changes you make, however, won't be seen until you close and reopen the editor on the importing file. It is not possible to define types for an aggregate analysis engine. In this case the type system is computed from the component AEs. The Type System information is shown in a grayed-out font.
Exporting In addition to importing type specifications, you can export as well. When you push the Export... button, the editor will create a new importable XML descriptor for the types in this type system, and change the existing descriptor to import that newly created one. Exporting a type system The base file name you type is inserted into the path in the line below automatically. You can change the path where the generated part descriptor is stored by overtyping the lower text box. When you click OK, the new part descriptor will be generated, and the current descriptor will be changed to import that part.
Capabilities Page Capabilities come in sets. You can have multiple sets of capabilities; each one specifies languages supported, plus inputs and outputs of the Analysis Engine. The idea behind having multiple sets is the concept that different inputs can result in different outputs. Many Analysis Engines, though, will probably define just one set of capabilities. A sample Capabilities page is given below: Capabilities page When defining the capabilities of a primitive analysis engine, input and output types can be any type defined in the type system. When defining the capabilities of an aggregate the inputs must be a subset of the union of the inputs in the constituent analysis engines and the outputs must be a subset of the union of the outputs of the constituent analysis engines. To add a type, first select something in the set you wish to add the type to, and press Add Type. The following dialog appears presenting the user with a list of types which are candidates for additional inputs: Adding a type to the capabilities page Follow the instructions to mark the types as input and / or output (a type can be both). By default, the <all features> flag is set to true. If you want to specify a subset of features of a type, read on. When types have features, you can specify what features are input and / or output. A type doesn't have to be an output to have an output feature. For example, an Analysis Engine might be passed as input a type Token, and it adds (outputs) a feature to the existing Token types. If no new Token instances were created, it would not be an output Type, but it would have features which are output. To specify features as input and / or output (they can be both), select a type, and press Add. The following dialog box appears: Specifying features as input or output To mark a feature as being input and / or output, click the mouse in the input and / or output column for the feature. If you select <all features>, it unmarks any individual feature you selected, since <all features> subsumes all the features. The Languages part of the capability is where you specify what languages are supported by the Analysis Engine. Supported languages should be listed using either a two letter ISO-639 language code, or an ISO-639 language code followed by a hyphen and then a two-letter ISO-3166 country code. Add a language by selecting Languages and pressing the Add button. The dialog for adding languages is given below. Specifying a language The Sofa part of the capability is optional; it allows defining Sofa names that this component uses, and whether they are input (meaning they are created outside of this component, and passed into it), or output (meaning that they are created by this component). Note that a Sofa can be either input or output, but can't be both. To add a Sofa name (which is synonymous with the view name), press the Add Sofa button, and this dialog appears: Specifying a Sofa name
Sofa (and view) name mappings Sofa names, once created, are used in Sofa Mappings. These are optional mappings, done in an aggregate, that specify which Sofas are the same ones but with different names. The Sofa Mappings section is minimized unless you are editing an Aggregate descriptor, and have one or more Sofa names defined for the aggregate. In that case, the Sofa Mappings section will look like this: Sofa mappings Here the aggregate has defined two input Sofas, named MyInputSofa, and AnotherSofa. Any named sofas in the aggregate's capabilities will appear in the Sofa Mapping section, listed either under Inputs or Outputs. Each name in the Mappings has 0 or more delegate (component) sofa names mapped to it. A delegate may have multiple Sofas, as in this example, where the GovernmentOfficialRecognizer delegate has Sofas named so1 and so2. Delegate components may be written as Single-View components. In this case, they have one implicit, default Sofa (_InitialView), and to map to it you use the form shown for the NameRecognizer – you map to the delegate's key name in the aggregate, without specifying a Sofa name. You can also specify the sofa name explicitly, e.g., NameRecognizer/_InitialView. To add a new mapping, select the Aggregate Sofa name you wish to add the mapping for, and press the Add button. This brings up a window like this, showing all available delegates and their Sofas; select one or more (use the normal multi-select methods) of these and press OK to add them. Adding a Sofa mapping To edit an existing mapping, select the mapping and press Edit. This will show the existing mapping with all mapped items selected, and other available items unselected. Change the items selected to match what you want, deselecting some, and perhaps selecting others, and press OK.
Indexes Page The Indexes page is where the user declares what indexes and type priority lists are used by the analysis engine. Indexes are used to determine which Feature Structures of a particular type are fetched, using an iterator in the UIMA API. An unpopulated Indexes page is displayed below: Index page Both indexes and type priority lists can have imports. These imports work just like the type system imports, described above. Both indexes and type priority lists can be exported to new component descriptors, using the Export... button, just like the type system export operation described above. The built-in Annotation Index is always present. It is based on the built-in type uima.tcas.Annotation and has keys begin (Ascending), end (Descending) and TYPE_PRIORITY. There are no built-in type priorities, so this last sort item does not play a role in the index unless type priorities are specified. Type priority may be combined with other keys. Type priorities are defined in the Priority Lists section, using one or more priority list. A given priority list gives an ordering among a group of types. Types that appear higher in the priority list are given higher priority, in other words, they sort first when TYPE_PRIORITY is specified as the index key. Subtypes of these types are also ordered in a consistent manner, unless overridden by another specific type priority specification. To get the ordering used among all the types, all of the type priority lists are merged. This gives a partial ordering among the types. Ties are resolved in an unspecified fashion. The Component Descriptor Editor checks for incompatible orderings, and informs the user if they exist, so they can be corrected. To create a new index, use the Add Index button in the top left section. This brings up this dialog: Adding a new index Each index needs a globally unique index name. Every index indexes one CAS type (including its subtypes). If you're using Eclipse 3.2 or later, the entry field for this has content assist (start typing the type name and press Control – Spacebar to get help, or press the Browse button to pick a type). Indexes can be sorted, in which case you need to specify one or more keys to sort on. Sort keys are selected from features whose range type is Integer, Float, or String. Some elements will be disabled if they are not relevant. For instance, if the index kind is bag, you cannot provide sort keys. The order of sort keys can be adjusted using the up and down buttons, if necessary. There is usually no need to explicitly declare a Bag index in your descriptor. As of UIMA v2.1, if you do not declare any index for a type (or any of its supertypes), a Bag index will be automatically created. This index is accessed using the getAllIndexedFS(...) method defined on the index repository. A set index will contain no duplicates of the same type, where a duplicate is defined by the indexing comparator. That is, if you commit two feature structures of the same type that are equal with respect to the indexing comparator, only the first one will be entered into the index. Note that you can still have duplicates with respect to the indexing order, if they are of a different type. A set index is not guaranteed to be sorted. If no keys are specified for a set index, then all instances are considered by default to be equal, so only the first instance (for a particular type or subtype of the type being indexed) is indexed. On the other hand, bag indicates that all annotation instances are indexed, including duplicates. The Priority Lists section of the Indexes page is used to specify Priority Lists of types. Priority Lists are unnamed ordered sets of type names. Add a new priority list by clicking the Add Set button. Add a type to an existing priority list by first selecting the set, and then clicking Add. You can use the up and down buttons to adjust the order as necessary; these buttons move the selected item up or down. Although it is possible to import self-contained index and type priority files, the creation of such files is not yet supported by the Component Descriptor Editor. If you create these files using another editor, they can be imported using the corresponding Import panels, shown on the right. Imports are specified in the same manner as they are for Type System imports.
Resources Page The resources page describes resource dependencies (for primitive Analysis Engines) and external Resource specification and their bindings to the resource dependencies. Only primitive Analysis Engines define resource dependencies. Primitive and Aggregate Analysis Engines can define external resources and connect them (bind them) to resource dependencies. When an Aggregate is providing an external resource to be bound to a dependency, the binding is specified using a possibly multi-level path, starting at the Aggregate, and specify which component (by its key name), and then if that component is, in turn, an Aggregate, which component (again by its key name), and so on until you reach a primitive. The sequence of key names is made into the binding specification by joining the parts with a / character. All of this is done for you by the Component Descriptor Editor. Any external resource provided by an Aggregate will override any binding provided by any lower level component for the same resource dependency. There are two views of the Resources page, depending on whether the Analysis Engine is an Aggregate or Primitive. Here's the view for a Primitive: Resources page for a primitive To declare a resource dependency, click the Add button in the right hand panel. This puts up the dialog: Specifying a resource dependency The Key must be unique within the descriptor declaring it. The Interface, if present, is the name of a Java interface the Analysis Engine uses to access the resource. Declare actual External resource on the left side of the page. Clicking Add brings up this dialog: Specifying an External Resource The Name must be unique within this Analysis Engine. The URL identifies a file resource. If both the URL and URL suffix are used, the file resource is formed by combining the first URL part with the language-identifier, followed by the URL suffix; see . URLs may be written as relative URLs; in this case they are resolved by looking them up relative to the classpath and/or datapath. A relative URL has the path part starting without an intial /; for example: file:my/directory/file. An absolute URL starts with file:/ or file:/// or file://some.network.address/. For more information about URLs, please read the javaDoc information for the Java class URL. The Implementation is optional, and if given, must be a Java class that implements the interface specified in any Resource Dependencies this resource is bound to.
Binding Once you have an external resource definition, and a Resource Dependency, you can bind them together. To do this, you select the two things (an external resource definition, and a Resource Dependency) that you want to bind together, and click Bind.
Resources with Aggregates When editing an Aggregate Descriptor, the Resource definitions panel will show all the resources at the primitive level, with paths down through the components (multiple levels, if needed) to get to the primitives. The Aggregate can define external resources, and bind them to one or more uses by the primitives.
Imports and Exports Resource definitions and their bindings can be imported, just like other imports. Existing Resource definitions and their bindings can be exported to a new importable part, and replaced with an import for that importable part, using the Export... button, just like the similar function on the Type System page.
Source Page The Source page is a text view of the xml content of the Analysis Engine or Type System being configured. An example of this page is displayed below: Source page Changes made in the GUI are immediately reflected in the xml source, and changes made in the xml source are immediately reflected back in the GUI. The thought here is that the GUI view and the Source view are just two ways of looking at the same data. When the data is in an unsaved state the file name is prefaced with an asterisk in the currently selected file tab in the editor pane inside Eclipse (as in the example above). You may accidentally create invalid descriptors or XML by editing directly in the Source view. If you do this, when you try and save or when you switch to a different view, the error will be detected and reported. In the case of saving, the file will be saved, even if it is in an error state.
Source formatting – indentation The XML is indented using an indentation amount saved as a global UIMA preference. To change this preference, use the Eclipse menu item: Windows → Preferences → UIMA Preferences.
Creating a Self-Contained Type System It is also possible to use the Component Descriptor Editor to create or edit self-contained type systems. To create a self-contained type system, select the menu item File → New → Other and then select Type System Descriptor File. From the next page of the selection wizard specify a Parent Folder and File name and click Finish. Working with a self-contained type system This will take you to a version of the Component Descriptor Editor for editing a type system file which contains just three pages: an overview page, a type system page, and a source page. The overview page is a bit more spartan than in the case of an AE. It looks like the following: Editing a type system object Just like an AE has an associated name, version, vendor and description, the same is true of a self-contained type system. The Type System page is identical to that in an AE descriptor file, as is the Source page. Note that a self-contained type system can import type systems just like the type system associated with an AE. A type system component can also be created from an existing descriptor which contains a type system definition section, by clicking on the Export... button on the Type System page.
Creating Other Descriptor Components The new wizard can create several other kinds of components: Collection Processing Management (CPM) components, flow controllers, and importable parts (besides Type Systems, described above, Indexes, Type Priorities, and Resource Manager Configuration imports). The CPM components supported by this editor include the Collection Reader, CAS Initializer, and CAS Consumer descriptors. Each of these is basically treated just like a primitive AE descriptor, with small changes to accommodate the different semantics. For instance, a CAS Consumer can't declare in its capabilities section that it outputs types or features. Flow controllers are components that control the flow of CASes within an aggregate, an are edited in a similar fashion as a primitive Analysis Engine. The importable part support requires context information to enable the editor to work, because much of the power of this editor comes from extensive checking that requires additional information, other than what is available in just the importable part. For instance, when you create or edit an Indexes import, the facility for adding new indexes needs the type information, which is not present in this part when it is edited alone. To overcome this, when you edit these descriptors, you will be asked to specify a context descriptor, usually a descriptor which would import the part being edited, which would have the additional information needed. Various methods are used to guess what the context descriptor should be - and if the guess is correct, you can just press the Enter key to confirm. The last successful context file is remembered and will be suggested as the context file to use at the next edit session
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.xml0000644000175000017500000000441411665471336022335 0ustar drazzibdrazzib UIMA Tools Guide and Reference uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.doc_analyzer.xml0000644000175000017500000002715311665471336025013 0ustar drazzibdrazzib %uimaents; ]> Document Analyzer User's Guide The Document Analyzer is a tool provided by the UIMA SDK for testing annotators and AEs. It reads text files from your disk, processes them using an AE, and allows you to view the results. The Document Analyzer is designed to work with text files and cannot be used with Analysis Engines that process other types of data. For an introduction to developing annotators and Analysis Engines, read . This chapter is a user's guide for using the Document Analyzer tool, and does not describe the process of developing annotators and Analysis Engines.
Starting the Document Analyzer To run the Document Analyzer, execute the documentAnalyzer script that is in the bin directory of your UIMA SDK installation, or, if you are using the example Eclipse project, execute the UIMA Document Analyzer run configuration supplied with that project. Note that if you're planning to run an Analysis Engine other than one of the examples included in the UIMA SDK, you'll first need to update your CLASSPATH environment variable to include the classes needed by that Analysis Engine. When you first run the Document Analyzer, you should see a screen that looks like this: Document Analyzer GUI
Running an AE To run a AE, you must first configure the six fields on the main screen of the Document Analyzer. Input Directory: Browse to or type the path of a directory containing text files that you want to analyze. Some sample documents are provided in the UIMA SDK under the examples/data directory. Output Directory: Browse to or type the path of a directory where you want output to be written. (As we'll see later, you won't normally need to look directly at these files, but the Document Analyzer needs to know where to write them.) The files written to this directory will be an XML representation of the analyzed documents. If this directory doesn't exist, it will be created. If the directory exists, any files in it will be deleted (but the tool will ask you to confirm this before doing so). If you leave this field blank, your AE will be run but no output will be generated. Location of AE XML Descriptor: Browse to or type the path of the descriptor for the AE that you want to run. There are some example descriptors provided in the UIMA SDK under the examples/descriptors/analysis_engine and examples/descriptors/tutorial directories. XML Tag containing Text: This is an optional feature. If you enter a value here, it specifies the name of an XML tag, expected to be found within the input documents, that contains the text to be analyzed. For example, the value TEXT would cause the AE to only analyze the portion of the document enclosed within <TEXT>...</TEXT> tags. Also, any XML tags occuring within that text will be removed prior to analysis. Language: Specify the language in which the documents are written. Some Analysis Engines, but not all, require that this be set correctly in order to do their analysis. You can select a value from the drop-down list or type your own. The value entered here must be an ISO language identifier, the list of which can be found here: . Character Encoding: The character encoding of the input files. The default, UTF-8, also works fine for ASCII text files. If you have a different encoding, enter it here. For more information on character sets and their names, see the Javadocs for java.nio.charset.Charset. Once you've filled in the appropriate values, press the Run button. If an error occurs, a dialog will appear with the error message. (A stack trace will also be printed to the console, which may help you if the error was generated by your own annotator code.) Otherwise, an Analysis Results window will appear.
Viewing the Analysis Results After a successful analysis, the Analysis Results window will appear. Analysis Results Window The Results Display Format options at the bottom of this window show the different ways you can view your analysis – the Java Viewer, Java Viewer (JV) with User Colors, HTML, and XML. The default, Java Viewer, is recommended. Once you have selected your desired Results Display Format, you can double-click on one of the files in the list to view the analysis done on that file. For the Java viewer, the results display looks like this (for the AE descriptor examples/descriptors/tutorial/ex4/MeetingDetectorAE.xml): Analysis Results Window showing results from tutorial example 4 You can click the mouse on one of the highlighted annotations to see a list of all its features in the frame on the right. If there are multiple annotation types in the view, you can control which ones are selected by using the checkboxes in the legend, the Select All button, or the Deselect All button. If you are viewing a CAS that contains multiple subjects of analysis, then a selector will appear at the bottom right of the Annotation Viewer window. This will allow you to choose the Sofa that you wish to view. Note that only text Sofas containing a non-null document are available for viewing.
Configuring the Annotation Viewer The JV User Colors and the HTML viewer allow you to specify exactly which colors are used to display each of your annotation types. For the Java Viewer, you can also specify which types should be initially selected, and you can hide types entirely. To configure the viewer, click the Edit Style Map button on the Analysis Results dialog. You should see a dialog that looks like this: Configuring the Analysis Results Viewer To change the color assigned to a type, simply click on the colored cell in the Background column for the type you wish to edit. This will display a dialog that allows you to choose the color. For the HTML viewer only, you can also change the foreground color. If you would like the type to be initially checked (selected) in the legend when the viewer is first launched, check the box in the Checked column. If you would like the type to never be shown in the viewer, click the box in the Hidden column. These settings only affect the Java Viewer, not the HTML view. When you are done editing, click the Save button. This will save your choices to a file in the same directory as your AE descriptor. From now on, when you view analysis results produced by this AE using the JV User Colors or HTML options, the viewer will be configured as you have specified.
Interactive Mode Interactive Mode allows you to analyze text that you type or cut-and-paste into the tool, rather than requiring that the documents be stored as files. In the main Document Analyzer window, you can invoke Interactive Mode by clicking the Interactive button instead of the Run button. This will display a dialog that looks like this: Invoking Interactive Mode You can type or cut-and-paste your text into this window, then choose your Results Display Format and click the Analyze button. Your AE will be run on the text that you supplied and the results will be displayed as usual.
View Mode If you have previously run a AE and saved its analysis results, you can use the Document Analyzer's View mode to view those results, without re-running your analysis. To do this, on the main Document Analyzer window simply select the location of your analyzed documents in the Output Directory dialog and click the View button. You can then view your analysis results as described in Section .
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.pear.packager.xml0000644000175000017500000004727311665471336025051 0ustar drazzibdrazzib %uimaents; ]> PEAR Packager User's Guide A PEAR (Processing Engine ARchive) file is a standard package for UIMA (Unstructured Information Management Architecture) components. The PEAR package can be used for distribution and reuse by other components or applications. It also allows applications and tools to manage UIMA components automatically for verification, deployment, invocation, testing, etc. Please refer to for more information about the internal structure of a PEAR file. This chapter describes how to use the PEAR Eclipse plugin or the PEAR command line packager to create PEAR files for standard UIMA components.
Using the PEAR Eclipse Plugin The PEAR Eclipse plugin is automatically installed if you followed the directions in . The use of the plugin involves the following two steps: Add the UIMA nature to your project Create a PEAR file using the PEAR generation wizard
Add UIMA Nature to your project First, create a project for your UIMA component: Create a Java project, which would contain all the files and folders needed for your UIMA component. Create a source folder called src in your project, and make it the only source folder, by clicking on Properties in your project's context menu (right-click), then select Java Build Path, then add the src folder to the source folders list, and remove any other folder from the list. Specify an output folder for your project called bin, by clicking on Properties in your project's context menu (right-click), then select Java Build Path, and specify your_project_name/bin as the default output folder. Then, add the UIMA nature to your project by clicking on Add UIMA Nature in the context menu (right-click) of your project. Click Yes on the Adding UIMA custom Nature dialog box. Click OK on the confirmation dialog box. Screenshot of Adding the UIMA Nature to your project Adding the UIMA nature to your project creates the PEAR structure in your project. The PEAR structure is a structured tree of folders and files, including the following elements: Required Elements: The metadata folder which contains the PEAR installation descriptor and properties files. The installation descriptor ( metadata/install.xml) Optional Elements: The desc folder to contain descriptor files of analysis engines, component analysis engines (all levels), and other component (Collection Readers, CAS Consumers, etc). The src folder to contain the source code The bin folder to contain executables, scripts, class files, dlls, shared libraries, etc. The lib folder to contain jar files. The doc folder containing documentation materials, preferably accessible through an index.html. The data folder to contain data files (e.g. for testing). The conf folder to contain configuration files. The resources folder to contain other resources and dependencies. Other user-defined folders or files are allowed, but should be avoided. For more information about the PEAR structure, please refer to the Processing Engine Archive section.
The Pear Structure Pear structure
Using the PEAR Generation Wizard Before using the PEAR Generation Wizard, add all the files needed to run your component including descriptors, jars, external libraries, resources, and component analysis engines (in the case of an aggregate analysis engine), etc. Do not add Jars for the UIMA framework, however. Doing so will cause class loading problems at run time. If you're using a Java IDE like Eclipse, instead of using the output folder (usually bin as the source of your classes, it's recommended that you generate a Jar file containing these classes. Then, click on Generate PEAR file from the context menu (right-click) of your project, to open the PEAR Generation wizard, and follow the instructions on the wizard to generate the PEAR file.
The Component Information page The first page of the PEAR generation wizard is the component information page. Specify in this page a component ID for your PEAR and select the main Analysis Engine descriptor. The descriptor must be specified using a pathname relative to the project's root (e.g. desc/MyAE.xml). The component id is a string that uniquely identifies the component. It should use the JAVA naming convention (e.g. org.apache.uima.mycomponent). Optionally, you can include specific Collection Iterator, CAS Initializer (deprecated as of Version 2.1), or CAS Consumers. In this case, specify the corresponding descriptors in this page.
The Component Information Page Pear Wizard - component information page
The Installation Environment page The installation environment page is used to specify the following: Preferred operating system Required JDK version, if applicable. Required Environment variable settings. This is where you specify special CLASSPATH paths. You do not need to specify this for any Jar that is listed in the your eclipse project classpath settings; those are automatically put into the generated CLASSPATH. Nor should you include paths to the UIMA Framework itself, here. Doing so may cause class loading problems. CLASSPATH segments are written here using a semicolon ";" as the separator; during PEAR installation, these will be adjusted to be the correct character for the target Operating System. In order to specify the UIMA datapath for your component you have to create an environment variable with the property name uima.datapath. The value of this property must contain the UIMA datapath settings. Path names should be specified using macros (see below), instead of hard-coded absolute paths that might work locally, but probably won't if the PEAR is deployed in a different machine and environment. Macros are variables such as $main_root, used to represent a string such as the full path of a certain directory. These macros should be defined in the PEAR.properties file using the local values. The tools and applications that use and deploy PEAR files should replace these macros (in the files included in the conf and desc folders) with the corresponding values in the local environment as part of the deployment process. Currently, there are two types of macros: $main_root, which represents the local absolute path of the main component root directory after deployment. $component_id$root, which represents the local absolute path to the root directory of the component which has component_id as component ID. This component could be, for instance, a delegate component.
The Installation Environment Page Pear Wizard - install environment page
The PEAR file content page The last page of the wizard is the PEAR file Export page, which allows the user to select the files to include in the PEAR file. The metadata folder and all its content is mandatory. Make sure you include all the files needed to run your component including descriptors, jars, external libraries, resources, and component analysis engines (in the case of an aggregate analysis engine), etc. It's recommended to generate a jar file from your code as an alternative to building the project and making sure the output folder (bin) contains the required class files. Eclipse compiles your class files into some output directory, often named "bin" when you take the usual defaults in Eclipse. The recommended practice is to take all these files and put them into a Jar file, perhaps using the Eclipse Export wizard. You would place that Jar file into the PEAR lib directory. If you are relying on the class files generated in the output folder (usually called bin) to run your code, then make sure the project is built properly, and all the required class files are generated without errors, and then put the output folder (e.g. $main_root/bin) in the classpath using the option to set environment variables, by setting the CLASSPATH variable to include this folder (see the Installation Environment page. Beware that using a Java output folder named "bin" in this case is a poor practice, because the PEAR installation tools will presume this folder contains binary executable files, and will adds this folder to the PATH environment variable.
The PEAR File Export Page Pear Wizard - File Export Page
Using the PEAR command line packager The PEAR command line packager takes some PEAR package parameter settings on the command line to create an UIMA PEAR file. To run the PEAR command line packager you can use the provided runPearPackager (.bat for Windows, and .sh for Unix) scripts. The packager can be used in three different modes. Mode 1: creates a complete PEAR package with the provided information (default mode) runPearPackager -compID <componentID> -mainCompDesc <mainComponentDesc> [-classpath <classpath>] [-datapath <datapath>] -mainCompDir <mainComponentDir> -targetDir <targetDir> [-envVars <propertiesFilePath>] The created PEAR file has the file name <componentID>.pear and is located in the <targetDir>. Mode 2: creates a PEAR installation descriptor without packaging the PEAR file runPearPackager -create -compID <componentID> -mainCompDesc <mainComponentDesc> [-classpath <classpath>] [-datapath <datapath>] -mainCompDir <mainComponentDir> [-envVars <propertiesFilePath>] The PEAR installation descriptor is created in the <mainComponentDir>/metadata directory. Mode 3: creates a PEAR package with an existing PEAR installation descriptor runPearPackager -package -compID <componentID> -mainCompDir <mainComponentDir> -targetDir <targetDir> The created PEAR file has the file name <componentID>.pear and is located in the <targetDir>. The modes 2 and 3 should be used when you want to manipulate the PEAR installation descriptor before packaging the PEAR file. Some more details about the PearPackager parameters is provided in the list below: <componentID>: PEAR package component ID. <mainComponentDesc>: Main component descriptor of the PEAR package. <classpath>: PEAR classpath settings. Use $main_root macros to specify path entries. Use ; to separate the entries. <datapath>: PEAR datapath settings. Use $main_root macros to specify path entries. Use ; to separate the path entries. <mainComponentDir>: Main component directory that contains the PEAR package content. <targetDir>: Target directory where the created PEAR file is written to. <propertiesFilePath>: Path name to a properties file that contains environment variables that must be set to run the PEAR content.
uimaj-2.4.0/uima-docbook-tools/src/docbook/tools.jcasgen.xml0000644000175000017500000002401711665471336023747 0ustar drazzibdrazzib %uimaents; ]> JCasGen User's Guide JCasGen reads a descriptor for an application (either an Analysis Engine Descriptor, or a Type System Descriptor), creates the merged type system specification by merging all the type system information from all the components referred to in the descriptor, and then uses this merged type system to create Java source files for classes that enable JCas access to the CAS. Java classes are not produced for the built-in types, since these classes are already provided by the UIMA SDK. (An exception is the built-in type uima.tcas.DocumentAnnotation, see the warning below.) If the components comprising the input to the type merging process have different definitions for the same type name, JCasGen will show a warning, and in some environments may offer to abort the operation. If you continue past this warning, JCasGen will produce correct Java source files representing the merged types (that is, the type definition containing all of the features defined on that type by all of the components). It is recommended that you do not use this capability (of having two different definitions for the same type name, with different feature sets) since it can make it difficult to combine/package your annotator with others. See for more information. Also note that if your type system declares a custom version of the uima.tcas.DocumentAnnotation built-in type, then JCasGen will generate a Java source file for it. If you do this, you need to be aware of the issues discussed in . There are several versions of JCasGen. The basic version reads an XML descriptor which contains a type system descriptor, and generates the corresponding Java Class Models for those types. Variants exist for the Eclipse environment that allow merging the newly generated Java source code with previously augmented versions; see for a discussion of how the Java Class Models can be augmented by adding additional methods and fields. Input to JCasGen needs to be mostly self-contained. In particular, any types that are defined to depend on user-defined supertypes must have that supertype defined, if the supertype is uima.tcas.Annotation or a subtype of it. Any features referencing ranges which are subtypes of uima.cas.String must have those subtypes included. If this is not followed, a warning message is given stating that the resulting generation may be inaccurate. JCasGen is typically invoked automatically when using the Component Descriptor Editor (see ), but can also be run using a shell script. These scripts can take 0, 1, or 2 arguments. The first argument is the location of the file containing the input XML descriptor. The second argument specifies where the generated Java source code should go. If it isn't given, JCasGen generates its output into a subfolder called JCas (or sometimes JCasNew – see below), of the first argument's path. The first argument, the input file, can be written as jar:<url>!{entry}, for example: jar:http://www.foo.com/bar/baz.jar!/COM/foo/quux.class If no arguments are given to JCasGen, then it launches a GUI to interact with the user and ask for the same input. The GUI will remember the arguments you previously used. Here's what it looks like: JCasGen tool showing fields for input arguments When running with automatic merging of the generated Java source with previously augmented versions, the output location is where the merge function obtains the source for the merge operation. As is customary for Java, the generated class source files are placed in the appropriate subdirectory structure according to Java conventions that correspond to the package (name space) name. The Java classes must be compiled and the resulting class files included in the class path of your application; you make these classes available for other annotator writers using your types, perhaps packaged as an xxx.jar file. If the xxx.jar file is made to contain only the Java Class Models for the CAS types, it can be reused by any users of these types.
Running stand-alone without Eclipse There is no capability to automatically merge the generated Java source with previous versions, unless running with Eclipse. If run without Eclipse, no automatic merging of the generated Java source is done with any previous versions. In this case, the output is put in a folder called JCasNew unless overridden by specifying a second argument. The distribution includes a shell script/bat file to run the stand-alone version, called jcasgen.
Running stand-alone with Eclipse If you have Eclipse and EMF (EMF = Eclipse Modeling Framework; both of these are available from ) installed (version 3 or later) JCasGen can merge the Java code it generates with previous versions, picking up changes you might have inserted by hand. The output (and source of the merge input) is in a folder JCas under the same path as the input XML file, unless overridden by specifying a second argument. You must install the UIMA plug-ins into Eclipse to enable this function. The distribution includes a shell script/bat file to run the stand-alone with Eclipse version, called jcasgen_merge. This works by starting Eclipse in headless mode (no GUI) and invoking JCasGen within Eclipse. You will need to set the ECLIPSE_HOME environment variable or modify the jcasgen_merge shell script to specify where to find Eclipse. The version of Eclipse needed is 3 or higher, with the EMF plug-in and the UIMA runtime plug-in installed. A temporary workspace is used; the name/location of this is customizable in the shell script. Log and error messages are written to the UIMA log. This file is called uima.log, and is located in the default working directory, which if not overridden, is the startup directory of Eclipse.
Running within Eclipse There are two ways to run JCasGen within Eclipse. The first way is to configure an Eclipse external tools launcher, and use it to run the stand-alone shell scripts, with the arguments filled in. Here's a picture of a typical launcher configuration screen (you get here by navigating from the top menu: Run –> External Tools –> External tools...). Running JCasGen within Eclipse using the external tool launcher The second way (which is the normal way it's done) to run within Eclipse is to use the Component Descriptor Editor (CDE) (see ). This tool can be configured to automatically launch JCasGen whenever the type system descriptor is modified. In this release, this operation completely regenerates the files, even if just a small thing changed. For very large type systems, you probably don't want to enable this all the time. The configurator tool has an option to enable/disable this function.
uimaj-2.4.0/uima-docbook-tools/src/docbook/images/0000755000175000017500000000000011665471326021714 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/0000755000175000017500000000000011665471334023053 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.installer/0000755000175000017500000000000011665471326027136 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.installer/image002.jpg0000644000175000017500000005670011665471326031154 0ustar drazzibdrazzibJFIF``PExifII*i,Software: Microsoft OfficeC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222>" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?6oi]* \|7v9S4; V+#Mbød<2i5IGg5f[1A@H 5xn:eDw;n]ʧ滩RRsԫ%t ӿ~Vգ[OK4 RGtڤLgf!mԒ~BzFk{2ϣōwnNdF@#4ܒlߡFlߡ\%`l`>T3{dbXYA"ռVQ PXЫrsN"NB CVԴ&VC2!/63/Xr͏zw_ ͗t(B~E]H.#y#eXp ;dWPRfcOp~9$%S/Q@ ;u ?*/*% p갉29G.r0xU-^iT:2Ir 8;Qu|:_:/Q/W5Vad>A3chKr*}F{MM-%XD"5nno8ad;3B~~sϨZMb[X~Lj41]zEmN{I/C [J.4Cn'lRIa}~hlfby 87$`J#{6_ӿУ :w?k{!lbc1mqR^)M\] C'9p bs͗t(͗t+ĺ/D<rIs? 5isqq Rhx|1Gbs:gI1 se@; 3e@; oݢFVlߡFlߡZ٭?[]/Q/Vkv@ef:wf:wݣ5EY~~jfhotVlߡFlߡZ٭?[]/Q/Vkv@ef:wf:wݣ9EY~~jg7hotVlߡFlߡZ?]/Q/Vsv@ef:wf:wݣ9EY~~jg7hotVlߡFlߡZ?]/Q/Vsv@ef:wf:wݣ9E_艠ip0I&?MCwjmYЅWng}Dމ߽ˣh#ĤpOB~Gm?FM;Z.ET]h3gz(8D'oqI ]8^AhϱKs\ӚYG71>ѪY[H=#byq%忊.mbYnZb'A>xٌۧ8*QsFe.~M7ÊYrHg&5c.gdrbcw#ӕ?ZM+h\n/eW.~DM߼~Rќ>Y;b(Sig{~NKgʩoڙ'`܄sR:7PKеFVY{`1Qo5+r{[ gnu?z Ւ z@kAycH$`FHrGLbTvmke:CNPZ@p" :)VX+T"at4mJ}JW6W0a&U[Y~# YֶgKa1)Pά  MMW, (E#ݿg7z}H;[tZ-rt:W)N=D$eQdV,ܬw#^1q;jׅIwyh.aqny^ Ftء2NF ZjXM5ܟeNzc{2Ag E; T_u~B1=[)1h׏Tn:t.TLvˠȼpyӨD\4 , k<}=Yʟnq`}:w_iS(nDO:ҭE\ZFcMPB9#4@TZp:{U( ӭ'doCsڦص}'SQE\BhWQIF؇4[/;g_zEArXFrDlZ<}zGt>[=s9tQd)KZ )VOvhtK GztVh.VRBKBko#R\m.7CӯY V+6 ht+i@4!KLQd)$Nbݿg؆޸_z{_)+!6tY Ue-wu UТliK,[BTp 涨.Go@C?߃RQEm/PԔQdv ?nz5%Yݿh۷^~ IE@Go@C?߃RQEm/PԔQdv ?nz5%Yݿh۷^~ IEAr?o@C,v ?nz5%Y߃GݿjJ( m/PԔQd#۷^~ v ?(.Go@C?߃RQE\nz4m/P ݿh۷^~ IEAs;VRӤPB'ً`O°Mɵ6WNP^MDvL%J$"D:h[P A*x8l-kAQno侶K왰ppq]5^tefy ˀ`N~bVzR-ǝvyٿwI&m/Bbl]Z˖nѭZf٭&U>rF6dOfN!I9svAZߤާ=n mmvCqƋI‚&{a-%:) 騣,r6Β6qu4r7[Q۟?6ύ9V2M+5,DždXdա?~Q݉mUnOxiXY,'PxM;he E 54ǚrIzN ύ9Q|n?*Koe`h )HǞQ랽G|.״V Գ 89J.JGrFpcGmUn-W]< kBKE{ӦW,[dy'y,29RW_bE?qTmsth|+4MB$h'p<,H AsޡEu! lfsp+wNthmsmUE J1,\Ya !8')3u)㳳PSsy rIN$H E?qTmsxJƊʖ|u%?2Op[\[ $Hc.7p;smUn⪝Peie*L)>e8e$ޡKa-̉z--# ϐ%;< 9'.ns>7X_Rirޙ A"(0w'Kk]YȒ9;g9 GE.;ns>7YcyWKibG 앇Ϝ){+;=Y4itJpc #yf@ {nx'4{:mUn#NH| {@1 {t[QL^4OhĪXCs;q3\;&۟?6ύ9UN[y&-Euʈ +nXlc)Ld'hXɄBTIqG. ?qTmsy,c[Kih3( c☟tImY5 ,=(u;{mUn|DqyfP]Ku!: {zf?"FkeW  ܐGGlF۟?6ύ9R[xnu]#R弴"eU%C|DͭWC"6w\9tt;ns>7YKbgWP{;tI#̡cWbK8U G d 7F۟?Ҽ{ ޔn.-[+D8!:OYޘh@$LqX|xhu/kkmUn[kCY)#|GS A 5Yӳ|n?*?qUE,`smUoQG3 ;ns>7[Q۟?6ύ9Vs0|n?*?qUE,`smUoQG3 ;ns>7[Q۟?j$EC$\㟿Mz]p?[jqwac.+[a?Š(EPEPEPEPEPEP~"^bhկc(pJW42k(8i$үq9d}!ڸ1WG8YnPizmzl%ORgE!T!,3I;ׯ@7cq\%|ڜSI*ZHP\+|U5wwRlme?ŖVѻM4i^zY/}+ԅM:c_v=.d`xGLHk M91rWO?SJӗY:ܛw^WOMkf=P9 Gf\Y%c}9 jg=6{{kna{ds0xG[Vg#r#T-^)T~ owAxM2 9(G*v o=E#RYyxOKْ]r30I#UTe=ا+rYʊzfb(%ى9$\QE ( ( ( ( ( ( ~#tWfȻo]V=(@QEQEQEQEQEQEfEW |ͦA>H`|־Af6'aֺӭS:ZT}F2rǯsUJ**cDFv7}70U :X_*6VmJ H;J ꣌MIH'vi}2FFӞ ?@I>AU$vvr#ʲ9PuEs+-%dVW,f5{mrq;XV4hʼm売9rȊPHeEsڞtR"n;^ERUp <63 ea1X ,^R*]<ۻr+M*c8G,JK"_(l.cOzuǏlmc}rѮT*B+3lgo|ɢMX o|&|&hk}4}5E[?ɣ?ɬ(oMoMdE}h}k&,GY4Q`5o|ynx.&9#ܬ=#͢TP0BoMdE}h}k&,GY4Q`5o|>o|ɢMX o|&|&hk}4}5E[?ɣ?ɬ(oMoMdE}k2KMw,|זXW$qҙEsg'Xl(V|-s[al"[Hp+;(UjXIfW,bR]n$Iԗ:Ɲg0;[wڹtzT4Q`-\跫nVVӭKa\ң[Ff'$w) qP> X6᧌FM@6;{v֟6ۉy)&yK1;rI?qQQEogZ1km>2lpgԸҿ~ۼ'>Oo|ɢMX o|&|&hk}5|A9s߮?=TV/ Z_kV((((((((((((((((((((((((((((((((((?=uT_UpfZ/IEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\?E_i/3_ÿ֭exw@}@Zդ(((((((((((((((((((((((((((((((((+Y\?E_wkw@}@Zլ/ ZQEQEQEsu6ryhO9,* r"ʑ)-cei6{k $,[\#v@e1ҽ$wUb^BINloTRѮ J{Ig_̞Ru_?(9o5I;fVM[UԖv+=sך}E`o"<ÚCmC4![u"Bow&bM[)>}< 7/睿o"_;E0!Q oh}<}y(*o_;E`v7G/睿o"!Q oh}<}y(*o_;E`v7G/睿o"!Q oh}<}y(*o_;E`v7G/睿o"!Q oh}<}y(*o_;E`v7G/睿o"!Q oh}<}y(*o_;E`v7G/睿o"!1ܽ?1X $]]2##u@#wҸHET߬o ~@&/* 誛M1To?7Q`E*o 5MQTX9rk?5MQTX9rk?⩯y{l*khdbLѸVbA s>QÙEr~4Uz+ӎ/ Z_kV((( :W](ֵ`J@7nBÂH?R}XX + R=LDP䈮۲ʲH#|X +Q{~N*EcpdcR}z~OEڢ~}=a',?UnߓQ`6__X?u*Ebz~OGۯTX +>}=`'mQXnߓQ?Uju*_X?⨰TV/ۯT}z~OEڢ~}=`',?UnߓQ`6__X?u*Ebz~OGۯTX +>}=`'mQXnߓQ?Uju*_X?⨰TV/ۯT}z~OEڢ~}=`',?UnߓQ`6__X?u*Ebz~OGۯTX #_|-j]OdΛGuŝnJ"* u 6vl~- '$իZ̗tok?:?`aOQ?+o1N ):> K;{&Oܣ^UA #K%Weεˍ1(H)6eыɷn~Onm7 xIaIwy jw]wiqo;U%.c( 0cZIyTRKfpI?݂+m#,aORaOSpjx]yx|)7)v~S1ȫ?ΰZm(o j}oGYtbjkT:-hcubr;#Rp@ gZݫXӢ+2¹?=uT_UpfZ/IEPEPEP)+Kͮy`((Fwr WG#EbZ2ojUMޥj#tfD(GLv0x6'4ἆ,m8̋&0zsK*~su?p9ABa{62?|n>_bÜ`9ɼ!Yɧ#uQ7ID F1*~su?p9ϧSS Y*FT1j3*0ڲo8%YiYPqxmCf8h{H ܓ{쫯GU8[CumhA5ؖFHGaA0vܠԦ6D`Q Cc*~su?p߃eʍuKUUyWp]Amje]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]Ve]??]V"+`6Bc&glCع .(>?_ +"[c*Ŀ0Lgg(5Ǥ_ .NHTq2[i8u4]QR}H}H]'٧?L9b]n@;Xǥ@%QL?=uT_UpfZ/IEPEPEP+?ZG+I D̡[hS3wy?14^MuO|`7:ch??&E`ן?Gy?14X +μ<oQX>uO|^Mz??&:chVy?14yן?Eޢ|μ,^MuO|`7:ch??&E`ן?Gy?14X +μ<oQX>uO|^Mz??&:chVy?14yן?Eޢ|μ,^MuO|`7:ch??&E`ן?Gy?14X +μ<oQX>uO|^Mz??&:chVy?14yן?E5/cЬͬ,+>.O PJto4.[2zNcZ=%4|_S-W1rT.ciXarpXq>zKh礿ƎPok4orI#o rx=8䚩]Aȑ`RD;`}MY礿ƏzKhΟ*"B!b:rxo/o񣕁P^DZy?!U~o/o#8 Ӱ EUW'OQ}Wg?=8 /Y^<_Ei=((((tP2oWE\ROM=cԶ?`S$?dz| g?O-ǿ]&h$?Tdg63 u$wj>VIq^lv4ݼ?qӾ7?U!upX32{)R7?G&j]cr 0 cŠ>s_R)RʡN9>=ݛI߲M=c9jdB%Y$6Ƹ2vF&h$?@Mªer!e. `FKHv&o N $?dz|HI3ml8(urϽMd.ZidȨI؍fNE|D{Z]25흖YX7B`sޮOEP6U*g >7?H-e DA֑/T0VCk q4q^B{vLh$?4D,{moΫyM}2p-1dz.9h$?G >X #i;>TI R&bp]I-'`Y$? hW&VUe5w?8ݸ~^ cڭ3%hl:me,`C4RAVho*#2T@ o.Pm. J 00~97?G&j\̷3,1E޻qv;)ԤIpc(<9cڎfM=cIB-=M-;39 9Rp cf?QE0 cۛkx ۼRIUU_]tH?y*З?u''^2ڿGǭ:tGL?_x?T?'f5 64 Ol#,t?KL?y!3% x2EhibUUhT6a@d~4=VIK3%Ui"1$amf@F <aa5 i'#^2ڿGǭ=B{Zgj+w@$JI OZy"[[o z-hETQEQET_U묮OƟN;5; x-jWk+6{kV0=Ԟh{QW?(ZtUo(?":*7?~QcFrs(?@V)6*.I'?֟ (?d \?ky}(,k8}o§?"o( }o<TuGQO_EAr<Q (?.Sfy$28PH W?(ztUo(?":XX1'8Uo(?"ky}^N:F (?d \?ky}(,ky}s8?7?~QcE\s8}o§?"o( }o<TuGQO_EAr<Q (?.A >7?ScG7?~QY>7?GqG*o(?" qG(\?OO_EuGQd d?}o§?"o( }o<TuGQO_EAr3!w z*7?~QcO@NO_EuGQ\X궪aR3#ǚ鿱(jVϮ{N4}\$k?"o*c>;I+O{9M.& $bNLy(?,sOi1!\d6<~P@#R[$k?"o( O&ӿMtuGQO_Ec>;Iի KdXyUl@DMry$cV7?~QcIñNO_EuGT;諟uGQO_EtS 3pH'F{aH#oL@\?=t6M7y 75rdmS\?E_n / ]/?Tuw@}@Z4_~cR(QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE07bI=S^/c_{rdǡL11+ҮկҪz ӜI%V`rȕOQ}Wgu_xT_U5; x-t/Q?_kJ(aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP_VՏR?Ji/u_xT_U5; x-t/Q?_kJ(aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP7?V\UZ#7_o?贮[Ɵ]OUi\?E_n c_ÿA|s<_E _>Ԣ*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQECsUjHFgEi\?E_}ҹo=R:<_E _/h_EGIƥQP0((((((((((((((((((((((((((((((((cUZTet_xT_U?y]Er4Uzt5; x-t/Q?_kJ(aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPWp}j YAM/J|i/7^Ei\?E_n.E*:; x-t/Q}CET ((((((((((((((((((((((((((((((((> XCMy]Er4Uz?贮SƟVC_ÿA|s<_E _>Ԣ*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEG7ZEL w-+W'/贮SƟVC_ÿA|s<_E _>Ԣ*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE2O>*Y>tƓBZW)OQ}WgO^Ei\?E_n.E*:; x-t/Q}CET ((((((((((((((((((((((((((((((((dt}jԢ*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE5SqNn`bI!-+Y/o贮OƟVC_ÿA|s<_E _>Ԣ*QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE5SiқL I#{]WEr~4Uz%u_T_U`+X%"+8 UYÿpsa?UX ?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?hXo,?2?>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;c"I!"1QUASc24Tabu#35qtB$CRV)!1AQaq"R( ?Z WB( dli #LV4QarWY-du+q穳XFzs,]nLS& p|^+Cԛ\'ڟ($4K7^M:-kcbp̦tʹNEK/ UnBjgJI)U]*i,md;2`⣨|LD$/?uЫCXsjcl=mԗLS& p|^*^;Rarb[d3`o,ĠěMK%4 XX7PomKrh\ɂvd;C~=;!852fM𳤨ESKrC x43ɂvd;Se@=tﺕ%#وR:3 X]{|'axLT1WS>*Y c]+fikI7;P⸵M4S\3Ԛ2`0NÃ^b<]?ȅ&+Y0NÃL'axu5M`0NÃRRPzB<'axLTԚԚ;2`Џ& p|^)8>/&&&y0NÃL'ax554#ɂvd;I=I=ILS& p|^*MAMAM`0NÃRjRjRhG8>/ɂvPzPzB<'axLTԚԚ;2`&LS& p|^*]AMAM`0NÃRRjRhE8>/ɂvPzPzB,'axLTԚԚd;2`Ћ& p|^)8>/.&&Y0NÃL'axu54"ɂvd;K=I=ILV~Ƕ>Cv1qv*}AZK.`ascpvnulmĽoFFGMqi w, {*z˕l@ 0N\rVZnk[oU?y^ϜsWOa]ؙn)L^h;xI$ao:-F0 e~W"wb_5ak+tz9Y9Z׋ǡq8T԰׾9'i+ÑCb\amOo3AAKEO@4990GQWyf#WN>jil5 YbwXSc)cԍa:7CX>8e ryf#NYwq,rNTKa35{fh \p}G5҇oX`/E->BCF)6v[BfĜ_X-ţ.dŸT*:;Fkνۛ+?T⭤Y(`+$dylM$n6#~:fĜ_I_F|>zƪvGUǵRU"GHwKͯmmah-׾hhlLטH^k.7˖kI5x$ƾ|8LKFV*$qSH^G2P:Ŷpsy*,-,u9e5E,!{s^nyfĜ_V)/KfFՊS9N [ѿ +<̢ sH署tw|_PW[58Y#p7y\~'61Z0ҙi*yѻpp kv7#pvjviˈ渁.Wr14`gkJ <%,#~U,yfĜ_[JeRǖkI5x$`=I,;8kIz`=KZw>$`=I-W;|IUyleRǖ>$62RlcUyrcGěl6Ա9j#MԛXcGĜ_&[M,yj#NZwc-&z<_'-W;|Iz`=KZw>$`=I-W;|IUyleRǖ>$62RlcUyrcGěl6Ա9j#MԛXcGĜ_&[M,yj#NZwc-&z<_'-W;|Iz`=KZw>$`=I-W;|IUylei[]KJ6zyf#Zlnj*)cnP'xXz\5wJ0Jx$+}ȹ'ٱ^ -9b359*b-we:ǵv|'k^|Enpb)SU4~|ݏQY~UGk@X-c7Vra[^1mp硭s, ik/w6[{ 3UCO-ؕ5,U>}\m>-7Il3[ ?Mon ۃEW]&׈bF+nlTҶ_+ciq a{M~.ZGbc`}@2L`fX#Vc\&1WS;5'0qZQӢj[`%ѳ[iN',viD5n \:.օ )+Mإ\2v9co\蝐ns{:C_OR|25c48 8{@? 9f6$Jjcfs!Z$:<+F+r;#c_E?iRIg3bہ5PKQOirŭ}kwu1`&KWSO]5K<,:# y*"\vYwA5>#v@^+f/5wt H|273c=$oNW:HcSm``jmIncv8anK(oHh, |j7S]s"ְI0  [>v(fZx~WcX ssX㿩rG+OEN k$ϙAv`D"ǝ`G:^&F# *cNxۘ[f|}N'uPs`WA k#38l1$N6Fa nI9m[GK+arG= 0爹N,95"ǣyn""" """ """ ""7J>_J>_lxFd-vHCYloX[wpVo+V-kmF jid| $q;c>*I=Nz' &?ŇGɋвgd,=^N+5}+ja@6KU=Nz' rwi_;M%XskccL,y 9j#~BgwH. EOv5ޢI¯bdcje1=_{s64ETkC׺H敭{Y}B\Vz' kEOv_ }Lv+kE;qx;ͭv-L'Y+e6f OQKmVTi8S]*{*)67tm{v^\憁\Njtݎb? v6zċr7ns ڞTi8S]*{*X<'G#l35ek\/ۀ;ܳ)+*5Q5Ιؗry Iz\kuޢIšQSݤ[)q<>5SGgXZhc<]~1}u3Z8c9d'CN1KmnTi8S]*{**:ZtmQ) \of ›mvU5W͛-ߢpmz' kEOvlq<>>ω׉#f3IUOJNQ fHsEqqKjQSݤMwp5EP`ux˫!-c u3_~f,*CVɒǞn?ޗյޢIšQSݤ[*\O :ji]x╯tNpnUht k!|3SCDc|r/ ߼u. kEOv5ޢI¬&TÅD9 %'`&Ӿ+ k^Æf# k~ԗmwpTi8UXPu+k!~)V7kZlzoBT:8n 3-6bW:bZmK&:VNa,f9:AUb$2G],ҺėFMD0FJ.ۀ4 i4/kp5M}ds30{;'ef }2f= qm#Y@s֐mA~1f4b{c*Lq˼z\Q%Svš0X à|d| {cF8GBTWa3UyiX>?rTz9KIM4xtðaYRǘF[6+pvbc>!UR)FͦGMML2TC]&/y؛CzdA#WKA5 i[=t~yQ@,Oofm4CnχK,QAvDnf&͗z9)4k[;c" ynH{$`-CnLmc*Z܌FL٬֍-.IvAVrh!WM[e%WWsgwbtQ#&P71CuA ; 0TdְS2ѿ-!ċ\sH`Q9KntfMIH\ˈ/bI66TܡS$tqUT5o,quA61ɗuâ2 WEgGIE1Ҷ컄o!@^+e }<ukja_U7oM"/~G14[(ZhQOv+y""ˆE\_vD/z/L37-yS][(Z>VDXQ*" """ """ """ """ """ """ """ """ """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDDA*" """ """ """ """ """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA*" """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD0/z&}Wݿ#za4[(ZhQOv+y""ˆE\_vD/z/L37-yS][(Z>VDXQ*" """ """ """ """ """ """ """ """ """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDDA*" """ """ """ """ """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA*" """ """ """ }Wݿ#4긿 o+Wb<)VqϕDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD0/z&}Wݿ#za4[(ZhQOv+y""ˆE\_vD/z/L37-yS][(Z>VDXQ*" """ """ """ """ """ """ """ """ """ """ """ }Wݿ#4긿 ا|OnH۰4o-zП؏i߻ ?3;Bb>YQfy'#L? y'#L? y'#L? y'#L? y'#L? y'#L? y'#L? I[Χ%=ghOG™;Bb>Χ&Χ%=ghOG™;Bb>Χ&Χ%=ghOG™;Bb>Χ&Χ%=ghOG™;Bb>Χ&Χ%=ghOG™;Bb>Χ&Χ%=ghOG™;Bb>r q~oQLrYIsv|)'#QmLrmLrYOfzП؏3v|*-NMNZ;Bb>Y𨶦u96u9,;Bb>Y𨶦u96u9,;Bb>Y𨶦u96u9,;Bb>Y𨶦u96u9,;Bb>Y#:^>vŤg S=ghOG¢ڙڙ䲒 S=ghOG¢ڙڙ䲒 S=ghOG¢ڙڙ䲒 S=ghOG¼A#n/m=NK).zП؏3v|*-NMNK).zП؏3v|*-NMNK).zП؏3v|*-NR1,;Bb>YQ,;Bb>YQ,qꨱ&sbqsrL.'(ҏ?E~(BSiщU@mX]DUr ۳v\ﵕ+80-S:OdLI2/r,Lc6-3fR2G] &m+4 \}!y1 \ک"|ohfLٚ OllHp"zaM,l3 SՔUL2=OM 5es0^^sV(!'и}6:4tTSg8R<6"87>}rQWPh*cIJ&86kz-n4 VT@Z>l?!\ߥw7{wZo٦3a5tP+d-g~P gmc`f`T qD]V6itsE/rB4I:j8TFa`cfkG6h.%.9UTj3B<ݻDtt,KK+]$rƮWFesZA Z 2~KPcZ{hssnzTQ쭦&hfs!vw?39isvo4wG'1|NπK-0-G:\t]/Td{-7"uzg21͑ۋ`Ak idh.XNvvF6."u _y8XpXk6Va69n<IXjtk96J-[]SQM1.Im*;S1ISKL!q.q`P7I T8dӊM.q96[lh0 DFfL'1ۣr8W?gCkTM:I [ByE{\>\ FFbO}QZ&h&zN7 m bx{\ 66ŋIGD7]VTRҺ16P9Gt?ɻ mD||l9Xqz[a8I9-8t}͚ItnZ*-pSD idy:Ɔ;v]{_ pJR( W-lEܬNT.DN?i$5{K V>(_ f'(9@e :KJF'Qj22뵣f_-{PqXd } θsw8 U] X)E,!j#,pve&rtǧЭo|bQ#3#e<~f}6\n nޤ3m6knɭg\u}+MA&#,ʺkrZִfn'؄zGdG;}Aiu$yy3=>OgYK5gy-k{fqhu5/PFe/k}Ŧ{ Wx$ ǜDQ_NAb"% i&1[s35im溰UXs@1?:~+GjdԲB׿p/x7qw8 o2>L(h1i&`|[lAᤆ{^ۺlzM8IxxUI{ZK=6b;7gC{#uP63+{ w:JCcHpML&1'ek ͸6iִ4Ժ1-<3uk@CXz[XM~U@ɲf\o\u&]OFi =-}l +-DAGqiGq`?w![~(BK"(#-mַܣ"D" /e+쿏M ?6_+D" "V^" /e+쿏M ?6_+D" /e+쿏M (unkBJ|.kdA_elV}?XD_&EaazuEaW/A_elV}hّH" t긏Q4긏QvDŽ߻ ??w![@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDAVJ}DPCW 0d8_Y3?yhoXZ8gs<> қ> ҳ|z<' l4oJ09{w49fK@LjSVK,mFѲA% s^ä/Щ]8_Ϥa,P"Ň*r:`̀Ѷ\:F[L b[TFZ3,Apd9|6f>k>} қ>} ҩɦ814.ԵrL_<˪1Ĵ;shq\ |R71쑭vs7X8h7rB_gO}OW5.CS Z#k@=-p w7-,Қ= 7 Nq12VK^,:)6!S5+eϤadnxg?}OSg?}OWq*RNۇLXD;lf ӹ78eupfU7}Lr>][j'cm ! ۜ[~SlI/IJlI/IJLdmVRC$C{hc.Ǹ局iʬ:Z7ÔL#xu,qx  *|I/IJ򖦥Sjak^DruHnSX硦_ n&6긏Q4긏Qtdž+t&AIXهigh{Sʮ"gh{,aI 4)gh{ 4)gh{ 4)gh{ 4)gh{ 4)gh{ 4)gh{j*|v'or4+T."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI."gh{,aI dl5L9XڧǠ^ Z? ugjz\O7E5m Y|p#;>}P-mwGXs\Z\-ѼE- XBETIw^l!l C>}P+pmp 8D6TbnZ}b<єnRPVRK ,S.r$6g^g`^Ϣf EOa4Km1rI[<8>pمnQEKbks=HX %6o'p[Qf `^M;PzI[>=XRSsm­ٰ/uO`)jx߮I%MglC\:JZ|WM{,![ڇޫ kMftouWg`^bcĩ~!0'r<6W6F#wk9ݼ)0l&SΧxs#[4l繲l{W\ XϢf> ٰ/u~ Q$Ϧ2k3InCȈ\sFPRaϒw3^VϏV=ᔔw4pl!l C%$ Z> n#Rf+IS{sQ\G?(9%FI೘Aᦢ=##hKc`csSD;lW"DV)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.D)_Kt<},.DlW"O)_Ktzj<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQ<},.wHQAYWӊz#1X4Quimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.doc_analyzer/image008.jpg0000644000175000017500000003123511665471326030705 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@"P !1AQSU"#RTaq2345stBr$bcC%6$!1AQa"R( ?ꄱI rGM+;CȽ̩ŋa  ϷҎ9ROpVѾ8ˣk<ʳLWѲSdzh"KKt9]{1' /%gá/0< ضLC~@=5eN >̔l$Fk>)G||Bj85D4R HA e_'մԼ]]A5yx1&89"ɽu4&R Ysi8 $<6ܹG:@}[A_ w4۟dPrDKXR:Nk z֕N ]1 ࣑C]5߽6j&7a5vZ\Hk$ 'Һ1|V|;SmõmqSy+mõat\MP+c9-HUbeWk'aɶޓll+(ZMpi'͸tܾKj  sYw8eG89K/Z,X?A5z5`JHlb'-[zt_e d iĚǐXkukb\Qܾ8)SzRT :,&:]޵%M5%6)Kt@$PCYkK&Lq_6[vܧ(*# 5R4X y,U3 D&1 a$i⛟rs%7&z>qY1p8O Y,l~m :ƍh=ZE|cޮ"Jo=Jo=AG-k/{A lm?fFNc)cl{)2Pg1ƟMXkZ1taun,?%7͏7qciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ )s+②TƽshxGޓKaj!OeTJ⟳`jGNOez؆OJ>4\BZS|1LZS|1Z1psC/ʲf4"&ly9\ٱc޾1,Z{iiTe`i܋qa'QIKh{䕵ysGX[1跄l4c}oGr8\bzz$18t< #'?޺L:j:lLekbepHu嬰bciMǽ3ciMǽ\EciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽ3ciMǽ\DciMǽx,j=}$H2$胛daK3ҲY#!vI[;YHgT̫wuo#cq+ @c寇?5D $eވHY;(͖; \]+.\[r  R`qr.̑$Ų+KNy Hb-wEȶp 흙h3h/j<,NʧDM^b68]AU=:O,VؒOJY i[sM۞otwTեE{6&GzQiQE=M&GzQiQE=M&GzQiQE=M&GzQiQE=M&GzQiQE=M&GzQiQE=M&GzQiQE=M&GzQiVv7mA7;~10} acs3 _wzpR(v/" Ljp72'f$ Nrn81qv8uy>1qi{Ü3<%:L̚grz` 1B4X5%eBS.Z\I/%X[ˋ[~QABQ/>weppGbM ZYaӹhp!{۔zêy-lmCr=C`J(6C -I#KCtjpLQlcKY4A9䆽}h ^Spku3cd:ҸR 1^")"{*ėk~[%Ekqw vah@Wpc~IDM9+H${r ԩV2hds^Wx'^]?̣00K FWCwMQ%S"'mv!{uu?qXl5Μ ZfI {l[ظ;w6 ǹokRkx]{~ANkm3O/ÙcA BHUݯX op7~ASiIIf}qk Blw:P؉^%qyvoyשx=e7Xٜ5,s@؈hvL{`xڛXekbg 䐉FPӮoo𶵍1x8Ѿ !GTG uWݴ-sxQAED1t9 X9NkxjXE,Q73kx9F\He~ؤu4̙ɞ75.ߩ#:dj&0Cݖ0 6:R5vk{ NS |k^' G pA`pc l2f,h֌V:ܫLlXdѰY`G+9UF=:HJ>f$Z?qS 'b/.\j7谟cN&lr560kŬM%@>uqxipqs,[knjGbe$39[I-S^!L$t;¶*2M`s*d&Rlm͝wozXq$9?jly48{ug>a0@I%5L+xV{eOsg>1$OV䱐/R`h]`#;K[8jE6-9{]Q+ ,nv7I]If y־>_Ħ>_ī0pEMf/7_^RoZMEV)Y5WSkؑ+F|/ry]v5 ]|pX,dxmmc( ~.GTVF]#61̏ƸG՚P➛scEk!i ܻ}Nz~)IޜiOO;i;m˨Ty[4!&'泬9^cI-DK %X _:KziOO;i;Ipނ: sfdyiO XsªV#tTIkhvcO7L?3WR`Mf6|[]_R{KA: 慳n:F48XH]hqxf:idf{8,i<OX. [$R9OEm[ q粙A)uV>1Vb2igYY.:hu+U~#0XLd.fk|_痛T¸Aa01lo Cmfpo}53e3&hfua&_) k8W5xַk*|̧Q#Q3i$D{lA8X߫VW9w呎\~~vJN}0p38Ԭ"(" """ """ """ (+Q~Juw*?tX%ȉȊI4Q90: .cyi/(V*3qG5$oh!BSc" tUg2٪G\M[ c kh~Vrn]upkOL֗؝} sWd[{_}V!pkC/}nr:lFasL$Nx8ŴZ]ԭ`!BI&ѝRw KޞUuՎ(ޜQQ{8&;gwz]Glc*="/pTzD^Nޓ te=6-9J*,A$;[r[l#lCr7ֶ,ƨTpM%Ye(ɉ7<'ٻO4rm\5nr<9ev1]wNppw ;g)/ic׼1fd?zEU L!I^RZlk)9 fih>_YSҼE!9Nz2/!gg6Zr޶6-m^Ob1:,m/~8მ3c'%чG9ہ"lKS4&s@c- rodMGIXl9c4q:*sjmX0qkP7-]=kytN;hl{G5Ssr lpqRf'co5Ё[(1#FIKXΥ~BY[<lОU bփyަ35>P-dmkߟTby`Փ$0.mtŵ n}C,/^2 xڝV\E){61gkC'ɩQ;y}MNGn?V"zp#"Cޜ]9]HgXKy6wzUmcjbE=׀VzL=^CyEQ`EcmDd4X>nX>UupԆUTۦw9QQ{|f ;"#?@jp &/-DL $4kp'O{ת|?2x.&[#{~`ǤS-sC-C^iUj.wzp$2Y%vgnN(ޓ0DJL%I%IG|M^μcWߤToڗי-ZE~W%HRp38Ԯ[iL.g.EA] ;S+Q~Ji,DNDUERot?jMngmOi+h""" """ """ ""5ecWߤU\~~viL.r N'au+9v@( T~ߒA] ;V;Igr"r"*~ۧURot?j{I[DDQ5ecWߤU\~~viL.r N'au+9v@( T~ߒA] ;V;Igr"r"*~ۧURot?j{I[DDQ5ecWߤU\~~viL.r N'au+9v@( T~ߒA] ;V;Igr"r"*~ۧURot?j{I[DDQ5ecWߤU\~~viL.r N'au+9v@( T~ߒA] ;V;Igr"r"*~ۧURot?j{I[DDQecWߤU\~~v8OW-ϴ~?R]G)`ӿ%cw"'"*7[U&O36DEV;qJYXw*i)8OW-ϴ~?Rd?`ӿ%:wvDETU&O36j߶" """ """ """ """ """ """ """ """ """ """ ""~?cIZ+%X$$5LZfsAX޶<&?^~'&?j#axD)j#a<&?B&?j#axD)j#a<&?B&?j#axD)j#a<&?B&?j#axD)Cj#a<&?ZJ{HX^dXR"IZge .bSڹ*iF摁(9ja (9i#n9z1~,M]cRpvr0eMӛ 3 dM& .q'/pk_mCJ=3i+Zy)"u4DHۍ`~ G,逸W#f\Z-mXE6u_:)pH+3[믰,𗃯H[Þ)a=ڛ).bm*cMItyiǧ é1 Dm \^ײprnfUfi 6 |`hQc\ְXcWpL7isX\LM$ѩZ-[mXE6u_k*|F*#G֋ig]uT&0<଻hrooXzc!uynRXf1D4c33Vɿr$' Ѱ4D9} =}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}9= HR=}ȥk!y@@媳ϱ7g=X ?CVi 3ZHd{_Ԥ:N2EWK'l8Ϋ̚#u],d:N2j:\tvY;gɨr>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;?"K !1"AQ#24RSTaq35UrstB$bCcd.!Q1Aa"#2Rb( ?b斎Wϒv{ rCa|V *k掘9['lstqF׆-n}#!}נiY# /Qfq"lӭdUc|3``lv$ PEߞ "NS{Rwټ؜؁H7!o{jZى⎞!h'pqȳuv(ʘ)щ L5ynwE1.זVcC 7_] VPVGɜ+;YmsHEJaKbU&bupaVbn7N3%!c$,6e1N@#(>c^ ߩ*vnJLٛRic$ \k^7XC,WGݢ˘ֽ݈XkjA[)(qԋ:׶vH2~FD#6,#a@%e`:,}+OKJ7oU~fSI?3~(e|{ZfWIӺx]?R| WIN$k$geU4^~-5@sMsu8ɥT9sEqFrFó5R$GvkF&f^oCsT 5X[CI`Yöljp2>7cH69,/:Zl6{EGm3:V?A{ l&Dp F1s^Nx]Qiv:i 87&bޑ|}F-XC{&nBk<4-N:rEDfbna9>!éެ7Oaz$9Eͻvrjb2ma*" """ """ """ """ """ """ """ ""t2B́ wuy01,99!= goM{۳7ަʲTDYQ64e4PFd¾V7Z1-C%{uT)iE΁37* kY#ƆumHIsU͌,|#D- SuhpbRsssl淯x&l¸vx9~Zҵl Js3<Nj湽[~2{Mg[D=F 2G*G [e-( H lh{ϚzVq7DFw fܳ<'i1J]iּsŠ7uu-S2J[C3 sk"ݨ ]6.-9q's\곓d*]͉w;$n7{AJ]/:\J M8{Yֹ,M8ܹ \EU4 2/ L{.Hݪ {$%waѹt̽^9Xh'GOE6= kA;]lm4C-w;# RS{y=>5튦F5'5@$:CX޽4f2׏?Xdnk_(k@kqq i1WH)6qVVGCa6g H)j0wNKDo\1uMЭXZd".."" """ """ """ ""*" """ """ """ ""wuyP^kwxasXG]=3}o|苝SL_|+w z*%QeDD@DDD@DDD@DDD@DDJb*oa~U{W}vIe c$`<4*68i&{s@;h(8ە487thwbטq<4/PS^x\6)msy^T<s]LZνCI_x?|F:*]dP01=ٸ&sNc}-mYtͫ|f*=5e<_Bo:PI_x?LX 7_8/s 5`YzsŃϜHgߛ}M6+#-RJq7A*" """ ""wuyVqwWnw z+u?;+goMe" """ """ """ ""hl%Ww7jd?S*ɿWJiS1Q' A=B.;M[ ٭涌5g\rh=<ڏOr‚ $LNpG#pCo.Ƨ^~Yķ_.JƌTKLs$1ecm[[C@}t 19  sZ @nn5I4tuϱfXs湷t`,L#4lz7"lJ$ZJƽ"p ]ηXYǧpj3/6'ulDZpFM5G0['kp`z7񺇓gij qiؘF o}wV9䟥vAťF"D3Y{$e9PꉛPdp88rec,c0Nmz4YYT#,p :Gpau욞W[̹`˕v{Mނ~ƶhL$kcZhu>&J t9nm{~MnoZ[4˕_-im\mvy !'\\3uhX)vidsXXx&b [EOUPPIK0 k7olk^e@7x=Gҹswal\q٣I|ٽ.͝ d{Z{f[qޓgoMD"(" """ """ *" """ ~U{W}v 6C?ؿʻtK@.SAfـ %~+\3Y#Z'7fcp8tn¡Lr(gu$6 6'4߻x'xhr@ AÜthHNvs3g1vSViNc>i$ v]ݨ:WFTAY;lڴfOb0q 1%|LNi 2 veeCl"J ^2/vqwqWv{d.C86W73\̻*p]5e(c$s 8(x!t b\D[%KRy@- pU`ıT2 ":|\ћ;}m$}mC\;-AGR!xV%É$%ױ\jټFW$^ih_}:*0n)玒CM)< fIhSpLqʉC)MC #s'K Yj-3.OCrucX<$`t[Snnߡ^=Oё|d1L dm/ [oˮvWb5l<1R {A{f mw: *tUdę 1ywouͥKdpsf)71馅Iǹ}/g^)k,G74:[]F⮋N+9" """ """ """ """ """ """ """ """ ""=8\VCG{jS{m;zOwV7Q!^Udݪ͐O/&]*ӃI$ScD9죉< 7s9 ,`&c/c}z0i8)8#(mD AqK1<XڨM{+аe\_) 1= VbtL8ZYj- #Ri6.7o0_{t,*j0EK#h e.R Y֎90sVpEe_Xex?M;8d$h[~ordyetS58ܽi$n-ϖ{5SN?!kvxk`#46SҡρR3o:6.Ok]V\śp4tt= N/%Fٺ7r54M=YְfM9qi= , GXNa.fe6W ttk 5m۴ :~? =¡0 RE}|,BʑLms0d[ӽX\*sy!W5vL};\ %maQbN6'HEKLΰ%wV[o|-{Ƹ:6DZpr~u.S+N!}µlp';+Vw z(TDQDD@DDD@DDD@DDD@DDJb*oa~U{W}vIjboHIhɩpdA w -rw-9qx!Ϧ Qt*IROƈkr3A{mm54 ˝3<g5Lt⑵2Dr\7NyugnX%D:ie[\\9k?)(v&&Ty8(֋e HEE42J[qGq.XOsGKzp#y5:U,v 9rpg9Yg=!q{nZiITTLHxP.νakyW8H{ dmjoa沱3nNkzIA]Sl!gAkg#w{QJ5\$$o\0ld4ؓkvY!44_68Gh~&Qre%ĀNpQ7v~=Dd|#C-_>z:l} mk=KCX:yofY1 8rogJ olp|9Fqԟ?k6zRre$&N' p-`$ mmd6ѺF1ipul9GVll=Ac%q{[[5}iEl+dt\),ZrG7u͗LFX˺MekkvJᘋ1Jn1O4*2G <`p0\EkH`7 kn 5aN(]L]M7,+)4D\_*" """ """ """ """ """ """ """ ""=8\VCG{jS{m;zOwV7Q!^Udݪ͐O/&]*e>y٪)'0~Wu_aD@DDD@DDD@DDD@DDD@DD*" """ """ """ """ """ ""=8\VCG{jS{m;zOwV7Q ]8 ٘wɿT`/huǔ _]MںU%|U|s۲װ.%L\b6<iiq.t=_QE+ĪjiTx"k(akLAużT21!ŀsf׽+:t>_GEH8KZf~9_M;RO/x-wib/g]t)Џ?| 9]S̍aI:ݡ=KC|qŝniGnt>_HE=gG[Sɹm6Ps|B|`7]:h|SVʞ i"{ q6H #&ڌFEC6"\eq&ݱ7B>cq stu.:NG1p.5c%Sвzx,2vm?q{>:wnЊ)䍑Zv$-,QT&Mt2,v26o0bQckfƲka`lI7Vm1%qPHסrzsa|VkhHߣryڸ#|L|s$62\s{}vOMT]Olwߣua]KXB\H!t׊֌_iKk9T'uDt?+lci9_U-;=H1ϗ/5o= ˩q p88`7ݧˢTIC济 Aw7kf?YOf8Q 242Hpb熑 :mu|p13 'K)qj:>qI]n,7 p蠩f7=9-o:hq%݆cZׂדy CW;vy8f8.$}@һF1AMt #o4=W4*žcۇ4$hw9\nGchiOM5\6bZ@K8}ۇcXpq~巐]nWTINlZ $_r|*ڊ<"`F扮#X^^ڞYt[-T4`['j;oDbu"9ǵoz5n'NRTU R:?9LY9>58/oꫯڹ&:+/ Ã#'ojQSR fPLͲ0 ؍-3Dג=+?'x9>1픵 4 M~h,=:^uiqp<p_:?VxfboRWB.x=DEY*" """ ""=8\VCG{jS{m;zOwV7Q!^Udݪ͐O/&]*eU6lдBb^׼45\e}/AԢJh)&C.q?R5NpamNE-bc0KHnPKq7tj; W0[sRASZs0p\[%l ^ƏOyue -cnx i\U[T0f[\eXYM#^N 宾W :׸ZCi}UVKZ{g;p$uvcJ<$e; {>e7Ff0pCC/CY FY*e(cl{ ݠ\ YzvStQZK#VmcbAPH:Rٸ)-vS{,5iȹ"әYgB7dp߰n^3h,.MeOu,$vۤ;SKˎӫ=*C?e&RBM3X+^٧&t͎.M*/9="ky$ҵɲ8c /E~Pl`w)#084؎.xHp˛fwPSJZVCei$t.۵yX˰Q 0@%N`4ܦxxgC³kC/i$+##pkyZkyP9oc-"lAt=IU.#l/mRQKܶ7~Voi{H *=8\VCG{jS{m;zOwV7Q!^Udݪ͐O/&]*gCũt4k{\u\)9$U׾pQgXܐ n?sloCsXRf6tCFhh`w ڽ B'B@@#kכpz⧑EDhaj*D#,bk_?K ,plg-s׿z vXL \j 0ol*}l0Jb[ \K[w[jdITʆH\ ;o&O\&lщL5 KqҬH]s>,&B_0#҇z>[<9m4ey9-%ZQB={pj^P#Iw6no1:]l; Z浭"t:խU4MS0}- c7eaGͅ uXc3]u7*؈*cu\r4ӕCHr-мb%f <>G0!su?+R 00>:7Æ\-K:܈4mb@Eګ^#E5Dk#V|OӅhn`vc]wgqS{FW b\d%kc4JS{YD",?*" """ """ """ ~U{W}v 6C?ؿʻtK ͎9]5.1rmzx%t }V0u0>zXvrs6lq87'^qS N3[j}7'X:j W4Z׮@$V[~q[e8(/87&V1'5>5vAN;Mᇠ1tՏZ+.3[j}i0z keXCaԓKOV\fCSxa)i03[j}D3䥩.;o =87h *X)0"]=3}o|0A$l,z7TUTDDD@DDD@DD*" """ ~U{W}v 6C?ؿʻtKF 31 >:8E V |>jQsQcn*1PYv ;Ǥ-2m3h:K^cnI$n!R̠ânX GzGNg7"uM'2eX&ェl1/!:z viA ۅ7w'COšX͏ Z:8H1q|'ҚOd!cO}E%Lln[+g#bŨwB`x7K=˒ܦm CXz 77|$}+nWÇF=qm᭝،O Y,KKbͨы0(\C4O~IťQkjCz&+ [yUL dq঍ô1 t豛k)s㢬t2 ˿.c ᬑ懶q%[ W"Rk9>  ;+X{&B5IsyÙ/pـ~yT[+S^ּYCO L )ll~ ok^v[)p%K4E?)Ǽ+//x})Mg+uJqy{Mgԯ=Dyc6{#sNM6Q;)7P fX;M.t%H^A{%5t$80^-mHoRqq8Ur6uMAXe1\c[[o\mu4Yfg/Sn tN8,-pb|,ѷۨ:F?F/6lNآ8JIt6:|ض|z^Y5pJh\K[WE܂&& Ć+F½EtvԻn@!;3=kg'z5 .Y2wަk>gQTKu5[:|JY7P fX;M.tS4 -l-$o$)b}tfF ŭ ^lO&,9%ˆL%3K-qmmK4#bpSRCQL5ٚ 7}Va s o?>|3FiYSL؟+D"p.H:|v WZ8W \ -qRJ>o4v?7R..ǯ3]g#g 31sAnRXCM8pD4IY=K:[M-Kz)M-4&%+ᡖV=sN(،O 3,Yz:J54g\-2S >L(x!Kuy{XSJc62 ׿JMIIKeߩ4W2\%3u ͭFe`-"Xܭ oJG,Y B^]!gi#_kMF#T#l18$J,Ģۑ 7)=07sb66Ck)LFCOPsHB#nc-RVU$Qj"-" """ """ """ """ """ """ """ """ """ "" snS{iwCϺgoM*(?!U_]Mڬ1Jb*oҩ,6oCaB}>VU$Qj"-" """ """ """ """ """ """ """ "" snS{iwCϺgoM*(?!U_]Mڬ1Jb*oҩ,6oCaB -H<.=`)#j-Yq32ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2ڋVy\zL2j-Yq3-gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> -gǬ?X> ,snS{sK$їDI'=򮍞7RD",?!U_]Mڬ1Jb*oҩ,k/*w~%`Vup\WOLPpR=HqiH 6>e &iͧoV!'՗Nڝ'KNR*7@,i豻zt+*mf$XbI{I. hb_ʘ?u'INE.!%d,aՇ u.pZ*)ㆨT#abM_LO.JQOKM41˩z4H34Ԏ L~ XpL$x/t_:_j?yTWVSE˺ږ5PQ()3H##(7;l`1~//_:OjwUa9blf@̲5t%U4ѝ${CQQ]$ч 3c6-66pwqS_:OjwN/x';(n)ɳtH=qi%/6% nH>KYtfê3Eޮ>vմB+)bc&E1}bEhEh*~(4ҩ\`z\Ţ `.KAH>u&0E\>3 {E={HKLhsCsߠ 7m#Hf-2XeCeVP *0:$5Fۛuj¶*`2T9$4]nPFQodtUz|/hU#!{N9kAgXkkon\T9xs8VU҈sT˚'1~+]~][A#iFr$ 7B OUb-33j(AM4oH[,uC#Y+Y7ݮs7h嚚Y |./uaqa !h}GNEFVNsK@sn |9oE V˙ĵ.6뮢,+\Ӵ:yY&1MP`KkX5b.R^ua&pk1"pBBb| KNDNd̈́]:؅ScR6LGhKcm.n?BЊAm n(+^\AԸm}5߹NJ_m+D@DDDA;ov{f^3 goM*(Ђ":ZS&FZoey;{Uv&͵H*6J徑Az6k/*$fZpvtv;YSYUo;YS;YSYDU_gN_gMdYV~?9~?5d\'NH}Oy~?9~?_%"?rE'}SRe$RuTtKIO5;i2[۬F@g~+?rg~+?}!-OI);j(_gN_gO%"?rE'}SRe$Rw>'NH}Oy~?9~?> V緵&{NNԫ|YߟꜿYߟŧ "*/w/w"*/w/w,|YߟꜿYߟȲ]o;YS;YSYDU_gN_gMdYV~?9~?5dKrg~+?rg~+?k"Ȋj*/w/w"Ȋ"*/w/w,|YߟꜿYߟȲ"g~+?rg~+?k"+ݞ7Uc‰ ,%Q$ "ܠof=>+V\s@' aBP`$۹FH5JJ6mq(C6ӿ~on H.,xI.3p΁X',^OMtLDn|y / Gr2ŗ.\͇4Fl?ߺ÷7:%ZpU29:{=[-iiNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l?ߺ3a@ ;և[4]iNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l?ߺ3a@ ;և[4]iNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l?ߺ3a@ ;և[4]iNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l?ߺ3a@ ;և[4]iNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l?ߺ3a@ ;և[4]iNu4} @gw6ӿh} aoCE~͇4ZaoCG[t~l"'l݂c$,iE5SN֬I 6+ɩYK\ |i9? *]YGbӕP)o-w"Bzެ_p=Z^ńirab-Gݿ@5F4fWNl J~<\7Rv;Cgjdu>ԺuZ7m7]투T,z4u2xrSv\6FPuV9\|̾&xUc0S?w d*#?g/bYJφaC4q/';I #zICg:qϚ6󢲾;co^ xSwPZK- X~o , :t ^nWyV8kWԛJ5 Kavy{؅g+;"R1 Ixg3H#vS;IqqUtٱh& /tGI.NJ=\M,PdhL! \`BNsuO!2BD)q lbHafcбtBy,=&FX3Gb ۲[3ۉn 1$d+gsxt`h {Khd] kFp9"[Ykt{ϛsZ{xt Yx ag0 Ayr2}UNzQ,Y&X&Flf?0-.Fy\[{xtYSO|mYiֲF9-6wxx2دRĪCrĶ-l:7E\c}M6++;HmcHQɫ۞>? nx{Q ZSo΍`燿)k۞>? nx{Q ZSo΍`燿)k۞>? nxwأsÿO:7Esÿ۞*}ѽ:,۞(-So΍` -G)k}{xtoo΋)k}?<;AK_T{xtX?<;AK_Q Zb?A ZbR>?RnxwةFnxwأsÿO:7Esÿ۞*}ѽ:,۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d۞(-So΍d>izaK-N+gr ԆYi%;OnvW=zʽ{xtooΩJ82?-9jW'_& L2Q}`pv!C? $#MIu ڹ]ҢmW5M:SH*t@᳜ףo΍M)3Z5F\O'R9s!lϽtZxKW{bP,c#I{xuf& xyj#J1wFkGV"KEm ;/Z{ ~b1ygP.FWPx7?[&z9,qdZ^mUH:Ċ0*~2N&}3QӮnnP'PJ:l5K,q7ֺM_!+]d cjSkoe]G -ˌЮrsǢE5e?Ə_񮖊95/4}-tQ9__mk`}-oo]-sk_mh}[h,s_ooG/KEc}[>e?Ư&tKJXF=fɧ-hexnП1Np2;Vu+W\i __mjox~ߨc3f0CzqZx4,RtG`H'6D?ooG/յV HR,j\$0RkDSA&dmPfA>.}[>e?ƬZpM2iS4㌞A=G54`JÇ<=};ԖzooG/ՉemFe,"%uu:p0:dzցō$:V3Py HhjKtooG/֚xEwDE+) A㊆oiqv:]G=4m2+4$)og+8- _ooG/>Y]\%%u6I9g~i\Gu.3!P,28Ii˰hA/4}-iE-kX7V-Lx~"D暤GH0=z`ҴB//5.@֋6e^cQ~nV~-uϳY\$.H#Мv`ZV[_mh}[Ӈ-3Ma$P8WK+Oe?Ƶ4:;/6nO=sq[DWiK,qrWg//5i۫X|\'I9Y<[骺RxVY8 u4ZOhT}[>e?ƭ(][LӮ;Qr\[fP=\ZҠmN9Fy2(FxsEk42>e?Ə_n|i˧mJ, vJiME 4 %2&IzNe?Ə_}6kˋ8 W]³)x g?e?ƺZ( //5G0Xe?Ə_񮖊95/5 ya)-!1W{\ǍqR, E]=s E]=LQE(((((+4j,.nnʟޕcE?_ K5؊EMWSVc^%nOs[Q5yb\*F%o [ibTTp?ٱV]{N8* d6(.]4yzo,F&Q^l tNח mgM Bxj褫M+_ցʎ+M?Ki{+M%cw1Na_>Qr €6("ěv2ʤN: uS!+Rh%Ibq]2uEPEPEPEPEPEP\ǍqO\ǍqGpǍI ;]mq.V/%V/=_4=_4yWre}<FEaWlEܢF6_ѢnQX~lG/`7+'MbzФUh=|F6_Ѡ !kvs9O I#EbN+ukc͗zhe}9/u|&I&ԛ$5 Z]EВU<ܹ8:e}<FPt<]wG7nvj/Ŧ2Aob9 saWlWcܢ^]NQ}Y*/(??Ƌ\?G?EsJJttW9GG`::+҇h҇hiC?4iC?4X??,GEsPP(??Ə(??Ƌw_nu$Kag3ß0UnO<hM}B{Rbdɔ_4J_37I8c;PPuI.5Hnlo KCc!FۦBX ? 1ib (/(y2dd$9 t?PPIܓ_۵ɞIJy.અScq{RCmU2Y>@@RsV??,_ \_}}e=Kd$a~o yj&pi[˨Z='6330cV?G?Ew_Z_EXLG_fL 9FFӹ ;xa+ p6$x%J ~PUrP+҇h҇h<+m%ٴfP;bʫ"9թcXozNgH !UZBHF9PP{ov=/#JڲDdWK6ed-}(P /-R+B#b̛;`rX [:PPKBƉ`G@9ѮsJJttW9GG`::+҇h҇hiC?4iC?4Xϕsc3礟ѢnQX~dOK=$r%F2_'hxgOv !}5M:M5 71mv:yjE/eݻyN|#Cml8XgMq5wٱAonec#.x<%¯Zh&9MtWA.t$G  rhy?kJY쮾uYqT';FOAYV#Eރy%άmoRS\YyK)L*Ny<&-6/'Ko,,JzARohkձMf[~ЛA՜g*G'ֱ5/wlt%;ϙ(Fфom p2ojzdZ|ڴQAbr > "a@ttM3G:j6F[35ƥEp;zըAiow K)3px\obӵkT֭^Y)JLXfrw3<uNj"/#3a8Qrpnn us0ÈcH77?7 #֩g6ͩr$>\ֱ|E࣪p4Cr[](JR6"#\`V]Bۋ|,c;|g4\xMv;&+{YC2 z)ih0:,+:˜@8 r:9/ U5A{:1\~Ȭ!PD"| Ov{QJ#[$d B*dT!R:7tx>弾[\ mHvs*9Qx|ZIvu0[F7ء󰓜8sfY6v٠XţmEc8* Unڭ@.#@&,,IԶ'gvx>&ҥDk"Aq22y#YFs`N)xMMR=:;3&XV6Q| 5ͽ7Lyq,D ,2洛yaIc!H~gbX Up_@i,_i{Q#-#8*c>v`CuαL~7ss-Pxɶk"~JJRegcdA8,H8yqX>.ebe ˴KmEgZg/+knv2qg5@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@jh.M.&0JIB2qQ%b:ŦvvX ܫfpǸ ؙyi `Gv{bMc "HUCx8Ev-;rs4X9.\џSw5-%w<ębV0 SMVeN!滅DeL0*=*yy9C^\VT8 9v@;L;gVR:V`T prxNudVAKv[kAfZ:a-~T=@<x@P˴14*yt]iAq$J; N*:zOۏ'=fY, ,gH#_*E rz=vIi8[om*۬O ǼURF8UKM:+,M,\tp;*ɵ30%rkQYqxGH-,Ck#0%vd|[ 2i854zΝ(l.#X6(?c)۱*Uw0sOmSПm]G5re\ܔ6д"E]ijB4qOV#ע &\ ++mE'A}y!c_ `0i.{?Mm U񞛧w IEտvd;Op:gs++"a@,Υr).( E{?Mm Ҿլ4lHv[Kt۳Qm7Y:",s]dr1T*F,yW$h qOR$[`҉A"AU.,dnp]rFEN!魾ՉUpOa 3(8$\ m >y=?5bo[-̷m^[)K 1y*&~K]y=?4oZ0Ķ֖ m^UP_rw9zeW.QMvf7,.b@Mo?&{?MY&7({Zx^%Aـp3q1Ik+2vs!G1䣨+f_OGo?&`}{)hmS\ {?Mm ߢqO[Qp0>y=?4}{)k~.o?&{?MoEmSq(m >y=?5EOGo?&sFI$i6(!فQ3~%=s:X>}iZ^6 67aI\M<笟ѣΛz}Ȏ)M#yvBH86w%FPgxͷ @%qƭS%6ϦOcG/"_qi?K=sO{3zNyv*Mԟe8T<^Xx'_RNty`f)YpÂ2O h0ûX'{Wot/K-li_B_)yPFj?n?Zv@7Om'om*ۤ((@QEQEQEQEJN7rqԶpsĪ#,\ CӪEsW^ b7QNm…8#i%3 s2D"2UA @5Q@k}[RMR8:2ĥUr9j+ ost+ I"..I$gtP;x7M  /H$qR`uո")b.Um6DE˙;r8E`n.V8 4#2<2x=.6K5ݸ9c<N:Pm]G5bm Sj*D`A ,.qU% o߼lOߥ *ZL, 3K]H< ~Gm>RECg<f;FT0e9CcNҏ~(P|8ӯlm !aY#o3h 6\g<~uAo yFr$)TH"s;J?ӿA#L"m+n^(̳wo->nu|]Y[=Kɮ&r LOۏ'+om*5AouKg<3U<7oP&k]RKD8lI\I2zޝ4!2| kqڪUֵFG 12JхlNr1j$[][G}t`xB%sFA$T6 ӣh%xd(G2Y9F0/( !URYHV!*vuiQA,S\`\2<^KK^#I4#2<2xKY 5ncOm0-5j'0F1k^j󠵵dwr !@?)a98S X$2)4KBc*yLބ8=ji+k }Yf6ӻ622d S5EcPXHnm Mu]NrycL :lt+;15^0pۜddݛURN~戌);!O!AæX7 Xx./ lO(JG,Y T@H=0u,F( qx_v ]+YVHY& ÀI'fŨx`ñ(R쬪2CFjށoL[M ;eF B*!l2WLM.7.R%Hb, Xu M]&9/Y$dXJ9b1Ll' gA}\vJ*m@b>SvNFrĆEi$W$ych;rNZ.uig3#41L`YUIGR3g#(ZZr\O.-H|̿/)/>OsȪM<1F\hWspsJ!€ S5DJ?jY[idYR6hԦ1)sgИegBHڹtUY[]$2Y@Ѿ=>WoA{[y4iki[eP ri#RCj71#Md[F*X3Y\u,3%oKWS"'^txfg{yسڴÆmλ:cdt$ z="Hi-KWDvw}1h/[bAY@TgpV \K|Lf-r0z d9"S]0Okqexɉ9>BO5 Emo*ܿ,q=U}vyNq DT.$s3K+paBqE: 47PLqs \7>@8 =4{nŽJf3 agjM"7ͧlU,ꬨelzpK${ E"'+sfv=-w,0e&HH #z<=@!oϓrB ipiRc t@l~7}J٭.+{xy |#$b&^ͺ0'%c5/kʷKt.7pQ'8vsJf!ˣ1IJĚOhɝ&b*!v?*F ;d_nui5(aUq p@=jկ,vq$S\xYFTlZ-6[y>\ + Bp} iЭM$2܈]73N=ꅏ 3Ut9lncdaLnRT.?2_ONX Ӊ,eb[qN~^s[^lmRDo'$C22XgQ]2CkV;`A,8lS096kXkVlE+.U*ׄkcEUHT T(;8 Ti_iе X$C-څܼU9Y#qxeI?Y++ nNЁ@0xKSn1M>ҤS\I"ʓ4xEGGR>8ϵ^n֬ek{.ՖKnۑx[_]jie?q$4{e3y@<I31c,r"#qս?ÖZ}+MxDis8ݟ^!@=o,V6e%62X)8hv瑵{iz^>akfM$rzN63ʂ3TIqӣmOR1[܅WGUS0$zo?n?ZNWm7Om'om*ۨ{QE )@ֱzKg&n$C^@#aO*J稠 +/IKq! J`OpLLAFzwݰ.l$&O4Ƕ'>[ɠ **kZJGi#j n 1QRϩXZ}M7,ʯw>s`>f=j-EBӮH 3TZt}ROSemP̡ 9,r;tg-edr5sJBPcE=u$MgMk({ĭ_8{t6nn`~hb@+? Z]BKm{]c%Kv.r =phFXӯ>.Bq#V7Ijhxi,rѮrF;z@VZCc4wWeXn28 GAz^1;(nN\q0; 0#ѢŪi5RoL\!F:|8z?,8=8%H 2́#r28;p \ø08;_oO u<.#]5 9?:GZhs_oO uAOEޟGk}?)֏?:KEzS#oO u.5GZ>ޟ]-\m/5&f=̤|??´5`o~QEo~QEo~QEo~QEo~QEo~QEo~QEo~QEo~QEo~QEo~QEo~QE4)G 9gӨ ( ( '{[uOۏ'7Om'om*ۡERF RRO2,h׃yO~gE׃yO~)٬()٣^?5EC^?4k<fM}}Qr$V%`QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEOۏ'ğO-5om*۬O ǼaT`їw%3' ®M?~O [ `) ((((((((((((((((+ğO-m'?n?Zkp Ǽ/hZ c(c)EOȾ4j c(c)EOȾ4j,:giH#=yPd=!Ư?Ə"|_'v[[Gi'9$ԾEO7pl c)gmI8ϯ4蒊u4⩶_i$Onc ޕ(Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@bx=vI孺'{Mn'7Om)QEQEQEQEj^6N^[F2lK}#Lk4-ʈ6+nw2qڧI%;!rRY}H=F:L39Kxxf(]?"4QH<_X]=T7`F LдukO9cUrY鎼ӯ3}q3fItOXTZ%BiVc%lomþ{SU#kyXS~K+2;Am(I5Y-"ztFk,UD% @N:t/XYm2I;2¡(+$acs s@cF:]Ghly 5#fYxQTpxM)y+1$|ѸfIwR#rtVemdNq {Iw F GȪWNT$H,|uH@$p?xƶڥ\q,NF Fn,ze99+/; "3@@x?>[rq֣𞑦=RnA bDz?Ɨq<}$|4k0 qX5;6/T5ʞ'5j)/k^GH$a>cQoQ]uQJT&no:$q90>|n֛WBg[^kkvRtFhʹ0-OzcQ۪%V ubg~$$9+rTt^B`b^BTzeC\PeT=T7P9<{ҳ nڃx\ߣG,Ѣ?F04h?4mA<.Ѣ.Ki!jO?5([(+H}?mM^mM46^$dOdWX U׵mړzK͟?_*iRr JUQUk!^((((((((((((((((OǼ?>Yve֢) jkm{F`.&o7(~2hQQ\\ޒW O( &բ( J9e9sVҿ6?*J|;A+#9e9sZÿҿ2?JƎW9sZ϶״k M^fr[(!_$GԞ+4DVW%TQ_O]w5hJ|=A+#?) h}w5m{F`.&o7(~օ&O`(QEQEQEQEQEQEQEQEQEQEV'?n?Z۬OǼ?<yݷxn<7oVp (Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ :<%"'tA&8LjIIu>$Ҭt=6T)b5VIAyDIٯ뱷 ]YB-D3͉n(Y<%qf{˷SnAjP +=FY q*’p'>QNIp ` lQ kֹ f+6E)%+*nH5_zwGRPrHwIC-fShD3\fUyd;W`b SQGK`dA+ 84N7/s8sF 8kv;ߩ!.6ys|Ǧ=GH$OC ê"YJlfPr8"aY{NΡw4Z 2ʻ,F3NiY[ΗgU/d7Lg<{?~ݴq츌u$Vhmҡ9pq*dԼ3̚LJ5(m<ۇ|KsIV;+,"WQyh;?x3+[FiNSp QHp\x: e=KNUKXm{"rLZg;EhBD+w:[_Y) cΌd;{o>c9G(ߪ Hakjg!o㘐뵔q>\c 6PAi(P",wrIIG`]ΗhmЕ 9=k@,$PN1ĨO IWGމG$(QEAaEPEPEPEPEPEPEPEPEPEPX$xݸyknQE@>Q _'Qd _'rJo[([rJo[(>*`#SWѩjQEAq>Q _'Qd _- 9G% -Qd0Po)C<mQd $?6Q $?6QE@C<mC<mQd $?6Q $?6QE@C<mC<mQd $?6Q $?6QE@C<mC<mQd $?6Q $?6QE@C<mC<mQd $?6Q $?6QE@C<mC<mQd $?6Q $?6QE@C<mPuXC K.I9aE$uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.doc_analyzer/image004.jpg0000644000175000017500000005456111665471326030710 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"L !"1UAQ#2Sat356d$BRqs4CbvTVru&!1Q"qAa( ?[*=p[>jճD8?jqb?T]䷒֨#4 81^8.1m٢xM'kN Ժ (Kdr̜w(3cSFKf7u:gc5f9L;vhfp~/}iX%Jy?SM77IUY܁<mfp~/}6h RjpuWA]3XZ <"N$ $Rm٢xM'ƺxxzieFF;=H9]Ve0v@FE42٢xM'bX"ڋcY}%vqlukƲ[st&"4:l٢xM'Jz$ fR|yVgTI n@`yjhwl<^ZfsjpΠY8sWel`8ёM#-'٢x[xNSCV^l<ﭼ诜覆'٢x[8NSC^^l<ﭜ)fp~/}6hS}׳D8?4O{g)>hk٢xM'}E45<^>phfp~/}lE8M {4O{D8?pV'٢x[xNSCV^l<ﭼ)fp~/}6hS}ճD8?4O{o)>hj٢xM'}E45l<^>phfp~/}mE8M Et@2tH?$.{-`ξjp]w@k^z38).pXgGܔf#㓏,7Hľ74M:X)S)܈lfZIX` Yw91ݑ e/>\('NO8zJi0 >̼4M#qUSw;z[5/z=m9U\gp{]Mk >)*8D;HpBdYMKf0@C(H#k7?'wM*x6Wv2=TdzFAg/HE5MwZPoiC;IP3Ood<NT31h6`U$b ~0s΢:/I(,nQPDa0ݜ>f7>*yf'Xk)scQ٧hżXĝ VMPY^uvoY !%H^RvRMl})[[WE 3;>*o~)zjzg_F{yT.B}@KWM"-B+ 8vP(9Ϧ|⧖ob|Un~6)1KUSKIfVIśL OPNpA{SN膣;.@Ј\6Hq7 ; yf'O,;1}PFu4]CMKe#k M̊NWeh:޲ucѮ-Ž{(fM^⧖ob|Uv*rhTzƑqukGeK`}]7T([5N9@vw>OYwSh˨E:V>YwS7>*le@+,;YMSEcYO-_;*le@+-_;*yjGSc}XjGSW?e@+-_;*yjGSc.}XjGSW?uP>W?ZwT˨E:V>ZwT]@)⧖d62N}d<#P>u|#YMSEcYO-_;*le@+-_;*yjGSc.}XjGSW?uP>W?ZwT˨E:V>ZwT&dSClw[H ~qy&(T?_&=G"G5}N EvE(dN`z'NMQGE8<'){ 2;ߌoukmnYJP)0Lv̹'yo7ot]jXi'[UjWJ+{YZ=2lIr=>=g<+^o,⑫ k?Ҳ{PQ源~#J'/m'4ou$9Y$D`v0Tϻ<]jntOԭBM#)GnR;DK6q5[X 6;ZWxB˂ܲ v|;67Ph'ު0Q#j1+]i'.̶-娸tl"Ō#~Y8"뚆A!_O20 +DXtPP3+&e!v[n-+`dG.Kx*QrAlsc!-f]]B^dA$NvHIzk -z?i{?y2~]BO5ieX鐘l,"fR5-gwIm >($$*ɖ;He#4~a$DӤ9їqK9&3'$.[WH5h뮶*LL%rxyE#wIr2ކ[ i1^JdXHˑldC ŸpAٌڸݏ>ݝlyAzA|w3l`BY0`vmn8b[zDmkuo$$!SfeeGg rN VvmܛBcv.=F;bN4ګVa \l㼲!ϥTE]*Xēdo^wv w+-[ Jc^9'\?{}6ᾕOšKٸӭ«d.W„@9Tp=u>k:lߌnیgA]{mo2='Ph}3H`HkWh3nfo!礷s]ZCg̏đrܑ~#bMykvVt*0vk "RY,짾Tey"F%*A# d6>h Ek6,SZZZ.$2̰vd38Kɖ`SRCVY"I%X}#y/㿒"]4JdE623s [G(D &=砀}:vSis#fVݔHZWCݷ紫gq=t.'I8 T*/$YUݻ%tԍ]>Q12TUJQ= )uѼw}TغGA5qA\Z۪KNܬi`lGN0t{FF sʥ ;&Ct`] b?&I4quY̫m=!'ǏҺNĂ4 )}He唜dPHҹO4[ډ I="~ N$P̤) ~TgJ̰JYP0 7 xt R R R R R R R R R R RR)@KR5ibqjc Gr5 GrvNx{ ZuGqmjnT5U97#:/\XdiЖ[[)I9BQ$UBÄgʂ̝[%#/Vڸ ˙E/:K-#`'d$Ȋ1#jk]q'#>5Z&u9$t@ e>mn/tfTd^;&QE0lxCAVmj]][ma41G*1` 0<AJ -y1Sȏ3+<ՙ[rjX{k??R8I C#+v@n{{P 2p^۽,"5:#eH`7eAz|R3-ES( pG\jsK$C+zh:+]lZآJWe. 9ۈ繋si1uuq+|HUN ®t5 8rc &Ā=9H9m*Fl#=4jGu&wC f"I#'*Y"= Źq 7=!7/G<Dwpea0pZ_J+[4+$8TNHǞ6l L"؛ĕ͌EWZ֥5ck# zNF|3TZ#>U<7w_q!pn4ߞGCCfiWPc2@'gpqY#MZN-ڗV#03 FiVGcvB<ݮ63Jo@G43p z?^4G??-MԣFޥ̳;XG@|}!u{\C,f BykE_H9m*Fl#=4|M;591U$HE4Z=ƷkꃃL:{#WgR\mb{Mːv\ҵ[k{}P,)&CN;KG??HzGEI/I&.Q4x&XZ.K h_lM_SmӪ&,({Uk%FrUqנn뗝[; qLqxǿU\y#Mkx4)5xۮK8& x9v>ogxD7?N Iܳ[Cu78单qN%E dR?CEg׮t 4ZmmR+8-v*A̙ʤ9&2PeSH<dG??HzGE]HzG\h=+\y#Mty#O$~si$~si׮t 4[׮t <ᦋsҺ<᧒?^4nzWG?^4G??-JG??HzGE]HzG\h=+\y#Mty#O$~siibqjg\MY2M $epyk3Jk3J"ȿ:?ҝ7Ofգ(Æ2ys$"1\s%$+:Gf*~]:i@uΒ$yl.DVn"ItjHu{d,&!v^u~MWBKwMIL372aB;|9ȅcJhp30 pyOu^wmqߞ].#ibyΟ*Āv"6wȃ$v2t?Ex)bGԫ#A Z/:3jOu{Wc|ZF$d~ʫUнL ]9'Vj{ mݐ =٨ҵ+ :K#}y{kڽ6|H'$e0px>conuYues ռ,2F0G R3DTeP@$8' Q,Ӧc,-Fsȩ )J+ 'T(Q@${k4W0N bA$(4TFFl)8ΕETK*vbG?9$<΁JRJRJRJRJRZR R R R R R M"Uwmֱ'k3Jk3J"ȿ:?ҝ7Ofգ(Æ2ys$"1\s%$+:Gf*~]:i@uΒ$yl.DVn"ItjHu{d,&!v^u~Ms{][M Il.hwb-6ȽfD/sWFKqHV-EQ:t: \2pr0r<5.#ۤj.kUL)M;ʼ/)+n]>5ڤv1j$C8 V,ėRŋM^RE YIVk*AmhZf'H<#rGYQʦioÌ7okPC>pіYbY)w&S1zhyHKU Iy$D񤒢4Ͳ5f`IǠE&' s4˝ZM^Ah̍1Ji%Pw=bVT{[ieM4VIc}Ē![FʥCDwHs oګ $` A84 7]/u)RKOȝj&Y/'U@cHSMJK[ο3Tl_$I&ou*+N ·uY$ڤ y+2~I+xk'H| 㻗un3KE}.KvudIf'"nI3EQ0Ki .16v ݬ:[xphB E_ACm!kMaVWH31T6cnd*S,Ir5ԠXjPjmBiw\Z;bPxr!aAsC.u(u{xcd[ p/  7 'T(Q@$^N%76تaq e$o˄G H 9%U#WR2#(((((((((((]oE5bM4}/cOO8H5fH5f:Eu_h+:nywG!ixQ dIDbKuHVt8TuҀ$H#}# \E[3t6bdXMC?@׮è,(++Q%niA8B;^C1r/Y #-sĕђqf#\`<8붼7Y ۟o<]GJOK$ƕ>4֍-*1.ϑ)S@A | mȚџWY--O^@L.o d@'5edʰۋͭfKKnc-5 9J|KY#.adWa "la[ U]#SOG zs@!F`Æ;G=!]zYGhXM|t귊 _\:UV7Zso,IImԕ<#\j&nu /R\G%!KrŪkZn}8ɪ]ZegsJnNUpɂ#WjPy徯?+[wgsu~ߓ9羻u=?YTl-_dQX*H%̋<*Ycbq jmt*y/v}^/3ϻY='KkS 稪4b;]DkA #jnaVWH31T6cnd*S,Ir5riR5,YU+: MEܴ֡!'uŮ#%+v^M ֗Um.崖Hc mm×~ ]^\IR][ڦfQ yC(Yp S5{;;\zbfՅ{̂>ٔ .!8%#V]Y.@y4=VFS  vզ=gJp;7{gSqVk,ZtzYL#k;s8'y}AO[Xh""D؋E8g{{Y y SXǫ sؘ*[12)$R\9&'$m0=' N=),@#RʁQI9"ac}kQ@n5t=-yqkHAq DWZdRIi}.B}Θ[JТ]W1#;UI1҂ST:朷w-}A 3.0m5BYM%4Z+]P|t9IFb㸍zpĈ6T퀹>>=Xt@R܍j;I)yW~E8ErXm*Ab"IQus ^#H$W(cb21!Hb6iAI{7l-RYgxՖ|#,1UYe'( )MݲE$C ֆ"ijB#18M?J.Bm\$Vܫ?0g,T)@)@)@)@)@)@)@)@)@)@)@)@M4}/WzkkzyƻA_4A_4,CC])t˾o-Z9 K\8l1'2O#g2[B}Fh=Өض\"GI]rEf*1ˤFWK"lm@eQٺ]Z}m?WwD^o"FZ+%F $yq=mxhB[Vk}~Y-Ȝp'bTF4Q.2+(is e8桇1VR>{k$v%,X$M,6vA<ʪwok-?Qjq$iwkK v"!V#JC-v_]&[ H5s{Σ# I#Et},h\*mq[k:U6pgoGA89S5:Gim +^ळI(l]j}(izs-)B˼B=ڤMOI*#L#V` `zNzPP^y-SK* '3Pv!Dպ}ĖOf y+6/2a *ې҃ͭWTilG8%{8+mJkK6o< [ԓ1[v&W]s̒=ڰh`x%IbCԌy)6_ZK>Z:d=g~Ϙݞ_Go+^@M) 6n豔M6 iTɎN$P̅a 1󕱽N![ _uqf#{0J~ovvgrZ9U%5'-Pk}o'6Æѳfi0Bg#(M”,Y!d77i'ӎAUC$;{;;\zbfՅ{̂>ٔ .!8%#)@)@)@)@)@)@)AZR R R R R R R R R R M"Uwmֱ'k3Jk3J"ȿ:?ҝ7Ofգ(Æ2ys$"1\s%$+:Gf*~]:i@uΒ$yl.DVn"ItjHu{d,&!v^u~Mp훨yu-Y8\.{,ﭮ%md0r#5AI-uk9lGe[ƙ@f8Y7+aѸ:A;\ͪI% p]"Yb4#* a~А>Q}bJ#&wtebA2}%(TdIb`Gk.;Aj71ܤ g O,)@+4K:eA+:Xne@Yr~ΕEƒJ6՘'}5mȿU]oE5{IҚһHְ/wtM.Yh-/ 5p \>~ȌV}+YA$R#e*V?_\2|3wFWK"lm@eQ%FuCL-4Y\4p rnda$mYlt]=x;; nrNO/]sn[]t5\=msۉ#c7XAp +t6ڈ5)oZ{D.XR!! kVUB:Ygf<!m[)P2`@7OعRQ4"@"$lBk뵹D:f}i%YZߋ(sbcV9ٞ+ CZqChCOneKqjXF2Mn؎%wo` cjPyI u-P]֫z#8Rwy]р^7SW%݂RM"u$ŌV인ɕs\$/mqܥzgrFg'l3Z 8j!3.=fc<{XuٻCq+DptI^UDj-O{2`rlSv (+\ X Q+[x$2*:DvnUq̍R6thCZ}=܅ D.R#K"iK;ٵ]VW{}Iw/HZD~ovCfa&o45mȿU]oE5{IҚһHt[E\jqGijE²^J19#lEw!X; ƿ5[~9cL9A_ @5*a{ymŎs!Ga! $I,Tdv=VWYC$ 8d]YXnRF1A%)PͮOg*[j2pw ,r)#=!y^+tEHiox0Ŗ'Dufe)*7H^ zQ`.."xeH%eNWi_LA+]RDٻrO!!;PzI4BڼwpmUh@Ŋ2cڽ!$XĬm CdPN 972^)Svosڝ91omWMs&%«ZVb%e#lQ)J==2 RqE,TFrycbfJK{yV84 Tz{Ozk.e/\SM+჏M5u{cI*Tq7r8?E+Wwe9?DdfQЮ zF eEFrܙ1*GYY7dpJ$*d h *gzlde]ˆ ʪ1ݹO!&iUۛ9XNL\4Πj0l.`ޏ{*./y ksW\6Q@ TeNu)D3H䪠Bs638nCncL-= ,1ue`d ̪E,TM%=ߺ3~ݑ;?߹Ǿ^]- ^>`>p*uyӊڂC),!պbn,|9sD}R%J]ݭ#[Yt '>-fg_8VvRHlޱmdaî<29EHҸn  ~2*7 8G`U8 )'i~Qnn+ rA2~h*')Jl).n) @G THAST0':GH8p.eŕK(7d *]E\D#4J#1ݹˁ+jtJkxì, nABDA)Jl5Vһ6Z'EyvfHiIgJ㿺#\\@K"Ti hK9#?ߚ.TfYiq,1^3(Dys~ʍr E7Uv0 4~PXVx]߁ϟ)Z/.KRB{0i8GW V:mA!Xя@?? 紘 .- w V"]tL].]JO٢xeGpBs˨~arNt ^ X:KNnRAɡ(#9!fW#"ȊTvŋũ4yA_4A_4+v:+mvSM:mˢ3ųh=NJ1۠]g]E! 4vMEHqf9lxUΊXOlˣ^X;^#2v܇0;1\ve͖][ͨ2_Fjd,6[ LˀHMtV-JXp+P g!Kw .L҂}R[d[fVK%J -swы`B[zBĭ;L%PT7[J Խin5k"vnBnX8ԃL{)֠%hs(U=F2ȹ9JKuԮ ۝H~S?[AQxj-/.3lo~d0<ҨB?9꺅\^7g8})[9U#l`\Rym@ӽ̱X˺w+m!If\kk_+y~ovG7t' 7iAUmF^‘m5Yⵙ5cvV %- ݅k]CrR(^ɧ8XL`n$$ oӒXT8a@,9%yppgk @U;fn=Yo#KvіF*@>[) teo pn#E2cxHpX8shh/ xڀHNy9TUvnIw=ks-pM`l󁾖C.suĻn'[-Vb E`3ݸZJLuol8iq魩X Z3),wPv+RtJ[}>̐ݐ,HQPݓW;,4m*^$2,a%* Ĩ $r;fFM\Nq:M̤6.#g&I0Hi&rr,)Tq2o}mK} ÚyOIql}\H &Ñs5J#ґ#lvp<`}O?h\n'kPGͻ㜽*4ϫ6$ۋ^ H3)3sD*mZK&.!#2#8ϞTjo,\#21+cD-lٴ۾䣏r yPAt23Ɨ.*Y‚2 8We*߉HV )#n!lӈ8nGvFB=J % ]p%oKh}#9Rk$/-w&BϿes_XZKV;j?{)j?{+t]gA} MW@)@)@)@)@)@)AqQ-7(k:DF7F*i)yVH+x$h6ffnYK͇)t歪Ǥk%ݤuEqy:\`}%AwW#]9yRho{J{AiO}ui}6[K[uHT1!#=q%x /#`3۪؅en¶sK >R>3a)ml}=-Ja2X^E/MUY RȬZ/ y{{x'XE"G+4I*bpAWhϔB{AhO}L햌 x΢m"e\#+@%qI4 jvs]Җr# 7sgh .<6M͏')Xs:<=~;xjs*g,pb~ wkJv?EuR@&;9dCT$;EMъT1 j1v?HHܣ*pU]l==f"aFj+Vcl 5G:üA|fSO{J{N>ii$g},hcp$Ǒ\^V𭪖4r矜NXm2.6Ҟ||fSS6rpx`Yi22N@V;椎GiRlvnݳݻfs,x2.6Ҟ||fSZޕel.;Kx !,&H+q`G#ΫqtȰW{0PI qml}=M͏'#zS~u=_}mnwE"M]/b(V30{66>О||f]W]1!Yu %H㍮YžH6A @;[:J]" m̶Yi#,g,\xmAhO}>Sh>3c .mSSiKʄFrˀNG.FwM.<6h20jr :'~yfcWU$cD?eBAh ]-H]QscD>bZAX|fSVh+x$h6{6F I$IIdW>R>3a)]l=='H-gƓ9$ݹ,2 ]>MF=^m\ѹr-ziq7ml}=M͏'$SNuc8}^Mv\xmY^eX`,u,O/zS+1"첡  Gk?ŋū3Լ] ~/S] ~/WX]˷,B?oY=R((((((#:K1}_5-5,ιb?ֹcl𧍣|w:n^ݾ,X%?V3vˤ+ +r*JU-ȅ#\z=\9-t綒"ZIxYwp?LTuu>"z7jzIi$qۘ%+d|ŪeF}cG&wkz(Egx *D/+rrzo,taxq,7\a ۼA7Jhַ:nt‚C.Zyn¶@Y!n?|x{:MռZJҰ6m->$ RhLcH㰧q- k '\[3]+GB@ ĂHkuo/SɺZc7>9f"0F4r\bwe%B1#U+/a hTOuo/SɺZ}K~O}k7ΫI֗ѯc{{RJJٔfSȀF##ԝWֳ tdp<Im5,ιb?ָuHbm'Y#77W\YdddgC8ŋ"P3|n֞ΧìI,4o4E\ʽ =֟q\d.ƐGy*c2uUx䧐#owuu}n֟V>ψK^y["'-;A#nB|x{:MռZJԹѯ\ެOV 'kTR6e 1=:T,_-ID,] Gr5 Grt bxC 'RQqȳ|u?cJW5>TA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈTA⺟ʈ4]:e,48h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h[4fB=5/ϥg>h h-0?E$28Tc?P& [jwbФ&rEۦ S oT\s"&,>IQXbʏ}nk7m&~y:k6M3In#tGI0,) Hh"/(MG,z$o8S42 c co! 0 O i^-*D0'qy86&d8o& d} \OۢЧ7O\Fqwqk^kp ׃qn =d]I [ĂI5H1G]m9y;3*6QN s7І7\eZOdut/;7Ky5ўa#=:ӭYFK* kJ7m\qY/R??6F 1^)|SY:䌩@ȯ;o'+ A (mh$;HTL06}GgM^ᠲv`>:?hn_E*W8*VN K[>fCt,.2>g$n~eCV oi~(WH@'ߊu/cԿ'/i7+oU8(c5ͨU·)X0i`5 ^~`Be81u==Կ'wR?.ikO2:Kw%"~O+ztkzMִv=+kz lIcn1$ֻKr?u/c黻0Z[GIv]Hؾio ˡ,,OR99WY𶳯O<Y%Ƌ-nIKdswۺtn_iFOg]uuwR?.Krz^bחૻ鷶 MP\mq9x/\ռA5S[<(7dc8^OG@9?]+1]iۢZ+~b 2{5K(eů{Cbv4ye1BԿ'wR?.?fJo@9?]ۺt{;4Q})ۺtn_Gin_OGO٧қOG@9?]>fJo@9?]ۺt{;4Q})ۺtn_Gin_OGO٧Kr?u/cfMԿ'wR?.@wi٧Kr?u/cfMԿ'wR?.@wi٧Kr?u/cfMԿ'wR?.@wi٧Kr?u/cfMԿ'wR?.@ʕF)X"I8 &Ըr& ȁdn#ǐ2z+{XZm&Q6ox+wL-6sԡv:t[<(8PY@Q@$j4Hu2iLos8Z>"چi?,CnҘ}MG*]PJ`I>Siy u'-%w(X/[[}a, 2(v;_E{hknqn,Krs,]KjZקKԭf.!KMT./. 3OCq\_w)h+JP"ᶞFG8OZouS&DЗBV&t!d`9xuMJ#1JO?oB3^5)Go>_?-$:-Ӗd(.s9uhrLZG#\|l[V񳗽O b0Fq$ճ~"[IsM曙ckX #6ұ̲4۽!I͕eK4O7#ApGZiCӵBxc[13C\:1;sp@$WG+oprE29v rI'ܒM (PI֫@ZYWVs L$MHr! 9f1M 42909Cx||0:3SMN9涞_&{yJSun ޠx>Kx=ZMB)PwLEB u KX4#"k%󧸟n_j$(UTUI (((((((((((((((((((((((((((((+|ASFI^^C2J~_8I+'Xguض^'\-џeq2Tbz\LUhQSqض^'G-V\ [/K dB.-Qeq2UE?dŲ?W<'vJ. v$z2~1i 5̑Քao#Ų??l.?&O*J:9 ǜcu_ċltE-tym yu獡Z"ӕIrjtض^'Htk<? o~. IcU*wn砨ͬߕ q 嘒K0;d`ƸgXxr~^澖}O+i.n{{x^Yo$EQIl t:^qs$KYH \GY>k2AZ K^^Ų??l.?&O*I||r޲}/jYK fz51yO\&FR7g89=W[~_G:;/[/K d⫐Լ](+JK%{')iѾG8Rgֳ`׼Ex.n> [xj׃LŽ''8PWs#l.?&O*[/K fOZ}ƽgw%i8YR@07^>^դXO5D%i 6 |ة2>duض^'G-W普xRXm4y[N:1jk0tZ;udR7!'.T_꿱l.?&O*[/K 6ľ&YZ^X4gT@T,ay'/sx^("e7Ku9chQ%k9bz\LUض^'\}(COz|As1ähvHL޽7{=wض^'G-W꺭~/o$g. ۰q}wk\x^]>gԠEo;#"{I/B̨@ ~ck&tz/-Qeq2UC~-?Na.例[WT1ƛ`Cy{ &dI]sp0HNvNO@CGceq2Tbz\LUrzw;3W-Sd*_3~n9?/XXElQC#nF2q4{ _אs#Ų??l.?&O*'jZz$yi9{q:o-*y RN.kS?dŲ?Т3l.?&O*[/K (ض^'G-V\ [/K dB.-Wx=?5?d1337Om]q 趮¢[QREPEPEP_ã27n>/ߗ-x,w:#c^Z1ZԚ[o d]] LuhPH^unb5s3'E\yaX I^76w CaW$zoS,4&7q>2PWtV3$g~a tglBY2;kV7ZZCa9Nbpv?t^׈I%2Q@1pylW-z2euJ*}=HTMNw毊]KU7 [<7`_xH+bc,~bY!>#'鞂ȁ襯άx9y. 亷0'[-gi>SwI9ђEo2i<񍣧jQ]gdb- S:tmrβ1]ף2 ZTV3[rzڢi>ddj~5wi8ø <RFzEE{PKdcmG0^:ܢRkfFEׅKyqDslO #iPpx'^xv yLAg29/sr~{V{Ip2_iPGY,DGs+(#R#85߅4+[2[DUB01dVadPMOD[ea7l/ZO)r}*+_ib[" 0[a{Srz֥sKYV^ qŦrD!*!p?O𞅥-gf .ʹ>7I{VIY>t'M&6f8CW'p*m%h|F R<ִh' #:B5 %{ci#~h^Wz/tlo 3Q=hNKfF$>`==;FrI<{56)'$Ig;tVEdrZ&Mk;+C+t֝xCӵ8V]!CDx9\9Zӵ.TdxkF[1b%r y'9A"YlOoo;^_ZԢ]da]Os K::9Q&{[B Ek >\d#u(s݅4K}F.pťH9|yX_k ͲvJntzfG}K(WOj*i/fBH_;נp5LҏukϢCwm8=3SN4aFvVrJWKfU*j{t6-J]:JX)!,ۛhˎl< t0%i$E{xن %1sn<%Uee}"&?B㚓Ul:mYUsk.fI-_[(X+ASab>\VPZHUKI^ !EУχz*(7It7x>k+ h7 Fuᙈ$=楠kI\ih6Z5 }0k>Уχz+:U){wZu\\יr+2G!Bt}a$Vkź-Ě{K+ڰ@I`z|??GOW:AIIt;f1R(Ť׺G׷+S?Rďm4m b?*Ko*#ĪA]'KEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIEG=SyTIQ\Cim-ċ!y$|??U4V6wA0"Ȅ @{k r/\>Tm:{,%E]9TVe}a (okӬ^$vq)討~ nKk侷ҴBv0/=ɤh3iٲkd7ZYc~(.f&,"Ӯ--]qTVe}a|C=n!biic Odrqn𶣪_Igbf`K[.pb3bxƕȲ\i:"Vbq(ּXizElJ-5Àd%CesYy>R3D]IdiwH#v~nEh, EP AVlH OL oNnVwO%7,>hˠ-7Am4R)iqVR 5xOB.4-|2$ ouRVB?+dw=e冏[\_ZXMj4vP9=*)to]7L1#!12x@29<.ݝ,fGHyQ'I! UhFOK\K Kx I"A7BTo9m7EQ_!\56<3D?n {Ȉee͝XuZ-х{*A.\p9ԗ\%󥶴 W2nGVdRA9^Fs%nS 9qs@6"o2Zi\Mxc3 '@`d=MgL-,Jв*G|??@QQT|??@QQT|??@QQT|??@QQT|??@Wx=?χz+[?-AER((((%}e{gS}s$I eq@msLw3] JբkT7\w/LEe}>k?0buQNln/[Cp${Nܠ`z?3isjkzkn HpϜ/\ ߶Z?أ햿*m/:>^iQ")Qm[ga"/Rr22>Bsgiսis=칎pTH>\ _Z?أ햿+ywRf@6Hvc0:+./xyٵ6;У_kހH; p*~al[Rjl::\j&eʦrG܁V}tF5VJKPur!|%:r `p*~al[ffʕ 2G۵_QTĺ 붷pnXsr1Ee}>k?0btoqpu7ȷHy>ԛbY19 *O\ Nդ}ŕLH\ lG-Uf;"i4dT6, JFdĺ ͑[egKd dad ,G` Ee}>k?0bմٵI G!M,eELy#xo;G +>oݳvq(~k?0bZ?ح5m6R.]B5 |V2]yS9#n@}*%J}~f7lݜn8.Z?أ햿*ֻ7C[F.n-ɮU%uezR,vnQp9Z?أ햿+~al]5\g햿(e}騢s?lG-WMEe}>k?0bj(e FA,l+G?wOPKbKx!,ޝHn_΍E^ gK:^q,mj+# F!v@`o;GDg<1 w\eW9{/.Ž?:Ghwy<͘czU 6xO^o[~f7lv9\Q_q' ΤK.YzVP^e^ڠy6hXM$ݐW^G2J?Ƕ`ђSS;6Et5xw>[?-AER((((-Vw ig'v3s6WfC1GڳiՇP[3N$jc@o d+8{oeMٛ ne~-ԅ#ȷl$unm˧m0Ȣ/-dq(IݏS]5hZ=Z'iP.`Fg((U ;Z#w67aLkYakw,Hq'i_~N縢8)}mjzcvm»۟  vi5=ZP-jxvlHi"bv+uP%qKx^@B}Fۡ&IvhVX[Od|6  ܼѝۀCOj@ wCZijhKX\cX1Xva2ՑYv0VWWO¬}PL Ԧat&i29 /UI`@&3s-U\Z<#I!cS,#-Urk~=-t}P,3~ ƕY^GȪۂlZgZXmxൟYKtZ1@ (znߨKo]o?祷o.ԮmE=aIYk.⠓ sgsO$VO*Xsxʻ;nQln@/Gm~[bcUk[i.u=|Bn QV=2kkZ1O-SL ׊ߨKo]o?祷o.}~;= Yฎ;2 Jx1ETɍ;xڅ9ӯo0څƞ.2,#KdGm~[f^J=7fo 1*8" Ŋe`´}~}bx$k/̹Rcrwk38eVHPYW:Gm~[r:߅k{+XPA ~or!R6;zf| ̖Or;s %f  #Am=Wm~[-`9CuhbNH,5i%ծ.:Ą9]dBڡpGW.t}K`W ^pS3f *$敖>m}P>ߨKo][4{n-ⵒyvc Y}|?Ǧ\@mơ-li%g AR oB k}P>ߨKo]<5^EwsYkVm\b}1{aH` 4<7@Եo뚵kXk w[3F?rF/!8_o?祷o.EujZ,A+vyYv4[@PjoHsƱkŎqgiݢO.mՒCo3A^wd[_o?祷o.EcUH,wnql ThX#17$okwh+Odpj1$L9' 7m~[-`9~ۦ`k^rLIB-Hɸ;w7yXo?祷o.Eڢ~ߨKo]o?祷o.EbP>ߨKo]j~=-t}P,Cz[ߖ~=-tX +-Cz[ߖ i :d"K{4\'G ~LǜP )IH2C0 *Rd7gFct:NioyӬC$Sv-,0!Sz-M BOΓ+:l)6ۛ;7|_?o{VUW}<1stKi9n9#°R=(͡듛;s=Vڳ1Ia~ %?:@[y;~Vf[-wKSzA%!Dʬ8%ox5c\iRɸjGmih%R)A7'djN3M8nZƵy?Cj++ASFISLw~mjյ "{ﴅ+Ci,q!@>Z ,'5o趫!Mhȷs>DOS-ƍ(e[#C"`*}S땻Ӽ-r! K fWy0?`|rZ/ii/T vc"^$Y\u# ='Q,\Is+{y'՛hf2́ȡ 0g`>+п} \3嵴UOܼH̥!`H1J:卅N*PElTH6^0`uAm53IKL03㎟*1ҧ6']$6S#4̯JCJ Ǩ?TmvD+eE2J߷|mR=65&4ӡS![gwDs\.\I}m=?[tw.|O ƱNJtvKxlo>?>MBc|j{6IayB fʅ 1]xC^]5[EoGIm.cto( @;,[I0ZZsi,,Pcӭ?NO0[H+y 6[i:mgq,̇[3qG^_Kesyqo#\# xR9!Te;J+ͤ6[W3MNU8QT0sSxWQOKJuydcsIl[rL 60qHBiu^Ip"Y-gڌX)&4`2Q4 H|Gm{6=./Imd]ڱ.19xC?M[GŗF;scm Om}-Y'.ԜN遫mwF mI\@C<1O08H$^eu^i[Y&I!#M .c8|?q(hTzi-mr{gW6XJTm ߙUu 4`2޵gSBd:KȇHʥ~N샷J[t{=2M5L3o)"F+ 96°u&\ӵb~ujP_,ɒ˜gmswĶu^O*͚7fw>x|4GaVQ_(BQύ_-y7G.^Kqd T3+ggnr0ϋ_F5 ]z,WH[ɾ;m@d.s@Nji%<(h7!#:U?|mp7> WNytH4nP 2!aw䗑>f]n䂪q'ueoz: REPYC"(bhɗ`hQMwh]v؀3¨%'f>6¼^ׯ4Y;myYn[B!qq 疣.vSKޛmB[m"-ftLjv;ݟ9MesetmTh,丑c E,@p=E\WڻXOE hZ2,JXb>F|$ *k[LE}:ijI!m6?|mq-ۦXw\3c=um XAQEŽseh^dp)Th( Im^ >D܇3${cJύ_'X.P8FhDJ#%1.-ޑSJhtinUvʏoUpB՗IѴkROE,U8s3Oo^c Ru;]2{,ⷞ B\3n0nJRGʨF+]kz̈́SݵMyn%RX*JHUiB! qV 6tg[ep9<883Oo^k56%Cgorٕ!c;eߏ`:#YҼ/Yi;͍(HQr0ݻ G4fim~W(Wx?QԆyhww sY3G(1 _>@60S!4] k8~-֞ |]#e2ۤb\kYPt,ָx;6\1 a~SGFdWoGWӮ :ݴuXL %YG-ʕʐ dXFqpkk?:9-$}v̬/Z]Dx۔A@;ɬ v 4,O" #.A:V:>gխ@&Hee `AHAotgks=ëշZ$q"-@u#\ɩD-R-At$ӻ̅.#o]a/?|mٚߕ n#"xv6ws{q\I ^D4fy'uFՔmkA]*LF9eKo-4H *$+rXǍs_Y-j;-.BXFDAc^g6s\]oI s5 'i"] m3HίVVH+yHN Vh_5.qjrϦǦ h5>r b9h5̙@漴k5]k8Ŵ2Cẏ`y<r^}Ö=K_rCtoW&]ʗwRFnDڅZc ѿ#[9T5D[ՑneiIR2 "Ե};H6ͯ&Ku8V r* g~p0EM4R#_PG$iASFI^^G2JTgwo趮6Et52h(@QEQEQEQEQEQEQEQEQE!PJUwFoƩ@?f~GhћtRO3u?#5N7S?GOS.h7S?TmO(-V=Ppcrxf~GhћB,P}<ڵRgT$mP;ܾyћFoƱ ~wožy4xReu# %w?C?vXw]?f~Gk#{?ask;_:[K=-:ԕ]H8{uB-0sWh?f~Ghћd`Ҋй7S?GOS.h7S?T 3u?#4h:(O3u?#5N7S?GOS.h7S?T 3u?#4h:(O3u?#5N7S?GOS.h7S?T$rB(QjdQ\β>GLqB*h,W~OΏƟߓi?:E cO3q\0XRPxA*s1X+ASFI^^G2J`ÿ m] smjjeQE(((((((((((((+&_+:]ȲkW=zږbqkQcg ҴfEM:{W%}iu/4UK4- 2A&{)rO Qй'A+_a}-_%ȚMbV|iU^b 2+-betw6˥,~ eۼSBohw\/aO;?{V/n w\Cx&.][Gy#rN>q$ܖhNi'}ln8J7 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ?Ƕ`ђWW=?iڏLeq22G9=N;tMSiE74GE74GQJ)?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?)?,?"?# ?"?# ()?ā*  VE 9ABEQuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.eclipse_launcher/0000755000175000017500000000000011665471326027520 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.eclipse_launcher/image01.png0000644000175000017500000013226011665471326031455 0ustar drazzibdrazzibPNG  IHDRK 2iCCPICC ProfilexՖgTTmHzRޛ* CQ`+""(" ؂% .Vɷٿ>{{ιkҼT U)wusHdb4fjYP_yB<&6bi1T;1v 3P2}k2,!A8~q+spd:'`qN6?C P(8c~/nuSSW/4ƚ7߾[ yB#/%1Zˌ O-5% ;E[z (Xx B#6JDF(صع8N&'dr챛 cC#Å66b-װX@}_13;Yo P=03;p@U'@*vk 6CP 5P'9W& <0 aA@ !:1Elg G($ YH.)Br G~B"H?rE&7'Q*(G=@t%|tZVVzDGЗ p4qq8\8.'mJqո&\w7}L<»||:~#~_owGAC$B 5B)(p0H''lќF #&w~qD"ɐtH$I* $']$ I4"٘B' [ȥ9y"FQXR|(1nJ-r2NS5@ju3DB}D}Kєi4?Z"-VF;IF}Kеz}~`3L.F=2 SD_]$FdHHȀ+Q*uEoNQxb*Ί ͈3ō}Sw7_ IK8KHKH\c*LG&Y˼gY,wVu˚4 \+Y!y^rc)S!')y){XRMRRKc ?pdeeʴeq};,,Y|4̴籯o~D?_ gF=̀ȀieuGφ8n&N ?>yC+5V]y}쪔U#E#yQ!Q Qy>jL{i#e]LIdulq8⸉x} S副ܒ*f}%ϧ4SR $ɂ ׮OI+HILߟ>-@2Vfg0p+K3뻬lkל^+VVv\+W)ws U6l4W9y/[ oy5dkG|~^w5 Ym}ۗn?kaL"âҢ;;n4Ys~Wܮf!kXx]>}%’w#_/5)<@=u`̫=?'V8T4;G4UWU~!{UUե5Ěg=?r?*{cc#uu r ƬN8hokjf7Y'_)S]Ψ9l)lEZsZFzhYcU<B.tuN]4r~ݽW<\rr}k]~FMLobKKYom}}/ \t]7 so~={DxTXq'տjr?| |ng/Z_:z~}4:?D`04b&k,3N</ļ:D|φE,#n" t!&M>Ͽ u|RiLtӶ ^zXnwq϶žz pHYs   IDATx|O IH7EA"EQ  {GE,Aa( ""ԧR R@7 w,dw$dfy= :x`0 =,$@$@$@$@$@$BpqYreVxHHHHH +R .L2T&JD6%p*:Ruj_i}C70q,Osci) LjR|i ¡Q(X#RAb]g)d}:L/_'[Z*t! %.TBb Cs!*{W勹q$@$@$@ S&`XGJ|by Ζ`iK0 zW5BZ%̵C"F7ʹGFI%LO>9"Q*>"*Nt~+ur8dI6J̙3o>)Wh_U>,ݺus!?=z}RHeжrd_j2+VKW`aP ˮiȊ? 5i\Kֿ\%99YsH(&II$);w.v%#hg;X%?;pi,b Teur`*92I]4_̑s+KDu✜;i^diAX?}]H.7=!ozRRkOH &@E3nV;ӡH\СCڵlذA`ezСҩS'%66V,Y"_l-$ĺ|jAᅦ5+-ҥKW3G%Pn.UL Ƃ>IJL E#L"z.~MrKz JQƥt!C>3iڴ\{Fvzĉ  7n{N.\p% LnF0Q_v^Y(W\q<7k,EI۶m /69JW_} "-.nJ=~m۷K2eN:]@o!8C1e-|rux m{*>Î&ouZ`2q(={DQS+Ѫa iaא$봣UKJJtvVٳرcaH Q9< &ȳ>kٲeRB;w.ݻw{>Qp"i͚5Zsb&  ܜ`8\/ot<~Dv,_i}Ͳnw KEيȾ[eՖt:OȲ\:nҦ4mw[r~fwm[=NEKJpi(zyycn#o\vAbxK.ո H#]z饺:^0_}պs FEE5\~rc}p5a ,RT)̡hxC" xX(jV$G/SkQHOKf1R4Yo`| ܂3h5k:Vof9r_M&}%[jXG V͑`hٲƷwF}8Tti6l+VL*W !BywS<'$PoF럴;VV0(:xp}X `!"yP6Lr!$(pPk ,"h%!  |JeLP%_%[J@Y4wn25Yl垔*g-AJKI+{HDdh%`AZPͷ$W N,v 4R.sU,BKHjƖBc CfIϻ8yԧOuoߦ d^n:n35FZ!i+kJ:!)GU0bo[OZJWkc8t萮6nBJ}`֔.L C1n8i߾c%W ܐp?ThQٳg _ v6AYߏO Ţ+ok/_2F~qZթ&'a!ﵩK彡mLVQfȳ,25==>&m삔HVʨ/ܳ7i 5dwn|.>AڷQmH;nX*~V37Ĥ$|9;sr+<eZ%,y_'{vlȹe>n@6b.PR0&!$) ŖŵgL;\QkɒC^+@bW\%IwE5_SΜ@!A@*Y7e~tM79~x L\\@ iŤf m|M,i n/o`OpK\D0l! <_~YV1wMk=!\?'U{(#~o(ceӔJu6)",T'֖Þ*{<55+ϰ8e5,xB)k; JJ*]N%IAk8~ZŒe)wS¹$CiC|dswf0G~tq+/_$ -X̘HHH\ P.UW/sp.ߖw6.V GYKVޙS'%2hiKC5[_Ag%Vp]}TnX!&&5{)^.Į_Ή]@5V#! cUڐB7iGMMwd|>QcU.P 5z0/#+԰Pɓ'%::Z &VE!uYg$&&@kVji3sF ?|tUjW..KGI"rߗ1Yܜ,)2v1K8s|LtuT}BuTxfx>=Mcia'Oer[qIǭ̘9 HH(;ve²@RE"`@F7ϩLXZ,P2$I[6ڶCcpjۺp9W$Հ^;$+PwhYI* EB @A%.{-rDWWk[T0@[ XymSZ+5،g     @(e]k{j/f٭%$    KT&\ba& @VLdEIHHHH\2 3IHHHH";Y~.]TRr))[LCCCJ*xbͺgϞ2c :t\~2n8u]'zٳgeO>rY;vl߾]ԩ#%KjJp*THV*:u+Wʆ 䧟~ѣGܹsg:C$@$@$@$@$=+gΜ+VȜ9sJKTT,X@bcc>8yᇥUVR|yuE,ӧOzz8p@K/$Ӹqc[_XO     ȑ#"X0d.A@ZtmV .1 4Pk޴A9("矲n:d_*Ȁ"*ʕ+<      =l$/TP"AAAsΩ{ xq>zkNd,pob"    [&ܙ WTbS&Md˖-RvmYꪫd͚5~ )&&F;|]1 d@P&jdtWHj.vv S߾}^xAnl;x`y'5}h"yWڵk婧k!     +!41o<ڵ3GץpGcƌZjIny.ab. F`oX;M1IHHHH< ƨnI.v풭[ ,i鸆bWDp *D     # z!{ݗBBBxM$@$@$@$@$xL`{VX 9_ݻw O$@$@$@$@>ˀ=-[{L:tHmۦC-)88Op{ IHHHHGT'ʔ)}IҥXb#"+ 63JNN'N{)P/;&ʄ_;;#    l2|vBQ6[׬3+ٓ2iHHHHH+paٹsCI N9N-p0ҵl߾]!ϟ' N} 6W#Ff͚Rd IJJ+%HH Iv0q%JҥK+*{0LZTRfԩ.leM6) :T|OWnF{<`V    游8 hҤ+Dl$X]: ͙3R(JYWɧ~ڶb.4\#H-n8w9 07ˆ1V܇|w)+(M:NSџ~qsZllٲE#1ooI&I߾}s#   ț <#N"22ҲJe皅夤$ s@F½ºRXdҡC1bR~/oȩscK.윐{մiS]$7ւ_)P~z%Wvc3xo3ylBYq`~`VFe"+2m4V⋺3FfΜ/^xAN:(UۼO$@$@$@$ `rM|Ȭ3is͛we7b/=uTX޽[&N(͓E}'f͒ݻk7{|CmǎEmmذ FR,{8ujɒ%o_!{}6Jg'~F`euGTe"lݺU؆ g'|R={Vyo%X|yy >aL$@$@$@$@M1z(pk(z6 3~XΝ^1G}( 7k=z{TbŤN:= V0@|zuITT7 dSm>ʽK_˯΁yݴgµʄшrj_|~e麭չsptYݣHHHH` Ѯ8AU(aTx {ȑ*C6VM[F?ŋRϞ=P,n,ۯ_?b2`- cǎjѸB]a1Ún:m ٳs3vܛe܍?ّs=f|xj0'  _-A+ă6_0x&   `tNb(p{5́Z]U}(!Hu֕mW\1NٸߠAB a@|/q!kJa~رZ[nOFǏ,#ƍl0uݰ߳\qKѣG XRe1j0 >ŝYڶm>DLRdT)biP_-A慉k3W^yT^]54D7jH A.?ig    O`h_r$9F%jp;ڸqc%|lla6m#nBX̶/n#߹ۃodRJ9n r}9:p+ `k] ~L@3`ESO=647D@q0)::Z~wL͇H=IHHH0k.ݞuȐ!*:`OL̮ч\r.MXQ0/Rk"=QBeyx3N* km]0y8*kk    x AP(Tv`,a;؀底3DM- ,<#^M6ovlB3! 9ܦi&u(5!T##$-MC䯣 =׷}tlHHH (ȊŒ!CB*fCS\\~;'5 (Xvm31e":L1B>34i*C 'OEBKβ[oUٓe9     O-BCC_~2w\7or-j* DEEI=䪫*k֬QԩSҶm[5 R矗ˮ]ѣ#GaÆk&%K1cHj䧟~#GHݥW^'ȱc䥗^&M=#zK8 aaarJƍ[z)3f̐C 惹)裏JFTRsIʕԩS>}͛W_ m2~x~1 @A%s7'g .,6ms̙3eɪ4lܸQRoˢE$88mK,QAZlP$LܩS'Tԭ[WV^m׉b СYNN`&qH7 < @A"DYC`_va-)""Bݘ5ܙ*V۷ԬYS>cYn] "EH5UVz2Q^=SN s#   N !!A6n1DYbZJ7n, *ddFoyQ+k׮ &H-e˖ ,2qEIj#$@$@$@$@sرcn.MP@,X 'O{L sSApuڵkKZ]v2eصkW]O |&L$@$@$@$@$Lʁ'KEnMgΜ{OAP9~[fe]w%|iݺ=۱A$@$@$@$@b>,;wC I N9N-p0ҵl߾]!ϟ)Wѣ9O=+ @>$jԬYSJ,!IIɒ`奤@ :պNθQX1 RFrբan_ؔ*YJ]֬Y|ĹL8p@}=+ @># D\\@1(g CSRrum3g\B d*xCvuMsuϞrgƜ1wĝ !Nl?`比+ʄ&~HHHH7ƈ%uW|~l  a "" K….x@Ə/:t#FoK P)׽{wi߾)SFh_|]h f|3* z9Ar2P.ݔ m߹c"   d,(gP 4d ʼ=u{~~+L LE"El*]M3K J{(Aɰkm+EFSg    ",o@P5*U"5kc-_8D@ @ҥK+0rV.l!gsL @A!gxǴiFx )[؄@gsH|+ +¦M]HwP|Lɟ{#   𞀑=iTPAoaOlAmr SLLrhܸ~.P$'ۧɼ8>d=;S d=;S d=;S !E&p@ 7'#~O 'c! #7ߕIF>Q&m%̇}ޟ{v&ޟ{v&ޟ{v&ޟs!`oeF@`]D#(a50w(H|v2Qg'    "`@)^h'~Zm $*X9)    =*gHHHHH PI P=c@$@$@$@$@ID@>VNHHHH|Oʄ    HT&rR$@$@$@$@${^)uAcg$@$@$@$@$+{L牉?sHHHHH [ C6zZD+OϘ{˓ X$̙32D\\vmǬG$@$@$@$@${BBBXb &%%E]CO<ܹSPRJҧOi֬OFIHHHH p- ,W_}5ӑ_>siӦ|M     2aw-iӦə3gFɮ]wߕ͛W_}%j(UV7ʌ3_֦O.rUWɔ)SSO=#((H*Tex'o;wNZn-rfԩSҶm[۵ KٲeeذaR| ׫W/?ѣȑ#eݺuٳg%$$D}Sŋ墋.;C`l ɓ'kY3vIHHHH e2o<&@؆)11QOQ.Q=&J\\*UJ{w"w^?v(hO>oQM6ɖ-[ (:ȇk֭jcʃ>}zcw5>8.\(^{@@3ftUG={Ȋ+d„ :'jٰ0ygH( !   ȋf "Ŋ*UȬY-=cٲezEjjZ;` 5kf @2%$e P.\Xʸ!pg*^6 kxX2㏫kSB]bPPQvDԵ+h2e8+ HHHHH SfG šCxR"Eȑ#?hǏ;~gt1oUhQQ޽[8  I7q խ[W^7-UViHl|Zuiҥ]p@1"((/d0 @^%WDfPÇˈ#hj/XR H$\~GdẺo9Qe} FӦM5Fő( \ʕ+''OgyFe6>-`v,>zh Bb10.Uvm7|SnAE/IHHHH Y+fF?Ӷmt&52{Ƃ( k7 uџ Xf%ž঄]2sYX#`pnnSh۹8$@$@$@$@$S2eHa(u#| )W ʅ`e6>SƜ3X\HHHH\Le"    _L îHL$@$@$@$@$@\ >mXKs;:v G$@$@$@$@$ņ@OxWΊHHHH|NceUL$@$@$@$@$@A ;,HHHHH#{ @^ u^0m6CʎS|L7N2 3OC:7+˗//8:>>^?]e|\"EH5UVz챳QQ2Q^=SNͱ!    +M/Ҏ;RJ隆& gA.]8rP # Hem۶r}W\q̞=[5jEi>ԩSukY\xquS2]63/]w[؋3fĉ'P\ϝ;W.]߯5kʕ9 ;q|w*ϛ7O6lBQ>S+v%KGQ=v̜GDD2+ǎ,vR~}Q=zc~z;h}3ξ}`) %1nGAeͶ2i$9sj&   E!C][n ?(@4B}'+W߸R 'b=zܣ+… u+ZX7ߨ|*b<Q^Z~W>1z{6sݴNT&w}Wbq;r=>Lh%!  ILL˦ /˛$   cѩST3ʂqvbTx {ȑe^ٳo ?dF+ŋ}gϞ nG|ү_?]6ma 7 (8+_+俞fd4&hfU'tW3HHHHBѰ;ё#G 9h۰J AWx&<X'P;#JTLi߾<3j}o= >\A~ǎ.ӯS PR ֭|(=z:zpS?Ld6/i~M- iۀk51 Fll@#s2Hw&    A>܉\ BP(]Elg SnݺXZ,87kLe4hV_<,p1 fAQ[n2h A^{ZF >yܸq2a͇ߒU&8k8ѣ0G<  #իWOLFP.Lx7J-P.S_THHHH 0DZ4zng\tIs鸏/Re믿G 8`ӶmTw-  xc ${f Y׾0ng:#"\Lf=~ZC2P("E+T{x`v, @$8,(ĊAʼ=u{;T\9U&,*MQ`Q(;f[&< +E”ÖaL$@$@$@$@EJXu(UTQva;f~6FEbݺ)6]ʎ|2H]ϔ$@$@$@$@U #iFx )[؄@g܃WK 'x bӦMQfQ.oCv{77{DM]O, @0'# dETZUn*oA 'ȭ0SиqcTZ$U$;(Ƿ#0h:Nμ8]b# xC<^2؅B&搡.,_B^i|C]|?B9vğ |L ޟJ2$?LM24$?LM24$?LM24$?CʌE JZ=] sRg(u|    )FXv& @@2"    2{HHHH| 3f$@$@$@$@$LcHHHHHL1{     $@e" +'E$@$@$@$@'@e $*X9)    =m82s/Zj_H[6 s$@$@$@JS>XL$%%ɺqRNe9"N%ʁ$$cXч,rC :%\"[+B.믿\KyǼ,^ثt!:uGMp '&&뮓f͚믿.#GԾmxԹ uϚ͆ !mڴ,Jgg"yHHH 2<埄`9r*A~5YJÖWK:y_W=&A .$A섫.aÆ _{5W|w 1C-^4nX UG%.R?~Me˖駟 z&   0|jHNNӅtRTS~yLp9~Jڽ[JbF{9 q.,BP'.+V3g8;rWK~sҹsg]ꪫܹs2qD7n k֬套^Rw[oU>#Kj܂Ǝ]s5rIG{pڼy?.ҡCٳg#k:~p5FX:VϞ=5{u;v/dˢE dfXl[:u꤁OvũSTkգ[n2ydU]=ÔmJ.:Xb Lap?~\X C{y!cقg cjo18,xX<3&iX+o o(<{U>x؝j*kԨ! C$@$@$ +}hP($D ʕKdLQٱfjN_X" kSVxanCbAP Ap)k $XEذaC;t.n&Bo[ T  9,A麊z1BXƊ/FRX7U}c6mR!'aaaҶm[Rw'Np(C=ڵkk:,7AK'xBWl g|(|&eʕ++\2%XbK2udܹ*ׯgoJ fmƈ3wf3|rblHPL`=)_I3?PN{}mԨS7gb7ú-(7D$@$@$\' GEHBR JEH!]D,х%)9R8%::"Ӟ!=zT Fp{ 0p(TJY3GyDc cc${aӼys!A0[1='2z~8C"CJݺu`5<~GPР|`u}2z%KT%~' Ive$3=;;{Ӯ9gTJ0,xO0~##@ٺar%ě{ W#X=IqCSתE n2eXPn>A-&   sDRH)#JFIHϻ/./JDIR*SddT zHTK5kA Z7X!Ї7 %BhBă>(XwN`e+HڵSw:c,v޴W^Se˖[gNBp3,ի š<@[|$,"pXjs:e !)RD- P\!b# $#\;U[` @Ex7V' s+ w!¼3UVժܵL|c.$(0A1;wUҏPlipEy$@$@$ \$tD ,9kzvreDZ JILXT"^, q@+& B&\ x7!%.˰O(.4 ,,F|IP.@BB ]Zb ֝/}H; +∧PBw\`a mGe2zVM4 ,^ IDAT]W *{NByx>w)r9Q=i01#bAQSI#%$ᝯSk{KxA615H[Al\&^ nJ\ `L$@$@$@C 8Mpڵ aԙ "V`njyK6No.QWUX+iK9>{6I/E:Wyx'6=Âdc0k֛yFEELϨ˛u; Z(0!3\ӏ }@<<`2\RJ; c _%W,0|F3ofzv-`.}X {< ܇ƛj6@')Ѐq>$@$@$@$@$@iLM       $@$@$@$@$@^JҘHHHHH7+TD$@$@$@$@$ @\x5,2ߏۻ/$!@R( (( uUE];bwU` bAW]dUIJ"4 𿿃wdf$L&~03|x 0zq}WX®*{W}*  @ j/3fe]f ڝev5ؿ/;sn3-S3gr-yWvk׮ǻcx˗/l @.bSqך*~=&L`l9rv9>O:hW\qYzj馛ܵiz6mO6va-77׭@@YĂUV٤I~@pvrL{ݐ(֭[>͛7۶m۬vvyY۶m8J6l3j(fƍs n1w\P}ƍ{Q x ;֭k}WCtLեs6qD\EժU]c*8JIIq@@d(`BHCի[ƍ-8HYz꩖nr͞=rrrFWjj͛7Ͻjʕ+gݺu3g^VZַo_:իgwAzUw?@yT?-Z_yG@@ J4P^E HeVRC=' PsN>r.ᒹ?\~ ^g@@ʬ@Ly*8cg R~ҥK>rz}|ЌN*!W*_|k*W=>}tI֥KS0'e)W/[n?  @R `BJ6ln5mt_G:h+۷w@_] C qíԓs*黨Eå-[/b|ըQP(/tAE>}FQ  $Rw~_%HZ" ,;Ô%N"B+ْU8w mR_UgJ(C=-Ju\.K  @8T=g"Ric $HJK)kP@@(k aLz@@KP=J`۷oO   4j&Mc Ks0dg9h" 7ja+~   fggv@”_ԩr{,]J  gI6nhjߗX0AS*)Z &JGL   Ԗ/JB=bŊnxDq@@P;^j<@exSa@@!BGZXO   P6&U!  ws& S#M=Ď?ن \EZCc=4-F}@@H@܃ +V^zɚxŸ馛vj׮]ko=#?4h@@Ί  @q M6٫j~]zVZuqUZ裏vh[-[D,:{ʕuM`oٲe/"OMlݺƍg7p͝;7f%,N%I@@LܹӦOzN:$,o۱c's1ָqc1c&\WZe]tn޽mvMz);蠃l{-ꪫ\_W;ZW/cƌq.UkZhyfݵ-?^~彶)Oڵ7x#p}_cǎ݆ f[g}_~#8n2}XnuYn}ڍ7޸z~0][%"(1zN sRz+'BĎ;,555;5vʶ<;q|eС֬Y3;vl`(2a@7|ӆ V}W6|4i^rKA_|v]w)bjX+0R[o5T\~Qy"*ժUsu[Ow٨Q_wT6|p{wyn;&>p] VУ 4̙3vA̒z_dO2*\rS)(  EkτUTzkL*Y:uܶY[(0`@ :/_~k |r駟ܢi\O5駟Z~[nCzWpp9e5o?nhv͚5-R%D}駭s@okz hhݻkqn_~y:fNUPfa^y;)StnH{J?3gk9smҥns6&;Fˋ/KYAz|<5S*8p` RnzPz7o_E@@(`BC4cz0 5V eZm4F Zݺu]E:j~.xPcW娣rL5{@^r3tg]S3p8}We获fEsrmݻrgds-{m?S dT󣞆 .]GC({GmĈ/ԩSݰ9I4I6rzP5j԰{k~/?w   @Lq(xPp smOhWR>#ڵU\ݵ5\c=I4h; \x S>\iJ.]ܝ| 7]zT/^^:իŁwjjѻ낞(&NhwQPikUC/zE\\=z? 33Ӟy+K׾zԣѾ}{7Hz!TK|E` 6t;oFlAPd~=߻z@@q &+yVCR AjRRf>iӦ7߄ru_T莺l ;Υ^hѢ;ixZt ZvWBrhC]9!wnTA5IN~apP.U ⯓r"-<5H=J>P(]pm[^ΣJpAs= ChEGێu  k0;ʙP΂ګ1FzZI] UK;O]t5ҕ뎵  ~CW|W#VwҐ, Ҹ~JTW?_S\ w NO>A Z(Yנ@yѪ Eãtzi`)]E :e 4IC=aF3%(XEzXUup 765M3>uL FA@(SRq-[>;?֏?hUۅ+JνܐWC^)Z uR^i\xᅮm5`СSYU䣞*_PnzM렆/+yM'E PpBYjʙ>zcgJ)!Z ꚾWiQzG})C6t)Y[`B@@ywO0}^`KUp_ELBUw^2hg5Gw5H=۶ms J~[jĆ:B*CuvjUxauh,~GCt~=CCw+KQ(}#m mlWwQ@@mFGDr'5Petw_= cRC= W"6,h<אI@y4-  { 5yާ7ïiTڕàu "X3#-$JﰯZHK  @q&T% 0h(?.KWUg@@H@8#  q6y@@$@0I   U`"*+@@@ D$#  @TOS9 =-OݶyhvUؘQ'P!_@(fbp TRjԨA0N6gY[{xDUy?9־avoY푻}s @(@jm߾=g{_YV)=ԯdݎ8NcZNC+ADVNwgK9/p\މrȎs﹖@@8޺P l:mj۳W6cm;F}b/]>ŞPeq l䔸Pjϻx"-VUl2! xRWf6nS여<{-ܶN;K= i6\i4z6om@`ժUSO`˲ɒ%K\4_!l߽۵=޲-;w[l./  ,s0KcΝ6(]h[l<[)זoεeY.man[tAvqY֭SOn1c֭[X6x`{7aҥv'WE?{)e/ֹsUU鎻7|or!<5k;v=XժUˎ8?S;ꫯVZٳ#n &vzABo(N} [msLR@@HC0=*B-[/Y2Z!ϲb_nkkUV,ool|*V ?￿tM.ѣß8d飏>jipFĉ'{^O>{챰KC=&O\gmz :*Wl`9sNW^y%l_.5jm֞}Y{'n Y!ŻjmpO/ɋ/3وg&Y #϶f+`ϵ * }s=]=fPr˥mѿ_~{}o^m+! jۢjePPE;3FXG}wiz+,ЖGyMg:h ݱxn|;=Bg}fz_~m韬,+줓N뮻.p~ ܝWYge+Vpoю>hw~cX,wieԩ~-\."3޽}ᇮ~ 'L⎡>O+wz[Kjlܸq.Iy̙֭[R[VVeʴ a;w^a˭z[c 6oD9 I/`BFuVFY9ͽxwV˹WŴr޲4fV&Tӡƫ~~z44I¤Iܰ+Wm֬Yc۶cKѭƽ|7m5u^m;♙.X?7bV^=p=W!Zy뭷@7vפD_`DW/UQ w C q{챮WDzxԻ#/E|rӃ^xKfȑ[ UP褤SR͛g{{͚5kUϓ&6mjjrA>wJ)ެW|ksҟtϜ8vXW޺rXzyۦ{iL$ }9B.d򐌫WX ТƠ+@P#V nr.WQc:ma[zꫯܝx Ґ[AzsEumkذa Ft:u 7ټy@~m;3]^+5 CjXjOzzQ)P q5u{m&E IDAT##h%xΧD]OE=P8 6t=)Z\o٭W"~iU+SoD=B /xm(&vhzoJm0Q &_Hdx#_/xhrV۾"={@] k^niuV45|i{헳تU7C% 1w\7$HCԈ֝x 4>@CԐKM=jk; [)K.:-Ӑ%<ýqW@f3`/%kelݺu֡C!Z¤R s1w5Ͷ*kӦM| r,1Qڵkv5*͑GvS6 ɭz#ƥ`aJi^'b Wv[{& ss/JޙjB   o{lR-ƼNV .1p]ƻnlma)H b5|%W+: Jd SNv9e5Ǐk S%=kV[n] W:%Muewذa8j_|q갟{zBԛѣG{vHy 6ԃ Sp=JXW 3K(4%wi^?RB,^ j S4z 4H/F~HaiA,ٝJkɬ\ΪynU<{UFqU^gW%7nRYj $@9βG(gϞװ ,p X|5 {=G=Go*yӧZnHaf<&l%,0krVC= zAA+HPYCz0ڐt<4JӐ' U*Jz i*Xk@$n:X_mEEi,$=-ջuNc5Ie7qVdnȖlNK{Z/ $n&bHqB\9)(PO y,;K>{Nz =)!V%A5T/]r{q|,o^}F $mazi"]sڵu|tPp)wDwqCR0UZkh &#4IG uegwMsk-(  @ 5PMuYw5kfVRO?kͺ;_@Xe|0%gk8RMf()}ы^@Q03r 0v{}M66?mR@@q&T5 0(o8j*%g";R\Θ1#0,BNw PRJpoPz@ED M_I&_zw@@ %L8&$NG2Z@@ q^*'@@]`"v3@@@O`?@@(D @@&@@@B *Q3   c&]v   Pxվ/l95kִ͛7a@ʳ   PDNNeee-1.ضm;yaO~   8^edd1:NX  F 有RSs*    H(?'G@@ y&  $T`"@@ Hߎ#  Psr@@W`"y;j  @B&@@H^9    H(?'G@@ yJ$ضmXWO2,X:>ÈB@@X 5u_~=vZS-^=\իWN|;wr;9sꫯ  >ܚ5k>s7oʴN .,@@@ Ls=vw֬YcCڵk[v!X޽n5 ij    Y no+"pvN(xoa;w;m>lۼy͜9'ލ#GZӦMMq[~~wyӎ:(۱c]|6n8?~wo%\K:ѣw)4]~g5jֲeK4hժU&Ozh֭[g[lnVwVZ  @[0d#жm[jE l;vvY֭=7n3f؍7n:  OECV\h&M2)ϩO0}s橧rBuiPaڴikcǎu1bXN>+zIp(BD6mvF`g>   EOHrj؇$ar)Vn]kذ 4]95ktL~jUTDGy =ί #==7nl FcZqs1{l{챁@B ddd@@d[D&ML= PC/jTG%)Ȼ*UdӨTPVi#oYʕ>ڻtt K  @ĭgE!=qĀ ߿[a@jt| -ZpKKeٲenzY#̛7Ah}ժU]z=B'>WB XX(ҲТ ]λtҽ%+BJVVDZr@@J@܂ ](naÆـ39i۠iZN:ɦN Ju,?h{6hȓJ=\E]@Dm%o+黠k׮aȐ!Gq^u󏣤oN(|̘1{\p]{vm{.r   Py JVV7mdWOCB[ gRBA10׀krb)J} [i  VHqBr&!ԐԘV@@B~h^+Z?n]p#  PZJ$(8@@@ *Д/vÍ ~*D@@" hzJ1W GaG@@HFJ;'6 b&~WSU^%5̄X@@ h\۸q}_b5j$h}&HgG@@ Vz-R [bT+VtÛ$ ~  $N@xj׫}_sCZZÛ ~  z-1=!  @ (['W  @ Lhl@@ʆ@Q1$]?@@ }lN#  PtG]/=/A?BQ´^ U\ѣG'dB)   uVCW޼yf1c{>ܹ=`;'tZ5o:u>/`bSK0q[˖-4gm]!B@(u6gΜk./vم^h>odTҼ-_ܾk{'cǎvizטL~ִiSs@@'c[~}54Io6mk .NUTC9>`ҥ?9/Oq & uEA@@ T@A,KS5eeeِ!C?BuԫWlƍs6w\ J@@,\5kآELwI}O"eyL.*T={?쌴$K\z&J8  @PrrZhajմ\y i?›}"j֬iuq0JT~|NѫvnӬYSNJ*D@mڴic?H%7XfJ ! W@m۶` &vv/B˕GN99k999R͜ /~#<]~}.T']w]]y'*ʓ͆ rT)s=gw^v_uy[6Eok{  $ʓ\+QMӡq*ZWb%w^*8+O>.L7۴9ݨ\)SK. =zpٻܐAujXG}i?}֯_?ꫯCߵ.ڴ]/]dU& ntIn̛~3g駟aȑb ?t~-X$~Gإ^j>ϟo{ku8@@(5kԨ)DpCoX@'pm-Wń gn-[>駟W[p_p{}&M:5~{]V+о]s5.hAYzUX*xdO뙸M?C4MPz)EӠAݶRMrg?KT~Yx}'kK  $jЫ>Tא0ϺJ5;@tݨQ#]xAk3<4۵7USn/tE &Aǔ>˪k* p?lZ}dff=Ԉ#\Eؕ,D@(j kƢ-[?XzLw}}o~w _6mԷo_ljj_ oK/䖭Z+}14{p`ecT)3)AD?_tæȩEL$k׮P%,D@(rhڵn4+,mJF%x[5?3s,wBhdz)T֭k?|p+jϪDzq[n ݇v{:PpyYofϞ+x.t?{pnkWu &?xdw9'Nݻ$%(?BE?MrJkyرcη  /)Xƴ A\cRu~o^U1c&9m`C# $^@yӹsg!s36)YOPՋ0w\>}i֨-[)pu2*L)J>.~Ts}@@#c9f, ~&Orq.XꑨmWG"ȡ]vְaC#Q@`BYz.(NA/\˿Mb]ab0IK0U,7u `^/9)Xz墔tJ~Do\ eۗd) ¿K{bK{bK{bK=QjͨMfQR1~Vxҽ~+]?RIvdLD:@@(.1]s%+{>xc"  @ (?+  @&o@@(eg@@D9  eR`L\   1g@@@L LɟB@@ 7   I2rQ  _O?wyvw9  Y G(;Xjj 8!@@@ 1wNkeٸ lͪRʅ쭣tmZ.ְaÐ-  }\rBÁ̄vQMN,=-{# $>z߲%۷o_իgnW_}ek׮=zl=]tEVj Go쭷޲uСC#7ް>Zjohm@@ ھh\s&rrrlm֨e#[-Vne+7x9{-^ٞ5lފl>ʪU\gϞvw[ݭm۶nΦMnbYqƌc[nkYI})J1zzߵk 2zmsL|'MdϷ\ &Nq]X  t1Lr;w߲-[ۮcZma&]:uc5v-4܉Т;͚5cz{b .K,?OޏDc=^x;蠃 ]}]?`5j԰v  kDnnmMK9)Va r4{Qvk>rQr?sHף[lʖ.]7{lVWwѹTwWr^:zַo_;SMCާW_}nv؞  !`Bi훕;-aGhuZ{g1Oچkvqc9vX9=… ;,-?&OlW\qw}nu*U쮻roԨ}l믭bŊwԿ{vgNp IDATk^K.` ҹ;wߵ|`⋦5w>+(Xl]5kړO>iÇw/_nsqAΰakqVj?8'h4]QGe} SN#F _SE9* ^t\pK# $@܃^b* /ʙlᬩz]YvVB)%O@ Vm=f5FUB>zZyrJ6ҹCvuz5*WzWt7_”[FFH+>}(H])24nN==11cظqcEt:v,C@(•2*Z͌4ze;m0{黬b,J%VJŰgoڴc;ں[NÓc;C=t#8=ҹCՐ *z#B{q0Uк'ğ]+۶mv'ZjRN&@@ ĽgbvVFկaǝwn}_ i`kfXUMZb(KOs4&\Rrf͚e-ZۻM)jk8?(>ǮE]{Rgt^1f͚)Ce޼yBmh)%>SЌZ͝;׭nTOhҤ[?  -`喑Vr|ֽVDݤ_eV(o miDM5u[C=\;˷5SNv9)d7mdgu?  7wkv }%mk(OܡXʑ]`Uo$eUE ]w˛+Bg}[/ Υdtr='Z]c]C(x)]pz(G ޕ  I*Pgǹ1rY AӬSBW#G>d'uި*u^J{p]۷7V|]sUXJR֘hCd((i/+ZP#Mw J.u;wꘪ\[sPNlҦL1PÕXGGk豣sÆ D=E@@ hrD3ifz~ϋg*Ur%dc6xp :N,EÆ Z;ܾ\ޑHx|>95䉂  PvL@w6l& Q*3#4?ZoCa/+QDgm8   L 4%lϊ p3   {0_/;  eC 9 &@@B&BE   (!  @D@@@@ &vs@@Hjc&7=ᙂ  -v}cS7o'\3kl  @b#cYYY}aKDff $mN^  $N %%=\:##Е9Йt¢еeG@@(51LS@@HDB99  +@05G@@    $Dv@@ L$#  Qs@@*@0P~N  @ L$oG@@HDB99  +@05G@@    $Dv@@ L$#  Qs@@*@0P~N  @ L$oG@@HDB99  +@05G@@    $Dv@@ L$#  Qs@@*@0P~N  @ L$oG@@HDB99  +\5kڤI@@•rVn@@@h s:@@(@0   M`"@@@ DDV   @4h:C@@iX  &@@" LDa  D :@@(!dIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/0000755000175000017500000000000011665471332024743 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/import-chooser.jpg0000644000175000017500000031562111665471332030427 0ustar drazzibdrazzibJFIF``LEAD Technologies Inc. V1.01  }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzw!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz| ?-?dwZҴ૿Tg/u5nӮ!x\[$KcR {lAӡW0Rxh:ni旴\#).gd.XS),#Ԓr~JMJsSP,e&A7 j0rs9Koxgi[W?"Vf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_0.^)Gg3E}]or  2:ȩ4lT,[fөN2<|QwმWs֏"?>L8۠Y!G)1XxR<[hF.)ƒWuz Jqu^S8֜ 4c*m(ҌG TmQd*$5^  MI_ ~ 75Ƣi[s ^N r"~QW(rSjrh٩+^6wJ̺Ї|J~y5+.M] [{wl*3xҥ\':Y^QbSS NpHQԫmP^U8W2\*14n8I,C^ɩ=+7:A?-{6u%si/.-V8m|hdʷb{3 jF(B:rxu"F-NS8*M^-ZhW*)ÚgNvU(Q*IOp#e, }I.e2[LU EӅ8WRʢF/kRAVR:NOy `Re ԞWRP?l9єBmR>/|"\|Wbj:toze$5;Yu-)(k̖^j 兯K'fa-y*b*aO hƤhqPnxIJkҥ^**Y,*X%Qv[\I)zƕO뺎~-𞳫xp uKB6Io8,l$Lh"' WᔁXZYKB<+GߧiBXS('] ƽ<+QiW`&RVѿW⿅/ƺ>i>0ejxĺVl/V&P{x7xc|kZWBP1Z8abԧj4*ByG2ź*h%XLLЯa9QV|G6ӌ2e/|y?i`t}F.s^|9uYuK)M{)Ę(bhcup!B75:Zz9B&c*uӇVjJ0x.IJx=JsЬפoS4㋌bNM'߈-<}yM+Q~2 .Q<7g[mbJrm]tD3T\._a/z.!KFtя4 wNjZཥG iRn/%BQ:IaNrTUT AxKTW4j.J(i94;KkW m`.VJ4j{Z9FչB7q夽=u1|ҭ^>59bFHT|oJ4յGvibE}ğo5mw6vd͠]YC0im4y%PM!qYBY~UV4?)NpC'$U4ZM5'J5)qx:q_Sr'ƶJri^nUol_ZӼQ{M÷q}lV˰E3nnv]\Lp U Iӌڃ?k+9'KwS*Wz(^Q-Oe.wjkT|'vn<]5 xmoBDf4;mBmQM֫wg'E.%Nd>iNu=~_0p"#ݓPllS [~R%Jy RqF-S5{ /'3ZjQ\xW| x:߀\|E맰uK/=2LkƵWܴ2\7t~/xL>"t&ҕ9աJjP M{*F=ĮW*n YUc{JRSJU:k4yF?x{{KdShqics7m "ed _mU>Iv\$[[JifDI#X7Uttрede$2 5R8IWqj5M=SOFFqc8MJJQ]M]4֍5kFdI<40ȓy/hf?Fk/a0ȓy/hf?Fk/a0ȓy/hf?Fk/a0ȓy/i{i/ '_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>a'_>bdH?'_ ^^4]kľ#'|kikn&&2\Z[xEeJ·+&y'Zsm><] b*I魔ݵvM? Y~?Q)qg(Q E9M s< {rxok}_Jׁm>\~7V|#>MD^xY%Z-pqvݤz#J׭Ҋ1VEx"nI/`p *KUg|aRSqU=_J0)KVڮeuqc{}gkiyţ&- eAqEۆ}sri_7(8KKV}YuGN]iSc.ITo5t|-o&J:!.֨˚2#/ᗄTYB~U.-1¼iv6)PFUJPS|qzᧆ|+,9034hN\ø|Y|2GN:l=JjRĸKj6[%[.f4)֩*YW*sU2眥wܵ߳Ŀke5E4_ S:Itsj:ׅt Ԯnn-l'[)RwWĜA.ڼ5sՕF;8XԔTSJN &&Ioյ};|T-h ӫVjN&ʼ;<:1ta^,)~MJ>*X9rb3Gv&]MNXz)rr^"?G;⵮"?d|>KsZ-ǎQ߇6Bn`7_gq3o+*e,َQ+{Z[iTyejsz_ˆd9ejW7~eUXsQ:S:/ڿ.>,׼[iw]xV^ 5>|TupkE4֕tmWFD:Ҵ!TգKlL1^)`KBj*='=%Vt4c (o+10u*Q̾L,\y(֗$7.iMӜJ<9'A6`ÑKIJ|GiN𝟄|eq/!׬[w](ע2j0tBaT5Uyq9 15 Sj* thFNѩ*RUt2uN7^O_UsFu#tJ i~pXP⅘֓x(WjBzReYvTuUU_|AxS77떼Ѵ;)5-2:guM4RL1OI%h̞#`7qSI5iʣN~g$+s48C(Uaa+F猣*sMm7+E/iI?Ï>"uOzYgu+m/A:o7b٠}?3 1ua> ЅLཛྷ^.bFz;jN5]{l4>iՕ?bsEl3yʅ>YScJpG=GwD h'ų->%\j-/Djn&G:sK 0\T3 d&2QRk\ӥRjҧZ;ԝ:rR}؊0))辱u*5]zNTjrUr)G| >'hzG,#/9.y_'oj7#]$ Ikvŗw?cQo{+\Z-|,'OdpaB#ÖQ N ,麎)0SNlXl)"`3كMޜׂ5V3)bg_F*UCu*49gž.>xG{H[VɣcoW/?U\ƭj]X\hQQFb[>yeJOk®#n&U}tBYJL,TrZ> 9>c&qX..2:f(իV(՜ڶWx&{;huo ~WX3669D zN"ƨYC1ctX7<yF[uO2ԋqeS ལ곊S bclR08|& )٨T{UI5p/x쮑v "Х%ԡZZM?M/f=΂/^xZdjχ2~ Ie.9}o^=oK4ix}/maNV*4^cgykUZNU*˱0ԦCSR>ƕO;N*2LY^TjW XʚB:sEi5K-Sfau SMмM]WOu':<]4# ř>-Mixfuj29WO*bOGsBx:T e(bghSJpTͣKQŮQ c0ZJrxzJr:~?u4#-lW)&|:_>']Z~$ѭb>d&:4^tڝs'U jK JkaI&F®cVIW9RXRZUG&sUW:8}z+rpa(t㈣ kZU=8ʓ/eWa[㷁~&'F? ks>uyף-MCDV@eɕeU"HLцN8.r>YSZ UT`zH7֌#)PRUOSbN*N\&35Z"PǼUjYF[Nom/-7៉ύ_g/[mx_]oVz>^_u!-Xyg̲5IUK >7.8bp%C*nWItN[|]ЧGq99IN4W|4iV8; et/xzSM_b+qc5UNj|E {+84J;[kYc56VteKX\Nܰ6':r9WtZqyԝ%5i=p ckюK32fPVh"aZ?+~.Kh:&\Kms%a ih.6jʠleF>z=:洓rp;RRr2M+B 3Vj7^aouhFMrrJ.iǫ\epcO*iWnxFkIrqJJ|Lѭ61#Klc߮x~5 \ԤM'V}ίK~ <yI;~}u٢E_ 1:f]kmA6ƭ[ڸx9ԩAdUO -ڐG}^GOwS} kǿG/x7>C#/Qa gIN|GCVR=%vSA:o,0ajB* OaYtJUE+)ԲVsi9]rI¬R5F2m9*Q|BR`7}[^== Ay'׏j_>o5}^G A kǿG/x7>C#^_#ڗmWAu?//PK 涏ຟ~(?mx[Gd]O ?ah^2׼2uGi W"բ 湪:˩l/򢼼L!i$]z4l$1gRԡV\D=j/MK5rJ+.U*QWFzI*tߖN+)մm>)>Ogiq-Z-{FUM,,M`EEU qܳF:RFuVnEJi:g)ԩ'yNnVro4ҥJ)QA%)4:jF ݌VRj}/-Կ}kj~C#^_#ڗmWAu?//P=qQ_owSw[^==z?]O A kǿG/x7>G A~(?mx[Gbu?5O-Կ}kh _.#ڗmWA ?{D{R1ຟ'׏j_>o5}^/S_PK 涏k[^==z?]O A kǿG/x7>G A~(?mx[Gbu?5O-Կ}kh _.4{R smW2:Ӻkymx[Gd]O A kǿG/x7>G#k[^==z?S_PK 涏ຟ'׏j_>o5}^G ?{D{R2?.#ڗmWAu?5O-Կ}kh A~(?mx[Gd]O A kǿG/x7>G#k[^==z?S_PK 涏ຟ'׏j_>o5}^G ?'-ԸE:&h+txZl(r_S,|1㏆\ԍ5\Iv|^jo+>Z.ZTf/*\9r#qIRB)UJThtҽ(Y55)B/J)Ӈ+ ɥ9qU/ow1OqRz8r?+F[?/ukm2_x:Wۭ峼3Qg43er:]మNJnN6yaɧ$FSR!8K K SfJe(kӍ76N3:2Yx^4}>0d D,,dpFC95*^i_W4>1!k"ZpbGEï>@ ( ( ( ( ( ( ( ( ( ( (ߌ !dSFǵT~,G}twϻ ZȧV^^/}i/xTN/a⋏ yi?xm>׻;ۼ0>\}b6?'*ֵB-{KᵵUj%8C{[J7{ۯtyƥռQuk D<;jZ[%ռOyx7ZփX7m.oVk{4+˖Qqyu7K]'V:)59ᅭR;ԧR9Na:kb(O4hAJj9cRNNp3ǁu7tGTVSŶu=!fm_E|yuw^-izvuynN@ݭ ՅIB-*0U\gʋ)l;ZIb)FtZFJ|iEFkƌ館EoCڸs{ VVk{9N(SU|]x4:Kvž6<=6ƭ^5m;AM2UӢ `VK˗m: Vi~xS'ҪՖ&Ya"U Ozpn=+ӝiҝL%LL4T){,C7w NZ΅*IGiJ}*п EݦgxWMgK#1:Լ6{s-m^8uմ?Pmb7V1X{F.{ZٖN󏰩,j{x|Ul_hЍJ٦SXIJ*Tn%koCVڕGv־gmIm&c$RtE}bU(ThV4梗U`CorʷN7VngRgBKhaǏRx~o7,jZo/?Mii_f]Yݤƙc _Z-"(aԔiӯVyIGO ]6PtkөNqR+rR(FU*Tף*tg~քiTN>:nV7;QǯS붾֧˨X[|EZχl5OZhxFմsHo;o 6l咯W (u(Z֕xLZHo(l<^.o FlN*TG;ڮg? x:7֢OD񮉤[ RKf5|kzᨬ|I\#>a|>OL5&eVkE݌x4 ΛA)It뵷K Ԅ0\(΂焛NJ28NoJ[8BJ$kt,*xf"*S=IY>|U%޻gxG_ 宫oiq滫i1i-xkM}t4^7V9ci,V)SW C:k=qncn8V_L-gG*B2j9*Mu)[^ .x KX=/^ 񧀵EIln:>r\5gsr,zN.ZJ5JmjJ0R)SR5cNJjS\*RZ4iUjVNm(MJ-:S>X=_km:Iŷ?-6??TdWJЦ?^_Xt*ҭF50غXuO MJ˒bfQR4\؏ecEN׶Ϳ/⾟7>qZUsu?Bmu7.!<-l6se6Vq?SqpaQv*mF R帬ҽJt0X:QjX9R)Q׻M% Zϋ!miO=sFnIu o55ȃsViՂ9ABu%<猎8F8ʔqPVkW寲 0c1^1dUӠqSJ&)kPNf÷>-4l?q<$.|%kzuQ~L]J}"/iz\Vi_k]6kjTԝTV&\j~P2tcU^WGCZEh h*W/kRz<],^F#,RhTT#!N|֫N*5eU^tg*?W'r(Ҕ9QJFYUTcNKx_,|_eן$״ ˪^\.ߌY]vX&7Wiڮ-e0ʗk)a1嫇[*Gs8OJTcFXWYKRXSXWӥ쪪U*k%:*үM(^<)V7gNF/_1ע׼%r*Cxᵷ|%o i\TZJs.KbχңNINXUO~33\*Q)ӭB)q t6NWRZ)ҕ?TPG 8ʕEE'p*ьQ υ=>>(x|KsOKzWom?'5:|w o]xk#Τ;(MƌppNZIM<s+VZХ2\_,LርWseV[SK F*tSj:*)BO JtlDj֚Ti>cÞ⯷D+_V}+tǫI|y(DS}7hfR7Fyޔsh-lғݨ{_NZTnl> rAr}ZTAFK1VJ'7N?,~H<#> Ӽ%GQ!O xL[x{1x䃍F:F}NZXܮlFY^'Iѥ_VX5J. )W8NuzcV:1,6%U*aSfiʜRqTSNq^7$xO|cm'^}Kþfg jmU7WmKĺHe6Egn[Qüe|N*Uiƾ#%FDRFLMIՕyT*u)ңpL._CaO)UukիVi{J؅59B(G B)ԯ*!|8NZ nfcqi$)ZĽKKR!Vwys[.kc=6B,'RBՠ–=8a)bO BXu,ejTiXztaF)b{*ZgQREV1Ja^!C0c)S*U E쓥Nm7){i āxo~xΰ}'mY\ZtZHhjNRZ"ԫ^ ӥ+RFWFpu!Z^zOju=Z#xv.8SX"R2Zr^hT[ߊux < ~Oh?j~s]Ҿ)ZF&cp\MwѵG}ii*ԖRjU֣:DKCNJ56!Ί!B!IҪ*qQrRU^a8_ r 7=;zoY&u9G;jܵgWb+RZRjRQPOkR /gxlzmiMOgֳ :G}NhB 5`rrI8L&DڒWQj^\=ZRlE|D]Wj6ӛӛeˬ_g;ྩ4},$g7zM 3ŗ6,೷7u;‘,5J5-^SXul,BHJ*rT,?=hRԌiN%*lj*rVrV:rQ)ԧkեE5kΤjUntoG%fXоWſQ+diy_o_yvчNx̫ͷ_gmy=??5쾱SU˛[k{Zx|דk.koB6}ց;/k>v&mywڮy[k=¼_.䷹QȹHaY-QwaKqqreB#_ *ԅz^V,;XUaU^jeFTjFp࿉NpS愭QJa(&şVx7,nbgË/[kxF]ѵCI~M5Zj: |? ukzv+}k0N3xҭ^R)TQVTjS z^/!kFN~+ʕGF.29%NtdR.qJZJ2N~? |1y쯅ouKF7OᛏZZy~+uS-_2(@ +'F4jQ'Uʟ-Je(ъ] rU=)M^u9#(Εzd9%rTJTs8Pj0PRn~#G~i ./歨O׾(ƗqxNkZk |=I5&[x>ERZ8*G^2Qcq򭉫j Fbqx=ƌ+^5'^ f8xP X\<(, hT*euk`ʩ(ʧ |E7%MOBg4:į7F_)MԮu|K>?izU/,֥r,SPQ Fj,2V6+ex<14Jhj+*F=6pu5Z<4GQRJXK07iե,*5M~ĺ mh宷-LCuy,]U=<Z.<1*`pJTg P:wbJUkaeNx,Va(ѩ%R՚x].ҥRGaNGxŗOo|/[Xxe7o>ҭ| J,/ƥ—;.i#N5ƥDX&"ZsOx?׌!uY|Yw\^ _5; ohn}>UhVF2YT\#u)Et)sХGJYmI`Zԕj8НOfS.b*Mx_ήRxyʴ)+GEeJXJK|9ᗆt$>iou\j&5s[˴D߃$Q[ YԥQ<%SZ-F0(sOW{NH›Z\iMF5'/ii9Z0Qy[UP@P@P@P@A??hň]Yw ]? +08!yy5m}_jacc`tSI4Zv.YYLKN *KW5*^7R4J<ҔnhiMMt&_cw*.H<,Z?~ΫQ?#o ~0O:= ?@{z[?~ΏeGh8PާhSj%ǁux[{uyĆ{㵵Yhk4/$ 0t/_#ˎ t?y7aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G? B] Z5].ؼq C_yeY{$huQZE,e&%EOa=E0uO%P80SV'/?/ɩ :—q?@ʿ0_\ N>|^ n|]MXM>oxJ<-*&m.lbv72:M9`e'ͮM[g[4շWkG{oi^'fŸGu :4WG𶳥Z /_,&0B;hQEsQF+ھ}mꗩoo~vÚM[?|A;._3.ZFڴ^v&OG}G "3VႡQڥ(dSg_ANq1Ώ-ZG1Lɺ/bsQ6WecF_u>U®iOF\:UP4=7,EJ4T狍wURsqL1>jwG5^}t/_5;GJ|OipC<Gy$?h+uKH9J(#J1u2g-)G0SJcZUdgPNLIׅ_xoc,+>X ^TjS:MZjNR9_ m^gK> .$tCֺRk*^ʎVqUa^jtibzxgRQP\RFXw^l]jXGVfqjsӢa^2"ӭxQ5 xqWxxIQ[ᇖk7|x@MB]RWm/}eAaZՒmBTgRi?UsՕ xLE*Jj5Q*T)|O- T<6_!5 )Wyҭ 62)WXƬ0r)Vl-lDwY$ivm7G1}zE{i~qWOY(uQɺ;96b)µF*SUHAsFwBQsUcV> ^3Oqqre)ҩN:Я5鸩JRz=s@P@P@P@P@P@P@m"\qq*#i]v쫨e i71$]OPV? N]KN/~ __@𮷨cMMБbHܰ˖ }?Ky;4$z'=RX/H-Z<;,>M3n db>n/ĿʭHlW!~F`O"7=b?sV}cB_E?gB ?#N#Hu~GMOPO1ԊUzUt߁ T:ƣjWi wBF]?J $fΐ2$1V38Fuz[xJ{*TpZJ2TjJb>AUzQ ΏjBRu!Q|&+ xkRj:5SJ[/FZ8XHre~Ƚ806m*NZyj|S3SGr(!V /c8;ƮO\iov^Eӕ[-OCeg?ռKŞ7U[Nv|,ԼSj6 ^Mb$i~nxZTǥ EX3 NY:X|,ZX8dAը,TZc… -<0FlEZz)Qb+Q^ҼqSScR I4O ыyIWJx+|Rw=6^.!մ]\h4F0K-YI q0zbcl>!V0j4 T**h)CVTe:1|KWƓKNTkFTkAF*qUʤ}(/ [?ך>D6֋r$v'~Dž5+Si#}6Sog9bhRG"xoů csx}&2Z]5gC֯9/%5*xjXoi* 0T,a0PɈJ*/MJ0p*(EC,D#c,1!k"Zyx:#pc&' _טE*=s*: (9?[ҭmVXC^Au[o_̺(mP3"I_XvYQIIYvϤ_],NϢ/%}w:' Eejhm<6|໯|?>ե>w7-SNw'PR O;Oc1y[C aV+' Pʳ:jiӅJjX<: *Ǟ&lzlNe?g{`tdYPRjHFqüJR[(bṛ{w3Mm3T^rx.xOF>5  j^uCU1L.'Iשఴ9lu,Ujg?֗& zxl]jҩJhӫ[ҭ]4eq|=>YJzTy):q,<]ZjЮ[xB#-o-CA^ k>-d%֬WcIm|K--%{dBFgRe5O,-LTps4J4:ըSV*RQ`*M­zXeҒ=,-yԥV5%|>.ha֖:J5),'b:zOQCL:ï>e|\|/w!ԣO5%EU~SjJU\*\z*T2U0SjOzΐ ( ( ( ( ( (9umGi|R%K/N_4q^Յ_V9_Ç}E#c E4oM|{_EGL}?~kGF3)^c _Ϡ ( d,o7۫kя']bKV/+>_حf;z9~~okGMd/r= 6knxd|9}Nq潧kW>DvggjVGڬ/t/e^~US{_sRp߽{z:LMu|Z&*iV=><֌z*|;MԯEw/|0|źo.oBox/Icsu=;گCnУN8z(bc^RnF3*U% >[ U'S#Bь*IUZ텩]S򤿍:Q՜jHF 3ƒVU:蟳-4_|5wW.MNMi4] Lzv!ؼ%.-.㻚GX5UX1 E&:x҆Rp((~TJ^51笩ӯZUX#RAVWQTSC x&Gw[u[Oxm/DΟsV4K]?t~ε]n#h`-Iգ[Ⴍlr]I冕8BSU[0¬$冖7}t6i;>众u 2[MHi.];OLj#.,| k>Rt>iwf0؏/cAޫ^/🅸Yt CZiɨivSFU0·UX'RmJ3Lt)YZCƶ"ZzNet'ZyT$XOPN9(µJ01?hab#C0j(P\G Voʽ ¨f8 S Ob*T, jU>Nt]U:kÛƄ}n9G*`Q~jxbSBt ҧ:a$NrJUOI?h ;.>x _|:ۏ}KJּ'=xhz1ҵX,ݖYmt*G(JZ_ӓ1MUEb"Ɲbiנp^<>scjPU(޶\Gy%*qkҥV!SK|7_ɩ :—q?@ʿ0_\ N ( O2f|ݺ?uF/+Կl>?+cc'=6~ޞVK])i爼=MwÚ|1dkvusKhZvi}zyJRUWU=5* _ i콷ѡW_gڕbirhsߣ#h]קRg-lϙ4Uu+[&|E񗈴[;<m/O#Ypksa [KjƳ|aU^ O(2z SkR7Nkbr=7VtV:XJJQxZ%[?l./*JSJ}?Jr-Y,_E5d|D |E5;֚燴Þx_BP׋ 1\Y}vK ]xR][HExyמ*cq xjҒ1...ºԧĬ&8.&7Jsvt,5Jq8zX2,e8QZ4\=W[]ԭjΧ^x1Ծ|J|]kz?5 >JE{bKascra \O-CFW5OԯcZvRUtU)?f)B)`!S ӯFOh:!N)WB w[fҼV'5X񷅄? _?Amo,S2K[7}*ٖ3()ңR7 R_.Qu]*SK ?it}*^R'eJVJ3 0xjhaJ%^U<躐ӪJ4- 7~e/JiϊCSӴ;H4д=-ola+R sLկ_SQ1|0\UW)JxУXhU- 6(J|STJ"Jѣ)aFwJ:;fF!VEP@P@P@P@P@P@P5rB/D ei7c]8_Kj>+pHsUu?CȦkX՟w|OPb_ӈ~_8|?Su/"`p@P E .Uм=g=>&3tZ]kXVԴ:wnI5(I#GlMpeTo1=-߃w~%nM26νo\Gdnq_G}y.}Nf T5nRMj+Z+%m쒶ks.O<G/ռ/-s-;=JVzDm4kRi[>d0MNX}YӏK1*R\hbq19NZ& oi G|«Ng)N8?fVPjڷ@+]|EkL4i>կ4'ŨI{[վ#[QX^|'i[45}BRIl5TaJ/cV*G<]DjrS<jYsNFx9ae*5MZ>nzuiΔ*凭O*X|B?M4X5m>E6PkZ.kk2]keMa}{i)Ͷ #gx\&2̓RQgN3TET&pں]h[%麖:]حիn|Gun7!gH7ySZHRկ,k|1qky֗m:[}.o[uRŚ{k'f潆f"xʛ)&5md켑|HnSxx_h!T^ ⻸5 [OkJKׯ5_xB7$毥(yVOC8?#~0'MS_Qq9O>1!k"Zyx:#pc&' _טE*=s*: (Ǿ,]ƫxz{|Mf z?ְitG$j6QۭF٢7{E^Nogmbz[hJ7%xƚemzDU5 oN(ZBŊ]h 6gG,'%xjܤVrVJwK%meĭ;vqm:ljzxj4Z֭.^U 40>ֵYP!B+ԩF(N6%שV)a;^sRhҥFsZiF<ҧZ?-k#|a2^0|Q'B<3cᏉ׆|Su> ]?BQ.agf1X+VffCUU\_a('%J0&*bܪUэU.ztht9q5%gyZ)`F>2\R*jNJiBc^x.])}_^Z^Q+:o*)MY4?]e> iѭ-u{&6 Wu 6 Y~Y a?oL<*JSVrKUԥAJ:K[ XGsӌoiJJPOEVs=i{JRê7>-x'#ɡxkQ-Γ{-7Z^g%Z][j6Wp}Lu $Mgusm,SIۉO :pRUhaRqXzxtSZJէN9^HBqWOΖWbpW\&" J)JHPI¤{\@P@P@P@P@P@P@P@PF?3|eU_r>8[%rCn$k_P(֋8jw3D`oe'fWvg$ }1!k"Zyx:#pc&' _טE*=s*: (WŞ,uO}SGtжKu-t[W^(ݖo&BΑ3]9oX+Yf_Y*b=~ /Kov:t]xŚNj5׉O{ͳ{ ;mE7SPMk//5+9Y-y#o+]ƻ3cMԴ[Ş4MFDuk M".Guſ9u*8 +¶* ]4+>#|Fw3zhSᾧiX8>o㟇^ ~٦[^([;% ^څ&qPx\wԖ';qYNS´.[: &Je N+*b#⧈äQ'USC ^>65-kXS.K^!)@z/x^P+Mtc>e-팒hկ׈-UvI=ԴkKo&a(_/o8773tGWQ&UCO= E4oM|{_EGL}?~kGF3)^c _Ϡ (8o/ivw9Q7/3WZ¶'!Ӽ;uIGnI;fkW{-:kyn+ti/u}=W'@> 5u;~"8|'uk )uv745P⡫rkWgZ׾IY+l].d=ǿi=Ŷ$xS>Jh:޹jڕ7~!4}JNӴ-nW4xF,k]FnuҕjZyT(èZg9BjNgR"4:H4^XPTyέHQJ!ujNi”j+JjH< -F5KVާi oSG>*xZ~#J3ݤ֟:!MJ^%kd,-XVdhs53 .SjsUe5)…uB*үF;:2N8}>NTQ)ڢ%jZқ#'JGog|!­umO>^?61Iz x'Zdžt˸-nZ{mJ/p]KT2fcFS9Ttpiӯ+!MXPV <М*?vR:Ru)F:U40eUէO,h2h02<`^/S/# nj"ƴ@4vz΋7iK떥e *U9p0ܿUUx1oX$QVCGGSTIKFhI׫q F7,mEZP-*i*bST1 O_.jW|~O٦UP)3׸UKGbnǖj=\>hӥ݊Z-DwVy2tSzǙZm5K4(Zhφ W]iz_~ Kӥŷ^,.I_on?xD?xZ5Ex=Sn4,j6z&XOmiwX;--Nkҫ*STКJ5pQ~ﵣC*8Qװ8Nd΅zuե$ӅD9I|T*֣$Viv7Zxf{;\\CxW~W>5q ~$]wMk-o%z-vmV{6j*SѧX):ÿ)n5+(O4jOR8.N*+ c9WR%VkPS:XITUu'Z&E[ּ;Eq#YpէÝ?_$hScoq߼6lx:RJ c&OAb*|Py}zjQxZ؜M՝KIRXOWƸ7C *NRK'.Z×> #Y=&ǥa"c E4oM|{_EGL}?~kGF3)^c _Ϡ (8o/ivw9Q7/3WZ¶'!Ӽ;uIGnI;fkW{-:kynx|Mko~)ipk|?֭u <$z7kujBTsRsM(ǖWZTkUE_h5鯴Z=kMiӌ^**$*<6&bkiWѷz}lS~O?t߆^!|F} |e6מ =+E֦\\55*F4a2Jp_XpNkan҆& Z'CJ ʭ:iB24awf:tfJΕ\CSXXTTjk|Lu;-l|Y㿇x]Kztq:?[gKҴ 8e }7F_O.[;ۥ׷_Z}J*xyt'8MWK ԕT˟WƦ_X$x<'QK,Gu[:8l<]\N*jVi;9Z*#^!ROO@~"\[jeI+6#MgŚ-{|G,<7:֋ol-twu gB5q1|,e,;#0u1r9F\uF{ xigWPPcUUS ӧS^i%8̤TjʴSP,Mz8KеF]'X}/UTluxm5%㝴Z(5+fs <񬑸I$Pө8Bk/ݩ5 ǤX+>ZԎӄ$V)* BneNN\Rx TR<)T9FOV,( ( ( ( ( ( (XyZVv"]~G?E1X^ /%^5c8?R9:ߌ !dSFǵT~,G}twϻ ZȧV^^/}i/?>ɩ :—q?@ʿ0_\ N (g..{ۺ4KEh-|YsDmnMgVT/wP[[ENhץVTU4j{9TR3kG^2%XUq)a_*p:S ӫJI rUFI¬3u|/}࿌_ 5q闿 5Cz|3v7?t@#x6"':v4M>d}iHDyWUQ?T^u1T%pU/7e˖(STۏjJsX5UW7'ЋQ*Jir2mJs\&&c|WpSNaĹSº0帕NJ'*xQugtjᜨa0J”f|$،iԖT_y|ӵ?I|%ޥq|>d֭ϪiRS/R|&axL*\=jR.T:Qiߖi٫5tͰԕ\NUN RIkWߵuO |;"CVxAu Pwz.?+fE:@20FpUOשC1pl&FSe yMKd ^,F?=FV}*p+U¿_/  zm/B־x]4ohMWTyjl Y2+Gm(b*PJT%V8|+M£457:4`uՆ6qG:9iΔo6^דNx9)rf,zT&UR>9|W|sIm$^JmO궺Կ YcG5He7./١XL)F/C:K}K*3Xʍ?jӥ6'Yxxcqxz#J 3Fx*4ѣ:3aĴ9OF"XM:U?cՏg~Ծ;xB/?d 4?>$T ^ 7rW׎<ŗ|%.6wziג xƌGBRuka,^UFL J!FG:P˚)8VrtaUƥ8C RXSR5VtgVztkΝJ8h|.WhZ?/\iI=KD' {XυnSFҼE{|OhzGc>oo QU孝JcԜ&u0i3ocŒ pINҥSBMt1RZ K1ruOJZiʔhjtK W0WҵxwOyAVpj7r% U#zJ*Q01UzJQƜG LՓ+J*^M훣 E] {V>-!|A5햿xS476mB-:Aq'D(Ԕz,F2fXiʒ* gʜrA!*NIbʝ8Izk*mƭ^}|q?H<='zoZA FcS̓%gٸ2zZ'*q5_WjmV1ICe#Mލ,UHR]%{Q ( ( ( ( ?^VHA,9_Oz? xCV I׺Xj7~ѿ5}_3)8Wa_qqC=G2jxΰoyP2L~>( ('E̳7nGF5uqe 7.b?jt: k~u3 )Ҽi{\.exr9iNRNMԧO:-Ф)젪UO%i(k1?fb־<xKLz68bYDvWMg,VW#2b(ӭ,X压Q#(cFZzUW³nZ8H%N8E9aF1ub*cԒ.)QIA`aS>x. s׃mx뻏W^4ڏujyi|V_NHBJaR1PxBjAa}{Z,laZ4F:ӝYTWTtpxuXiⴳOXcQRѣypҌ* TagJOY%<4iӔ*TgOI9Jtt%;cgB(9i{ʼiӞ%)Ujѕi/k[*zxMo hGݼ.g9Ir)4saㆬڊRP4RQm6CM6=m^2j2r/= M X|3u+gǍ4}[An4\k:Ž kW(ӌyd[ƒ~^WM=]]v>lj|KzrZ[.I%7WV?ktNkw 'ִco g+Fr̛jtNK-G0~ٿ e|!iS_Jѥ Ƴj:i~*krH/(>l}TY?2ŸN B 5NB241Zt:BւQJzï:/xÞ[KvO >:'e_5 3K|;C= #/mbk 9Stq{XXe^%aNkJN:iA]Iҫ]>Yέ1UJiҜVQSU iGAsh>x"^g'm^iš/]o -Bh6sh:vs8kXc3WUj50|\^ Ry=UhJJ91RTZTү,e}&-W4OxOR<&_(Ei\[M+H]>u%giQi SIegN.P)U+µNUcZ+ R%Rx7Eh{*)RqSF8RR*z(ՊZZV~Z0u*Rtv?;-?7{/Ǟik/hڶ-2qk1͜xѼ-iku{jt%V*' ԥJ)f50c*J1 ZXzic _ K?'FF(f"1JW u1p՜*4ƺs u=Sw/>oX:|Lfiic>+/1&iAr#[ gzZ(GJUiK.׫jӧ&ZHsEJERJ ˚5Vۖf愯 $d8rϖq9A$ 5 ( ( ( ( (9umGi|R%K/N_4q^Յ_V9_Ç}E#c E4oM|{_EGL}?~kGF3)^c _Ϡ ( d,o7۫kя']bKV/+>_حf;z9~~okGMd/sZG)N֛84}*X{ :Nt>ǏƖ_/-DV|Vьlg^dr|٫kѽ$iG:%i>Z$-rnf3q$ v#*0"<]*+ǚ&3Hݫ¢qoWM5ѧ9ʌԦgJQ]N4[H|!֧&|:/i/Aw<3xFO ?Ɲo{/Y -gy9롋BuoS:1gCrB40Rc*!}QT(BN8mzMR+S5GRYtx MuʯMC<[{#=W5-K\uO q=Ε]ᘿ..4'k?욤sG9Q)Qʂy{5a4SQXu>֬bxz2~Z]:#^ 5j=.QZ5U֣;s{l<ЩS9JoJV妩ө^y__m{>1wxŗM>cˡYyךׄu$E]`4} غ"̫R a' pCEӕ71֧.OJ" 5)N+hԔ'Kb0bUU5^8-(OFO5ɨl2[liHc,t( 0S T$)ԥ8ԨړΖk ]/gQ1^ѤyRC Vҟ,0T6 *~֍4iЅJxzs #8r,-1X˜<' {[xg:Oo¾?w!Լ-<zs~T2xŷkXu=EaWo MZ9ԆJtNW2Qx*K>CqYa(թ:<B(X}EV9yqZXƢpuGVo|UXxƲ Gm/ xoo:%.-aŦև۸g^xXX\.P):b*¶&^%7J\=YJnR"I֍)R9FzYӭ*DtxzU(j*V^0/rrN#^'*R(TteZ ;/RJ4W[. σ>!zRmogAxz>L (U[X]_cV8jO N8l"c tpHiIΤm9CNQՈ{ZjIVC BUTK ubB[ҋo~XGK|B>#;AQ+Z't'~fuw emuG70O'N-kQƥLNS4*i P\+eY[І&oMXe' xתļ6W&6F)SUaJ4`a XJ4#Ba hэ8{;x3W>ϋG io knZZbzǂ*xօjTyʨQO *Qԩտ-Xi*:hΕz Ԫƭ8N>k_M}߈y-3-2$HzC^ M3pZyjRS%*iS8rB-s%ԓ) (rJ*.0qdԚs~U49b( ( ( ( ( ?^VHA,9_Oz? xCV I׺Xj7~ѿ5}_3)8Wa_qqC=G2jxΰoyP2L~>( ('E̳7nGFnt|yY?.Kn5^O0^С|kI3QO'ڟiwL<'Z߻?/wcg<Jkr}Yտ}Y[_n_h>4ĿE|3i}wEiY|DJ|=kߓ Xld];>~Z8]JpjeSIqC$х(bt׫ìʛ_SJ1P&φ*iTpT}nJ?՝X8Rlh=OEo_Ӛŏ9uM#QރZfVRҴ=WMSE{A s*Tkj4x|JPeW.XF5(Sbظ VxH#S>w> ]v_>&j>L߇0&\K @LD^WQI``RFJ\œUxFnRsiq<#IR\B*JpJJ5)(Spԯ*0RpW B֞NKtohGO{x~hV~>GZ㺏ʾkoA,|V4$JʋSI*\I•(Wb[" Fu(Rh`{xNPNU#Յ| ZԱK U9Yt)};"i^*2%Ķ.m-<]Xic'NrSU\)Z4VT9]j.V8Jx=OW7v ._sWжEVjiimGBXu0cVx96R NuSajƜjK _&ЭIjU񕅅$SJT`]*q8u|%UJqabV/*Wh,^[GV+O<6:TkӔSTYtpU:JeK NqRK_-Pm|FޱiFk_4ͦ}j.\(a+_[۬RZo Juh¼[:tb -֩ tU)JP?ƥXP R8J\J7Z>Q(UY=:RjJ5)b5|_j|%f8i_ /MyiPi|;ƕ}|d2.t;} p|&ֵiwP]t}խ>)[]4[-Ɠ*(z*bեNP~࿲"S#Y95T\eL<9}?.Tե]F5^J:ũ*ʔ**:45($_Մ/Wgjg7^#᷆|Gom2fH|ArW_g[+b6i> 'F4QMږ'(ʳL,~$5kUҥB0 מ&pcFz51XŁKS5[JH^`?c<2X5|_jZ|CmsF? k9[~<s7 GV\cÞ״YC ֣ 麘6IҞcMJ5Nj~y+ыTWKl=jyQ/i½5Q:r*XZXNX{:*Pq(ի)C/ i5<+v:0u kFt NZ{SMl.f{k1i%쪵ѕE*~=5 MN)A֥bcIoBhQp%MJHCޅ&"ӧ*Մ?e88UrUFQk?h?Z|it|$о'x'6aWݭx[ĺO5k6e[mAZƳp)mMݥkY)>7nu oޭUkKΟ^/ҭxŝ֥>9]GMmKVѣJ~WK0խ_ 6" JnYьJ\^VTկ<59sxib*ԝz(*r԰%iӝ:ʟ/LJ=x_ " Kp뿴Y>Z7uw >6~вi:_'.O^0<;{'dQ L"SQ\>]f8j5ia 2qtm|ㆩN0^8ShN1~ΦJXcpَ+RjK ҡiPUTΆ6HU8aѓjsTŸ ֽk^0;kZf^⶗W/ןUŝ77zVsZE#aqj&R\M|$%5NxN.'y[J2*7J/[Ɨ^*΍9Su9Ɲv1R8ʬ?#?kO6 Mx~3vM[z|s/xI_[j4qB-,Ɠ}.cm%tNNԫ[/(\2#w'OS MRU*>"&tCTPzE£i)N4u*$ +Gkx;%,K7`_Wa{x{UMsߛ S䴛>7pcV;bx-/ JU0X]T2Q4\x#cUt*Re05:JW VTJSƵhFxjT^Iƞ#SakQUc (5)ѯNjQJ཯_]ciEJA,9_Oz? xCV I׺Xj7~ѿ5}_3)8Wa_qqC=G2jxΰoyP2L~>( ('E̳7nGFnt|yY?.Kn5^O3ZG>/֢F1aԼG1ો{ sskzoHo/nm.MR8/¥ԥJraNuN*ߗҭ5*Q){zrJ\jI,*Oiі!PXTgJ::ju^/Njz )k7 P߂K⏆Fx;Z_xZ}~U^{m]t۫ \]NuIcjf#$V|psHVՆ'GiEp:q?ZTN 4s]ҥJX,=>Q O6P=׏nkmx;X'n<Nx,~%>oCsڒsasP0z,_JZW[*ƯU)M8YSxx"*Ws>VSV֣ OcR: 9c8ʖ&TUM ҭa0ui-?)Jlu|E=N|Um_Ű|<Fm/mՋ5DžlʹNӃٌD)f8fS(P>Τy8F.eV`Ѡ:u)VU1FP䄥N9C݌g(?dNSS5XG3}O-^%l%Iш}Cމl-THHd6toxb< X[\xVJm4h墒얢ۧ㱪[Y/gi`Fx3')ε = %|.6X<*UZyoN<~`*r% RTBT1TeR~Ĵ}|F#YoO7sooq`c7/xu)_˺ԵKoHmAiJX' B5)N;(M^2aG%NI5zK xFJrOJymJPT EjCJRK뗛^mq-sRS> /Ğӭ?z4_h߄|StM#R>Ym\ۍZfO2Y'[N',MJ>%\\%C?i aJj0jBr·:c]Ī) OZ(sZ :iQp*1Tk^>?gď>2յ=*-Y'y&m>Ӽ#F, +NWc/5y'}T12Uzp,_g9UqZȱ|y{O$}2Q)ҋqB0(RMW#wՓ>j QN>xc8A/ 7t)? zenj|#Z%o}$.n2Zjvv6v:gXeTՕ7Ĭ^JFQ0V%/|=>"pxڞң4<'{I{iwxe,Xt-UV9a^0| \ldžI%ɴ!^ b/g࣌y*T5N ц"x9PX[UΕ/h0:t)sԍ\=|eZu%'N+aRujsѫSڥUB&,cS-tI_7{Ǟ9iX>;gDңf>Uɾᦝ*y](JRA8_8 iFKСaABT1(uycVҩFvXrB**`ԃp,&"GR#_N:O'yx_*D։_ tO֏i:@5MI-uׅ$,VJY~/ Q~U9 Ӟ.*IJSJՌ1xOg`էGN |!tzPnK[i)Eeb~'V8LZNZӔeji4'VR.:s8F )>,4='Zfxχhއ7~˻;_LPdW 8J`"2si㱵xՅ|-Ju!تW0le#ua*8T0ᆄqTQѭVԕN/өRn,mgiVԾj}F}zXKkv;SW;F 66IiV+S8TӇdU9j1eulJTac(.W4T0JTV7CN#xJzB)c(<\U13,j:*d=Ooz¯FC0k: Qݭ!k7Aa{XR8M\}L[(S8ccPsƵ y*2b!Jq0J8hNSJ5]jE))ӫBybujW-k}U57ORzNlZ/hVyhoW0]dkЪغxTiƽ9a&/RHb5W ʜ\]e Oj:l5Iի(Nw,3)$ {|NpgK_5jltk?) ȷOOpx<.gV1~XG "6w#Ha7'~{GsWM۴JZJiWQW)kU抩{Ja_U>Ҽ |W;~!wkj&כO6u5X^'ѣMiZk$',u)FTxU4apPˡpKRt,MZԨ¼00:`7KN*p|WQ{ƔТ$:RR'[~ʞβu;2{᎑~ iV)T:敢s? "xJԤ#WeW(Ύ"U*p VRIK c>2ُzf?QFC?^ ?uhMw巬tjʆ :u\o\I~9E?SIFĩO #U<<0WŻ[m+Eu/?+J;K]~G?E1X^ /%^5c8?R9:ߌ !dSFǵT~,G}twϻ ZȧV^^/}i/?>ɩ :—q?@ʿ0_\ N ( O2f|ݺ?uF/+Կl>?+cc'=6~ޞVK]5d&wNۻI֤||߳jGy~n7:)zN+m%K u{I쟓_ZFN'kRG2y|s7M7qcwڭ3dwm/U֍y?M{Bu&/#F<j}0=k~lȽݏ_i+y/agV5|C^ͨx>N^CO+tPŮ;jo j3xN &é(5Jg/ЩBnJfO1 7jUp،F&g<=˪\c1(OY01ה^5xJxwqjqB8R_^-_ ԗ׾. gǚx[ھ5Ӄ[Y>(øme$Ko pU[]Ztpٗh99F\*Uf5 3xZUy>8իO޾)N ibIJf4+Q+P]oeBnTƞLJ?k? } [ŭN?_.hҴ⤒=.lM F bR}Ri9.4eYjns~.z%N?U 0Tc9E:8)u!7)af3 \Y(WNtNXҩVg [^" x~!_3kO O):LuݮYMߞp>A# L+ OOV Ptkx.Y9WTc_be*u![ᆓuhbW,}l&)Q%ԧfp0ԛG ПfX(WSYC>+GG񷇾ml(<Śgu 3] {To趦Hе(mgZs%~WZ2Rs7*u2xU1Ԕ#YJ,HVtSRKO•gtcZ8,C$hЬ։yR"K:*TڷA~B/N3scp 8XQJ; )a8fczU诇QZhƤXy0ZJ' sBuQR4V[vZ1g58/>/2X:hgVFc]eĀ/c6ԟI.ku saU'_jTa d2K R)Twh`><=Z11W˫g57i)W؜e pUl%9TR*J4h^:4*U,¶Oi@h:M߇xoiY`u mF4KQẎ`W,cIXqʚT*k-QBs*冫FuI,DX6FOƞ2j4PמBRLG1K,-K7W>lFUuWΝ~+t|AV7!)igKiM&xފrbc1L*F)VӔqajUz%9Jh5F^# ,G^7N2'RcKRYRw'iz>t?avOM׃Ba5oMoMzD?nK fT,/ٵ]6̼PZr< [ [F8aBrZN.q*ΝXSXK(5Z,T^!*Rq Wg5h>wïh:M ]CI/M}^NGEKI((Q|5G;Pxu:V!G_[K`aZ3uK_`i?/>.]x_} _~ x:ñ2b+Oj~7(|H/jO}4^=CãZG 9RXUJN5)EcJ*kb%BuUʅIk: [k|s@εEkX?8 >/j> ud%XZ߽%ZUiU| ^̝4W'J9hҨ,mkN$i޾5S 9~;xU j2\Ɩ_ȹQuNί7Z|XһGxK*O߉>5.Lm'*q Ԫ4<b#^U}cn5ƥlE5ӯS`yBRiԫYbGc^xZ/,?)nH.?>ӴH-+xfmij5G4&Xf!jѫ :O5jf]udwMRt$N,<1xj5hӧ NK C 8KJʥ[P:t*+Tt:?Wu׌$D|+yh-<--):<=6j̉ǟڽW̫WajZZVnR;,T%j*8Uҕ mQƦ"uy<ؿ|Y֧Cj-»$eʗ3j9oA4?)[3jh{:fk:+\p-[%,8.mʂcprN N8&q*(tҶ&O9Ռ:ƃ*sU~_?9I}6 V Øb +,6Z,Zg&HꖺvC-Y:֖1ӜLNh֧V_BXy'MւVB*VHS)Sj1'{JYJ|qJJU)j\^ϩY-< -JMs 4x7Z{jz巂S'3}˸|^ABٜS].mygif?qǗ?埴U#(GJ\Э(L=YԥtkT#^:P>0:qx迲-GSo>uw|;ox$ԡ[#_Ck=nLrCe%MRbFЂtS?iF`BR\Idi{8FQjӨ&aRJnPJ-JWI9A$.^Ihx|C/ć< Ὲ0xnF'<5e {{{=WJcRS$ >gL-1tjqRVia'Q#^.UI׮ZucG =ҩ:0FWGJeNS+Sp'- iM:pf՝NW.Ÿ>42xbTum3_焕mOY3u+j:'^Yri_/S2-IIRsr,mAygw64kwW*11h iɘ؛]JFF+Sөǖ2VcUk'ƶ.i(2s)FD pkKZqݧUjP@' + ZiQ_jީqqyi]>X[k(t"cʏ iJ\KdߣQI.r]Urd,x 7:@9A2+{VՖ4]cJ7OOO5uXfw߇֚w:El:& zs+zS{5kuwkYo}9_Ç}E!+?#~0'MS_Qq9O>1!k"Zyx:#pc&' _טE*=s*: (2tY<9v{cu3Ro/-+Yގ_SzyY/w֪4u:/7n'Z4~|/?;ԥ8=/.'~M~Mj:NKVyevYo4߳7GOٍjǛHKVZ5 5 7ִ?54~7t"v>/s}^w,مg[ޏ xg6;Ey<\XSY_ u*e>7P(ݩUb1U#O.r`=g®SR^Qxx^%)iŨQF EI}z|&R\N^KL3iLO^i(YojN mgT /-+YeWAmwqkcf\C(O%rԩV_Tւ(iUV?gz_oȥ:x,2QO%(F3ˠQGrTBwu IS{+5o;\t潣xBJ4Kcĺiƻmw[{[N{V46X/Υ*ץK J(ӭe7|J0a8W,.2PʫMQƌ⨧QԄ-:|J8߉91| ֋[e,6&*NWW,<'Jrظb*P11ĸ+W*PBZ؜S9(ξ*)rf u]9ҡ:cJXVtR_/o xG&֓>/ͯk?-<ZKT 3ive4~zp*a0jx)</i|7w5R[ڛ#Bԡw7kp]h JQjW\TRP=e*t!YXZҩO K,e/‚(FQ. &]:ч%GZU<=j.mVRԥ~ZV M+d⏈qa-).%_^Xg]ԣO\TG=ڦG Nc b0לj‹q ^jVѯYQpkjf)ҕz& -\F'Ч# <ө ӆ'J4'X{E5|Qi7>0Ꮜ~)VÿhW?`گ񎷦P_|RmJ:zEmK%Xuh<^ku`K20UjFpyrҫF\"5>[N8z*jӫzf ĺ{⭅ i5-oY7Tl#&[gC8伛eyztV['^KumcRԵ=?zeOO6[Y.$㷒FTi*d~PT+|oVcwCR)po)k*?#:g;ug?-udSp+X/?4_{:5kLײXi57NgZ\E& f]FT# U5(Ry&j2kn1,[_$唣 ˖Iѭ`+sI+۩_=[(/T=[(/T=x5N=s(j,9QTa+΍jS*)b)ʓUiS*ݡRNQjM>|#ѣӴψl1iwW> i~ 7zG|Gj o8n!dxl ïf.+_[:2*mRB Y}Z0OԞ6xRZ*28|-TӣPRt(aӭ:XRbeMyk4eU^߳-?MST-|С?Y|nAFWX"4AV-7__Z072U*iMZ:*椔k)T-MTk҅%JX- ԕ J3Ŭk~q4r:7/ >?Iݽ?I}cWmmS ֫Zaebk Rfb竄b)8u*^|$WVՆ& _+թBXKN:sa*"8iQYהتtZ֟,Uj{գBjxH<4[ /ag<7ě-Dt?ƫhox]G {K[uc]y.:SL "XeR*> `4<kKmK3\޴sBeScjѫNe(!9Y]Ey*T'MAZ8J|aRҭV=:pPNҡ:V#N(JJ8.yΥ>kI]M~:k> Jk~m3^cLIei,{YϨ)x 1ѭ<]JqXΓ_ V,kU#J*%J'WN)nUbuV.G ^RVZv*pNntԢJ5*_o?xJů,Ͷ(/Cet-GIhZqyK,C]˦Fmn`IR E*ժү,E(QOWNiTuhJQVYRIӨ1)S(zy5NrbJ5# RIF*tj8ҫ*~J]Ś^#&_VOڿƭi|#B 45am>Dk?6i|a4]FNUK(NX 5Z!fP暵7Zԗ4=RA½8ҫJTN0Wa:JJ+FR.$+O1xZ,^iO7'NTV:+&G(M̓r7ђ({iWzViXjjNN *Twv^ 7GNM\忄l|x'L=4Kң:s^ ѧ)ҼA%մMx6 r`j, ^1apѣNJqV3Яɇ%R¹b: (W9;֚t*UTU0'AkG/wo|mkSþ!E? 3[WKX.ҾY_x[6%]6}ܤe^*x|F5<2QOaөW kVibJNupR:njzQ sƞ.5(&ya*U_T]Ӥhю: ¯|6>3Jux|9.Kwok>xgX%*hwB:Kڬi#Sl*?]𸺱N'kfCǚuҕM&XxlLjZ(WlE*pNgȹ(ԔywCQ/᷇55G p5˜qXzV7Kq­xqUڃT%YSSJ:u1QcO XX`DhG%Bu*(b)TjJ84բ(Ԩ:TeO~xr?tHOOᯃ+M.N־7A.UӬ-'b5RN*Pq÷VXl .ԅXV2,+K')BUbR*#K,+;RSUӚ8F)rB1**”iBH׬7|Yc^Wx~ռ-Ut${ޡujڎe%aM/UӮucRtp\jjUqiT7Y՝LX?hIiS NkXfTUVxxV8jКsUƒV2Z\EuN5<*biPR紏|$->(5K)u LK}cх[epj|h֝i.XJ\M*ةbʤWZZ:M'htwz OğAUŒ?-RZOA OğA>[(/T=[(/T=[(/T=[(/T=.D/|RC];o^GʉZi.bKoyCakeSpu=[C[Fi W]'(r)ST\VR*RrҲFu*8B~֋֍hF96ܩmlzuy~F`O"7=b?sV}cB_E?gB ?#N#Hu~GЕhP@P@P@P@P@P@P@P@P@P@P@A??hň]Yw ]? +08!Kŷ5? 4xSھy{jH5M&Ět]x^X&h˩ZOovX=_][M|6QӭVJt֫C uҝ_g8zPN9V TY(Ժ%Cㆋ'Jh0өFqF,BXu(}ψv |=/|S GFmY]o~&w\LÞAL5*Y (U^XTĬ!NtR,(OVSܰ1561)!FJJ.t…|r*Fs*5* FQ,>+(QWjWz¿j7z޲.nH-jWZ4]|OGGźk۟xsH[-Y:7hyssrO7~:єUL_ Ea!Nb_ RB4x%T'MJK VtiԅYsTJTV: 1SZ~\F@P@P@P@P@P@P@P@P@P@P@~F`O"7=b?sV}cB_E?gB ?#N#Hu~G:.=*Bkm%k66i_E-峯  y)S R1&(%:sJrM)Bq-8I6MNN E,8[IBR-6m^𦝥i_57zm;EoỷҬ8aӯnm{tKٖW <~^)Pݣ::+)VkJXƣNi3%EM(F*Ri$B*/`c'yF)E4Fhz=ƭwhVujΝZXkZզQ>gio$U1F>r(SZB2RUj1^eVRI9Ԕ+ɶ\ꎬ겅:noYR-(9=\)EӍH ( ( ( ( ( ( ( ( ( ( E4oM|{_EGL}?~kGFboeLJ+M6T.? xgBͼAo{:[aI'ϒ*Yq^((թ9$TQ^*z98Rqʬ 7*T콥jOTTE=s*z` Dwp11$0Ż&v}Pufz]ۻy`*?{wC[l g#hGc7TG/4{l]`{<0E_! wObmGovͿ3U>7TG/4{l]`{<0E_! wObmGovͿ3U>7TG/4{l]`{<0E_! wObmGovͿ3Us~2>.|4|x4/h!}OLeu G1^- XAKI-&y$Qխ uJ3)ӝOw qJ5qaPNtajOGR˫:tZpB9M%F4N"j/קo ,N\? -/o|֗p:~'u/[iM.m+֫kpm- ~Vm`iR ls fqFF3{LNjN*z3ZUSƥ7,ffZ:t0ԨY%(s\&5(N*xVmSԬ<]}+K汪c kKIѾ _+ž8Lψ?=ee.[^jqe 1ƕ?RG:i0(JqUWS (|58 7w_8ji8RUUbjGڼ7֯V`գOIהh^%Tj_.~%%>LkE{?lEqg\meԚ=EP_l>&XPa*ѧ:^c?j]Xrt%F\MV9pCz[êh]jʢTZWQѩ*ѨҦP:YOi:~SF~=j|IԼ=€ z?!j]Eݥ+OnLiѣ9_/^e0O,MY{jX8JKC [ҫ7^44id7*T?,T)NzJ ң^.j_޷e>iCVv77>|;%U્;z> w{z~A<aiGQr-iPjp%<}t­E BthV##JQ8N jqzq9GGqΛk~Ӟ*GH_KWh]XnO< ->OXKyu.;닛-ev-#W{_;ERX0'J5VlڨrJwF.RBYRxZQфJy}I(J8n#-Ui]R\Lks:u' :K<𥉯85!|'\x)>-?aI4Z4σ/5;{S?jQ׼^!>q=Ʃs5ńm}JFXJBt(ψXatG*TbquJ:Υ(T,-$ZPٺV:eRnYҦ׍+Qu)˚ZOxԼ-9< \\]^i4^j%޹}|T4oR>Gfw ֶWWiOaf'a!'lڻ~NZ4F5cN?Wbu¦3 ZTcMC J2^Yia =7XT^()S98d[~4ƕs[|*|'g[GxV:{= Z1xoN𷋯ZGqN%[IRⰲ^5pxd+P-(`T 63VXyft>lR)dx%**jѩkK*B-uN/BX1U|f ^YqW|NW<)xWź>X7ck+]U^+ & ^J-qJug4|M+ʝ&U#WqU*5a%~׎gN08N%[`ՒSu֧,6*\[FUcC?Im)}^oɾ>|lc/91kI+rpM~l+4L5o j_҉+[/Dz}0 ( ( ( ( ( ( (ߌ !dSFǵT~,G}twϻ ZȧV^^/}i/_p6wotʀ͊2F8%iCFbp1|ƍ_8ƌ"QZaJV3BPeROSҾqbq2UpR9hӍJVJtu*ԝNHʤNG.z%)<~3@ ~&PWh.C>‹7D:xn/,$X|0{c"$JHjRVRj)+S*PTU9}k)}U*U5=N;ʜiXo-u"xcCm$>PW=jt5u[UԤ}NZE\ʮd5JU(常x:JiR2^P]FS9n%8UrQ%ԭVB5!Sp*Uc5VThEFt)Q6S}TZn? n<={uh~^^is1X5[NAq*yTGIcjxGe͇:5*+xz/<%(IIC8ʩkJJUc|MJ rmͶѶy3f>N4si>:j~? =3 f-2}>_kKefU3*սYJ+<}xTTXK9b! Q7*:gtJe_4BiҩiKԅ:թ*fVM¤|D&I.ៀoi).n>gky_IgI"եJrhE]^U)B)jd,NE",Iu FR [MYFA4i=}!eYݕ3,TI'*g8RTNrc]MEE+Wc\SI+މ$mE{-NRo-u : ,cY.⸶IXٕ) ZΜTTSn2$(8i"2Ԗh՟fUP@P@P@P@P@P@P@P@P@~F`O"7=b?sV}cB_E?gB ?#N#Hu~GgU-Nm/Ǿ<[{L]G^F;rsTv]ùTR Mi|zo}ۚ){ӢӂNSWz>,ʞuYZ,хgJ 7eWEt[WUBK":x[Y1n7pɥJB8rJ1Is_D8S(Ɣcvݹym5oou+_Xx(C x~8rhZ}Wy&Z˦^2 NR%:&h˖u֥R$#(Ӕa%ԱwKiKQra<- B#Ma4q8\M5%:u t&1,ɾ7g/|fg|EM-#7;xKwz4o[:$$+k^EEE%ԫeج٪eye1R0ө8Rc9`jJ$xq<&|Ж}:vxėZ z6VJSoaOx>G]w cBҡYfNi\X kP' >5#ZqJ|UZcreTj/>.nK x/<>xX4Kox67h,{\NGEtQcx<ʫqV嫂Ӕ*Sx1,%Iy9)ʳZԥB2jIQjxQ5Jx~چO)Oiw[[Mqm?'|O;ƾw_o iz--IupSkbeo46X|4R(RF/X jsrRW*.ϖdZ iՍ:N8|F&8PI+j_z+k7Ե{跺+5 :uח%'Чy%WvJ7J*(ӭR0^*Ԋ:pS( M)BQwIPS Z"jМjBV8IJ/IVi;I8kB'JӴ-/M4{84'G4 T#܆xG`1&WNU*M99JVI%v۲I-HУK F#E]*]۲նޭ4+` ( ( ( ( ( ( ( ( (7~ѿ5}_3)8Wa_qqC= Ҽ/Zȶ0FHVklm LA/,Ɗ 0j4jWTyJJ)R1S$jVa/6QbRj1KVH㇋<mb5GVmMnHe.Js>X_%*u*Jݧ 1Cc)v4J- BSiz^Yō7p-ޝw5ŭŴtRterVtANH g +P[M0Sҧ'GdꝚ.R ( ( ( ( ( ( ( (7~ѿ5}_3)8Wa_qqC=43k]y,KFY'G CKK}/ɪA1#챺r(sSН(NN3fPt[z%QrcԔ08kBvݺ>uY%tI9xu_iAz]Ww&7YP6w7Vc{'8Hǜn'*c狭*U#$Ҍӄl^(k8MYm{a2.%q=N f.44(rq‹iTx+{_xgQ些⧁G7<-T֗/(<{qK#Ic?g7>[C2W(T 9҄T]YIBU2l~Y|ؚ7S!J?iR66VxyJ4|]*UJ<ϖ \UJtO(⥈T]"EҔpR95*mB]TL$g)Ks_|Eo~k5v+kI#{ ~'i4?g4Ӣyױ9S[JaN8 =vK}qOBx*˩Xa: )Ԝab:!*\x8 ꔢgYQ7ύty(u>|M_7oh;߉tfÞ8}i>K[k7^/Ḋ{;M4jh6NiYU{<3k`aMTp1)qkUG0_ai_&5n Τ)(󣂆:R QW{GT/UC>xxNO 7ÿ ?h `uZ|=SZ{ sٵKۯ &g5C  id7 cT#9ס5%WbqY/ rFJU>熎"J'MӇlT)9uYNrN2$ctjXʄ'boVtJ512>~QӬtbW^>|-6=T0VXj2.&:U, sX_c祇W֍z>ڦiOV*akMR̩RySo&Rz8>(_)W~(<#oq{[#At3Mk7WZ.aMiG2ϨW\4I"[W$UΣ,+QGS:Nj)ժa'OV[δiRueXV#%Zʌ\'Fg:8'UY8¶}sלTb0:tQa&xƉmMlhotR/xqZxno^msۏnᶓí|)U1Qw)dS KV xZUxx2sMN$0Z5(Ǝ#2T5M.iSU>/ib>;$>)|EM6ww l4cSg ,ϳc״/)sG+ޯ7eK^ڼVgX_x_o<Wޫ|QX'-kEy4o_]Fc&4a4/$kKq}-&8S0r~խ*EhbѡN&*bjcUY˖l6aAS*jx*y՛UT*Q:Tiӣ* B ( ( ( ( ( ( ( (7~ѿ5}_3)8Wa_qqC>Cly_ ~^PݾAΊI 6Jp'*jԕMN -8l<*:Ӎio5Y% €)\Lӭms_m\\\M&7K,Hؗ{F6B#ASN+hœ#B ф"H>')>R{;jެH n.6{k%VI'txYYX+:iWVzPB%N:S48NN2e&m4*FpJrR8BQw%gEM4a !QbbPEH":JNNRr);&mvfP)BB4ӊ!*ьbI$$,( ( ( ( ( ( ( ( ( E4oM|{_EGL}?~kGF+( ( ( ( ( ( ( ( ( ( ( (7~ѿ5}_3)8Wa_qqC>@ ( ( ( ( ( ( ( ( ( ( (ߌ !dSFǵT~,G}twϻ ZȧV^^/}i/M ( ( ( ( ( (I[}k8m-gf[s4w-j4d%X՜ҋF"A_?QY{Z/]?1ZG*(?_cWTQj7tƯio"A_?QG߂ EkS@5HE֧~ ?O jʊ=O}b][ܭ rho\֔&wm6_qy03G_a?ne+ k:#Ǻ/fy0>XLwˏtՇ {(|h6ԼU<}?mυ3\վCeM޿ke#x.zk㶩jRt5?'m"[TJ7zm:&2ed84&ܵ,^NB)_ 8TѫVX|?Eh<%yIWêx骒j҅GNXzqzu(E*hU?CT"lb8Šя<{Ϸsi*B$?o<⦪+aϑP9Ǚ?]uk+_0WQc?#~0'MS_Qq9O>1!k"Zyx:#J4 ( ( ( ( ( (%o nAwicrmqu[It;X7-{[fgs&i+iI}mg$a 6=/MI+$G69%`fKyiȥ` r^BT^f*:t)Ÿ${1Mv%(^cnTJVOkKVZLu_ {e>;Lyfb{̸rf9j](A<i{p\U/kh^dRiwjJIJ1oiE=.MKk?/sH&_G$m#z_Y}W005+5=B[D,Yn-m=H㺊7}i!f nQ֌e6ӊJ:W|5{oi_/So hڧM2ľ&c=6 ShڻYNb٤ ,=ӝ Fԅ:k8Rxs^ң8o0O00?Xo~?#Qkx:6Ҿ G\}7,e\-{?^UyfF)3G5Zp4+V),<B%F\RJ[1!Nz8:p:u}7 \+~ %Wԭ>~Cޑ*L.n%Fs=¨kmy}ۼ#d0|0Tia0L=*Tq Tѩb#(ՠR)/rrus<5jj֥Vu/'')aܟ3~ov˾$u+9|oV=zğ=r\=*-f{mOlͪVkvf[x5 &Ye){.ie_dTuk*w{YJ^[snrf6QF8фj%o|KOY)F41qQVIeZ$h3_?Ϝg:Y⟇i񾟦x?kŞlm!c#6z}񮁥>^j(?-bQGƛr\M5nDy'BSgFIETuJ%˵wuБc7wVS1/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?hHc(o;C/,n >[a6?|Vs/?"o q:?>DëxfOZ_Gk_ |73}Yiޗm&m%",$b!hLȲ9wS^Iݹ ktuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image050.jpg0000644000175000017500000004403411665471332026761 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"N !1AQS"2Uaq4RTsu#Bt3bc$56Cr%7*!1AQaq"2( ?W-c@vjO-c[Giʮ<)={cF#|LkAWFKL/F_+UZ3 <1ԮqwKh/vKe=WEof [xAUݥeS]) ldrkעZnGfnv%Ɯs||uzbaËʙm=6 (eM$ H^V~Qt<s;g\VUӕ:Y<4FLJtECdU5dkZAO>Q'3y.4v%ƺmꁿh,ժYHel4J*}ewZ|wK9qPr8t5tc{t8~o=+5;ஔ#s 7|OK9qrvڧ懱[?3y.4v%Ʈ9Nh{S;gNgl\j懱.?3y.4v%Ʈ9Nh{S;gNgl\j懱.?3y.4v%Ʈ9Nh{S;gNgl\j懱.?3y.4v%Ʈ9Nh{S;gNgl\j懱.?3y.4v%Ʈ9Nh{S;gNgl\j懱.?3y.4v%Ʈ9Nh{S;gNgl\j㚞槱-Tә<槱9Kә<槱9Kә<槱9Kә<槱9Kә<槱9Kә<槱9Kә<槱9KRZ["o$ 皞]v6i_Ϝj Ni>UK E ϙ%EЏ>*0s 8]VVW>!*`cDN[qګm[~B׵)4`wymS1sm5-' } jes#..gQ',_+("^+n򶟓TNLH nۿzTvJzYQNV m~#r*siimF紹⬸<4O+t4-GMLZR߹C[~IL)ծQKQnAl|-!BA cs鮕\E_0(t'35koӡsR*`PV.Wzk֖pUW~۝mX/t͎z}cഝ m~t5qiQ0Q h JDژKHY!(* m1'Só-?h99_5qi߹^v%(e2$d:C%:xkm3SGG{߹C[~RF; y;nX魲VG3ۧh7jV[J.Q߹C[~DTRiE3֛J.Q߹C[~oM|ZkoӡsL }|Zm(zGC[~ m~`\m(&ҋbkoӡsLciE16]?C[~ m~ҋbm(*~?:84QwM|O߹C[~J.84koiE16]?C[~ m~`\m(&ҋbkoӡsL |iE1Tt5qi߹ҋbm(*?:84QwM|Q߹C[~J.:84koiE16]GC[~ m~`[(&ҋbkoӡsL }|QwU m~t5qioJ.sN?0-]iE1Tt5qi߹ҋb ,7+M%4 fN=.?:84]3:f&8d00F=)8hU\lRShb3SKtM@qK(CFDxo u}XzE,w{c ) &!cv w#YnuF䥆l$;:s<|4HU]9ILZ$`GrԑH9!ŵ貕Ha'هS[Vtj8/7dQDdl8>4x9Y8 s['_V]kIFLᔺ_ 5vp8;{Vw}ưR11CNjF3c3SZyCpGM<-}K^zS67~C6-\SH$5d9G⧅a_s]8Y_n[0DSNf%vsC]rz*馬X|suïq%_h pF{~0rIiU@9nH\_As*ʪ IY@\ haszSi3M,?)/(]If]%>0XQ?ھ;H(,԰I-LQ8Ӈ ]`p\)7O NctHJ@DDD@DDD@DDD@DDDA5GSI QRw?Kl?wZbx@#U~W{5ڸjvLZZ?EἚm"8;pó~KA}tHdku$.f jpSP:90WflR9La~(MiL)p.'S0IzEE`TP({r23`ܝEm`tl"66rH##U ՞TG͑i-8]MQ68ci '9>Ԉ+)9hqt4xqs]HANឡtTZ說Ͳ0\pXx3%EiCk\\<ĕ]WT0l 5!#ڈhσ6ёV^#! q8^#Ziil<cN^_Wn2n=<0>fӃ$>|DPpKJMA T:\Z@.xx#w}[#ca H:NIR^cF${9Q]IM p,LphުBg5qo'Y(`l4Ж1mqqwi$ߪ\%7;32ǰw֨"T1SFN ~'EΊ*sCI$88>ԀmTz\Y^@U`\ְwa_ƽkC!}@DQ6U?`{ 'J$G={\Xt'Pi=.qZ Q%K#ci こ(㭦aى|జPN쉎G1.s=(~?;WAwTRw?Kl?wZbm[4S9$k$Tp+ї8p MC2Z{uߤ(c (CӓxҾQU_襂_YEi? 643&ޜGkngoNގԁzRG/<8arjp2(a-n%i͌˶38/3ٕ[4k.ngVF1۔=}`N[36piMK ZFJ :+|YKeݻv-ikDzppy{p^ox18w顸OuDl3Lgqx7uX'mUMpŏN%laEc\WNBC<}/nZycJ2p-0cdvI9@8inL<o9[65s1M zB䡹S2|\ꑽGq < 7(h%T́4p%pӆ;yMzZ.w#VIV\UtωΩla~x=EPUM"s3&{FtV&XY d~@Si8N_s*CHZ\nvc7W2I7 1ϐ:"@=1-C̲{~+˧k \{A>֤mK2đWl[ ucM!/cK8-[dVL!7vz2x<3oZgTS4odhz3B$lN ok Vo,sR  h1qߞuvnUGM4$F˙3Ԭhk]쥆GG$nËHauyʑ'vG:x~ŏW9eǨz KSLU_jbm+Gry5< _+L7vaDH#,k\07uq)%|n+fC%^\͋t8PQW:;Dv<ӐF7wa~` 0Kiu}B g=-|Ihj&smzsZ>hpP.z* {|O?<=sIPgU[5\ [7>m Sr{`ϑd`nԿAp3ۄp3ۅ+ jNR j\ je]!)\ ;Ry/.e͌ :w=nb mC] /XΑ+9HS.tv*kjjk)26W42 [B西V:QqŪi2aڎ@'?;V Υ'HfauK,5qa[1nU^D1Nj%/{.'~`uqH53f_U==Qd-s;xNxT쪸־Pk Iphqsca'w^Vx}!7vRS -dT׺)%1>i1iѸ nPYtl2MM;߈ #G an椂Xe=w6`*36 X.uŕ=[ sx˰}\UZ uoMr4IP[<0H]]muW0foٸh /rU)t5:)gy_юŽ ݃Ԅ?;\Lzжge\43sZk]U5e4y*1م$ae_KQYV]HppwNFW=$uTXPCς]R~bEʪiKLw3Lq N,n.Յ +lQ[FSV66<jn yg  浺ix-!v9STRw8pܣI~y~mGr%ŶAȻ5V?\ H$et8\v?\ rdni+_Y".e4sVt䞥[Kɪ{dͧ¡i2ibc \9Sxk4qF?1j pAwV8IW$ݮ5gƜqE8Ŀ=+g'dN[sN?R\g H;?got^#V1ٕ[6&냥ͺ:Nud 82\tu 4WG?`0v!3Ko ֿ@E# jD<:C 4;sA!7*z7bwnW ƵрD@DD5u?T*EO''| /-.Dx#xev/Wؿ+\ j |.s0]\=p\un$E5=έL%ct8%vʉ]Y==js`sZpH@/QdUA6sߴ3v֚jx7uҺV5;DhQf}it}1m;$fm7~쉏>flp2GMCv*vdk_ 3);LjAA n6Ԭ R9#j^Us8}- l\7p*[RYcJlQ-g- c[tOv0 :񃸏Z 2,')E\UY iuGVpǯ ܬdP>Im5#]=yEnQ8En ތpr~H$p2RpFWYʃ$J(8.8 FY_}KOC.ԲS0"p-n**T2-P.ź#^rwՑ֢w+㦦t (q<k8^)ˇ$Y.YEqJ5aFvN ]9c9\w΢jj+)H DZ5࿉8WFM rSVK!=p&竵V2[_(*91/l`.xop{|z\Un@_R\Ɔۺjf0d5sv7pw)Ŝ|WC%܍1d?:+czKEP7:K׌uyN%ᲒHKkӂ}+rwڦe!6s+r;w4Qnϝ3@ vѮ Vj[]-!|bM3 `h_"u/e1`}^yhDwox)–(衪2($cfHó8`qܠ"ji*ic!6Z流̯xv-ը8#ΨDDD@DDDA5GSI QRw?Kl?wZbz]i)r/lNETZeM+{YRs4Gf8._6 itExY woQ\[L]E= TNl.fa]> %+򇔯m+)yiN i:ܝ>˾W2`i+*hp`H H#PBfeʢ9S4%>'600o#Ԩ+9OwnH {asd;A CEJVUԾwN~1FIS 1 . kU>[U]J2ldf#Ús$.ynw:H垪3̀k E2ugyܒs]=5M}4:iFEn6Uk^dq#FWR|eSz#S Tlc G$ԴZ&[s8<;#WqhLqUP4j{\0s;e |Y>^F]W)C5$5Q-K.@x{7ZK =$Q{9M%[h㥠|LmFQ{I$:fW>ODptfpqTJ/ox+~㆕ ~}Rձ36Pb𙑝^uy3KhbQlT6W@qⓓWT+ꤎ^tD ԯt0r2Y4 cq8W\[]-SPxx@ǥKUӓl%CvAs)FIq :NK3+dr\#ag ݆pT;Tl 0gVzتyOw@+ .kIw+U|O'̗j*UN1i35jbys\do<qe-ZyD6{w\x\s_.qcG_J} E8&hOrܪ"lSVH1$0SSYnRWI ӌ Xo[֛s)@ٞ[gtHq Rآۋ*a y C:w~}:5HNwE^ s}=]tPQӲy#lZևg9ϙ(ZI`4i$t5vMi0Nocnm*e/ҺYqvw"vr["XM> q:pע*)&("숷gC\8Sq_C\pVnYpM\rH kIu;oX{'5l-/`0d{Bث@ :ON""_[g\2Xp+bd[9Z0U-~W<6j)h2Z25+<5MSMMT ligvT6+]e441 3xY+h[m'(.UFG^#'_| e{.U펚R kvMƪjTOmwcq$ZgS>ҙr'BTn7j'L'fpZMHܪg9jplvX!d7DcqmʘSV2xA5#޳ 7 RV\B  } ;販T߷ҽ;;qH;Xu:(8#??'T9=H4fᑜrӶIEʸ<2떡KݨCpܴ42+ɮxke `?&>Nح3S:J n>.sxYib} 6oIU 窠4u4쒜6d`np_)T{>mM[&[rGt7muk#5әrtm-;|QHA.Րv"Gnt@ϯ懓h;"B 2Pw~VH⧳[i"(( '5& cc@>Zղ*+Z'[|N6oOn15D ?Dڤuk"uC!p8u{[lq#5;pRD|ΖGhCNY4v5}tHVFֈ"wHblfB# `{<Ul&w/zD6LٛDfuvz7.qg ">vK'v8p.ATKXX% ݼ88/4\QI\)%C/cݟ8V肬rf$NTvwg̻ !cC4lt"Pxde!M+='Q9[lqRDƶ3!G++堢 /sK#y*: eEClиƠsef9"G#14g7eFb29ϽY ~O) f f6:6;o;_#9hB& V8o}qhSPIA l:ó>'&袶MAlc-fWZ I 1#u/ 2D9HzZ*+!v F~{wVR(~?;P~y~mGr%ŶAȻ-U~WTV?\ q7vR"(!},2UERfXCߢ R"=JZH(1-./$OIS"" "\2dxG"o}o}H==~M=~A"(a6aGG"o}o}H==~M=~A"(a6aGG"o}o}H==~M=~A"(a6aGG5{x{x{$E?l&?l {x{x{DQm G $E?l&?l {x{x{DQ&$8oAGSI QRw?Kl?wZbz];毸 U=iv0=yk(y|dw+2QE ߤ"Ɠq Y)׃upB=¢Xt%$:x###b8/u]tIEoѴҹ/gUtUS_m3F O,s1~B[MVؽgEl~M~k%ҳ%%J/>"߻λT_R+D1E4xtZwoñ+OrvZ ,/{#I⠊IFi4iqe:KjkY] u 3iǙtsؼղ +bl^O/&?5l*~ؼ譋ɱz[" /&?4+bl^VȂ譋ɱz>ؼղ +bl^O/&?5l*~ؼ譋ɱz[" /&?4+bl^VȂ譋ɱz>ؼղ +bl^O/&?5l*~ؼ譋ɱz[" /&?5OheE= qdY/PJH|cQRw/-.Dx#xev/Wؿ+^3O0FvHh pྡྷ@<@9y@=K:[7v83}DDAp}mzXֺVq< F\:6`E(X>;9ҮDb'gxYeZBO =}1Jb'Ɓ8#z  v\а #f rsk7̫JxG Y*V =}1J97NsoQ(Ys}1J97NsoQ(Ys}1J97NsoQ(Ys}1J97NsoQ(Ys}1J97NsoQ(Ys}1J97NsoQ(Ys}1J97_ Dnѿ*R>O''| GSI ? )ڈ dx|Q5Έa#{O 2{S'+qGp`{1$״@()QxdQJu<c%{D@DDD@DDD@DDD@DDD@DD5u?T*EO''| /-.Dx#xev/Wؿ+^3B"(U?ҋiFG|) n\"OC[lڟI~umT>7zf>7zf>7zf>7m뤡5 1+➝84g/mG8%z7 b$Ry{7 p"E/7No/c}$Ry{7 p"E/7No/c}%O''| 3C#$:I^j~?;U_[g\~mGr.Uc_U~W\gvDP5Ҫ,.|aU<%Ư$\mMk%{i{]o(*7T9Z<~b]-U]#mUָK᡺]7+-7gA%;68 G]VMu*_ ?.-'3زrrBJotSq2g<=Z*hg԰H #j;m/xZm^JwNOG XVn`A_K'~@*6fRZjk vOXkṊ5vijiP`p.?T778Β {Hӎ8p8X ]{* J̴v3ݻwimǮ ΘZ59h: z cNkIsakN0HiYkm :zvӵϗ-n㌞*˒ڪbl&LfkHnX%DE]g$~aSI + ONŶAȗ"C-U~WTV?\ q@DDD@DDD@DDD@DDD@DDD@DDD@DDDA90E,il[tTS:W{q1-o'Ccw6n>Oڟ-o'm޴?փ">j>Oڶ;GzhZ wC">jM۽h1-o'~K6˪PO/ ̱9vo+sw|.sIA]zs)ٞgp_T]WV#iEEUEGUmZj=ւuUuU}iZ T}WOT]WVڏi}h*~QwU_9>QwU_9[j=֚ietwPP [sSI >>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;??"U !1Q"ASa2q#35RTUrs4B$Vbt6Cf%c!A1Qa( ?9DZ\UU']\˪BVKceq KL$V$DT0R*+Ԧ dUvRR7Z>EmG<UԴ~:#v"69$E.y.&ia 8,CaYxc)o g+~2, K{ $q퇺ܨ$?9i3Z M " QCqkq!H}8"6\7CT'lUWcHRzt+Y RXB38_(3}|R~RL,#\a$cͷeHP O(PcφxR2DX'e%ݕ=! ~߲$3&;Yn<Ƃ_2ReXn5~Hh鞿1efMcۋiD걜@€Bm%;$`:D5CC1"?G? Y#D*z#3ͳmźlyceOM4BȰǬ? AgʭٛiDw0|wtp/!hm埾EnX #ɩe0nnJzDACOIѡx K->iBJF>p+~C (wI{RUL] zcLKo_m.>D^Ko_m.>y-|%^/T>`PE y-|%^/T>`PE y-|%^/T>`PE y-|%^/T>`PE y-|%^/T>`PE y-|%^/T>`PQj\asy*9#qKo&Ձ*ˈL@='x[K NpB?UNE/MMW/տ3ZJ4OUI&Ħ%?+Ǚ|dfĺJDJj,$vT3ZJ[m[X#YpRT>[m_-\b#zlʦ0D.2y5=jF[yRı$zlm$H$<=ubVm}-CW"S`B6|GXi$!ВI^mI۔Fhȭv n$|s48K#0f(۔SA\Y[VG,(V<ݷzՊ(+waP3 P˜E*N=qV(豷]PTbTksMIEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEi`y.K1mϿ4̺¢trXzz>QV\f2Ek ZC$r9zs 2¶Og֊k]ccjNߝ^ ",*dr6W wvKp1V)9CƲ)F={M_>o kqf!-YW% eU/:g}>ýs"ˎsTūi=W]G𬀺G_Xu Fw72d$ɊUI+B@JӰڤB.6xDʮ=Íʸ9cz?}KE'z#Jןuۚ*ֺmEiIP4QEEPQE-Q@QEQ@QEQ@QEڳ49bISUkdY-J8ʱ N?v9s8 "մy.$4+ .Ǻ {)f qt/eY9] h{."fVxg'*U6PGƒygE\ArMD*{-PIq2Dv's${vCWഎI n^ۏXZז9|Xeel1~T/;}VV7w2[^C4Hb9:'e4\W7蔿wDlb2pB:j[Vh-Air%S:Ro-@ 9QX8{w]Is um!7A!s/5Vױ]DUV-Y*/ܹݎѨInI  ,7w<.CǬsXZMP=ſwR5RBC w3DnEU, dGPūi_=WuC뎹}b],gvHݟ1 8iZiEiIP,EEPQEEPQEEPQEIObR~}5縺(6X>P(>[mOk}ŦMgnF3;+:=ھ` cmD8 x5kȴϹ;8/ߝ5V]Jʒ4>)#)5cpk)dnyc[ׁOvgwRsao[rrx2%}=O'v܅lQV 66uwZ5AQyR[>5~*BFrrǓ{f{YwZmk6}$?r,^ϣ<&CmY1^GSFc]#JCcLұo&XH+9r*mDCmUߎs'5w1tf3ck$Wd2Vc! 93= .k{S62W9>ƴP- PPV9,7r}#Tzش3,RJpi  ?{$!`8K,A"(‘0z$=#98г[ȯ")<&s7w:R}Gqdsͬ"IO@AܡXx=ORQƚlaq,j1)p3?΃HVoO!w_/"+цC)"mبgg2e@ H9ϺiqҬcV$q'&F{EEPP}k|Nc7>G梁}΋&&ؘEK*Τ <Nm4NE%ν +)3Ӟ3dc2.#goGmtdUx٤@'$J۲M+HqjL1Z]0黕<ԶݚAs${䔲.  wt2-4ki)]Up\L=ɽp{㑞IX'LiH$V<HѢ,r >K.w6}#Lڹ|M<+3υUF/)ݵ2!fRA<ҪI-ocR-Y0DdPsO뱯wxGv 欷}Ck %w's^+-# 0[zvā5OWǝStG e)_EK$co@Cg 'wx7{KMJ!Oxbm&lsFؔSzZ{\[lr2y}yV9^jT2VhN䏵2<8C֒dhfE}H8zW?nS|9ZgT "6x_y[{$-$'m (Sj7>mUv3D27 |@a-7FSЬU/ [Nv95GLYjŽ <uD; Y\"aDñ@asaͧݳFCck 8lpsȨ '0#Fb:廚[7\0Cv`W#@<@7G Ы 5Aqi#([bpw6q'YvfMnH R8[myZgh-RU[cHFzAmJg4=섺ҚFg^Br@+3:M,bL_Yǰ}oҒ;to޻m=3V T:t)[ A_5_ɱG}!d#zzkBQI1JUw :|S׎E@YII1+F8SE},DJ[vO>*K-65>>y!} F =_*O %N0:=+: *8* IЗ#S} tOPO)W&@ӭ0=4TKUW x*DځDڏ_AjR_Aj>4O1}QJ~4O1}(?(mE)(?(DځDڏ_AjR_Aj>4O1}QJ~4O1}(?(mE)(?(DځDڏ_AjR_Aj>4O1}QJ~4O1}Ŗ346w"h*)q&R9d̙H1.n84]oq2$b0vGXp7:M7fX]4RņǪ&ۤoe$6 3H犺"#f 6?:rz7n[ّٞ#w NKg {]]_S[K740mϑ1 1*r8R@xJj4 Fr#`8sWǡrj,ΖLkt@ `g#kMQD<,m[8n&g&1\I4Sc¿WJ^{nn\F'gdV1Lc}Y5A?gut0nNw[>#9W-"+;TvV@wT׺})Mm'p_GHu]qڙ +Z$•;Imp t]i8n%K4.#%<\w&]#-yas=tEmG*Tuώj=0\L3*@R'1\V"nxV&FIJ}{jfhtr+ +J"jU6m] d`cݚnII*$8;AHS\& +<:/.g ʱD2-ԓ֧gٻ;ͤK ,Xg`#vxAbFٕ ,Blo#'ke.#B>HmČҬ m;[;[wu+:[nRܴ`$.H'J-S_xAeGd K7T5R5 VUdc([28@=sӞ)uޣژU2,.0c3O"_Ef-^:גwKʩn!Vǫr}fn5nR/IL cP sUFjڦkK YYr?IL4;Vndv劌.\`-dS+,ڬjI;Cgb,}J`a1N/5c2CG߀'wZVN)xsKr‚C6@cnHr!x:8H>~m, YZOh<2W>zt #p2<Q8҃UEgtu]fuXXj"y2Lqlgi;6W.xw19QXèQBDeo'l%eg#9=hͥDN[)d Ǹ|?iSOtO\4i o 2( NON >[m^eWRd uikKTܳ(< ۵sictL{Ӵeb@;@lִE#0XĄ iZơډh GػX*}`o{ۖ%^$/JܠdsuX]cQ{MՀ5Fn.'ʣvoYB"6|O}[лA&pѼ0.;wa ?]90[qG'`J'$&HϏTґNH zGEÕp2YH2:u"];QY~_qQv>* EUw_oFI& |FF~A\Noz26ďOv>* EhHDnUݦaK=GAַܺɺA9)/!JR5_CyR.iE+^p]}D?G/!JR5_CyR.iE+^p]}D?G/!JR5_CyR.iE+^p]}D?G/!JR5_CyR.iJ5_C՞,\3"1(BA?%GnN ˆww8\4^ΓCY*~qYBCЊsy"E+=pԸRE[C=Մ/pTD `q'^c+uqjvIcN@†ݑlu{#fD| ,N4}:$|xts^h]as3LcO 289?]EQ^I~qXzƒRx`er+Th y4bD1.#X*E톐 }r>H88]ڽ: \ƅ2n~Y"EGx %6U irLUm<0MsS`e$Gyh ?HfubR#_brA?W;Ptl[7p6'*مuayIF>Ou\׈KI#q<}U܀.04P$KI.ai3Hg'xPZ2R]16])8$`r@8;iu ["IId/=7 8=l6aQ$XP d1)A[Zۀݗj2w3s${@ٽ nΡY,su[֧Rh8ې5l9*dNpr:f0V5Lvx0"H4` 8#A$;K.0:/}jTYu%q* v2=N~}tI,yȵFT˼žyOi-'ӍΤrH}!Q齜%%pILz]"6Pm$jAnd$.j7vvX!Y$llo_ѡyc|cdgձ{Rn;K.oLqFҖ}muqOq$L@$IJ!#ϨԷ3_,JU_i+zR?jtԽ;Ovh 'tϾB^]j3EQ(7f@bwoԚkm:ha%`ScAwZ͍Zi+511Qr0U&n Dmv(Y 3)A.t$NKW#$z@ qTN]8--i3ߜ"IWO}K/itSK3D ƛ.H}6kg%o&0 (Fc`<mI{Ir-yNy|.v U֛ɣ<̨'89Ӭu{H ?>=zć)) Q (f8 ɍ܎VUܹkk"D9)RTaH}b)"㑅ƊU)0g u)K[HcOzeLā%>؈@ ;rI#AZE X9g21Ǎ\ѵ{FB!4{$,v+@U5TE]b O_AgDoHf "zEy}ںΈ2x }lD6jV("#p@\rK1ԞX+.Iַ!B(G j+p׍H$aTp;ÏXbF1{KHMDV4* mx?>+a{h!GAQnEQ6=us.{L +1gzV B2Z,^`FqPf-3Cw 21A`óʤԯnV<`meEKrј#6VG_ZƮ6܏u%&reW7zfdW350moq'ێN7 ۍh~jM]6Mu?Qh!A%CQQQD>?Qh!A%& ,I ( (((4y d9`GNz⢛KPX1HFTte_ҏ⪗ |WM6`0sҋI {6Zq Hݒ:5Bb1vu醮ݙɃd-G]WR`ҭ̚t{, ;'QOSIŜkr3jf4cg8e6RnkpC41 1d{9'RW,2"G"#4tiJ;[id Ķ(bA>9t\滷0;) Ͼi]tlJ7 :gg*&Ҵ`bDc鞕!y/pzc- lo\ `b-*E L"W3.8>mqiWh50c`y$G=X5Ě6*ȭ`d@džc>Ks}V/q1ml#>j{cVXhII8^OAWv qһrY敭k=wn03+QA/P_5-^P_4yB9~ԴPE G/KE^P_4yB9~ԴPss)?޿go,?޿ :'ދͫRe?]Eթ~4 geH~Vр \뗉g0ǣԓxv718%N ⺺$S$UN8Anln%7&6Qʈ2g|*ݦ5okKkQ! FGgc+wCg)#84e@{6[! `xtV :nt-*HdpS$RFq&)wɺ`OGerszZ)WLIRe£w`T&C h rü?)U]HӠX]m¸X[_,m\+2̨iaɫ:]^C4K2Ae8ϳM}yl`)v+C)R|ߺQ}RCGPJj(ڿ>ume-wlk{$8t5ս+,R23q҂m#j+0㯮j,$np]x`|ƂQ}Z=JKH,RcG."Iaw+xI}m_EsA"Er8<ڿ>6ͫ#j+(<ڿ>6TG i.ee-1m3v\tK5:O^YDyf}Ե +0(n8_?=wL%53薹/z_ 8%)j Q7ok4op SY_{/?o޻O'GU/@>xGU>TgRcpm U-E)a-p=E~=|H0U~__R>h̐8HN>ױS[n&;x[toW{K[V25R#Xdz[$GBj}ŽSnEGs =!R6]CrC22c92F*}O1vVe,2cǯTڽ䪳Ƒ 2 V>pr hƑyo{w*U'8ի_O7*$1Hu?EP֖Al(Kac< WZ鷋֣a&HbG9'> =$u$ϯ'r9>5TvbA{Sd(XgI#{Uײʆ>dm})0W b|MԌ2x?Q[,);N=@x*@QEyAQ@Q\s' (ilnѷ. ( (-Q@QEQAo74z)o74z(,z-6KX8 'ދͫR?h:o.5RzWtM>HIKwM&ZUWF `Dq GMcR~ (u")q Xx`VێKujVk v;FŰ>lBULd`c9.`eKԭrDO@=@,j9`$ye!' ss{oC_I἗=bvzxɻ]%ƚt;"o *qԀ0sGy=Z[ۻ#.H.1㸕✗-g$D*1س8sL*L#rZ'zHĐ8TZP;U^Q w9 pNxd]y=ybr5 꾖zg-ZkXfě.="w6 d]1"|" iS7 #8?I7l/:3 &HR8n(4@31H UgW-sn7Lb 29늙{C ,gbER3"'7`ݭm 6&?,Gpp~cP{?aìKhFcs~HRp4YW#p<3[gQ-3"}Vy=U-M#4%ވatW(g}Յoh!ow0p8'=y[#ZT+d`(8N}y7Gnl1s5N㴷sH`Gg'{ظ0,9.Xw8V̛8<uiqQBcFɭÝW ,͒@jN]$Ec|ŀ~!0jQVIIr3@ n>H 2S.-Ki`{7!A >Ok wh VbNҤ/ i|[s8=+G8*YGjW̟*?CAQ@T0{󚚡H0 2{{-[^0uj;_Zy=In[lJZoncDd>jZZ SIc9=@$m)O_oMOW Nw(9 F 9wxc4;E5ApE}ZH#r8NΓvmumޘ@*'4VI-.3;J-HwaKd Z]'WXiE9J+8qr>XݦRx/-(n;FH\zd vt n$7t$0E<1W{-˩Z3\"J$Nvmk{U4w ;<,`,H8n sGݰVYc(y \ht廳;UN)Vܺmsy+|>ώ5.M5Fg2u'So&XiPʼ=G8kg=|F2DTFG]'z$ ק?51zgf!/㻊sEƱ*'=^4򀢊( (뮑%PwҌ[iv2:u\JBaj3[ tU"a[9bͩ$ʶ㹳2G9Uo'ݝ4y7Y٪,mc=)S^%#N~Q'O:'h>Ai7pXȾl3]EggAh"FrOZkYD̫H|23GU>TGJ?4EGܗ\oŮ,l_ )iUnڼz/9XIޞT˖'8 tg/.煢Uu)<]ݏKZIoy6Up7'= |QG `wjTuq-cr3E(9< SXIo#zn k3saؔljip^ mQBL2}1ܬ`q㚿H5KD̖oE,yS#,ٽ)diVmʪrgǧL%] @ێX9$N3ҳI,w\C(0 o$r8VaAn{pq99I"u|t[qJ).]zrO&ًC",92K$\;<(k.㻆,V'ANsOPzd:购rYqq9m.m1ʯ*6ӥ@ ObPO3'UŴPT Y#IG=#:Gi"߾GY]qtr , cn < .8DWSww{:3Ҩy6Nw4NC++ N9>Ŏ$m/vN޹Ǿ[_#N$v-}zH7VK$4c2w=NU{?h!YdU5d濕akmR$3Y!f=lsUE.ڢ%$,s*y<6O6TTK2X'3,j$;zX]O@QE[#~K;Ob#~K;ObΉjԿu𚫢}ڵ/a&~iJbI=Usqwi =I>}W2XI{˩-V-=q0=gϺ=ê8==t SPUp3VRomOi7}GȜv>tݲ읠s}U]'aᤑB3HlOv]*nuS7d`H,3]KKR%FQ,VL\*Ցe7`}˜>A6xNceIH;pۀ䁞H7lq$)E*c4Pb[V `Y唼R@` Gc5=ޣڋh]T,lwՀ#;T1lq־=jd8UW/ڶIqSɨu@V&&st|kM-4G#FrgKATAF:71ٽ]ovT -\Ũ3,V V7ρ0iV$~#`!^ҴMAU-fNQp_'}QIvh% -HQҥ:S#n'h!D3avrybO9ʨJ.2Y5ZI^X)ˎs) Ufhmd˾ұPrxskjmu*HNχCh䶷d(ʟ&{5$2:I[:#3[MNbk,*PO!_(mG>5Ʊiז0ٖF9UaNO5擣r'r+@͵3IPv 񤞉EԿ=lsOH͸?hK -E7ĝ~HR00k;Y'y*#;8l4nQ6H(6p>:A{(]0F %rRA+q3֮I\iE{/<1}y7s4Z|y=i`|?Q:DAi#}7@vJt"i #5slbBiEY2{s; q.M.c?MyoiV #8A=~q&sģh P3Gsywڳ@u2U;~RNr|)E[-DcE$c# ?Mk(VC& $PQl bN";]x>C^AvN!{duQݪ׎W4iJE|16=UtA~`&4]%v}>kx"iz`歯iMe合wyGOېaӭЌJCg zGW5o74z)o74z* :'ދͫR?jjԿu |ŤPe(N} AP*~WxwvaU|yx3i9bAyɦP)nX4j̥1NPG`ThV4ۄRIgu $,}d55PQEEPQE-Q@QEQ@QEQ@QE\tJ;Eo ֗bXy #t$BdS{if tO}/%V>3JӹU003cUsaYdČ`2N.% V#[*G }*ܬb7Dǥ *b쫪2Cvx|Omو;`@ r@设Őcd ރN3ȯ.#mt$-y`Z020T1Iu}i#Mt2!IĶjI$P}~t{RES}3]E(?QUݝ̷H湍C"pTe_ҏ⫕bd&#ad KٍCQK.)QL#8Pcz֨ _]5†24H#| E""k}@`Y&Q+<CR[YKd)խbaSǬ;hMWS$H:F@A^5eC 'Z|Mte7ac!mĒrF^ilH-m-w30a!sn- >Qz۴wiĽȱƏ BuX2(8TV2WL{Gcܾ} %YJD 'r~zvOPi<<Fi8Rv-22/\ O9dҠvܖ14whPA'cP.N #.07NpN 7&wݢ /kؒ+ʞP{+]K]ռ6򢢻7vP7#\mC7[\[J (c 6p[͜cݑ]c.c\ӫ6Apuqs "IVs-o)VbФ"*\ Y .EdIfp 0nI}]JQA 5ĸn'r+E\I^XA3l2a1)QWF4CP⓾ݖWPso:iKZ@޳ωTTEPQEEPQEEPQEEPEo,?޿go,?޿ :'ދͫR?jjԿu h((((((((((-Q@QE\tQzkWDi2?Q5%HH- M >4/6T) 4/6T(п$}PP*=H )P@ʿW*WP0e0T*j(< 2X IlT3Ҧ"D#'4 4Ynb' Vb/=}X7zkYN#UNh直O$AQ>Pw\z}UgFhj0#T蚽H-QCij HӃ8մT(!;R+f|h!V?^ ҝ5vX\̆~k8Â)tW)6bY('x} *zx6m%j#>8瞔Kfc`p 0x9gMTWRHa%#<UK *Z A(>V@Xv~4٪ZҊSiV{7iaopo4d@U-(Qq`Ubg.$68^>>HoҭZ]U[0pJpPe-p̃'>[g(q(bӢy<붒U[mZqUtOV?KEPQEEPQEEPQEEPQEEPQEEPQEEPEq?-KQ\tRQE-Q@QEʿW*WEP[sV26sVj(h |VU$ N TG箮u R Q!@ʟx2Ěd%UM^6vzݼq+DJ@ S+4X)v498:٭ؽK5 -3Ny{fW$~r3P8kO,1E m0b*φ<ҵmf[fBIϳҼ1ǪL>{_ikR\hbgG@TxT_[QPhet ^}y'5c8X NO~XV[CܱI>cxS+$/MA"Jrv/QPG%ɑ9 xV89,jQ sӌzZa;Œzt׳ڍWhUn=BgU3Hǔ1^[]8#p_FjhQKh4A18|p, ʚQJG\C g*#pXOWQ֣ yzR`ArG4=QK[^ﮠ+Gn/uu.BҬC?c>W1ȒƲFe`r= u@QE[#~K;Ob#~K;ObΉjԿu𚫢}ڵ/a&Z(( (( (( (( (( (( (+jZZ( (()J?U8GU(-C qa)>$T,F@볶,̒1bCc;'xtW!8P0qӌZz2M92= I?P:T2*n T}n>Ns28mvikѬb<7ci{4`0s-]ϢnxxSAm~-J+[$ DnO]So4x--"}K>m9qӎ{:i*-&I&mʯG=x5Nq]5ķ '!xL~O ג=UgNn/Q{߱c 6x1$z%kmJ۴͵wc2Z]TxcN7i] yv 8+M+q<Pp(zxR[{Aux02g*u%'}=ݶB`CrxkK-TYD*$`r=;8mE31>skvk;Tv9B$pȩx"fR٤VNBd Nܷ=ITò+.}IgImn;L'(mF}c#H{y;0| ϬcZ߳v\,Q<0bkRmry5{GNwYU 8TaG< к9(w nn9nO>H=Jgmwɥe1iǫoy$4  U ֝ۤnEJl0}cM9H}ʄ#sz<[-Fh$w!I%N2sՃ%ŹhZe͌.ޒy(Q$0?%q#[po.N );~؃S$r0jЭIvIpIIP[$3HT'svS1n{& e+ 8 9?Lj3^I%p(b#+NOQ. GOs9U[Eb-.;O$4u4w`'[O Iܘc(PKl6G=14V!H߼v!H߼,z-6KX8 'ދͫR?h%( (( (( (( (( (( ((":GEh (( (WSBI (?V<m($= BJ*?(G <m($Y,:W>QyD?PIEG{h!GAT~QyD?P-AQQQD?Q{h!A%AQQQD?Q{h!A%AQQQD?Q{h!A%AQQQD?Q{h!A 4*T@+(G <m($= BJ*?(G <m(< Fv_2!b `}ڳ1 $$UOFm B`\c鬞޽Aqov,V.鍛BRrq\B?h?QA01c ;Bw{8G}E~~!K= e {B?h?QA01c ;Bw{8G}E~~!Kx'JL9 2~~!G{_Rg(qC.?h/)o}}ǽ/(c ]A?S?h/)w}w{8L{_Q ;==~~!^#]~[@wqtO:7 GSxgF²/CSwO:e̖E;/+n8Z*( ((7Xvzg{; @$zvS7PqElaFuʰ? WwցMλgsL̕6uʰ~?䪷L\b/Q0(I}/Qqϸґv+[{LFa7NG'{4*-!Ltj>2Vn/afvJ訲4\ `J=by5Q@oX1fszdj~? Հՠ?GJ`6׌-FY98 8($HQ'^^ݱ B\ 3\ rwJ?tU%fg;BI,2dq:HA|֮0$QsSY*aSLSI`~Z8ݲQU⹒O$pdWw閸ӺLaFuʰ? ڲfՠ I6 >-'8$;wӦ +?]'/ G6ڣ7?nz6uʰ~?:X`VbM²̐xpn~W _ג H\]ʤ@w( <'돚*aI'fKiZ0Ǹv;g:RIa& Xs]0iwyq#8G'm&kvOĜ[kjO{to(i-dNf (:6Zqijs[)vA?<0;ίVI"}bTu&?靠SܵPOGCprp:5F`Nn6e㟚4*aT4}V.ӀC 6du>KS꿭9T%%_֏2\:UixYTeiB2\:Uh%_֛wE~~!O*G.O۽/(c yP̗?Zdu>KS꿭6c ;BT)%_֏2\:Ui{_Qt?r蒰l+EM{B?hкI+{uFݴG>M+?h/*n;B?h㽏/(c ;B?hsb5={.d;Nsz5rI:9<aMđb?hO[?aN;B?hO[?aN;B?hO[?aN;B?hO[?aN;B?hO[?aN;B?hO[?aN;B?hS{ji2[eMk/''Hb{R8ʖ3S?h/(V#FbGS?h/(V#FbGS?h/(V#FbGS?h/(V#FbGS?h/(V#FbGS?h/(V#FbGS?h/(?W5o?4jߖ!58c ;B?5o?4jߖ!58c ;B?5o?F#X##{_QiYw^p\n=sUR?޿kYO:,\Y%qz6xk:^ک&p^8l:K:m9-nJFe$f[%{ PB{jQDƪ!Rp:ti,͓3Ԅq29&P<DH;OP|Et2Ld+w|?>lu7-HeE#S\jX31Ry"fMX'6I?]CO."bT5AT="G,X{KxOvOQ[LQ 0UP?EUm@hf 3|m3='>fdHw||?4ML@Rx]kw6ƭ#,aw,=óְfqt˒ p8ǪE.i$K!ʎxIjwwVZtKc[C@%lmc’WFUQR'C棏[YvdFbARF8vRNL9p* ӶPe]6OAN`IOh[ne* W$e tz⡂G.amO?_u^9i4f%6Iy$!ӯeݸp6:Zis4a`c)zZR$K)%>A5j1 0%0ʑABG\C-w uL}$gAv;Kg-b)*MN[ c b;u~ʖzmO1G1a`;YO yҫ:c &h;M0deHB*H cOUfbsHD1˓T+ ƛ ٕxPCSAhdfY ѯI(9AO L17 p<>Bۣ[n܈^xM^X!W|$W5K{sM H&X# ϿZ״w2E3P1z>?01J?~#΃ č -Rzuwv#`YJqT{EnY];\mmv32IS"O<y4If蘆<=~WV-~t5S[HS޺m^;LyF PX]raBl^'cK8)8eKFIW ЯF#1{{mr"Br<8L4(Nc =Bb" *8%E{h&uM7Z]r8,ZQpG H$&(3#]$w-rr\Gh#^xcIdo >=3?QCcUŧ7hŧ7j ]>?QCcUŧ7hŧ7h-wGqW  Cc>?U_?QCcUŧ7hŧ7h-wGqW  Cc>?U_?QCcUŧ7hŧ7h-wThK)( oqhȌwdAuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image040.jpg0000644000175000017500000005070611665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;y"M!Q1AT"2SUaq45Rsu#3Bbr$Ct7Ec(!1AQaqѱ( ? ܜ f9ì{C;CI-m RZiN#oڇV:'U^83v:=wW^-͏T[G#ֆܸpc:JScgyZ(咬8UK"z{O{!6:=w` 689&d3GI+dwDK-jL lt{ )d3?0cgyM{!hvE]!g>vfXq=JO'w=Ɂd3G= ;ɰ9ƩScgy_[j@QT=포tٱd3G (ڨnb9{pr `HScgyQhki_G.MfqR$tGC;8|@Ha)d3G= %iX*3`xp)cgyM{!geM01d3G&ܘScgyY{eL lt{ )d3ɲ&6:=wVv^{C;lt{ +;/rlɁ{!6:=w6^GC;ܛ/r`ccgyM{!geM01d3G&ܘScgyY{eL lt{ )d3ɲ&6:=wVv^{C;g@H8+5іT8d#rgxMAS 269A]ވ ߿z蘈=4j3hYhj65x,s 4K¥ttŝέ6>}MʑL8nѣ$p31˷M3xtq-=4j!M.szÏv\6{d^/n{c{F:IWPY}C?u_d=H4]Rqb4-SɔkQhntH2vN_O)Z/*!Ư7v#涔Cm+ $RgDf]Gnt7iv)-qTlpιۓ$dzw`Ge?Aߟ5oUU 5q@gdIoK+}3gKK[Y"w5]zpw-7W2[Vzkh,9Kd.Ig2ȝO]5awKC@H([_bS:mgj[Iݒ !{--=\ ķTg#~J_=XRI₢BXDxƦcKLR[\[[Zǽj9yiIheC}< ]Q~{:5ϖ98$, l|TqpR<^IE%=LHXTL4 s0Q';@1:y^qY_04Mld~iv#5{ǞCdZ QQ3λ*g!!X-=viHGI3tٛckrր0߇eNJr58>䉪Iϟ6h+"xQ\'fsy=xshC=|^ĴEÃj;l!y~)KFO6˵hlm|SW%]34atg(q#xot!EQse} ݌tfo7+3Z xÉ+hnA~XIs-뤆WÒP;TcQߎ YW=3TPmgy持55rZRF cqLSO#sPGKfmT76G5o8}hu{XʷltXGN;ǽz &FIHem@[nqbW399m9mK|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n,K|NFx+N[n,N[n1J+!\\=]3bi4ѫL꩗KUY -2,l1W``:wn\(^G#j5^tB,r!tRYh+=eZx"ӪuD=3=Ztk/6d!ůO!:)%#B/~ .MM\-JpU5[ lL3Dwa݆S#XRDwa݆Rֹj`FG4F׼4K݆Njv<KD9`wak\[wK݆Njv<KD9`waU50vd[Dwa݆R.DNjv<9`-Dwa݆R.DNjv<9`,I s^89dr \n0xsU ZÜ4 hI8.D^jv<9`(FA+)r"sU V)h"'5[ n0x9ks} YK݆Njv<KX.hxap#!G.D^jv<9`-Dwa݆Rg5\pEwa݆R.DNjv<9`%kXgiK݆Njv<KD9`wa^##.jv<9`-`I W"/5[ n0xG23g w<0d7;%ȍV'5[ \n0xsU Z%ȉV'5[ isCw\n0xmVaCO R}!K痰i0EVax%~5Ez=ڠoGLE45t裡 q\4۫h6W,lWZ̜j~ &I g L"Pc߂U#f)AtͶt iՐ֤TXlQGKQm-8gíI!Z([$-5ψJ縷XjU/zbpR5Nr = cAIX-sH-gPS㢂M<-1s[4tIG}-R5E+Xn~ UmrOky]cΨ'#.=ne9$oq'$k5Tb$h֜A[Ur4@!$Yypv|4۳6t1H[u;ǣyQguơxYܠ3DkeK<;3Lg9*GPJK|!LY.3H3Z`;vv㬺ti첛\s[v>_4uGIL7 }%Ӳ2N͹įp-A Ny˛ y!㓭;Ek΢9hh*#/dFz-q.Wb@ dQŘ kZkYIA 5δr7[sUԲzaIIX6F]FJ.T,My,@Z .#q]c\xexI'߸w(3falHI{zs+0J4533Dǵߝڿܶr5z26B#]!qq漜tQָQ--T s_4cú}qMh9Ʈcv 띤i Ͳ3:InCK5g-f[leе͌Gp@k]%BZi(!奭q=ܝ([um3T: a(kw3>oz Ue6C$L o8V6;U`h(k̍oCIEr&X$k y7v}!VSYo(akZw1>vKeUurR6:X 9ݬWYe̈sO+lV |QȞ4tSKc95MTRZF>M$43I!j޴ Se-;\@ c\@Zec *i"2?]>Y'}84 .;5d'iҢ=$HȦSSF ڶG p@: 7}"WRiEΫ{]!6Ltyj[6&g[2S2'jtZ=/drq'/n;\}m=C(%'#S*-< 4j_[gWUt&l44l$>=]k:=f5b`۴$1< ,6kgTF$h-Vǖt޹k uDʭR>fa8kхi; dld3Y8 y%ۉ@]h cI(L~1hC% (m,!vzVi-VIG:ꎀz{fSsCHsUE5$"OYoKQ- jm-;|w$ߝߞ}%c_n. Kw'#}U}^uTtQAtZϔzY< G[&P imoVB-4-qol†*u L!ǤEqtm-V"BIZ<ސJVii@Ʊ9~JZI zYbט] -ՌUpRGQG,k枍$rWW-+Fdr%y/w~r%ŶWI5CBUk÷jy]tE$Pа-ZzG|RYmt k)(!h[c?& שa5&-d`;pvKӜz%U}}_UWNj3,Ʃߟ;+얪A Ꙃو: +dSSOE 23F R19MhI 9[CG8#-Y{|?"_>O K".>Pils7HY1Xp+SPK*#I}CNڝXw:kPF͕<+ ->OϪ}S..ȿ ^+".6]-U["h-/a{F\HOB< \տI&U5NmtTh''<[#1ĝ[42SUUKP!{CNOEF.s\wIk3WiqlwF])RRG^ȝK5y=gƒEQA#}DLv,ncI>qs\K~ ջI-l{&9w,RIz(*u<9`Qa# \=IKn͒ ctm \[ݔ* 2SBK C'/s 3#KquXSftyz9z@Ax~*SA$ 4ZN8K}=TUAll Mc1HҺX$}SL3lf6>'c;GT+L#O%<eDmiِqu*ye˄46hӻY'vxivѲ ^Q`:F9:0\oAc2h#@t o,KW5ԗjZ4\p99B))7,<ۍGvEjY\5%]$hvWt?q>nrm&䍖5ƫ9"Һ)> wT:`;R]ˍW'1mj$fq˴MVDŻ⨱EYQ~Hg 38=l߿ TG$PW!1pJE%ٲ:rfQW45G2)cJ՚ŻA*(DZCⰲH|PyT|?"2,L҉lԌ`ՓW[TqЫlLGOq@\gҊF*kꪫf/kΥ-VLY_M|"tAAgGRyGkefzM} OW'2 rѱd^M5`g׻\ hx`lOJ٘ZZAa=>h9V zY&ht22B kNw4n^Q{YO(~,b5Fek"lrPiĬn I㞥DOI5?-s $DH_(~,v^TrYU:J53f`kzSm}EK{`cF7 K_v^S;_w)Fm#]$sFAԲcf<:ZfBd k=JGv^S;_w)c[lOuE=EiJA#Wpnz<;DASqZ(I~|qMyGke,EnvT 뫪5/&kQ8[.E PUPT03jgenyGke,@DQTn }k,{$tdk.G :zh.NeNya1=NT(~,v^RĈ;+651¬F,7\32wx)~Q{YO(~,Ԕ` mf2]0:jac sӜ`Q{YO(~,͑]LMMP7[|hjmUM aeC` 07;sJyGke.Ɖtb*R7`,hSZ࢒i$e9hX;w wv^S;_w)x_ws}]=N)l#9ϘGI½Z9!OϪ}S/Dpˤ2/SQ}P,LutW\ #uYTip:!;-@p-]r:A-.[fjjnޫѷRU M#a9/1|E/E=RG):,2Le8blfWB&a [>O3I] ' )K]5:s#%|)N z?5f+yS4%TTBf;88!nH-MJض4@AӼsܭ%HD7PVj g+UMJ%GTֲVQ%t~;] 8$]enF--U4)&ۮT+ֵ6B1Hڲ`pL"\ `pD@08&D  `pD@08&D  `pD@08&D  `pD@08&D  `pD@iSUs}!V5?wJo>*VaUXEt?E\ c۪5=-p*ȿ ^3M`5r*{YTܜN ZQ*U''*{JIʤnRporr87iDTܜN ZQ*U''*{JIʤnRporr87iDTܜN ZQ*U''*{JIʤnRporr87iDTܜN ZQ*U''*{JIʤnRporr87iDTܜN ZQ*>U''*{VnRporr87iDTܜN ZQ*U''*{JIʤnRporr87iDTܜN ZQ*U''*{JsKHn񎅭,{|?"_>O.ȿ ^+".z-""" """ """ """ """ """ """ """ """ """ """ """ ""}!XYo>(:Ain_u籠FwV*y`tytQ8ӹhݪa:m(<٘ӳii tŠ,u2[õU<ӫ ;>?*o4H_ZD@:uw;_Em4>c#KCP9팞jŢZ[SsYQOmAp)P[t\%I]%;1H| qpUS 27nG"|QeU=Np1T"Kj-*罂&=v# c$tdefT4},MP6t 菊Q5s6 W!eTO-su7r&\c -ԱUӶ)loՌ/ݿmYyL!}C|Cs8z%26@|tv;#޴ݩ|c tT51W~WQ3Ghv,ydr=KA5Q%$E Ż k D7WYui%FwTk}J;EeRP7 WԶy\:1ْ rDuhԺULkdN#3J3nOcǣJ~ښ!"Yfnlp9`2vW[)_Y]%2D5H?e/YLVZ mt<XwZ 9M$̒Ia8|ͧyp0NNô)Qb\H'IŽגmeMvsÈ8zrn˟?ql5ő.߿=ItWD&2is -Û=9[[Vg6gZ^^\ֽ:gJ,NFzG,otO0 SKu_sGjq<bG%xX+pAd*Ӹa?ʱP]ld/⩯;AuQ^`t3핡D絍=z?qQ.ȈvNasA-5 O$-㓸;iE_ 8tq!'ZmJi[,p2spzWlUi0 L6b'ӼH\FGEcmdW_ì:ONW.ݮ4Ϊ5k;N[Eki Cu.kt{ i=5Mޚ:%2ywQΊjldx#vnEdFk)O@nv.r*g3C1}nZ(d `>6ǬԷ< -aeVaUXE8eXp+$d1IƌIcd_壞}sկRucG>65sy tQvQl,sZWm'zMkxӞ}mzjfXٮ2py6F+Dm~pH)}kxӞ}EpUKPGE0QϿ[R7 fɚS6zX_oƜk5d$7:ai1(=_lW/sZ߆18=@_oƜkxոcK0koIϻil:QT-fdt%zޢ[dP[D-y2x=G_oƜkxՔo'[d4 1tu55VZdRAAVƐ \@Xdt=Z|5QvGJuѰVxo•9-41k|I+]klWsկNzOϪ}S/Dpˤ2/SQ}P,LutW\ UuU]lfjFI]h*Ƃʘ`a8~ZHz@VNշz!gY!eB@Kpw&^-_e,(@${v㦞E4<:%Dn/.\[zO\K@Rܮ Ej]c:S/nNpz%UUZn}y=IpSݑVT4+d&0Z]./nXggTTQnm:7}p.i<_hG!e:mhkuI9n7n?k./nL2[]d Ece&:T]Rh-1m #8- 2(ې[t:ə a۸C ҦsuKbdjTmcvFmwj4nHu[yǟ9Ů%ۜ7'%5GSQI6c Fltwzyγ*QnEnV6Z U9͑$n[ ɵ5bƆtT7]wOY]N_ޙwzV(uVPkyņ&2199x#U-;{nS2I%fɍύk `q]z\)w<WwvZ$ct-y7t:Gc)(*/TU570ccwIcIZ2i4>>[}sl"1, FrCG ncV+u4H^FوoNYw8 8>gWmdtrԗٍ]OB{jk娤6)&d.x3*Sc哌`yT|?" K".>gȿ [WRC =qP:[l1ie+6&DDlk2 /uƥ[Ƴ ~ࣲV$J̞}rY+pڃj O)zxJvGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg)vGg))ĘHPZIVLmnT9E62KH|Vf8jPBH|V=}Uo/U[^Icd_U~\gDPDZD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Yo>+ ->OϪ}S..ȿ ^+".z-OxWE&{ PSTYI6`("""dѽnHNFGJD" """ """ """ """ ""DZD@DDD@DDD@DDD@DDD@DDCⰲH|PyT|?"2,L㵋`L<Ɗ#0:=Iݶq/vzsRmh kF |VM#˜}9+e Jț[cIËs_O[O;`0c=p㎌tctrYU[};WJq _U6J%mrKFCo{r͹Zj[J!8w_;ѻ6یH& uhnvAA]PX-VGSR@HqP<+}-E#Fi; XWgePK$l6@K7*Uq:_OW_,D5˝tкGJ+ hT|YtuPsӒtJuךiuZhՍN 8IY$^ܚXˏ߁=먨c3t#OF> c 3ęZ0zIjGR99|RS[̂#?8߮p}Xd"ykkisE8,PJMjQ݌˳[n%WP3VAq M;y>77Z,FH߮N:T=pqXNL_=*btՖCⰲH|V>OϪ}S..ȿ ^+".xZ ޸-#(SSE[pp=._{Z;wZ+#u8gp6 :8㆝:6(mUYVښ₈J3 j_'J.>AUjS syttȹUu Zk6˵-ў;k[luvcg;&lg+CEMkM~R $.` sInp:R[k MrY$!i25wIT*eܪdypv,RYRJCZ1VO.wJikmV1E1suFWI.6xb4tO XaY Z:a8:D\M3Ƴ4n&-|w-ieU<"klmIp7!2*mҶԕpӸ')~ZN0쁃V -aeVaUXE8eXp+Ecd_W%㍡8n$]/YWUu5Ytlzq޳[b7Y(qqWT:'T(4R*-\50"/1;?Ri,Tr3]Q4ymō?4vT1ԗiPL/.>bE(SǢϫ,IoX~ܜjδu\qoW(],rP͜lU׵-x_EIyAca3ZޑcE*SC9ݪzDDZD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Yo>+ ->OϪ}S..ȿ ^+".z-""" """ """ """ """ """ """ "*鴆O3C:c O2_?,}~-UOܷr<n[g_?,}~?U~S-ܳO)ۖY DU~S-ܳR)/+%LkC3\q(&"c2=ge'wr_[)=[e'wr_[)=[e'wr_[)=[e'wr_[)=[e'wrCb5![vOCoU[KVaxIcd_U~\gDPHT3ۻ% Xstro>*_µo>(ڻ|>$WoĥrZnrZn zem14үxH!{|?"_>O.j-T42UG%Ǵ`?QXt"zg9W{9ʻؕ56AoL*bT|'9W{y&-]J*bT|/3D3QX]Jh sw*>kQXdr%Gbsw*>klޙUĨNr%Gb4M[9ʻؕ5UĨ^f zg9W{9ʻؕ56AoL*bT|'9W{y&-]J*bT|/3D3QX]Jh ʻؕ5UĨ^fKzg9W{9ʻؕ56AoL*bT|'9W{y&-]J*bT|/3D3QX]Jh sw*>kQXdr%Gbsw*>klޙUĨNr%Gb4M[9ʻؕ5UĨ^f zg9W{9ʻؕ56AoL*bT|'9W{y&-]J*bT|/3D3QX]Jh sw*>kQXdr%Gbȹ2T/2E6AnH`n3󸰐Hˁpuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image044.jpg0000644000175000017500000004167311665471332026772 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"P  !1Qa"ARTU245Sqt#bsu3Br$%6CdDc'!1AaQq( ?^.W6py;4 r%>5USF9jjkgT[@1鮕8J<8~5<-:\vQEN{4L[ZЕQ5Jy+Spl5ٌ$'5>>(vENl[u]٭y-G-dFI[յ+T؈{J'yG'}힋nw{b$"C1@ZBϷll7cФg4Q~De힋nB\;/< 묥!HIN=աmfZs!/֮ZwCz-t;gۮi_c-\KCP\s՚6@io8ozQQ)wCz-t;gۭ7{Ţq'P@^<轫"bB$2w)pWl[tvER%l:2#rY/Hf(u 8ۨ #<sM5t;gۧCz-nqT]jQP<;vI d7ymB5.Dfm@x*jn鳡=:mK!5+yCiW"NkVb)lÁ I9?®;gۧCz-mH]!,14INQ)иwtNpI'?XM'zmӡ=B[vɷxqC8ZaIVRH ÍLB[MD6#ndCz-t;gۮmp;p#Aq%ihxxVmt]̗T s #Tl[tvEQQ=h@IJ-m}m[!xCt;gۧCz-臲RCt;gۧCz-臲RCt;gۧCz-臲RCt;gۧCz-臲R 힋ngtCK힋nz!D= 힋ngtCK힋nz!D= 힋ngtCK힋nz!D= 힋ngtCKCt;g۬f5ne 2MNtSPw5R5YRRH8Fk,έWOҟ&3/ (svi^qqr?SJURZO*q$ySr.qBHy($g^k̹Q қk*Q<¥+]<~_x|1-{)U{Mʝh֧5ZZ/jNu$J{7>^Զ6u{>O$k_ڏzf/VKlqwvã[N`HF<9rYcGKmaNT+žְJÍ- 6[Wn= arR-͇}q]-"3nҚNBȞ#M>=1._4Qn)L1gxw\ƕ重tlT@Z*V\د p5.W)KUhz >Tr9:c.<~?7.BTR Ƶ '(-l+쨫L,xKA8* 'LXarJw!qꠑV[;h\v VE* h;g%DK[FAm/ <G3N[iQwKe3 wd8ڝ&J'O^&VhSZp pG9J+ho ؃ v^i8>$";+!ӝc9[2u[̬\29 JۣA+q,% uimXQP@f1]F3:+]SS{XUM6R0XT/[Ag@m)^ys6upɐr0iViCORjڻMCtkuPN3jŒ0*^m,-\ oJ4!EN%JWS%GD*uz^MV\Ch㑩95p[v6 a^ 8cUF`>D-8[CONJG#SE aj)г9?u*xUp.OP #%8 ~Nq#<+= V҈#K{[ݺ=A'vRMbdnBYQS.VxnDY\tj.G9xU`Z)U'\ȂN1Jf(}D6G(Y[o73im)KQ )!p#$?Jutp4* 2 Oa+])@BrNr$xYDž;Js,4^eii9$jIU-2RŸio:ަV''STq"3-OhejRӁ?Eȕx]i%j p u4.4ӷҰn5xsbۘw#M8 Oi՜:6HkgTF~IljS4isWhetlTۭ!V˃(q%*P?JvL@6# q?vsWM@D1(Fpq)™K&JH:Qs?ƣߝ*.vm*PQ@Ӄ kˍ$%#ANxcH8س=d!qP0>d4C=x2Qf)Ho$:!C$`_&4ŝ6xIZTVR<3c cv*ݥ) C<'U/Vex 'qR;Spr#e•ZNd(ћ -KC889YfZJ99㚯͛ttEwiu։MVp<ku$\Y܎S%zRӧ $p짿.SGu3JH$8kO#ս0%*uԵrң85^[&p22*-'[{˻ TpǶA/eq eJZuE:R˅JRTd(4AIJRqjG --qNӄj98{1jq>WK )G$U7]em6(^qRcǍo]招]ń2RamA^ i)Xٻk )Ra6 8㺹m/܆!KB-CRR|Gϝ24֥2_l$XIRsiP:Sâ+kk'WyxՈ~pu-)nTA>QrvYz4Y~Ӯ <)d酧,񦠾QBpZR|]wJ%AIP R:Opgru7:Rstg/f܂AJAcA wYhGt<c[h,k?' Qcn(-$`''d)JҮS{nӐp\1ʚAi&RoےԱă]nZ jk 0R[JTF]t9Zd(A HA;V^ tBy!JX`'RtmaDp»cFffGFHkm(}$Jo$5XyisRﴹ+2XZ*tA0AbTX@M \ur1Een 8rB{0kbaCim1J Hl㳺N Z2CP^3yVn[-Gn;#8_ٴRRcnvʶzSsUWjF!=l9+2}2I_kVhJ]@ZBU‰)ܑjq [R#V%:`c'h:ԋ=-*BXH1XnvʶzVu -mm%J:}Ը Y[TjR@G$c8g8ma#_Íh#5!=\-Y쭛򭞺ԸNƎsq--*Իe\aS))AsUW򭞺nB"D6B*KG"s_Qmۈ:R1>hf2 4<\򭞺lp7Ł <}_tF~V6K},Eo)PQMyV]^nvʶzRoz);;۟췍nÞ_u}Q:QY Nk#<\򭞺l,&q#3䥤{p+ L3D60_ݍx:lh $ oN-)֒O$`;w=26(tBu-x8qƾʟfhpp'JS(%G\WF;Urur+)qxGVꏶ%yl0ӭA# >:m\u:R7V<8㊏ݲ<6Et-*"%J.uc4KVj-g ׬+<ʘ#9cĿ2 eA.7JA5)U]7c) WG $c O_jF|#|#$Q>u>u:.4ҷD[nc 7'+[d$i,g\q8) 9<X)#ֹxe)Q<~K,9. ,` *j<[a%nEB#ہ1 EN2ݩsYa?LXBF2<}cyY,:xU- 8;"Â%mm.dP : !H6 <>aZy^S-jIN|]Vݺ%#I q!dqۥ˫l2՘،ƊbJyR@ԏ# Xpr;JV2ty\wayTy($/pq#8:x&*"Hp׿z-݋˄%PFGP۵P-LK}Kl:߶}bc\L[ w%IS)JaV 9 xXk՞s @ h9FqNjқs$ /؏,&-L08#RI'sSJaIR-͌\uVML BT)xP2aYZhK: JW Lv@-$˷lmKH=LIe  ><9ՂVhTȅR+S 8Iv}UoJz2.8IJԆ6E@ciGi̋Sz lO!yO넓) VAIZ-IZUf$^$DNXq"Hu*O'r@yW+aq*KwJ.U'lҝ/͞CwT IPVyʹ`QkDvWSUdy5i՝;r՜rXtegGo.ORT6$]ytvUޑ^Aoܯ[T(#Mvuggi5էVtVq˳R1Μjyvȹ pR?jF8c7EvW^p;N:@Go\yvWמV5gOGG-@`#z~uiƮ=8.5%J=fg8q˰^Xt T^z¤AmӰ@s+'jsY}HR7[+VjӌYu|Y5c9GG,])A-ӀuQ8OwrnX=[L-޵ZI ";d 1OjT+1rzЛDG+tn W**8(LIÀ#¾*,پ',t8oPܙi֥t\H:a W^ͦ2më⸣y0t%927p?bAض]L=+T&[Q +'rϏUf~6CfDq#O3q$Vec8礌.3^zX՝;rN9vpB-ӴUc=xH.O}6qtPop=h3ˣڞnXED.D%G )PV9s˺*8H8;㺃B< hGYR)BeJ t#Oy (1Џ!?š'VTB< hGYR*jRnB@gjM?t<ﴹ)xw\ƕWKYH~eTubo?2gG.)1i!/J)* {s50v|t[Sc \1g<3B)MRJsv @`Ea9pV$!@Σ nlFEb$8Sn g{G45YHR"Srd8W ?5nܰ)I:;?q-+6!řHJ2RA>}}EδX:d-=Z`'cxoOHAQ:۔':+JX9ؑ5n60ȏǒR N4H#͒ nW1Yaa샟/'GkEF?:~R-%>Wa?Y4-zujBڻA,pBtc)sďǴFpß?s;R{P~=(:4cO\<T(8zx{:||jVE#N19`+# H҃aIq9C=ZleS%!2eX'iSbo[b8򌂤n ?`djChrbP)TPǏU[ItVZRџF\W!ǎlj;i%C VtHe:-KҒL HVy消UL2It jJ;q]H{b%ƌ ʐ0I-tA[6e OH\tap8'*tD{*J&L D<άu?i٭δ BIWb*Mȴ] }+Cn:]$B4(q>xðD%uc95(1s#cͅѯī]':ݹ&Zd. zt R0iSӶ[[kRc-k`<7 Ξ/Tl6p6q*BeĝG>)@)@)@)@)@)@)@%^mHu\[/'Riλkϣl)v3ˎ8vzC/jG?cQz]$^mqVBJ%8r|~*ݥ-qiEϫ7mVG\믰uԐ|_IpJtȷc:I}98B?e_luS/NG1BN}eFC%NH9b}Mju3sRZa*Br7I8j{cpwt WǗ XƕltȈoJ ImR0.nߓX8ÐS)P)JP)JP)JP)JP)JP)JP)JP*jn5M&|j S4isW],-g[#ygUQ?0lNl#㩤G\;. cV{Ε='Ε=':Vx XoM{3aO}7Ε=':Vx XoM{3aO}7Ε=':Vx XoM{3aO}7Ε=', kaO}7Ε=':Vx XoM{3aO}7Ε=':Vx XoM{3aO}7Ε=':گS6Ԭ*x櫧7}iKS4D2ַZ*zl-g[=[R((((((((((((((((((((((((}$Jo$5XyisRﴹ+2XZ*zl-g[=\urJRRRRRRRRRRRR)@)@)@)@)@)@)@)@)@)@)@)@)@#RU}$#=NKҗ}i]uSck?ة㫖R;Qb)ز.m6*4x8_;VO;VPMR~lZk>lZk*UfUfMR~lZk>lZk*UfUfMRm׫ez-[Y 8QYʑ lyPaJ5SjJ5SjJ5SjVΎѪUQjG{Ao$5HkIum>4j>HkgUG>z?1/=NKһ+buSW-*)J)J)J)J)J)J)J)J)J)J)J)JFmW…mԕE9?{RDI{ :KHk])CgI{ R .5u%LC4O}e!.pBQ;еJ!{+KKHwX+%x +QC<$vvRI{ :KHk])CgI{ }^!T(TQjsjkQR'$U\]$%<T͑I&?us{ ^vMJ?ƾR[h}]Va:.M-M%4 V. +qQC:V[Ռ+G=vkϑ}X$_4SD}ȮX5.y=aD}|?Og1N;5}?m}Xz$_4SD}ȮX5.y=aD}|?OfH5#tHiاN#QiLWRK,J\ݲ3aٍ$'9i 4y9-6I%yJm>zO6=o_Bߨ)k[+H9?>󞞜_Bߨ)k[+Q9iՌtcwnZAM_Bߨ(8~ڸף.u [krз nZAA4Ciܵ-PPEXjDۣ̬-[$5H)OJS?c}iKS4oqYL\ܷPS8뿬l1ʕβG)SEy) zgYO#)"Δ3luB?^gJlޙSE:ȯ36AoL)"e?ЏdWқ uB?NG+M[:ȧYO#t-e?ЏdSl:SdβG)SEy) zgYO#)"Δ3luB?^gJlޙSE:ȯ36AoL)"e?ЏdWқ uB?NG+M[:ȧYO#t-e?ЏdSl:SdβG)SEy) zgYO#)"Δ3luB?^gJlҽB?NG+]B[:ȧYO#t-e?ЏdSl:SdβG)SEy) zgYO#)"Δ3luB?^gJlޙSEsrpK Sm-Nʼ;.9+uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image030.jpg0000644000175000017500000011137411665471332026761 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;lj"V !1"AQT4RSar2q#35sBCUV$6btu%&EFc*!A1aQq"( ?Ҙd9\ʟ EWPm92 xUTI|KK!QJ5I!֦ixv|=N4tU qrk0 4RP6>^Ubq%#-2[QBCe!ɾ[rR4;^iךG+>κg`n'% ~mPUkfkn|! .*ގBBG0O#cPj8v|=N4tU̬.+i2ZKv[q ב֮0%HÙ- 2=~~4v;^iQuN8ӂg#n^/MrI%pĝ!U%Z#=`{0+ךG+5σCDwr[͔ .CI8$)oR˪u $+=k#ݧϚG+8##g_YuݨH$ׄct^2]-ʢ Móp{1a&Du%@e Yj}.˕%X%mHAQ\FUhse>|3v`Ǜ\ixiϚG+ 1!š^wwb^*㘂t9.0[]/f^\9M]о29`a.ZEVqxkai\v  3ϝ5XNEf67j2L5^Id9Z½-mHW%$ k3FIS~R۠GG7;_\)^f7ޥQc9 ;EE:wV}_0gu[pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;> pQ;>  ՐBB^i+HRnF5X W?`wtA+PFmm!bRƶ%Ò-]&n!6  HOyE\C )@ARG,z\R!{uY#̇C% )H:Wq͛ 6huԔoRHH}"S0:#Bn}iC0!hZb09PAH T 72TDX5cU/pE9Z VHb{*6 F b)B[}l!fF`E:[ZeO.RR; |3 -˓.AlP":NId6 jQ]?D TIɒlgm7ͼEQH $cc}d!e.AkU ۮ Aҕ@7ҵN%f O!siU(yr;/'+˖@"ݚWC27&ʖ<7 6nyY6B2-X )PE3Y c{iP}zY VNlq_Qξ+O"il{^io)J9sM 'xOƜ|NKkܵ ?q;~5. Srא("wi ԻM^@'RZ7-y.>'xOƜ|NKkܵ ?q;~5. Srא("wi ԻM^@'RZ7-y.>'xOƜ|NKkܵ ?q;~5. Srא("wi ԻM^@'RZ7-y.>'xOƜ|NKkܵ ?q;~5. Srא("wi ԻM^@'RZ7-y.>'xOƜ|NKkܵ ?q;~5. Srא("Nf%)*n qj!H}swpf8[KAb7c\?ђ䔥(8>~s~^9rϡ T~goͣV%#;. !6Hyi*Xҡ+*f' C i9Amn~-FܷnhE"h" )-=zFߣϞVRcVd5] c[6tStכG*j,bNu܅E԰u+.=W{ofEbM4D['-GC6tSrߛG)G,kxk(s!āqt 扂Gd $ :\J@7]/7nhE,~w+gpm m t* Q!v 8+-v6+dS.Mhɭ#=M^m襌f!3̇^lՅT<ʞ1خBLyXs-RJT+&=M^m襌C,w'wGCN :*u)eJ4&+}O Sym/ʶ[=M~m襌>jac,6TrW]Th2!>iJU5nhE,~rqV[uYd)a](u1V+-`ozh nhE,~v%^RJ^m._=…ӝv̆ڇ) 3($$ \}kooͣ7XÌ+Xb30u$JRpTu(SZ*Ȑc( H\:&3!2a#,0(@*C&3 6\sn8?]@m1%.1Rʕdۢ=]x8.ǂzR$4'R Uv}hX` KmgQ$$(JHݬqdaНo$lА򊃀8eUϒ *)jN¾mlHĔ:nvvV!>&(p)˭|(mXߒ`"47mF1ڙC1ڳ}Vٸ04*k|D$BRBC'vؖ1qh:#΍x ̒ l5 phcI;Ⱥ]Q; tJ~郅C߰[ br==YN&;~9uK}FU;s=!1.' WMJ.q~|wef9`g\J:@viò c~Cz0&m QTlH MbX6.앩q۸dx'nVq6f\|O(QrּCmˍ5N- RkmOVG1~?xfp"3 ?.dJ!7*]{y'ZyBmG^9fCn_vI^ʆ^LbY'b/sݠ$ΞO3ݤiiho 0Z]:  (Xxy Niʯ=ԥ)P)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP+Y+*+Ւb‚&:!n2:qE1C\Kʵ)C{9T@ba4ͶWIq-L%ptu%zZkꙎ;/G3i(3kU)۴ww!9,/VpjEζz/XnHia⸑a084(gGPh8i13!MfKn HU.*[WiX.:GTTpU%yϘwLͭʓ LD}=VU{5g3m+XD~u%%k Q.9>- <6Td[ǂͬt7R^-6!EoN:nɳF?;?a[-i6HH#6]lq55̹"K.6)(ޑrzQ;i3 a $%+2*Ro8TtO)x֕Rl1(!0Wmf^P-7vMݬð*VΔȧp|KMZnXCQx)ь0R !Imԥ97"i"l)QJR R R R R R R R R R R R R R R R R ajS(쮊4Ii8n+2ثWx3v$ss|/ԯ̛< {A!/MSPnkZB~w5`)2cSc8c\-7&Q#^_ķiL2l`7'$Ar/@ !0c6%k ȫzEN7]_R>F/ڔV8Z 9j?9EhX#Up:Ӊr(%*9P ZJVd]#mq㈼ʞ\H"6`'Qb{{eōO;>=oi_&t"f! r0is7BIV]އ>'b8oÌԿa* u9BrazY2٩Mذ"9](AvVk# i| 4ḇaDڛ8CYŢW2`4:xd[ / 7 Ju[:N m6+/lD0ႉji-,!`,RoN,i-+{Nlux+" *ҪwR>*Ҡp;1.fqpeAӑ^cm^ϵ)R]}j@@ eA)$ }a7i3]y}N)%#+-齪4bJ r:7ւmVpQpϖ|U-IӍG6U8ZVdOGQBvcHaAb( W.6TIJ¥.6>ಶoQ/-uuBW?q6|"ֽV ơh-! l.JB_aѿ*Y %l);+$e!!Vݹt"[;9ƧJI ³܄VRV2/kR*@Y䛋{-ݎm.BGP.+GS\;&xQ-gEzr-hL؉){̇ɽT(kBm@8<(+Ki)@0͒ ~ʼn`j7koxUf/f+h, J %M,!E& 3 Kبߌxf@SgaQaxq ›^ֽZijP0k|u:}u!tt< -JJR%*)?A@ܽF8+ av7D4z@O3ʭ?*pnY@ix3uFUoF ?򯿔?{Wʧ18{!堸q(uM6̡{]k[M)jBAT@o6򯿔G{WʬJȸ_R-!H)RO"5OzWʾQa]M_*J+GJ)k$e^͈cbc%瓼!\ _S\(=P]M_*~Pa}WxqrWVaomE|3_*&$Q J$齹.U҅)*Ԝ/WaWq>D0ӉVd ߮ĆIP$#*t[_KA?_*?_*[7lBo1|ћɸ/ y+O ?*#LC H'_et. ܐ4=SayL,$%A7P&ОeHغԔmu(9) 5>јM0`TBknTF')j`D)AY?HiФ)’Sk( F5|N,#,!K$e$+CVӘ\EN2?1:arq(!`0JUt8_q#CME!DPlFS)%C8C^W¤{}ޣ^Ax=3\WP+7?WMsFj %NK(ZwK6#C^-vuB}+W[Y~K =N'@\e\X-3hUqaAj^\-Ehgn Aֺ-YcU}~1B.;>A}u1x5SaJB$gob}8W)er`nRHH]l,z+1![LBj.2jñHmcvl, #ng H=..9*oCm9TMG6Ϸ"\|(:}5h!'RRH6;[dgn/(v[ SX`rrt`mv[[xY!K&ڻ6*; .~JoԊu}%:RE881WV쇲pѵ!YEaC¹mf>֡mN{2sn/q%K@Qz #^fl_Ū$a |Pj ePEʮhRАHT)RKg 7wĩ+HRHP<7E+_?zxޡ+a\5`m6wR>*ҪwR>*Ҡp216P=l$Lg "4i3"Kl- SIۭ@V8X0%-J.lmQm8 1piKk2w#N&5'bF#NK't@ 9Uc-!nelmHOtW֯#mU!IymĸW_>]W[;mSu+ BMt`ojm<5yeKJp)1Uku|9fI3"8a1!C1 GuE  8˦XZVM ߤ妵{#idMz á%?Jģ!5+D\ku#RQt:V.&%9sb"%[{N%06Nv ]N@:2\b%8ʲe)Er^8RdE>, `Tťx3 e2*h)*)'fRxb.Z%=c(I3OAaoKXHIpO8nI*ZHk +č08IyB.@Pt=uܽ)[8<2⃹3!eZ{\97 wL;#yVxgMOHkn/lY*\uFYmu¶8'&#ql'xJHNfLGϻD[9IhZ)5VMs\; ZЙha q'{̪Ξ{}6g#<I_2l9r GNڷvF+žV͒0mN+bA׳fT5*uA,[Xp( MmҮ0VtBC 4PB7Omz+m/dTV%(+G=͚WI ^ ib}2BVʺAV^2#d L% Kz9M@ @/IZNMl!9rt6^dž/@uԻ!") ͨ:dp9 >qn`~*Qr+Q;CvN ى+[`;%6Jm(͒V@IR_m0a108PXS")Q9fs%bжEcȗDK(L/)k BW-Äҭ델.+J$Mqnĝ~j6*K.rStPT{QP1j<xy)d( H9H9z 3e-ŲSn\ lc)1XeKPR䱺؞cmK\!)!Ksx#'mʠFٕ,`֊ۼ3ZWW;kHbU86Lb(u*f:BmųbB[[92ga.8b=MH H(IS- *tVI$iciq||r MzV!IHilU3kTIUGT$Y@I]O1 @*$GQfLuV5$) I-Vڙd' \Ap7?UHץF%B3*vVR)* n4Cϥ鍼cC1BQv('SVa8e%LiKĔ]! 26#޵,q&QX'z., \kڨ >Z^e%љ^fMw4ΝJCͥ)qԻ`ү0"f [ԬIH]ODU4&(N.KQܻ*.)2q{hMM;\4FPeKKnDWԬ佫z'‹(ZeJ@S"Wƶ!ph9#2@F7:jRM-%p-DK'-YɄZSȻVFae^BUZJVnv?' Ƨo"" $UrX^CqᬰaSFR"Ɗxt4o֠Űs<2l)3!];fPq*[k\hiM I mVKŴ)N"KqK!δ ּE-ICѡ:$B8:줄h`FFČ'[Y-C{::uZl5l38ԁ^Ifn6Ho<-TT@ ϟ*r,8%%R;N@ YG)#;1T0)$E,:ZWs9o( ZRrFIBnGRRJrf6>GÞd,gǒ'IR U` fHM+ImƑ![-4.Ts#T9ol19.E2c@$Z螐MI1xG`V)LrA js_O+^.ʦw "CPBA^`8b&HśŶ̆!!@76+hqlO n̠S^Ҷ*vg8f fK6ZkRny D@jR͈xޡ+a\5{?~x9Ɛ6;_iU{;_iPr?Ǔ!ol n7?mWL0wj#-PJД{oTrcck$q1a!iɾ]+EyGD$}JsNUh5oa(@D MJk]ݕÂiLVq>KBntG]eq8ŏτIPRfC>n4Ǣj"FD2]fk" dPJ]E֭g~u S;GKoV@=GMDabDl/p/Uls=H$4(HsתQHR{uƓ%0T.]}U+8{#9Jo|r-֭흃>pI!!Ko-=v^,آ;̲ۨC-8.JB+P~KgeM8z\r4)3^ViM߭iƛZFvh o>JRH3q!.a-8e\Xf0$lAexe ۠-snwvzF i q,7%* zD+U-doGSwJTԒK#+/.;ہH.E.avm !1 w$<ۏc 0d2hCJ GnP@6g5mO-L<)ń^RR{2[A7!'?mq<_"KmՂZk=2r*ceRVV ]",wek&zR+(H%iPg8M?JVĜ@NDq^C;r:D59н6B47}— e^a[4$/mzVRVLB/9LPRTBÅ$u-_:VvJ;鈘dE1ԑmf6\̽mo! 69*?Pm؊Z"v$e[Pۊ)6A_*dsfb2$Tdˈe%KRmF/ӄp8׿zHQV`Q\ڒ>RVڡA-E$NehȖy5%YJP*θׅ8Q99Nk ,ZM YԼ5v+t{X;1>ӯRK*[A'D' z+.}3"'"+m-szC>M?Oy-b}&% eWCf]ͭ{a{7 =hSD @ʫhe|+FAyA;*;.Wxi!6/YB^,kLYYCIZP4"U\$RSğ N-(:(ٯbEij}'ix\)N$$$8I+H*\~-JR: ) 2:dX's=8um)l PBK 5LjIFn3=9.Yc*ˢ:M%bщb4j)/(Sl)UY"]D1ݘ-*&b8RS+qY⸤XO8i&DQ[n%N۵}/+R p|)N/̶!(p =Sj Nu6sN|_"JBgL-ʋC7bBU\܂ E]lܻa-sԯ!ɓ5/kiHSiM>[#v˥^ڟ?' Pb SXRWK7).iJ*͘I+TwKQU&YXQ-D(D&)MPFaJ^##ER ,y6 ZѤ2lIvF`mlFwJ vvj2_[C㗉ikS4bF(.SQA0ӥ!TJRok}u8v^x9%/!CjHԬ}U,] ZaOnNs9]Dޭ)AKfṙQ!R^S^\1xCl˥ t 0[҂ݜßW4({:WX N&Ps:eYRlP1 I/9I(I6z*v6kpKI-_U(*ټ:DVc.eaD8B. AWl&zV w]Jtnʷ,TsLy]4.lӡ7dp6 M\򥥵vRNks՝((x( rAηRf5 x*}KSҋ*sy*OUοiS@Ò"j@CKTT=V#J6JT̹<ېCf7!G\^k#M&11M HM렺NBF"WKxV^}i/fLn;%;!n4ۥ-*:eVLk+ژ'*Xl9r^m~B3$^c"5Ĺr來ЄϺT)"ɹuT  y4\(%*ROh5OV1NSjc_E)<\m J@ OHH[?)QBfd-[եRƓ.6d85NC/:g/H"ž a/c8J Չ\ڧ"B$d}Z&(zkوiy/F6"9:EVWm+ژ')V1NUņE>/]VuX4]+ژ')V1NPjiX^ 5s"⸰u#y9kII5"z=srQP06;_iU{;_iP@e%,)"ֿk{O+6a)RU%k7Е-Awwڟ8Yg6$G\.@dT\ۜrBK5*JJ sc5jdlN(w}Z^1"&8m2\2\QPk_bke/Je ̇kr˛7?EAwwڟ8Y63Fx3XBNTuT&aXTօfM~6*ԍ$m6Q$ IRGOβNmdF--ÙSiUc^_ ťâF;KjK) Olܝ:Awwڟ8X6&ĜS C<6T^GAs*^DN,--,ݕ7g9NkX+0Ӵ N=j~twwڟd0˗ USeμHQaoF}e␍9TO;_f(QS v"֐AYN]e;p!)!)sAzUTvq-Y!]$A+PZ?w=j~twwڟd](̐2-JN`UNu cź>rTPWjnIi[)Bz7Q篰TQS?p]6;̂tSkX+)os&wwڟ8YGDHp)aRV)RT\nm(ofD;Iu@%DcR>i(w}ӊ=j~uctI͍Q _ xL+~37$ƴhAIIYiHqGOΜYSTj{w}.8aRQzQ'Mm_"m~7c *ZRM.F[[JDY[?:qGOγ2viES*%mHΫ]:__XE.@ Ev?a5i(w}ӊ=j~u^CY&&r2݅"lP0=E̕+B$ˑ֕#F$u-JȻeV8T8OĿ)OPv%-8H uwwڟgp ;,é2uB8ɓ))in4\ u$le##}?:qGOαq b%-қRVO.JkL=CHe$$ʝbF A"9Uwwڟ8X7ː7uM!I9mco许1*DuRp~iJwwڟ8Xؖ+Мݭ1) :$Yf詟V a%Kو%Cۡ5\QSՉLq CM$lejQx)^d en+sR54<^Zt֒9;+)I"ʦeu8 J0 /5ma7G~_:Vw>jΏ\Zo6[ ܿ4ti?Z^#B3 IbLZ[pK{(4xM)JeMdN)K[8(zs3IPMN Zސ!QS 2G@~{מ7byZqk՜]q-H>V=kt$6+_[^N.Snm 9Nf~mm8HkӎĿxGVRb9$&>s&!(jxD<Npwknѯ:XFVqku+XFVn#>7(v⺰)x3uZn9'OEsq;51*z-~s6PH$_Q_Q3 +f;l~ZCM:%Q%CBMCM:)I/w}]UĿXGVqknSBTXϼQHʼ8-JSa*9@]MvO8G}h9*NͺTUv.T,oo-aOmNuĨg VƠW=¿<_GCWÞjl}UU}UAE>r}Ƒ\$4^P~S%.HҶ:: &:ճkNwy-{[5-*c,3cKG`fZnYOCacBm;K0&b*v51Cm.͑%(R-^oG۹&C)> YU77AmE3J#, Uô,ZŋceCm~ewo"6W L`gJ@ :_v1um&dlrDB|cв@X5whpm6qВf+hᮼ-)m$cxz s7U8!b v\yܦHK >VTgNbڼ1&xu dԏm.2qHPmTR(x9 g&ϘԬN0q 7RU=*(c< !a3Kr y'J;*0hJyEB?8P~^q]yISTnA<Ⱥyge%R3L}'CD,mUVj;VԢc35.ṶRZlƎDi+uRi^iIbg٬۲e쌆w\!ir _=#]siqI0c5S|dJ [U"-X"d vOcގwda2S7J>줜c ;cRkUHByh5W4o֮M)Jeϗ<Čyj\UVvV$-XV>"Չ>6J>3~Waf(ة*95ǣ (J6@)rs_!-l'!Fe VyJ;AjX{,,9PP/ZnCa:ODtDQ2Awho=ekQDۘ nYc#xR.E yս>EU_+LU[Xl(mAp)JuD](y\[,=m iͅ6Jٱ@7 knuFEy*S"{+1-qܥ6@JАuZ UEy*U)b"{)^JoJXȯ%^dWe[Җ*2+WVUEy*U)b"{)^JoJXȯ%^>G1յA+ڦ>bᲦi)O2 U+{AN|AlEw/-нxط"øq?ZqxUQ+LpܘH-);!N$B,{9JBmu :øq?ZqxUXn)7ƚ.DTXS\eDם^R?qx_S"371ڔ`:mD.[?(9Ah0]5W3I 8|>;kbNԬEaj BltIiZ-8Ϻ%El3^m˒שTړ&:KC+dEX(h>2 2鴼I*~-8ϺX̷2!DXZnB.h3앖rDZs_kMŻUN-8Ϻ q]BҸiZFP @|W1yòq,[\g mbVw3[quTi,s%"K^GfnrCŻUN-8Ϻ+=fHo6FK$2KZ.-8Ϻqn}TRū~5?gUm+w3[quTuRl Uk]9vG+_?zxޡ+a\5`m6wR>*ҪwR>*Ҡ7=VçȸAWzZQ"Tvv8[RB.y\}=*ϒ-fPO3(Xwؐe:mZZ˒˜Ò`;!1eaV`TKIyۘw!2r F6Am(LH{:ȊR^E(a>Chq( U1nc,d[9˩JJJHU7Hӕ]R+ cR\Η\q* UJT R R R R R R W?MOPJ_[{ AqA#rޠ*r7CriE 5X hJ)"tߒ/DwqN@ys$l)jPKyk|)U& +s?r7;s+ձAm 7-Iq͔D\E]OIⷭ=%-BDcŇѿA zjų-*RT9ּM'4DrUltMtm9>MP[9]<1O 0>9k5{ej*{A*|uG v.QXj:cܨahjDzJV) 'QWol!+qӑ+QQ)Ogxof%ȭ*vlF yĢ1n%+R㠸z]qAoGvcqSF*[͝I67 j;78'*nɺ޷ӣ81&!#a& SkP(i23π'=.n[*ѕ-$i/].LlHOCy**Q1ۍXQKpHuҠ;30_8F ]P_JZOf\V qّF Q-l-kne+=.+d*iz\tʺ<W|P~fUG İҳ #o5^JNoJ\ _𦻫6Em䡨Q.K,:>/5}U"GM+/5}T6az[;DTVyȸmEƠdniZDTPxz=srQP0@l}UU}UALe2A)4{#?S :;JNGJu\U  ͳd8]fJH de1t59BZ]:*CzgS:#\ HIy&cnEVК܊{rҔ 6^CAV/Şq$njod_Nd67ɵtœ=‘oYĥ(wzA7j9x.;z_d:)JKJAVyĔ*Slo:(=46T5@I'vsjvc/aK 8Rɾee\<'$'9 ]a9+ qe*-9I1sbFyI Rq*$< ) h!r5T{|#y)E&PV,Fr 1sPqIMnu\W}9%*K1Z~TMI<">軠VEgU@*&A͠,$E [|6E $5%ip]A9AWLyoa$m*Ϧ>q TnʭZlT$·=r+֛-'5ny}tMOSSh8ſ^\B_6ſ^\R?[VN=+`IߥjLYHm 7:r m-i qcq}uWf!̑5pgP}PU,ܫ힔ןC!1@6k]X~>ᥧAK ^A@@WoVi+XلLMLBR4 :s:k]ŖV( Yw$s#;sXsaUطQr55xA'OF"~jz)J)J)J)J)J)J)J)J ']WDTPxz=srQP06;_iU{;_iPA?S O@)A iĵy̅5ҹN 譵BnF6޳HMsK9ʛ]wEu^Gurl(O=!(M$r܀yiVE#H'f%M), 4VUn4+&{wVV7MԫfӚE>u2v81hx47:CI$XeUVmlYIb3R!Ilat_*6ʱ;xȓ=h2]A 1䄋X\[7,ȏi1\v;Y&K˗(<\*j 08q"F.+iCINeX,9# DeN,9 $%ZQkk%2oȖ qJm{MEXb!5+s pYKϩa@$V`وQ#+-Ra9ԁnB"CI+TgMeAP\( 5穭&@)@yl–cL>5 *yO;WEfvXYrŊrf̋l[Ya҈kv&YrVZaXruVpefyiL◺':*+?OA%Ck R)6z՞xz[.8nR i6ֺ)(HRS3fbRB`eוH @tI*:ٷo\VS]ZMԿe+I{h)JTWOSSh2My6Iz5D 16jR΀嫝o9%2qYb6M=Z9ii 7z3 l8Kd E:ߪxXACPm,_9ii,3*\- Opp\}g Ÿ"[M+r;֘rcj` :_Y+UiYOa.#0gY& mءAh0]5=D OП/O@)@)@)@)@)@)@)@)AwW^=Q^$ QP0W=¿<VgU#B*gU#B*#}'jS?(9"F#ϥ* 밹pb.$fcM=7Cᒈ (9ՕA@'5*VgqxS)DCs:FlVbG‘RL8w)(=H tkVbѤ> dB1C 1TTJNj zkL̏y,4苛ן 6up4?~i%3wlK7e!i !&u$gEDӂ%$a}5`a8ܽ۳ "sETx5T$(7wN7.fT%%N} >kUꍈovIm*E%k?IO񿢭v# }VH%^K 25a~+K0^NI sfS 5U 1"(݈KsDeI$Z]]&wuc6wh[fax0%n.s$v rDuqerr .cnv#X5Nȼ]ښ/+) F|RjpV"ǕGaJB&#G20.>IRҪ,9f&[OnBPf{o˨W3;'.c̒[d:phrv&"^!E{XB0.6ֳi ᫗bֽRPHV[nGMd܃ yGt8nCamVM=)JROSSh9MVnBlRB VmxL =)9-bϤu_[{ fV1!R .cA!2@qZBOמ_?~}Q\qg)_h)?k 忢[xB35K:* JstJkkZZj⟽$^@s6Ix+*6=Ψ“'eӊoA)s0mYTse[kk߅C9"ptEeM5YEwOL$Ӱ6JPAJGP=w>3#=5-|k55xA'OF"~jz)J)J)J)J)J)J)J)J ']WDTPxz=srQP06;_iU{;_iPA?S O@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)AOSSh!Ƣ7"0u6MR@5Fqm{3$ ',-ZPfxc+c:fӕ-%"2]iAⱏį|c݉_֚+JΡucXbjue4hnOJW4o֮~jz'OFRRRRRRRRO+m~|UQ_{kHE^( s?~+_?zi!VW!V?IڟT R R R R R R R R R R R R R R R ROSSh'sb3JfV@6͕$Tx!Bi z؋ *T?*T?*Ubd6fT…\N4o֮~jz'OFRRRRRRRRO+m~|UQ_{kHE^( s?~+_?zi!VW!V?IڟT R R R R R R R R R R R R R R R R ROSSh8ſ^\ )J a( G@k][K b/y[,l6 m#PQqLNB ʣgR%ˎqIH@:vT6?cq-7Cnk5ÇF@NfWb[,w!ƥ)Xns2꒒+%k(5kkmQLm ξRi9T)#*]kqzT:eb]ejr2ZBH)Cg`F@* )%k-$rʲɷUa; H*!Z\7uf#A=UDC[[xl].r:W^-|kQBRdzy^,q82C$X~45UxA'OF"~jz)J)J)J)J)J)J)J)J ']WDTPxz=srQP06;_iU{;_iPr5!\}.8wBcyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cy{N67MOJ8y4cyQ=!V[p)[l+V:ڛq Z T 0EV~Kl Z҂[g0m-g6UkJ m?`aU(*%w ʤ$G"6n?Qi@h0]5 -)eh!bK !H[*.ƥcyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cyN67MOJ8y4cy2:I( [=Q^A{?~x9ƿCz=sՁd0h:)@Bؽ埼x1! yr N1ø I˨+i\.mm](kؽ埼b~VvN%CR F[   :Tg3$ -YZ'*O"H}b~SYY<6-7a][i诸N:ج=Enx uT~Cl7<@I-&Q4&`c8~&| vzEu*%=F)h)6ꗴD)/I ,3rH:[[P-)T3ոto3$\z-JK H-$}47XNtkCi*ZeF£b~W q1lEc:<ٮ74Á"cl8gP{jA6:[Zn6/yg8ؽ埼V)cHFe!l*t픞}u8 !\eԬ4yD Ph5l^ q{?x+Q5(ZLeK_6b-jr9ėtnIW_P{?x),଄fCRe)iEwQ:u쮑`6W"۰Ql3tz:ҵ(iȽ埼b~UZo~ XeU\m4=0RAxJ])^6l^ q{?x+%/Y]q͒$IPmưWPVP]L):<Ȟ^Pq{?x),˸ nQMʔ$'A=5,|G 5p[n<˧;*6Q l^ TP鑻CeA*s(X۟eF3 Fy,8STZi(jؽ埼b~Vk8)yfYG["4eK%asncOM(ixؽ埼b~Vs¸Go/܌ s:T> %ћ(W Q #4{?x)E,1\!وۭ-) h.:V6޾x1 n Y @$t4\l^ q{?x+&3DJ,x,ʙpI_ț-Z1)eM6JzCC,7 |<6jS zZbT{f"^P{?x),FZk}$Dy"ܵPb~SYU[=M^i ^6/yg8ؽ埼Uk#ܵPb~SYU[=M^i *3L( Zl6@6?z񠾏pEEp!(؀GUD5 /ĖIi 2Q9JI76=VsXJu׆%'dcdVNP AD;nyL0PP6%%'d:w Q)#K@{6: 8M]$Mľ~tľ~tqY Vk[KY# FSmFSjR{ZޚV/)I)VRi}8`Xa٤3%26 [BTrIWz&+.XÖNh+10Muxb_j~?:xb_j~?:#ٔMAt;xqԵ'/,([Z JwQThQu Җml@}whْ)&}9~q v[ KOO KOVĐvQ1N))37wQ6^k|/jV:0åCJSk(YZz*O KOO KORc%n,(&fQ<I;&!rtJx%(YJq9\SS뉁? 0Pc9iImĩ9ND[eEf5.3NmEX-$4A) *71Pb_j~?:xb_j~?: pR#$sKK@ R5Β[ D MR%RnR76/[)B<1/?<1/?H9j䅉R @KqRu6IJ-gIPk>$!ۖ`M5>ewzfF akChlU)\r}+f``/xua;1m$yg1Zq̳N0}6~K|%JcZ[WRb 6Nk,FY-newz1=[S#Ҝm7%\B2PHKԑ6Sg.xl\KqX(l:Vl ;ֳa,ӌ>ewzr(,-|g*f? el6$4\BR,A\Zoufmy\?{ľ~tb)*T\*S'{pd `[Mb3"0# -GmT(83]Z4^ڟΞڟΨdDi#͈2[OFPHGKNveYLPd-/%%b769m2%}qid9g6_Q}1]e0]RQQH9'Ps^<1/?<1/?,_lZk檜? 3qf;4Hj}Is\T2:%=Kܦ*ɔku+M1?9HBYqT *" 55SSy{c9RJ3Á227`J+W~?v_^k1 (3T-k qxb_j~?:xb_j~?:,bZ<Jp3[VtEeȦ4w˱XZQ5GWHr{<1/?K%]޳q :!Ա|{(6n~vd/QqT!7mI^<1/?<1/?[PyU1RMim[o%(mOmsٹ؋Qxt!CV[( gm>ڟΞڟΠ艳EcRFTr#㶬8&!jN`XTڟ΃ #($K7g.3cuARn׹ +vVSi,Jx(( Q޾xb_j~?:xb_j~?:X4aRDJpnTpR=|\6dƎ"_R[䬍r5+}5%%R'EOYƞڟ΃MJb_j~?:xb_j~?: 5+3}}4Ԭφ%%9%}F2>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@"P!U1QR"ABSTar2bqs#3$6ctd457D!!A1a"( ?&3`Xx.zZoE.=ɤũ#KV-uxqPxs^[_3;ӑqG <T) U=;r5 Ndcaxҳ67Nx=.Lz]PDM&dmcKZZ3Jt;^CHZz]P8vh4Gփ<T&x=.]#M CfD}h:quBg٢>Zz]P8vh4Gփ<T&x=.]#M CfD}h:quBg٢>Zz]P8vh4Gփ<T&x=.]#M CfD}h:quBg٢>Zz]P8vh4Gփ<T&x=.]#M CfD}h:quBg٢>Zz]P8vh4Gփ<T&x=.]#M CfD}h:quBg٢>Zz]P8vh4Gփ<T.A%xs^ǤD&5I,AlNƹ݇@^SӷY ,u[ڸia'K Z'37`6.1IݵkG/K.!O-ݚ_gFS64eoa-bo|#5kcm>5\/Å@ly:ɞO='Y \* wf hG^Wp3|n\4ַ'u mcG%=YuyCgIY|̆8$fc]{{_gWaEU:mK*:,MbNNqJ9MRL6maoQK3l^w1 LcZ`ɕ68v827F99cm 44 ٽ$FWmvq^k v>ʝDKKCK#E'q*X^uvBA؂8a`5:6t؆ (Ce|ݒ2Zol첱\ClA3J@'+<,fZ!<:v>WNfkۋ/z= ׶Sмu,n8D?9.e6;.zy"2E0-` n\-l6z r k؛ӱvu/&jR:8DZf,E :NIQ j](-֣59l7ٰ $~E,0lD|<@f-Ұ=ဒܥ-ǃN|y[Le桤Fֶťܒ6qY 0B$a#s^V h*!{cKL*38:PIFcY5xUUT`6ġŎq-;vr :% q{l]mn+[] }) PfٲZmd\z Eq@qn $0U{?؟fc8d/ k[4.y@?hP{4 5&j RMTک tՇ7i h)jkH3tԥJm~gjQy*n 6NBF:vɛ==YA-'i1A.jGDs?ї 5ug|MU e/FҨjڸY6's-\]yO$ /kX28.֩"/x[YŸ6!тc%ο&o/&MEJ陚B;/⷏gRYXI3[y9 i9êkpsMF8?(.nq>aEb>)5 f0  )tWg [DZnCgqF'L3xTbT$xVgH%{?8l70l TG3m% '4zC6sJ z8DI h_*pL.|Q  ."-n+]O@_K`L!۶ne+QW:gLv .U?{^(lz .@kX+ ˪S6"@ lH'i$!ЯgLCWalT@,7awL"9_yL^XrEKnv4lV7Cc1B̳~0\˟o%}%Ki hk@$=)̓.t4]'N\]O61S33=.kfԭ~ NwQbk4mho{ ݼ8.ORʘiC&`; mcnPFb$SOxVɟ]m,/ dft029ÈVކ19 \3Yn+)C;nrEMuA]Si\v\'.PZx-]`짒aTÅSE#+ŮsAփn-Ja8hk8U5|yG>MQLɩ4 $*>RO莖d뉚1+NF4Ĝ88lB1,"Ŗ3MOӸǟ7W뻊RÈIvMvF۵Yfy8ڠIlƫ`]MzU=v$ g;:Uﱋ귡;ޛ}V3Pb6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU ib6gNU i/oC?w6g[HoC?w6g[HoC?w6g[HoC?w6g[HoC?w6g[HoC?w6g[HV5G8H8tw/ߒ?;h8;pjG_S((䔐xÏF Rڊٲp̠S>aDGXڲXNk Ϣ蒱cEȷQ;z~ɯ;z~Q\ 0飆w076\lӱSbWP{ÜZbn6)ּi&i)Q ^w4^w4U;z~ɯ;z~TH*ם=?dם=?e*$k枟k枟 sOO5sOOJZ󹧧󹧧DyMyRAVi&i)Q ^w4^w4U;z~ɯ;z~TH*ם=?dם=?e*$k枟k枟 sOO5sOOJZ󹧧󹧧DyMyRAVi&i)Q ^w4^w4U;z~ɯ;z~TH*ם=?dם=?e*$k枟k枟 sOO5sOOJZ󹧧󹧧DyMyRAVi&i)Q ^w4^w4U;z~ɯ;z~TH*ם=?dם=?e*$k枟k枟 sOO5sOOJ_^w4^w4k枟k枟u*6@d.?ܹ"@kc#mpىsˉ6aE|aE~SSQt&6ٴX;v({ )**jtTtt̞I#tAKzz UC($Ë@/X*7 )+́$[ouNLwvS|O2c~QJ)c~ɓݔJ)E6LwvS|O2c~E(Ɏo&LwvS|O(1M?dɎo%&;)'1M?dSdwe7&;)'Rldwe7QMݔLQJ)c~ɓݔJ)E6LwvS|O2c~E(Ɏo&LwvS|O(1M?dɎo%&;)'1M?dSdwe7&;)'Rldwe7QMݔLQJ)c~ɓݔJ)E6LwvS|O2c~E(Ɏo&LwvS|O(1M?dɎo%&;)'1M?dSdwe7&;)'Rldwe7QMݔLQJ)c~ɓݔJ)E6LwvS|O2c~E(Ɏo&LwvS|O(1M?dɎo%&;)'1M?dSdwe7&;)'Rldwe7QMݔLQJ)c~ɓݔJ)_RO3E+XFFche6QG~SM{򟒂Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^Qߔ^]?U}|` G}ϢA#d|`tqۺKYg>65x1CdeC~VE-$k"N*q zZ:<= 7!V%7*ˣE#X[JKkmqh+;x3@꼙#o،J)_,QֆIL$s;xEf=QˢuT.5Hlt%S񸱊Z9'f209d'6K891]Tjae>'23g;0%ι#6\[W:i_ q )@ ?NUq(TS^ꗺ8^ȿ.гΖpʸ [N G8Bac{be l óFm#\,mclc MSG+,Hm?I,M/4H.8PpxTD){d{omvTkEaӸ6 ,1ӗa;vUa4*cn'PXTv-cal6>;5\KBZ*"Z:ɩ7(|$IO2Q0K$l o-lw{ĵ:Ik )bͻM@7К8}uh*&>6}RݚgeM<]4R#}=|] jU͌nWL}";ܯS61_1D͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>͌nWL}ܯWDw61_1lcrc^yڙz$Ascjf7+&>,"_UM;5 É }CQyG\({ /E1VNeоCgKYЉtxCpk om$yG5~;Apa#69RWBnw0R/p=iCMy[H#p9ѴJ^9@ѳĥp:G,ݙ^P@qڐok=tכz>,VѝΟ/ݿ5]57}S6}m3NP:fm)6!GN&TfIfkG;$7}^o!1*fgV9^V'KISOLXgdA>Yo{lH65k=u ^d2i7%k1䭦c.fؐj=tכz>%k16I 49]tU%$1<~?RA7}^o!VR)",)ka}7 -&$ oc:V9䃳 Ɛk^o!CY̞"d{^ ]ӗiAn?X6k=uݺFG"l:̯ax,WQtF+nq۷],Ũ909l!.Sa כz>7}H[7}^o! ^o!CQ"AnCMyDyyGDyG5 uk=u$=tכz>$H-כz>7}H[7}^o! ^o!CQ"AnCMyDyyGDyG5 uk=u$=tכz>$H-כz>7}H[7}^o! ^o!CQ"AQ;fh7OaE|PPb8c)%l3H_aE-Ms*Ie[`njƒ*okYg9(mMyXA(%|ݤ2~6[%oK;S4fKxD12B_LFb-ZevrVc,J $i/b |nrV5[ԣ "h%XcH\2l?.x lؿ-mXpB-nrV5[Ծ]K<&fekieh'Zv%BAZ&MEg(n~.#n%nJޖv]+zYڔbWZAO#3M<..#|MUCni#Xd"C%oK;S[ܕ,J3( LBR xf1yr\x5uM3f+TAs7Z%oK;S[ܕ,J1cZxZnl L,g Wx1P䖗D)J=r Gl g[ܕ,MnrV(ŢD5Ln:9f @mWn#$d]1iӶɔxZvgjkuےGojHG*iMLl˗5A 41i4K' [emnJޖv]+zYڔ`CzH),Re{fl 7#ski,c!~vb6nrV5[ԣ mEL M/Ũ|Ҵ灀GsC8vKѷj%oK;S[ܕ,J!ub'daVvgxJ9)#*Xc,vuJ%oK;S[ܕ,J3-J2ͩ͑ٚFʤ$?rTGg|1-n] u\+gk'osYmNRjږ>) M<8enJޖv]+zYڥZȫྛ6a i"xܻl{0phC_;n.;nJޖv]+zYڕ5zvgjkuےb([%oK;RGnJޖv]+zYڔX=nrV5[ԢQuےnJޖv"[ܕ,MnrV(zvgjkuےE%oK;S[ܕ,J,E]+zYښvgjQb([%oK;RGnJޖv]+zYڔX=nrV5[ԢQuےnJޖv"[ܕ,MnrV(zvgjkuےE%oK;S[ܕ,J,E]+zYښvgjQb([%oK;RGnJޖv]+zYڔXyGq jY)kHEϯbaEC>VO3规ۄ&QQX191g6A$K؛0 ;3_eɿ8DbV9<9$}Ƃ?'5Gk-3[Xl]}ϡ:fX务k݁ >>bH:ƾC(᥺3a7\[QS1t-7(!6n+xnB(>- eσkm<\[-@D Śnp?̅Nx4a!g1]ҽ0>W5K b n9̸.5\URᴯ|--:&h7~ڻNXFu lEuv"("kɝT bM2RV:Jsٞw6fcď #m]k2ϮnzY}C`s}3/ =eT8MǪ 2:A$eWX6^geljl:GE rQA(8̌-i"x 1 tE4h#fąckn j :I"A>#pwAG RI#d45 uQ_SMjEQ=[b˚039đP5I ?-z|6hE,p1uHU]G]G;i犼eQ%׃M<{֦֤"NkSNkR O55ӿӿԂSjijAB)4 KfqF{UCQyGWV)]>Q]H044$uyGk>G}75 :pUP]4˫K"5D8KZ4A&\΍ åc3kߡe7k}+_Rq%;#MtN2Š\xYm7i\>--=l2+7qŨii9ڳM=Xi]S^ݫRַnkG#b<;JsI|L hkv7 ٲ*(es+*W:S)+a){`O&Yiܢ<.0&KHgo4EgamA򻄴t6ZbEXZQcX|7E҂[.m{~eOXI`f ..]C#Ɍq$Nl 1Zt59 ]h3ϛfnDfF[J3Eʜ<=$0 ^G胃2htՑi kavc{`S]o 0L/ƍ>V7. h'X2 hJ)3ccG2gICONڦv:;hnjrx;,W\ !{~86]KBtql,OFJi`^w'6̈́zUU* #&K.F1v㲩范-kn"KOpԔsj@p_2*.u-]E\r r Z/^Zt  ;:F0fv?"190 tDcdMѺ)5ŧfcvxb@=uZG#oR jBG'8ov56IW3J쭊G׽蘆zXs;|-hlR6k l{]}Bq㲢jN9{Xvp8$3Ss#LtQa5TZd c"-~W xFgGOQ$Fȼ/ Lƙd16Id-{]T| kJa=[sEwUWT$bn7U5F#&&OoR35Y>/ٶx 'c;kX~EGX+32t\wkm`xۈRMbFf[aDZY2aLdUfiq,s<'\47XL5وbM5LE\Dƌpq].|Esx^1͉أ}+YbA VJ:Jɥ|!B\2=ױ'eQxmo m;*!Gc~'r(=x{M`|vr1ƺ?UKC@.!c_ay9si&R&6|&4*q( 32Klq^E>"j=#vi68fqsx=KN<6~QR>#ZA@&!J 0a%SjZHA'5ߢvANڈ!v^ q7ڻ?al%"ua;4qj';[vwo{lv4.|hYX6#USRhkHp ]]URjFLi,Y5ֹ" XXtht? 8m* YpBI[# dB,8Ai6-ʻbP;#9^\2Eo{BE(.3#"y/q fl-vyG>:頫 MbI`VyCgA/K-'ժhkjkjD'Z'Z~Ab{媊9+'s!N6҇\X*d_gth""" """ """ """ """ """ """ """ """ """ """ """ """ 5|yG>RU2ƵBϢe%[)E%eLf $m(O'Fq Zkià[xśnt8tPQPƉ!Pi'?䳡0v!tʹdqõwW n9֝AW|?>K2,k+c6naw's6U ]f'T4% 䙣kw m؅* ;)0̭m&׺7{ckihyv𺨙,u_!Ҵm tdt24śnQJ)bx! ^vxXK]4m- \ωb.ki*IU-XtrYi} mfjcξ@v E0Ĩng4L۵n.qUNj!HE+${F͈;I\7GѤ)nӶmv\#ưjfeLzJw9P 'nAr){dХ7n6mvٱuVc4T[4s "F ƠT0m^. Ēb4Jdr}QL1\+6i۷]ULeU]\ZL`Na{%Ƞ1z|JaDv?FO'E[KP8s絹g!m£M&+iɨ [_gnqZ\5HĒپ" (*E0(д>V[x++ nC6ǰvԕhcH<\[x\:Zl&qmQX}mڨZxͷgS8>)2Hf#q8~Y%K dn-/`$6\ K6%E QlBFp&~/ZR&diR M* u00 ͼ~ݟwK>m~GLܭ](Ġ)m$wvt;lvxK1Gh ;a[}(*E9XWw9}WTDUC0#C|fv\UB&9?3>>Y[MKcFqiMև=}աte0SH]XiA<"vƵQx2nPK&t12k~k6 Y_HxjE@+>0|V۳[9en2hF R[Rzm,U^ta՗ױWSek}3) ]Hёub;Gښ#*}_Fė51䑲D\cvfGۓ`]cG{i f8Bs\I6#-]cܕ^>1U#Aa5>(dV+LlƆ@ۈad -g8_G+uGrU{SXw%W7hŧ#M<qB*)cX5ngxü/͊Ea%4N.:).;DZ]b;Gښ#*}FW+k]QSSLC1U#J3pi)u0Rk ˘x4|X]%U+iԲQ 󝤹,䝼{Xw%W5GrU{RG<ko4gMXa/d"~PU}-(FGkZ#*}b;Gڔ@h $nzйV`c,14O{da/e^+>EnJyjkgOn"*oO4n~g1K@$sPc|KtEuEDQ cGȯ1U#Mcܕ^>ԣN G$q Wc/pqmzclN=Q3M<2Ͼfo{q-cܕ^>1U#KRWaqN^"vgD CEN[qW,; [UfC o|GXw%W5GrU{R %k K /袭sL-+),0ΐ-wm-cܕ^>1U#J8b2VSDm  ̕xS'KEI rDlpmJyjQ$x9oE4~lb!؏FE+r]ikJyjQki#e|%=ҹ҂̻/Ub y̝KQDrXAvJyjk]ˉ $ }%2 pmm/A-Cbwל;K#c\{Xw%W5GrU{RrwjH&)̏qk77fT:}$T_Ci\lcܕ^>1U#J#~j-ab%kl@<~"T= 5#H,o'`񃴭cܕ^>1U#Jg vH,|C,l&Z*Mcܕ^>1U#J+E&JyjkXw%W5GrU{RIb;Gښ#*}Eh1U#Mcܕ^>ԢRkJyjQZ)5GrU{SXw%W(#*}b;GڔVMcܕ^>1U#J+E&JyjkXw%W5GrU{R(.0d5I\?yCgdc54PG n,[ZP_xO5%,SFڇ֟A/zyiRAau? (AJIGlfjbqZdJȥN|׸}VHC^.M!ĝ\΄D׽9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЂR= 3 9Bk=*E.CК9B K3&CЃwT^QTTٚ-{ߑOaEp<3IQEIXiCgetTMͿHqvʋ fe\.sCʼnm/\"Ű褭E}$ ?Rm=; 'WUSCI$<4q y+dͦ7JaCxho BvA.}?T8%i*tʜ;ⓜrK!$44lhm[ +jVE>YBܲ#ckeoÎa5T܍]\z Ev6i#6i?ns["5R09n3\r\.O!;;ߩu}Fv'{;Ŷ Nw_QN3m Nw_QN3m Nw_QN3m+WgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[hWgbwS[h!.,RԽξy,ظG[]?U}ϢyCg}Tƀ y.dr/奓wJ-,tN{WH9id绥4sҸAK'=)ZY9M,t(rwJid绥qDN{SK'=+$sҚY9\Q ?K'=)N{SK'=+$sҚY9\Q 奓wJ-,tN{WH9id绥4sҸAK'=)ZY9M,t(rwJid绥qDN{SK'=+$sҚY9\Q 奓wJ-,tN{WH9id绥4sҸAK'=)ZY9M,t(rwJid绥qDN{SK'=+$sҚY9\Q 奓wJ-,tN{WH9id绥4sҸAK'=){,>Q_W(*P_W({ ,Ja:2 ֍W. DYXEtu!C&0 p;H]+c{x:P\*44؋(.pDڔ5E!XS㰀GjΥǰ *͌>vOaԵ.p ٢m`m׺Yx@tⵥv[?16mstqa4lmK9^so,|mxl35م]HP1)d ťIAF_&Jݞ۷0UQcl9pPrDDD@DDD@DDD@DDD@DD5|yG>J{وMM%;|%ADX[֫ϢPaá& \'Vf+\fbf!11ܓb3q fŪh2t f}v|2VֲIZNF#aEDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD5|yG>:t# $ EP_A-ppGA͸-tIiy}v>?1U̦Gӆ69xgh_% @h+j[SSJec ZLCzf&>S *A.A™?͛ -nZt2gZFMK%8R.aW^#}v۶ꈢ1pECqV=쁷v/"MLOP \c7-}~%:YLЍFyB*Ji[;Zo@1Va5T<ݶe$˲:wfTs@. X8طh"٧i褤-+3\IuXFZ8qhav } xY=KX|%NyXbLKd:Tdqk:mkĴa0vG`csF.wyCguKM8n䛎0ZZGbK=LsftYA#dfb F%GB6fGՀpw QGI<Ҹ&r ~'Ƴ:ڑ-3d҉̮qi'r 构=KSйY}NWC^+K]r(ܴus/x6/eGtd |  Qa8x[׵{,x 0B'W>xAm\ٱ}~Y.?,}]BS#A i;?!C,'K+#`%wro.ݢ׸^vlK<s`-a7'iubt8&pBc`4Zmt[PzYocxMؼV]$; 3O,0xpl6 돃ؓ 5K lFL3ERv,6r)u/KQvJ[UHaF>ׇIFc^ {#asm""" """ """ """ """ """ """ """ """ """ """ """ ""5|yG>aE|yG3>aEhfɉ;HɤԲ!w70RYO(3[P5gpbD3[P5gpbG |k)!6F^0m~AqƂ}o-Gؚ3[PhqZ;[w .qYigd͵^n|7FDܭ.70SF<ީI?^fyR6yJ* Rmd̈́o9TU Vy% M,ۤ =yR6yJ3 +I #i.K w::!26ClG6yJh*jWJH^w:6yIvGS#捤-)u-{YvyG@O6`yCg}_<3辪5xc,={Hqn(p2m5^IQ-, {r`Ο`Οwn\;Y؝[Vv `oik*r̍ր`عn\;Y؝[Vv 8E5ĩN0]O\.Np-ˇ|+;qte++Bäf),ulյpgbp)tԘu%r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SKD ,>r^{SM9q@quimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image022.jpg0000644000175000017500000007714211665471332026766 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;S"W  !1"AQR2as#SVdq3BTU$46bu5Cr%7c+!1AaQq2B( ?F&(vz?M[_@s7t$+xeGar:F[7f6l^[B&2c`vC6:2+S|kѹ:fEm"hl'ʑ{t5WC9d:fiI#1'ß g+O*Vjzozx=7oe.slcު'p&K2F"%|lHRpGGA4zozď\..9V\$0ItW"7rg=;81!cd#Iq1 :9T?M[O Ӧ"#:P!\$^ FZ$yݔ.x:3=1Vt^?M[Ozs3iϔ-ճcJ0#bs|]AUn*]Dw` Sn`;uH{|kWKHe Lvg$ꧪvʱtuR{`H#|i5߼QԷG*W1ݕ0Y ==utqF. a9ȦtC3 xϣzozx=7oeD9tVw [zw6̂GQI&I`smd+e!HS7|z=}(zozx=7oa\k)k$d""N w]=reIyOc=dE׊Vf.!P zn cQPl=7o<޷ƱۈmƘb $jJ]oAՎ!gM/brZxr݁uGN>?M[Oa5G^uKK3!WvSwm7Mhæum\H`6l'^s|i5}f=Nr 1ž8+2rpii:jb-Kr<ǚ>rç_O4zoz U91 ̑*OZݍ2{h{ҖpYa}^|i5ƭsݖTPzRNju$Nsڼz6"^K7|۾six=7o<޷ưbQM:8,.rUe8^z8Ǥ \ؖy3uI&r./n&_NHE82c7[;ȢO3͸n|cųuv$M5@t5,j Hyi{S{;kjv?X~Z`dUy$^4HjzUy$^4HjzPA{S{"AEMO$ڛ߿ƧI7,S::TDXFd'a;A#98m׏1Xs.I2)'B=t̶ܿhS̶ܿhPr6ցvm`)%Չl^"e}+Ԯmn":6  ޮخ̶ܿhS̶ܿhPrZU$ѷ1WzHi$`:"u[\V (XHg'Im-/>"96OSh뵚FH?T't`c+??b)wOؿ XJwOؿ |/–V!k4!P"g5ݲZ%\u *Avn~^F;( 04H Fņ>Wm"ctΟ@ʼʾzGKc@+\2 mCq} 6orXE) CeܪsК$(4a aC8R%+2M*g~~l!`"e_яHTRK5Gkw"\dca!E!%F269s~EhiFAg=ƝA֎B8+4mkעi䷒>T+=`ԫsYg +% DqEx#$Dۿ fk7$_41'C՘o#x#fAoHds ۖ G0OT瘝wE"Ss70a:}gup;n_!cX]*P `PI*\A$46qCGwMko SߠQeeXO0z֔BC\8 kԳ9yam-`3S_dAw i4p.c15)["F  תK8HN%*z(((((?Vlu1{&c(wBTGa Yq-6ߓX 'vQ׶OqznUZԃV@1G\R"iZ󯧞)JIZ5ct1"Jαq;!"T^jO-mIi28yA~\8iiW+3,Cog$6ӡ  u*r pm<$m}Vl}{֏GZU4Z~Vc=歊JRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRJRAtQBFT' G `$hqQ*+^)џ B oad̈0Cum KV. Cdj"Zڭ7љuj\[6-ZS48(IVVTA =]k5{%}o{,3ۘA <8 JҺ#_|S#"˿rfW]NfkWϵ&9Tz>Y_ƫwMn#ٴzy- O&i1y-ˇ8[OEOH1;FWrA3a-qiΗ7"Md_`f&iZ3?r꺮ڝս\ [@I A9VASbkvO[b'D-9K.{n$wWU׿}{1e4=_BT^=ɣ4(Pe(}FO'>UFU|BOy!RJȻ{"BZV]<Su!J,ҫrn+&b,Rn)ɹu 9Wο\9 R9W?)SRN\?5*\ߟpW\ߟpPKJ//ң/'ݨ$GO_vh=Ҽmu6^v{A u}+J_h(1Z>Қ{OyiVAw5lV>Ojب9-Id[xm{4 ̊`A#'vu}@|W:7` ;w8tV^"M$$x) M*U^YzUzvMqLM/n. )lJGs2M6ב[QQvz:V-!紅ZM<*,uZж&;{fHU@xWhbX/MnǦI\[oQEin<-3؎..7I IBVc +w^zy:qZ]+3! Ӄ:)'B[")s4;v[z4$Y#27_on$9'''-6fX%KD9p7zzk]Iq`݋2Q!bNCwf]\F` ,B.:Ul+xI7 "LS~Mw/kĚBֶsR [veb9lǽX#kF TF46 $qDUR& ;V:8) Y $Cm,I߶:WoJ ZEE>’و$`uW e!Hg[8GZ̗QX) ym)2eVS?fWB#9O%7S$;~M4O7(]0Tg ڣ' 0.b㋮o-4O ͼ9ȧ 0 i]Az9!y}y Hi+7/s|1ēRZ, RrTEgX`"*nm}6-=u.\рUԆ2q]#4.PxM| hY1O3!:c8'?ZXhri’D$a<-6~W-<_OhzmŨt!pxvwLRKX-ivKsw !",qĦ2zGAV-8t/6[?/\nXsG3\԰ln"i$*h挨ŒtRZLKo'vb2*;FVd zOotUZ[]ˤ@RxVᢊie" *̣է1Dy>;XisXx3?Vz&bUWw`IbvRI* C]~w|=56o-3nY&gcb6BnUPz:_=*զ8cYlͲ(: :7<']DIo2Ʊu,BD8}7,|Yj[.'hm#+Au,,77#A=H:'L&./h͖3i7PpHS:uȇ7 tztA4V^";UVU;tg-RyH2 $Z4X/4ly,B_)nd#]q'=Cjk:X'mlkaDAF[ 1$SA$2 r9rՈ0vH'$w:%s$8L'ggÀ2TЏOy(Zޫ|-N$0.9(ۤBQC+*X o`o&Rׅ"*"b#@🤌촻-8i2w,Ğ䞹t[ ;; 3;Nk4VYB<ܸ^ToRwB+Kxi-m^]G!}##y#1HI R8*桤Yji\ǂw!3=ȇn 6I5KubC+3H#cn]~HP2p Vg?OW:5/ 6aAz(;Mv{-9%}n'ZdV}`Yگ ZI, q (cRdv>'e!v`u8;q_=e8*A#-gMcQ{JAʀ!A-  6[g-^ 2BM7,+DUhę3 gqolQԬ \\2#&V-ma$^E{ykn=:RnT g:oe1_ndQ<@gÆ*O5/v@_\r0@Ng0G׋=yBˀw2?;v!{8^CGGZS^i-*h=歊{i[>GZS^i-*h=歊{i[>GZS^i-*h=歊{i[>GZS^i-*h=歊{i[fKx F^G2,mTpzTՏ5Į5Vk Vֱ6]l.rA: mh|adzBY+K'309HgAלD(CtӍD} mF .1DWv  3_֯r r\L;s@-\?Gȸ< S5a>kl"ᵴ3俑-luiz6>qٜtҢ׉ nP %{{zozu- #kD|l$uO^Lⳍۘca2x23Ҳ{piLzM P]w+H&:jƇa գvF(nIُf; Flsu?M[Osk%ޥ-ݻ[%A[7Hdki =9'kH'S6wJI9qcHY8v?M[^^NX$PHQf'\Vi=҈f2#uun0F:+ 1P0]*"ӴJ;nP*rv#U䘍55s#Y|^,NORD>I7I7I7I7Yp./^!tk'-{u0Vz^AwxE zFFz҇ߖ\-KnTg q,D/#fv'ROXn#gbjٶKtK7%  1ۨȞkG.0#v:k4:WT` cs{-̼1'ibrSt+%9"24rcr2VSFAt$U-sI:b0 (d`W9|3q;C:[XVIKLOwd'8ξ Ne; g1U{fagQaG&Cn2u }G6:sKmyRܸ) XA-_ҸY8A{x-m$i 1pVC|ʞ t3g5l_b$ `褨`` H֥)P)JP)JP)JP)JP)JP)JP)JP)JP*O[d榨m?o )?鎧g]U&kWpV<k#X${H^|Qi;FY XAӯ\jvFqs%ݻJ2r ޾"~^5yn1^=}5Z>ҬOjج}֟ձPBRT KImSP)JPEl6D1 cWT ZOw n0BA9lӧ5=L *BAQLgkLY@K&@* .w0AjYoQ-+2[x$m9uGyˬT!86=~ѵ};QQ{C},e$m@dvټ2r:}#RmVP9nKfpwultFN >I9XE `Jzjy[Aaw\s V2q.ʣ@3މo-am:lh ႀFESK;[RӥcHddSeNAŘ4iCiջAJ r=VPevLH\yfH;xK$>XKtdRNºקZ7\X钾qlUW$-;#iO>i\5[IWGbyX9p æM}.y T"|EXztȢVy|ǘFI;sjŅԷin,r2?}WfF=Oi,q@ bjisıBѲ[,aJ01=LIS8-b9*ZfBL^N FUF [:c?HÇz6Ӵ|IpTûP;:>u@?5t;;[Yl$wkpcd>DzI jb9uVױMuj}á;U}aV+Gu{&L7<+ixvq5*KiqM9ELRB*Rsyt=56 ꫫ]Cw$.x%(tgeiGP۰H55֑%;OkD'Y6yţ;\uvUsC)P)JP)JP)JP)JP)JP)JP)JP*O[d榨m?o ]CP.,,.bgyGz%@_z_}/'$:eu_Z|/5x ^GgK?i_}/'}y4s2 mc__Wݲ|.J̧:AĿ_&Os8_Kd3RE!F2nɝM==gӎnYG8+&Ve=:3_}/'Cu }X ֟ձX{?yb?ץ6^ڦRmcAOV*A9_L`r#OFj{xA]@Un״uDK2+LT]Cz:aڂ՞m}$[ Ve¶Hs__WTkYʩ_Cnp1lzǣjvXI:Ȁ'߳yQe^tF*;~ڭws6ܗ ,C1SDhzHشr TAAEz#,guV*G_k6E$#ǶY&0["vƟ>s8 C9*i? u۵Y. m{zo%EnJ@$ cӷQ_[hQ3S6-$0 K7\څ؉blr@pv׊ [ ($yu8FGL$WqrZXax3DRvǣ:T .s}OXZ򠍄 H7;fRpWl cJR}oz%}!mQgm6*0I#~[vw!F;}Ҹk.{D-2("M"6s݇L\5u]I{cu;5uA:E u$YjZ(ryvwY@:;܁SXmOl*N]8#&qr-tWH+8(2 у階q7饄%ѱӤO1F &=)6[us WP I+Ը9\Ǥ-]6Rc gOuAnb{~KQG$˸x#;q׭u$+* B}E$CpRl8Nxt]6?9Gqlc/j,[>p@=~׭7'9]J+Vf(j,[=ӚZźHP=!Gj4)-oDmB; !A<"k:9oCp k?eo1Vٷn FR'ER>i}(;:;Ynd0wl; $kmKҥM86"a,6u=1z*-OMyI|en\]t%:0 6d`=Ck{i-3$k*en$wq=8vZMUh3Va#ޒ1̙5girkŧڤ?-}70\47MDgkgM3ȬuRfP@׸jNKqDӭNeU$Y ;cm.dZ;+f#vGʚO#-ZWsu=6tv{h#a sw!-9R"BVvAnc0V(.G/ӅCZW)hv\W{z L$s#R\ɆazH^]]Mܥ)@)@)@m?o%Oh0:euVC@2#p۔I?UuXQ6&z*jZ3VEYQF!s$,FA zO_|- \}9ǷGp'w'5!T$c;XQ.ƥak|*7;z<(:.Q7vĉw/>6f")2p=qAR1Z>Қ{OyiVAw5lV>Ojب!O~?ͪj?ץ6("mt1ՁC jKyN\0@|N Go^NUfpG~bKamϩpXA::::1dpN3ڢq%-u͵ͳWe;c=T1؂i>‘qph8 mp^Ρ6e;W[r̡޻CDt8h"[i1\#dW?ƄS*ǀ9tl9ep ǢLg"džG$Vc;@\U#ºdbo&bܢ]dsȫ+s 1V BG.YӱO+Y?V?ȿq =U:' XL{Gckۂh A12Mݹd`Ǣ_2=]MK nbr{Oy:j?Oxj˒ICA[LWG7å>x H∖ 6,l󊎣|iiZ5j~O%2C fFI8OoMK5g}u&2zF72hR@U;e{z/DfKpZݾ#,2On_o4n-@6q$vr:m dӮ,xO6c.P*C_;Zv=t92 sy5RP($&QשZ M'H'xe/nI Ԍ2W?N[Uv#~nCPcIqshvu153qplsf-Vr) H;?t7 ̚wkȄ3Vty'F*$\ZJXsԒIrP2G0gc֦4K4]sG$$`-!wu/at秖g-+Ǧq,v<4ڀgu܈Xß^K٠sN !}''>h-䶅"Eifv! T u )߆MW1}Bi{0Q0L4F& o6>ȃ|Fw(H=Gpۅ oDz7-s[!\W!`tUV%ڒ !g8JK. 2>z¦=yؖɬ nm΅-g=(nҸ^.)@C> N2OBt_Al(#ܹw N+ch5MNa,&FVyYdo Rw#rzp(b8Sӹ'07 M\g-8oVi[C5q$Z^A;2dƝ adl$yp:LdjהhԖ\?hmd\wlz{U]_Bl/`~^TrK& D =r}+wGԭ^kmK˾k33ז0J *=ϣƣc-ޛ4lm.ʑ:}9q9Þt xzALEuKch;zwW,.y##g@|\+5֒hqu$G(: z=[IH]B쐻tP:usLEht[x#㚰I<$2)iUN@* n$s+5ҳ mFn$lw+*8MiW =ד!G@:Q9];A]Q8) ZN'2p+ͦIwenFuڱȠUz'lt/TهoqV#XmXu$[Ηc\=?ΗcYvH@@%x%I3v2kFt1ڼW2q˺eUbn# ja)K+Ve wFqj:SKiIaq8V#;O_I+Ppۛ`#P!!G/:vqVYKzGm:yǹnYOбpWSJR׻}hJk>}X ֟ձX{?yb?ץ6^ڦRR/ٷmYڞ5Mqʑ"(PÃiœ(cVЍ{͸j4{sp 39P d.vu¹F#TZYcؒEcG|Yb.1 ֝ %Cfmņp$OH ڤ4nuf}ȧ7Ve`W؎Gn=Ƌasc L@ t!BGC3Mn/bK]K(*+E y8dψ)힕^2 ›ieiK2oh `69Y"قFIW2)%$bzZi>?ktZY!yH#3$8_c=zg4EZ2X2lRU93Q߸=:+Sws"蛣1@Rz)F Zemö0FZד˃#Izj5]!`xW X*mвޠdRS4Hј_~EpvHX_!98{g|KW$\l CU6R8ʌ6tP$v@-غשI''j [xD\+r#kHl>#ש+v[_]΍|ȨgC~S)Ld}<6 rLm^ERG_-Cd[ !ES&f )C ,xN;zhMGy,+]dO!aFGLvfEŗ cۤh{dP:ȽFt#t+Y[2G"B6Aө8ۗB%Py rkax{M[ȮR}ČTaYAץIqX_yl;Mg v>ʃޜgi¼+6,0ŃG 11T97un!k&R[KW>#~`H>z: P&ԧ3bIS&DEWC t$&-dM m1)B<,F)VkqX>n/ӑ&6Vrʐ#l9kWP]+-ϘƦyU Dۏ`N: rG[J9c-̼܆!6r@9Ҫ9ؠ@Z6G9;JC8%xFW#ٗO(IUBf'W[شdХfiDBC; \L@b-$yKofoNP'z3ƈd7R$`sA HVMWTm>+cyvpaUE|A[',Ʀc1AhvyJ۵F#QCG%OgcC32Hp*8}U\ dh ːB(Dp Lnz9 ֢Zr\܃vUTaf@tzV>Z]  2d# #"BscMt7MbIlUC9\9Sbhtu+3򼥙Q0vl0uLh1u 8uI&KHM(m-'D.dmlz+ƷW֭}iii 2$ zU4FmB'A饖9BF%HE8SjZNh]H96۱4W-:0,:tQҳMM,Y,VQ+FfDp6|sXZS^䚎B(k@Y"VT6v ? XV%0^ `z Uy]:lo6dlI Ϭՙ#bNA7VI&Et1H˃$ ОN].K뷲i0 mF㵎`dpeKdIO#C73ochxSGkx-NZLciUUEVh'hkHۜ1QVcz=\%]݇enݽCY[ȲEQ"6XgW]2bH>q>77¸^1쵞ĉ_b!-TN~sID:յrZp,HIy@lv 1`A[n KZcq T *.yR Q$q݌kS=>xp)Zã_[Mi6[$CEGcWz˱5n+bgyKuPC޵K/d_Nǖ??uэ_3L4q/ɓfٳzm$Q3\{c{iw;j[JX̓Pl rv KwͩiP 72cp>Wq|e<6M (T9};-I6D,jL*rNA ec ]$m4fY"PXK'PVOcTSH\5#8YbHb]FhZc4RuXo"BW72GUMZ[tD'rz`j^.~9&l%(5Yđ\FI¬l7p;֩pjΧS!i7mr@ ;:.{ m1]ϧϔM FpcM^-˅#öcf۴uw럠mϺ+ >Q-ϙB(;ZO/u `51TC=H:zՙ8EB> JYUܬ7Y[R:zI'8$VB63.d C},ȒFo;V'iBh +-+OEde[b1:I WC\kV|pO =Dn%P~f1߽JM[Ys{1d ,G uLɽ99NVkVMv^Hn²ɍ088V7r$C%E4r$ݱp*kh>-R=vNRY)_ HǬUs/a{ mc'&F@>STƃ*-%6è+I,s7$!iI{몙oPȔ7#\7gbkwTCf9P: SJV7-M{Y[{bCʙ|@91ҴB^wӹ6R^]͐.JAatPTkֽRz!%GC#~ocminь#2nbt^gYӘ, ֵZ\MH[5Nx  @'N~Mc+My志^$ ܤ4.c=l;M.ܼʳw8rl p:#6dyQ[yr3fs}#Yr:CiSo 71+aH9G$ Tpƥ Hoc1I<{1^hاnHzz-ܗSIw$+U_Y@:tQ/k6`Ъ([cr79F =7Kz^=->X|/mx??yx+ƣy|m[M#e9#$jWE>]NiHNl,J>gb{Z<:_&K(@{^lR 26Ȅee`<8`Z D9?g&1'iF!W W}>|EqàۭeKPFcYw1;8J[}R xJ)9f{( j.7?Tw[͸{]K@:hQ:b8212N}]xu QZ&9[uKUEf) $m'F{Ț~rnF{4 ; 좷w'yd2"AUCSX׎pNtSg.I\8)W/x.l&S';rTѮ%o *ikh澷q+;?f+bp?JH:Y~q{ _ =E, QzDe F;=4tIm!Cb1*) XbzR⬷f׆ Ťxr_&"yהmNoն=YxU #:C2|!CVq}5Ҭ^ǃ&DS*"-:嘙~h3{|BLM$c%Ⱦll&P^RpF cG#16Nb|WƓq6-rd iܲ:g^:|o]#t_)Y,[H.%?Er.%?E˅It~*ܥ<-˅It~*|o]#t_)O* ao]#t_,[HSʂ,[H.%?Er.%?E˅It~*ܥ<-˅It~*|o]#t_)O* ao]#t_,[HSʂ,[H.%?Er.%?E˅It~*ܥ<-审yVW0ɩ.a:6-mPG)JJRJRJR^i-)w`4Z~Vs]ߒI.[moYoԮ~AJW?lvJPhR⧝RcT;~sk+$k"Y\`>T;~soԮ~+?ߩ\*y+?AJW?lvJPhR];,o23'*nVj$oԮ~<Хg+?O;~s4)YvJSߩ\* Vk+嬮@$w'_MzW?lBoԮ~<Хg+?O;~s4)YvJWV5Y\HN *VRcTW?lBoԮ~<Хg+?O;~s4)Y3%t8EzW?lBoԮ~<Хg+?^_YXi*It֠ҥg+?O;~s4)YvJSߩ\* VRcTW?lBoԮ~y]eY-(p3>(4YvJSߩ\* VRcTW?lGZU}Rʍ$l/UyV &x?]wR]6'L%eR?Ct NNwlTϹ?FҠ.gs1;UNH>V iQZ5r9L¤X7P3߉;[[$r,Bl sң?Nx91.`9z13ޖZ^a h N;n۝Ė>9vՕqő[ 5+伥v~otmbWIfUU*̉ 9PRrFnsaeo%-(&nR`b\ׯS\=u-LtCWa JzT悺qkw myO7q rǎ==W<*ơ9% u)t@i"T G.%jB-c*TVBpNHE$*7ڕl9NPј܂9OAgJx xc+.F7T#k0<<=2̦vdI_LrqocҴ ];: H@N:( bd k$hk^#ph67KcyRQw\Jx1؂6Gu%ɯ-/2 G=?ޡqjp$7Oq:4Bhd:aBGCؑYVleuujiFcqs$xrDE,'p鞕qH뢎mK%MH7Gl ea*%U I-D2UW;fv`۾v[vwd9tzrXɗy=1,ՉrI$F e,[}J bsL=WW]Ŧwo*4눊8h.^r#"H$c>ʥsiWwW0s&H̸$`u#=Tڕ?^[Z[KRhDs$@`_O`:we1Qf1)s g\Wx{F8G " ]hem7fҴ1VIa6'UţQƎ4:],IvL1rʐ0Ǯ'd&F !PYU}88fM,X2yC7mV =z֨ip3rNGROn":%~?++,[8 <*"B0#'h#HF2W=}+[Stx) o Kt4RKvxe'+=}5t:`"$X1 FE+ 繇}ݯD Q'>/$:ɕt-$[<92;!m{I&໻մXPL(8PJEeii7&` .!m+bUJp2s:|zq!e!l$rI$IzG(*5ɹ$ wrTd} dsW|5ln$X *1ۿWc/Fv8QYqsCtdhi+^@lci@VۣEa}a:EpdPdQɩWAR~jۢrČ" .;zgLבhm\o$y@ě#TS>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"\!1"AQ2RSTaq#34Urstb$5BV6u%CcdF'Df,!1AQa"#Bqѡ( ?8[MI$L!}]:֯wZ|J/P&d).U=== bx{O`mע4ƨժ\i?֟SuĢV-um3UU+ ڶ-FsHqQn`(k"q6֙ڛZ|J/M֟Vs"wÿI Ɩ0ݶ{>%ЦOE+_:px~z+͏ {h3i(7Z|J/X4+Ѫ% HR1#Kvb3i(7Z|J/X%Ь$q͚4Q`!E-H=ݺQ} n_BY!tiX =]}jr(=i(7Z|J/Z!v>LZcFIeV1)p6_B>%ЭK4\GH̪ ج٢GXDWn[eQ} n_B9Z6Fhn֐._d)nS-֟SuĢ',M~w +g,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} n_Br>%ЦOE+Y,yQ} E,֑$+.Yf:0CZb!\17Ogfoo6yalq߯$Gn%%}o>_Hnt5Z^4ml!WO=>vI寣@ժ1y0Ix )he:=2BdHVwomeov-5'zEl\񺎳UͬV3G {ԩ-eG L VU Gcԁ#)&Wgu#Lq GzgbUIח"*p\dyD|EJUKov$1]@eϟ~OA?#rqϧOkܩ{RNW88>YyD|E*D }6tW*r<݇4˸NL)JS |O(hG?Rt! Zf8 Gxae}={|٩QO(hD[&O "E`8F"Yo^ATkm1\ԯ(hG?RQУvTk2=˧M2]4e wm;d+غǶD|E2+tˉgx9Jh̲4 '|с[>QJM>IoD[en]qQZan A$p.Y6F:`giP'˶Ku2yw9 3JXtgLg5/#)r+eӮMYmpA#|沛Nc<",Wn@1߮r1ՇG?S#)R 6E`=G_eZrEjyD|E*FH$V(hG?S#o$S+WG?S#))#)dmrEjyD|E26E9"yD|E<>y"Z>QLNH^QO(hFH$V(hG?S#o$S+WG?S#))#)dmrEjyD|E26E9"yD|E<>y"kqҥoS' wkgdq2)Rf%Eg= 2doŏ4~~o@~2{]60ퟐz^{/}{}UzoN'@]S*=tVi NYU&O{릘\j]tO^ׇ'SU~y")BZiHg >L$+U[٬IaD^tdU88f4Ė!E<$uDY9PB:Q]R/ ׍..6wc$w^`RI}FͬYEy1# '#ۼ&J~()7.C"J|/2qRblf6Q!%Cr\F;ɍF@$Q'R45$&S b;A9^íjq%.4N=#?Jy(.2ax%zt^/-~tmk*ĩa+AE* Z͌9$2c هu#kˍj@軤u83SϜGLz #3N<6HNWqAtv@s$*f*Xrb8>ޕRxG "Q6 ,nۙ0s~:5&>(:ǔ񼍹NFsM*JF/b{9F$0wl:ב bO`fULK4MeH_W\8.)nuÝ.FqOAA*ʭSVW;m{`/K.>I;Iԋ:х1Z1fiR ncsʭSVW8cc}no7=9{!Lw5iFsJkA|9dsՇ[^ʭSlC&s,k\ (9#WvgnqݚʭSVW"j(8m/y%*M3vPV>ym\N=J9&+sTudbN}CU<ߊ?ޭO֞8VIC IݲO9Lk}މs<ױ{vW01MGV}u'ʭSVW0 ?ru/Jb1EGP0YF$0*4;mqIC̷Xi&r.ԜjʭSVWm-srf=IU/k|w;3>{12xj;9,e<,PdDsۙ*O7[^ԙ_ >xeƙ]:pyo<6,ַv/ܚ~b9ޒ>8m 3wVW~+czXd4Ǒ2Mo`zW?*鶜}>cGZ6Su}Aa{~+czyUHRi{'5I9!DF@?q3{S Ƽ-e,VpB H۸AO*O7[^AmxRU+KS +YR+\^Iqۼ۝3Ss孞UozoO*O7bށ5/l;`0̈_pTD\9ʊ$yjl|/ʤu:^֏;\zsH؜ִYG m3r>;yߥGx^=^<ÖR;a4YMRFD} xkާY I"78{ }۶ӱmQg!{0pqaBH!1ȹ,cݱЩzL^#ړh{k/*O7[ Kk/.k%c015piv-=$΅]JN*O7[^=j%VIFZy$xnfruʓmFC0Y{RhuuyX26SQyVW~+czXY ľ}"#\29=: 9ginyrhr;UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoO*O7UozoZ_-rY#Z݁ZUGůg5ei8KDI3H$N=T&j/ajaIUZ8'STWi⬋=OVMJO*bK368SV iRؠh灆wq}R$C4iHxv${%IiQTBI#lx줚:f/ۧ^ qA:kfˌxKn^śS%N@c髭zۉt*qW:@acksuҪxot1Q&®zwǯT}6}BKtm"f_;Y:9u+Y=NZ*[d =p=y-7agjfi\Kgvi=3\H^[kCe3* in)/2$lXP_7vN_$ mރmwzoysKP- 9ޜیmҵ }>IrH<.6*A V7|wXZ\4Ip %'FU xFu%73+Ox8b-| ǧo~ hH EF+79fbJc{c\Y>ͷ|Wke w+cl h'}v n /Bs+A츊쏛7^drm`ٔ 'GcOn0ɸ>;7gp݂zVV6Z@cgpǫUU#lJRJRJRJRJR>1jx{BHcX-s9Q{zHm{Z p[Aـt@a#,b -p$eXyI?coZ >ƽ%GaG(@'OZ9O^ӚU|F#oAvu;v]3 4V<.KU,@:Uw=9Z$ͷ0" Gq7G5լue͌Da%0:Mdu:Ρ:f̰^m#6n>9fue04q$Hz AȰ4Xf8f>Tk-BC׷IOnh궖dz"(Yطe ,=I5 }J58*Yx]O~0G ̺ykG1  I7Ldg5Qujk5γl2etּ*lv DGH`wɦV)\ &kٷ:%w%׽Qiwl;<"IAsdf}хdzIžJfH[m.K(1BCXeZ%iqv,Yr+3g>? #k w5k`}p#'q ['E57C͖gg]I#Z.v̌Ϻ0b p[=O[IZ8fG=e # YQ<:e4'{$ky)g*j4U5>WLxM1cdӦzft ,}1 L (bh*u8iܫ%VIomٞGTk?w\(lIUJobmc8sc5z}4pFd`gk<;tt<;oZ" qSY/zӨpޯu^]Ǧ\L'I#KX6<0cU:^#//|RN%.Xv\UvPF@Oc5i\Y\]HDs-beB݅cf=jte5Du: #25:W\S‡Gd3nM;.r9VX ^J ov^4 G EbnEc"p0Оv՝r3pLvX$x#ث3V$[rO|g&N[#I+[aV [)Prw빉>UeKW>%Y-%\dQUZ6iG{jmQE| e0 V#}V9xwSmi*fMԆ8;Ol'|y=<swH*GCRFww"ϗvcP^m'P {T,啧Ht!ѸZֶwM-˶Jl Ch֪/vƶZ7L03\z|`-\O?8j低3\ąRA;5s U癔rA`bQ~CUe0_5[Zҋ)*qSO̧:ObUҔ4]$0nhr蠰 ɊXk^&/)eBpudos OpX lUj{{BA;XڜcNNx.BR[yJ,y=~q57썤_ d\Ĩǫ;'xJ<[*\}M|l[%Pq(#H8:cXFVī,'1çҨx_@~uտL55bUW&7PYl\C @M=v|7:uΘZ~~q;okXcdt|3e ˌg*lݴ)p%GKfŽ0G^xҴƴ^}Ӭf_svzGndG$[#'-Mn[(ltힵwcdq(PqRG]3PwUPE@i:yݜgtgGiN<a~_ߦB8g6V)E,A w0D<=}F!HᑭlPfȹYcd, @,@$ :M6Q-VCfm'' VU<[[3Nw+*$0 ǯ=q/To57-70zRsԅ"50,imT*$ [ MB$kK[:fInd%98$R'+ &0;v @m3f ?kbɞzRvE|^.#Xm/,Z .=Dd_fÎӵk애M̉#nbI//6c=qwVvK7GU6ղp;.խmN8$p )1z y{j1q^Z,k=1 >냎IאH GҭM6; \,rUW%$@QԞTڲ*)J d|ƪ-`2,dOrM[UGEXg8l.V5 TWk̟?zO5'U'j>4z яVv';|O}˷ ڪ2N^K:;[ D\۠'@uqŜYw<Ar.:$iy3ԓ謋]^Kբ!{丏8v(ƖF9 1[6߱ƀ[g[*60bZ0R:}9uv|}F d$ds[RXgXW1 rTQ7>M'ahhϠIz˭yi$M]8vXQu;_ ʹm"qJl55o4'TX'V=~=FzZl_XP--̊]DyۍT1$HbieuHfcw$+ȥxhdY#C#`{}"%&n,bG`IYܒrѴ܄;T7M.$M/QKHl\Yʑ6Z6(BU=t-rn.d+: 1 EhX_MR{:W\W".)ɨ l a9e=o}bM4#ea!0*\1GN9P,Zni\e.o,ݗYM;Z[$O6M0KGSf<|5{HET*Ԗ; q3F]7PI4q>r /F]][X=VF2GOA_C#&XA۽ڔ=A2>28 &*%ψ4M@Jl r_[`)9M $ryrE=xg[Y'Y&-rY0,v>[lC U)>s.[3NUn["8LZEw{e6YdB~CUe0_5[[ҋ)*qSO̧:ObUҔ(j\Sc^[AZIq;$& O,\{Y7/5hQ\|qӜtȂUژI%ugV0pONO5*+*;_ ER5E :` 5-;ñfbBd=}u _kom{ȧ0\<ӓsU]paMvP|vE;z簮{Mp.cUʄXX=t wy{{SW6_I̋h=%^y,Y2,z=|3ެ|G̨uvԕoĖt!{(ՑHa 1Y뚕Ν>pBtX:rHX[wSɍDB!yQH\H}M>OOA~S/l2*FXc }'OHyEwj%DEކ&AuǩإqbdebHg6Wp]E$HNnɕ:V6VQ["fe2W?zO5'U'j- y}0j\d-Ys֯iO 76qwj|,Prj[ h$VQ)wz%TP2I$zj}w%ter56VFpXpͭf >݀3tethS+36?Z+m1اy.G+>N}#˝s54wD:DBAF͘۷1F+:/W^:~b-~LѬ⽊kȷD}aQNf:q3 iJu584-oı.SGxd`m?tY1z4m++MOM^iRMcUR.9'~ZN.dI>c2[95Z:֥RqW&GIu8B2/ _Gמ$!sTMWz]VCҬ~~u?՞_mYEL? Vִ)*qSO̧:ObUҔ(j\Sc^[AZIq;$& O,\{Y7/5hQ\|qӜtȂUژI%ugV0pONO5*+*;_ ER5E :` 5-;ñfbBd=}u _kom{ȧ0\<ӓsU]paMvP|vE;z簮{Mp.cUʄXX=t wy{{SW6_I̋h=%^y,Y2,z=|3ެ|G̨uvԕoĖt!{(ՑHa 1S5=M4آ>{ #`BNIKLj"ʊBClz}=2 OL]J(h$E<w`у)b0Atg:vD.}x3NXHy/5WL7oNzʓ򼷺lm,I7:T=Pg:ȣp]HR"Yh6DΥP#{>\ԋomitrG NYeލԯBGzw$'Tִ5BL3FH8 FTz=DʉvKkʡAf,ŎpVwH)JTR2}cT EA9pq*OjWg<*mEL)ϽU5_2\y?ԝWk̟;9%D}W=z5 Ku{]?܍{ Օe-¶KgF̬S`ZQo2K*ˉ =Go+ac6Lx`|>qSV#wA1[+8".sjm#h;C: $oNqQƭ2åZih!Ȯ6F&U$90i\6n/$U iѤ 9e8USu#wj3"^%oo$I YZUCr`@v' zEJvNQbV5F,$eY2nƫ]4GY4I.y`{zA>~yWu}vQ`H]$Pxr6jGue4{ll)$N$:bqR8oJ8\}C{]E< BBϻ^ ;>6[#Im7$BCVY"s M+M{Pk{kxl wu*tdtb#sZ\In-> 2=P$pQ'H ZgsJnXh`äۏLg*#pqץ[]yFH ; n eA93Y4hWMq4ڊc"J$1Q* zzk_U6,لѴYbg.0(]vzyez/KwQ $y$ k}ݕ)JJRU:ߤX.u]nsL jxG~CUe0_5[WHaIUZ8'STWi⬎@)@sR2 ^K%` 0ydg@j$,ayFrv3滎ޜDMı+:р3ztRQqU]]qWmn()8XWѭh!3%믟b]׃|o}^E?*朞˞ڨ">Ȝ/kkE|eC,Lݳ=uRkvT rČ#Skwڞ¾IO2O(E>d[GE*]N+d䈼7c)dכ>eGcK~${ FD  iM<`.b`rH=xv]cQG^TRSeGOfjzbQDA'2)۽NC^ k=IS'sIAӭM\w. bWU.7GFd`#Z ;}x$Hm4a[ z %,Zk.D11gۨzTh?jzp!yČWI=فlo 8gځ.$Ȟv@iz~m9ۇzzEG{mInԑ# ݓ n86h:H,ijI$,z G= :R R R RUGEZIUGEX~qȷNK+8/$k!K{Wo-F'P/!ج։Idjo+aY4o+,^M'Lq?QZgKm젷 ZX,]Ϡ#ֻK6tKLf{ UAhL/﭅E[;o3K7E(NڍݩiM͕ EFv(t1鮴}2Z鶗̂)`W@$z)4ƼSur»\[/{njg $cnZy~@x[;|&I 3\%r$TL ۇr@8GB[ļbtGt>AX+@G,`!T|NsENh*[k}vjp,.׈F0cm|ɷj:eռ{]^rǓ,q"@hf<:s8;mcKCy2BW%Rg6 M-6bݢR!JqNN}y>]i啽LdYbWAu$Us<]ykrhmw\G-dwy0]ĂGOMo~#ԣ:{xt &&Vwٕ F[0NIse:l[&jڌ@ 0oN=F&+i!Kd9P0zX{IVX,5^ J)rFAm턾Ne+̈d[L`zRh.ķ ى$7:` $` =&{he&6# ln^r.{ Yy%X+S|6I2ztvs-1)cC =:u3ӿSf>O狏8NXgfGDtZ c~-Fkz2_ 2;Q_^<RO$ 4M;_66# Qi\\|GX2Iwi'cK҇FF!{6j\S.q4v)k{"|1ݧOs]Jd;)7o:^j>Qf4b6U(=N0H+7oj.L,1Տa;DV@@e^:Ռ; FTmA۲z4=8Ѽ/+EM,aT!v/t96V3HyJ{N2#=GCHdM~z$S$mdC2?35!_mYEL? V,O̧:ON>?2 O>WOJRRUX]79HdC2#c#ڄ""8!$T4D[ߌ{ ;{0q,Jέ`3 k?\U}WW\Uv[+=@jA=:tkhZv3bąb{dA>a(jO8aʹy';HᏲ' Ě_P+wla]d]#6\#'$z@qp櫨pr^QpKp{=]N+d䈼7c)dכ>eGcK~${ FD  iM<`.b`rH=xv]cQG^TRSeGOfjzbQDA'2)۽NC^ k=IS'sIAӭM\w. bWU.7GFm#9gw$V4<`y`ܬK o |{ %,Zk.D11gۨzV3]_3H~Pka8 0,>|\qC>k5S* I.%E93dU̱6RY% c ,?p tKvT{)[h݌lEϣ*>o2}Ir"h-Gʈ6a󘎧1p5Zqtk&% mCC1n`P=;Xa Y.$'3Y`b3OJcܞJ,O 6;HNXˍm,jSFc6#+)_8#*o? 9RDd@ܹ2;iXAenƱ,:0+:/O*3a΋ sDBΕ:/O+$lpIURUz5;Ձ ynp;4A=j>5OիcUZ??AI}— jzf䛽.>dh;=J{gXeuA[JFnV#!:EUqakc3Si=2=컱0zjG}3OmZF[X,O;YPp_lzJ'e5h,aȘRc+F+>m`lesOhMw˭ҙnv9Ȥ7"Iw+\O+K}6l"b#~(N3'^C.a:Nou, ˜699O^OaQ7V[kN;kTok6wC=J#+*#cgPq8nFֳ} -Yg4S̱8v$܌8ZW4t- 4Ap3Qf@vو$`u*) I6=իD Rpǣ;A~z>q`u -n-g+$/RG:eT;|</8t܎J&nKfTf$r~uҫ︊ID7*erW zd' Ug/ Բ©(8c8r'4=CpѪrUˉe%B߂r3^E6V Dۦ?]SjSjVvO%̀Z7 "ӵu $PVfm]8d|⬼v{nz'?=i:u#Grkƚygp8Vb\'dsiۡw|[mc`wVW0I[wwion-@0QFPu98Zqkּwf,*U_9n-{8Ôk!Yeydco4طh I0}=AcZߋ.wa쑰{:su=7wE<4RG扤3d Ԫ`QfQf{B-ɱ6#ѻ%\Yvyqoom?.6;6R.S2:׮-Eϸsb!qW:g=z}Z_KovKX2-k=.xXVa$!qObzz=1ZKFKV8UuVN{N+1m93K wt|hdVk7,:1z*'ڼQf6Jlʂ0+;b,4 Т̹9 cj9ǩ8chMo=C[yc-'Iy$da',jyEY %ȯBL1Ǡz C=&cqn1,6;<@vœo`LQXHn."QqbL¹ǹ' QC[;.$ܫ4˗~W^''sncO2ZHr)wTH*sq*5xn!4{Lq$/PK`jluYVZ.QNzʷ\q\_rom$8m#^)al`<=1lkDNHNQi%0ĒFk',oPd P7O>ɭdy7t@T'n힙'emJ81nU;CJ Hl d8KwI*#Gwd pNpGNt7zŅ9v[˸/68t*q:5܀!kmcž{.FqCeVCҷi_O4~`鄑~+L?}'-*u?֛G9&<#ؿ ڲ/XtOPu_u}~e?A}֟|+@)@RI2ӌ7mRI2ӌ7R"D ɻjpNp>SNka>+[kW/uщlHdB}u(:9'5񥎻zމWɞ+H>oz堯]+5=F3ⶖY_S%K*GLЯfnWs5Λs%IϧבGwwg|es<lޥs =V5۩++]\;:W.wdnN'\Yp!d:pNs.2E2)h0KXvQ ‚3l"ǫ#qkgl7Vs'tǡ=itGO%&.6[xec^QOQXY񥆣qi&nSDy(\0 ~g?P"4uKi @ 3zsֱP&d i yL.p)NXR:zpzuʮHUHY؜*\H-NcKuI@w"BXK:VSA5 >وn},L*ʭ8V3]_Q<`0ʅ8'$obagyg .4[Aۃ'M(&|ձ>il#w`j~ݭb;L24rFZ@#:s:zs[۹ N$w1 =v/Pwhm)Jq&e<;Ļ:'3 hcRJKN#"R"E$9 UHzO+H$.$Cތ׆RDZ!QeLLmPmH%To]Y'S^kqo4|𠺐lp:N3kEv0YYcRǩ`g[5xQӽHO&z@zoV5OիcUZ??Ak:oDYy9Youn;;3>2H9XoRqٯ5wpVkJ򝬼ټ2OQ߬t#^:Ohm$#)lg'|T{iMۓwkmhB azn1Bg <3K<îC*wj*'vrpZʖj-Ѭ"):z|aKǨiۅ#x.:t q>mׅyovm]ةlW9$vW,bɨ2{T3-ѡRK 1UafA>ũGX<$hdG*5uz6o 6MbŠKq4zs,re`N16h$j)OˑFvqZGIKX졂)\(c$op/y?ͬ0I$`"8f !rFO"-4=/Eqkbdc !PIo;goS->mMlbs!n"hSX O+n"nZ!o+4V̋1R739ޣW" ֛lfDApG3\Zxnhf!}BS)_zrNIl9U:q*Ee,9.63zuǪ]q. SYQTKk9iUٶA`ƥ^hu'DI e )rJ@X_x/uڭg2B۴_k0-([AMequ|N-$\-rFX1^1[,Kxf{~㯝v 16r5&3-h;Fq?%Dڭ,M䠂XuR%@IV)zYwzNAEz֕/voΧ_75퟇/G7dz#=#*zt7+q%g*%˃uR =T+Ԯ[Tk+Ii$eL67wt }ZY}1s7O;á0A;dxމw:cfx;^)QO;bJ_C/v'=k-C|vٴ%K>|OF0pNn=:AmuoyxᔐpFG?UUq$w7nuR$1"n\AeRGF¾O?3[qߧm߻Z Oa\ "ME$c9l:I뷏Ze7B=R͖|NۅSNka>+[kW/uщlHdB}u(:9'5񥎻zމWɞ+H>oz堯]+5=F3ⶖY_S%K*GLЯfnWs5Λs%IϧבGwwg|es<lޥs =V5۩++]\;:W.wdnN'\Yp!d:pNs.2E2)h0KXvQ ‚3l"ǫ#qkgl7Vs'tǡ=itGO%&.6[xec^QOQXY񥆣qi&nSDy(\0 ~g?P"4uKi @ 3zsֱP&d i yL.p)NXR:zpz4T4qzjlo-EЊH$"dgE8 \obKvڎa$i-w2Lg[[,>,#HP3sWN%_cœ^ۈRDr˅=w`]6gwg5m-\ؓ 9i; g$b^]%d@"J|n:ڲV\{yq?4JHɖ`c=B+摮ܭݣ[ȑ}[uWvjGfio Uj\d-KY"l8&5Or:Z~z:F[[ c3QWaHkn9pgva ' zdԍO^ӚU|F#oAvu;v]3 4V<.KU,@:Tlc-YEbWr0r1Qy-.T! ع9#ڰ.u56e iĽɳvk7)8 @smoզfI.ngOe$q-QF;[k}} jZܬ$e8[o9@cԅ$_OY_N,sDH@8'Zߛs$/aHYɷzU֍%Ԗ#Fc`XF<:V Z.yn٧.Xeѱ gqQ㽎MBk ̆4bcZM MG ;nd1L#.3_{j8S[o$vPFrUB6Hb=GAP=?L[[rU3ȄNT謴ٯY Pee q8Og= 2pXYsr͎/OPm8";h@E]&tѬldb"Bpu׵nn _[xK]$ʆ$?FԴl#QFŒFI j J\Zm&6qUM?qÚ%M&"Ku_XE,t],O\`GR\םTAuB:ճqN5mRIJvBϰ0E%N `t>}SM.>(.`iQ{H h"6Y #@Ek.kL0p&qiCw |gv7PFNc嘅Q"ջɶךŞo4vOu3;v]?KIZI$i f#Dq)OFr:T=ޙmH1!sHÔamn Pn[X*d\Z/"bP r)Oigssc -6iw U*K: kVZck8ER11'`ꛎ7u;$0+$f.bAQZ֨nh}#k`6>^='8E'aYAOs$0$F]/gNlMEaW|n`8u ݥ|M"4=UHvڈ<7 HV'Y#${}UoLZs~[J s˜Pc0_5[VQ~CU(>?2 O>8 dXG!U/f'V%]M**2X##WA'E١`qҠJN9He#+q}TkTB3>iFr| V-xDwkd#sA.'pU+im-%2T`tȫ n{3\M,w;R[$}y5W"C-gmԮqq٤ZeYIO[Y.EWP#z5˭=Ӯ>9w,5Y:@\Ǡ| k̶LpZ7 scD [`3VG*խ G d١b}$+Bz}ԎBh KȓKB/r捪[/ҫ$ӕN34@t'PbXRKwiS6aO/XwOb5m "jd܄IbBqW[;:58dPMqr*-3A+X0!AX1N&VkYhBd'dr[l& 91cW֦'Y kx;q wMW]:K(0z>$8 ;=ߢwFFu@d d0S;զmg LR>)'SZp-J%sUM L$2s}a,6P]5ܦYل!ڪ60/d\Qaz`-UNR;FB ּXYAS5aV  L\<0Hb{:;MYHYm*I*h܀ tl$ZYo{fpx灣ѐV Nv2GZT׿dx0a"i %),5Oquh#Y[qnSXQZ}2"]^Zk(9cR(XvI5Mr{XI۴rvzi<7ax$S3gM]w:d)\CT^[Ʒt6.UTӏWϟZML1pM ;y0m$[E¢&ȘFdq#q Ku2mUq _:pOL Wk̟娆dJ$FBp mR_28!4o{s- In`E܏EHoj-YZ<ˋ<,s2J`u>l[-5to6ۢfHجOӞǧї8VF&EiV115z\)mJU zJx\&6*"Tn=x""nZHrzTSqAK :q8"c[͸It˥uSѱaB+sǮ|WlfQhdG6P -YwFvs#|7>h'pUy1#SkPi7qE$y-ţRr*{oA>߅57f侎ḹtkV%8B`:]GOᾪx\8˞6[61Oo r䏚 > {p޹LgIa1`% J 3u$ |r| S'pUN(q&E{KD0RXme@fۃQn8NKRY-u .Ka\6gI 8q}TK蝙@%Y >ʣR[4;y&𪱅F26lg5V%z @\Η9c6k #lblTm$*0pw!}~x8r2-z$wc2Oa-V逐1*+Llw"Gs}E~tB%x[ 11>z Hc&_uXcprw0ION/oZRTN{2BjS,P]C;BKBϘ[rh 1AnSѝ4X"T+k( V8Az:f"E,\OꪛiJb{QAV7?:6 N o˙$ӎ AgQI!\-NDdMHgVB/aj&kZQ`}~e?SqO?I]j6[GO@OYTN3;GLGy!]I#1ُAVqH0p]?0NRhtɞ)69Z-[XI%`TJǰϠSe>>rz[xq9eW뫁cij}t_Fo]0,|OFq=Bb6rP 0=b6^_FoUiGnt6 'ǣ"뫄Xx_Fo]9'L OU܋"3}$6[IaT#__vzLjiz$v$OO%c ȣ SѧѪEfIӑ}uzhhw"3}$ȿI>`X?撫'SItjN s򇲤Й˧.~ ~ -Xˬe7e,c˧.~ ~ ..n pе[&GB9=qzOvIiM)bqmdy2;V+YӔGI9Bzސ&X4V6.^0H`y*U!,۠?)3YJrUA/aj&kzQ`}~e?{^tOUӋw J-d88eV4CR5 64ɵ{拘⠴I'/Uc`p!CAGNiqR2Gb@J'u=j)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)Jb&j/ajaIܦ$*Gb`=}~e?Wj7M[X2^\M$BI:(e5ٲve(v؎r;VSq֬ͤ /hbc:ȯ0;B=+ۉ;{[;k{S,$Uwǘ!9mpV;Kv{deZӇ4ە;rdv,Ypz`U?N\iQU9c@'2@g^K֛s# #osЃukfHKF.%7mN3ԯ&Yܟ?el{҄Vp?ƠAxnL|,=܎}=zT>(md058Q \'s_>kVQ;EoAm)JRRRRRRRRRRRRRRRRRR/aj&kZQ`}~e?Em%n9'27wѶd f5( _jS~㚿iJ~㚿_1weZR~㚿_1weZR~㚿_1weZR~㚿_1weZR~㚿_1weZR~㚿_1weZR~㚿_1weZRM66pY'. x8$U'+u)T)JP)JP)JP)JP)JP)JP)JP)JP)JP)JPm)JRRRRRRRR/aj&kZQ`}~e?{^tO^TBƝ|?gj@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)A_mYEL? VִaIX"q3SO̧kB."n->Oݻo#Yc2\R`q`ϗ~OM W3F"tuXVf0[[ (mdHŽ;ݙ%f*N݁\Ќۈui{p|Uh\ʼBfyc݌kҴXVƸG %@=>S;,-嗅,fܽ2 ,I?5nf&R\Oo%%#E F+۰ArnOv8O[mk3@>;y H>p,GO7e0F8CꭳZ[\I[+ۢg@Lg֤?5OA Rxݭ_Sc#H*۰1i^u}Ii"FhXRꭴRRRRRRRRRRRRRRRm)JRRRRRRRR/aj&kZQ`}~e?{^tO^T)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)A_mYEL? VִaI}l +:RHܬt>ϺO̧4mOX[H{EWŖOr=]3ֵ#LkwzE p7Wܫ\΢04td=rOqswWv6y^]YXpun^4V2ya;qL TKf8ݎT:]9 .&f[}I-Iib틹D=XAw<˸od簊y;E ,c.?':Hnt͚$y!NAss^Es2r%12e#fE_<_\?$^H#.q*PZ&]2-F=:M\>eHw/{8>i^\(#܂62 ]X:G~ׇ"t7@hڡA;<;Uՙ#m<5,ȗ:w q*.n4{"yH@LeAqԋ^K 7[$T.[r U#<|` y2;2qtEfch6;\FW +Sn8ባ㗻/t'ڋȫ<'Q{KV1%󸃳x$`=+~ ﮮIg  ?>쪺K_T"8Dp%cɸ#cyk香 (,Y8Ån=]I?hR<4Y^EPU;9_H"]{g_eWwl|TVzõN\YiP^M, P \wWA [KRGx@9$LA-Fӂzgt5hiq,@#%:&n*( H9uvRG>P Ff`A,) Hyvsps!EapQvcS HY݆HڥޡֱL~(BX''z6*Y׶Xc1?'#`H2= OF* g{zI`O @;ZcW3]]DiomP12rz} \,tkDk,ǜD{plue2As)d' 5HSTXuqsseԶH ]u%JLjHv]]r#1[SmS@%GN#f&Pϫ#[U\?go4rK9nu-F"(rRRRRRRRRRRRRRRRRR/aj&kZQ`}~e?{^tO^T)@)@)@)@)@)@)@)@)Am)JRRRRRRRRRRRRRRRRRR/aj&kZQ`}~e?{^tO^T)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@ڍZfu2Ek ,UA'5Qş;Z|KZO(mqCG:i}YV287OP'{M\(RhYjIC@,p;d}~Y3.}=#S":i}<Օ)[O>6Go=Zyb У0# :VUp/޵MA6 >SWOKt9#OPuӬѤUHЀB2IFQYkWn]V0:zނߒ>?i UHQRn$9@m*A݌c+lFLyFv@.l6Nzc4ܑONHh{]j;J-xdgȌX:>zQJdl䏆~."kɭQ<*vp?wﭵ[gԿ"q~CUe0_5[[ҋ)+ )J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JTqgֿ[MZʚ=xy!mݷr:gqCxIۋ"' ?w6^?[ڃ]2A0# hc{?aoid'Y3^(eb1)U!^>>׸6kQG Aҹo({#ͧu5p/޵MO({#ͫЭ.庹3<<\cs{^\~=k-eg:KӠ7A5Ju2$d1Hea U^zj"lg"lx̤pG**o Woj|(ze [ #d?:F1W\7quisXK!8}7A5<?Ԝ}#ƙqXDQ$SFPꫪzxdSVŕV/ȇ5<?ղ{kpf6>PO/( ޔ[2&aN1=j:*0>ꮔ1=kG/Os_ 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}C1=iO~} S 1=kG/Os_7߯>ߏU<}ϿA~PO~s߯x~>T>}BL,sVuH#x>UEuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image028.jpg0000644000175000017500000007310111665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Q@"R !1"AQS2Taq5r#34BRsCUVbt$%6&cd(!A1"Qaq( ?IKͪD=J[ySk& }xUR%KJhה,y\sdžf90iS(Ûø{nGQ4c2҇jlEcM<6Tmk/jZ *>(8V qK!ea\qug3Eó#N׍ˊdl[ 怢B^ʓ~=J8b ]}\W:SQ3) vn3ȖnylmY{': -FM MĜBa`wK`؋YV M~MXW,_CK9㮭n ~P vu\V'}Ixqs1*F9R,s s"xjgG;=<51LY*ҤSPҭ̓YssQfz7*\fxTڷRm"Qõ#NSObsT%:BVJIRŇ?U0Zk꧰ҥ>1l+*gG;=<53gZ}eYg$f:?MSF7Ȓc7&2},$_M7 m+Â#JJ\ $ k>!2\52iyCݣ._=6+NIqUo Z8#i՜ cTt~GWp6FPr +Pr!TdIJ"VFʁy¾)!BƤHz3>N '3IeD2k񫕡љ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ pQ=Aљ !E&3>SWAc̈JZO%&) 2#pJH[d  gDD߀wAUy^Y&i`qH˘ò*p蕆G VScku;[.⸊ZJTcn`Q{ Bi+: vbf8m Ptvd##/| (_kbz;~p1=uAˮ3ZnR pC9B {/ꮣvm ) !*ѻ[ )U oeu OGoN':fʷg2.9OhC^-m d󸮟v嫤t螈_;%l4fNdev_'PrBPr+ Ve4]S롅IRLV VP-&:kjߺ OGoA((-6R(쯂3d=]p1=u8ߺ 4!D$i쯪i QIIbz;~p1=u2[AXp%`X*^]'S9 (Xԭ}i$r78ߺ OGoA1tRM🺶u8=lbB'|<'"w~bS#KP 🺶=bR/"w~yB'|<'/pu8=Ա🺞P k#N/pu,bB'|<'"w~bS#KP 🺶=bR/"w~yB'|<'/pu8=Ա🺞P k#N/pu,bB'|<'"w~bS#KP 🺶=bR/"w~yB'|<'/pu8=Ա🺞P k#N/pu,bB'|<'"w~bS#KP 🺶=bR/"w~yB'|<'/pu8=Ա🺞P k#N/pu,bB'|<'"w~bS#KP 🺶=bR/"w~yB'|<'/pu8=Ա🺞P k#N/pu,bB'|<'"w~}: >P0_c?;?u<V UNe/I2|S;?ump1{{o(s.]EVGq쳅MEXg~IG*(iYVFת;J=Vq6@&T$,S tRZ!ue@H-k(F\EVVcd[j`8w6jM4ĚDݺ{߲&8+uRU-j#zBjl$Tå8Ԕ.uK'^U01&#pqy3X}xF/iia:Dha@RAG|Ýpclgm+ըM6B[q, Vˈ`Kz=lfTO+m"PnLI -$MnYuhJ-}c55c+@RG ة*R((((((((((((((((((((*bc~%*nP F۶11kpCzQ'|>J,yҵ!9?NiG 또fKRa'*z]3_Q1;ȏ7yŧu(-Iq)EO;\^ުV9bl X̄#>%) & :Ϻ`'r;mO.Q9j^|o֥e+ 6w{~+/g~IG+RJRJRJRJRJRJRJRJR=F$O2^@)@)AnXXhqRFPBt Y#@ʤNU_0*ۭ]JBR꯴r+>IQ` O2uKJ_$5Y{EJ@ߒQ Ԭ%߀J+;ĤaIL2k)+]\e+yȹ@U՘KIJ SţQ"Ĕʖ%%D_B9G?S.N*tDNmzfUwR4=ŦaBb*aHjlFS236Q.;m-oBTI}$衶 9.{=s?g{ÿphix{0e.Ko*ۧ?a8[mÐ-A 3y~6{#=ﻱ~o Y j&—ʴ8tZזM8[V2Ȑ7!nOK P )I[p[cmS Z} RȹN`G-}]٫E)pX", SҸHOa$.ck%nmL}W&#J7A=xKpp5%o27YW$rSXi\K_ sLW1![wu$js DzJ6@j s ͭyܴԝҸӷ?9 eZiJʐV&6jfsB1ث  (mg1V`HJ<:JWbM" Jٙ\.Gm*s$ Z{N "pfu!Wa{dʡW-mDWJRRRRRk2 SUiߘ8PYQ”aŁp_Xn%"{ YmRkUKhҹͥťx5O–-"_1obx6\QIyLu%Z*PڨS*Wq6L=òX6# H*$ {9 j2"`=2B Rd!F;i혛}+;~c00XYLƐ؂HBl /vt,)E)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP+/hI_kR~$Y{;J=Z\ r[HZMEyf8(8a;N}.Pv67åaC Nfu6Gm lq1-uyZPkYIjx4̆Pm܆N$2^SsMc;^N?p׀Seo-Ÿe)մZ0kf,E D-(=U>PIa-8"ꧦHsh=V܁02-cZ' u97HIY;da[<3~Uq]FdJH'3 Ȧ$TԼ/'s\c_U웉t-^ Z,Nb;An,CmZK"JEas*B_rޟ el0p6w$oI=s ٷVWaX{9r16NSqռ2~6hs7nbgGS2Hx3n:Z]RE*PVXmQ[,9u N=gGU,>|K>'*q`;E`2>U3ݷd% U>X˩c0[r*b);jMy{wptLbgL9KR,!m P {9 iTff/;ޫ)]&J9KЖi;,,@G%Nzrv pݒㅵbARWU{g (f㯭̙ $&+Stv>LT~1#^MiSvO8;{3ާGw,4\J(@s5KJTR@ 0z}7w׭?a>dG'L;>Q#RP <6%)ݷ/2lt6PKoﯻ~ܩTT7L_r%Kbd;qt4&#젟2hS0n6@^jʝ/s^;(,+N¬iߘ8P,El-RI*61_qQB2%R$uME^D0R!Iabm&8FpԽ *%:PgqtfoNR.=vXSm(H$O! _IcHBRSG*um%Y2 M+6A1cCLRR$-. β³k}u|4ȍL=q9h%C:3'ڜ[%l)2^O>,< Kan- TA#֯S^*co)ñܷ^QMx~׊KTHQH Y MJZ(DS^<[S-M=<"2a%c%!)J<0e?S SpW$ \eV-wH`>27~}}#w׽}<">Xm! VOP \~1#_,H9@ZnhE\fVȕ:y 0>,w!>G'PGRCI;6XaR>u2'G7}޷cU0J.(JHwM m*TP|#3}?d{Eun%J̤XJO1j 'S0e,;(V^|o֥e+ g~IG+Rw{~(2hRqW\;96 l9P⼇ցEW@6?Ĕ2:W6Fۜ>Z%; : 4H'VR<̊k3pd\d-Ґt$c`OXҹÜhFmTB|W!%Y)9&׵tی=RbYPN ijQ* mH^sQ\&4BnBs ´SV[%ZDv 7PcjnR@Ilks,*PY9zZ<8y Kμ=uʐr,*nA9i:>a<3eTJVSkOٹoD?vUe#OZ BF+8qIXM(uZX.49 ʎ#5'-pAI zC+hD%MےRв.urkIĤpp<\l^8T!PΕV@VR/nv'+h~4'lz:AYԥkp%c %B-JI V^*;qH,qRʀKa (Zͦb=xB i.T4V %" xflRؔn/nZWEd0 y֒$,yj!b/}6JVpDT ٹ’*Cl6!%OטIH'UUm0@rR P)XuX66"AP [seu+#g&$HY\ Ki2OcnuWC+ 2-3 I]Jt87Q(Bʔ22.yWYm$|5~ [Kݡ*+(KʹF¸ (d$%HVRWp|t1M`!Jä:K.Zr BWezu-ȓ72Z RE`O+s6.7eFk]tI yI-ۊkgo&,ww"VrJUams9X[~Oi&ɒ{u\ nWuX ΐl8"%%'ki`LESQҀmJu_KeOgv@boҜq E,r ExKbPAB2)3>pS[xpM#AVI!J:rxХHK܄%sp u 9=Gg`Mð\=C SdogRUI!k]fleN7%c΄yK_C*'bɅ"\&#RK#ub@ozm! f6L1 sq $!ʰrQju]~ +},9nY_0±|Y6+*΂?D8c)oaRhabUkrs଺*TQ5.3RVf@Z .*ZU~`|Vj( KB;1$ʂ\ɹ!j+~,7t NbUzHʧ`.[ WmbicD^ *')W=u'm0Q,TJVU$(t9AEIl1)R2IB 䵔Mx=3 \X3XJH辰tsmtҷ%m(qS-2یu2@RBӨ#:J<Ө :ū?;NxKyEA]!sMXa=%)ɒRRIRPt>2!>Ɏ󻦈ߡ'QB^@ޥ3M?g יt-7(ptרΫç8e*1qmHݡjW\׹:mX83D9ϼҥ$8rYtHБkS3uqpӺ'33eӟϴV$_ j;Uu:YRrX_P2j]˭.:Ӻ.-'v@kׯLKkfdp9% Wn27s{1ZBXi#:)7cRO{"L_"cݭ)Ks)UӞ^tV!"2܎[%Z+8P#eb!mp = KU[aQ>"R[dױJ ґ˫i92L &B@$=fوlLR N临Rn,ӝSjN)#e`)SV$=%%]3$sO]vGq)!2qYpдTJVAY.Vz_# LߩIu%yj#g0%0%: 2n/uXιiF#%x԰u e$s"7ÃdH/0c[RS˻3M#ʓ֔KI$^Wk_1*c|VIy @ HW+#hqo(A). qf2ZJurxP[ŢTFޒM4'Cz姅q*:iZwZnۨc]4PBs*q7!hR3H $Ic1Yq b&8VUktUULoPI1  D6o$ 'Vg}m;( S不e8sfI+5Hڮ@`my8@/-C(\;t&0l%dXtjl>R_"S*~:RގkWjnV'3*DU%AAT[S5 HB|(܅tl?Uox“r.;A"5@ ˬzPe 8l2uJHm?&U0ҳ,[jE.']n}uJj,f4&%)@ӿ0>p5Zwq-OLr!ճIEB1) C QUTAnuBձ+deڛ.1KkiKhjRs$bƦNAKr:8^RN"d<xRB,WܝI$\gfY/8,$ '.uY7nUJņ"6MiCIAbtURaJRJRJRJR~+/hI_h;J=Z$A3))i6%)⏣j07[󒥑7\TΔe%*+eAG *^ :\״z"1}Xke%[ YBMXcM2pkqG5+kfC-aIJr+ո{Dځ7 d:d)Ra@5qG5vҧFEG7Jmom9֪q'ZŸ L;U`9O1{(NqG5=*8+ Ds>ݲUm9tsXZqG4⏣jzPAGӊ>ANAjS%j ixqG4⏣jzPAGӊ>A}N(;ƧQw?8qG4⏣jzPAGӊ>AOZB+_^g~`|A`r>[D"#M y*IGZx/9 ]q9(1Ƣn|H,-)HJU sp:M=qԭJB)Ee&Qbl#-#Ͳ Oj$6'!(S̄ J *D{UbbKI$lJlIӘfg2R;$6 I6RRRRRRRRR~+/hI_h;J=Z$AYíImWZMuP\S%Mx)Q˗eKުExN/p*[p`_R<^I~ g Ӳ/)ं4۝Xqح -Y,adՠ$ ΕŐ嘔E`4H7H6Q:~K#81-峓E%~*J_ RBÉ($.y1ךTY][ea="{zU+3mirWJ]y5vVʠa2aiA]./3cKhd4 -@ "*&"lE:%=4NbPlH]#g`,۫!⠥K#*=5(dde܁$a)H|H_@o/"6xK  ʴ̝l䅍zR\̄-*)$ʳi6; bjg*X/))*7XNW^<4CϛJ׳\|i0MؒRˋ2a{Q B\N\bDF \m%ߨm+NM$1-&Iq,&_"PRBRD).Fys Z ##PnR!yV4 !H18DLJ#6/)yn.@MHr&#~z`20.\AT8q@hBZja_:Hqa $'ZYv;hM\)8Z)#_&vRRR30>pM~#?eyQ`rB R R TO)J klA=* 񟺗ݳ?u//g~^_vόҠy}>3POJ|glA=* 񟺗ݳ?u//g~^_vόҠ^P *'A=)J)J)J)Je+ jV^|oGg~IG+Rw{~( USzD%ih% P Ԣ.s`}FTHEqF Y-4eY(R:jZl x ń|ۦ$vSEpRDn!J {aM()ňkY*PXEOoJl#(DfculJR#YWn]T8T2 ,;hS1 w[V_tZorUt#gy?BV\IRrt :Wa1gYjF^@k_iWy5;™?je",Wm1&"1%Zke +)?s&rg/hI_kR~l(jV^oVz/߽UO@(Եdm=|NY[VT yW߰gjlTxڊi`iXLrC2oZJR[k~UU半`q ,`2Yt饦HHn>kheJT>ze_KSPpP \[A:~G^jlyVgmjnn}eՆh%HB2fiYWul";4gq.A_zhX ^9ĸwjm,ٹv{Gd\wx%ێÏn^RuJVI⯳! ʕ%Vw)(^[ٶK-l.QEG7->e%4QݕN9mņ[C +iɨܬt7s1q,Y_BVV[YJL ͯcxLV,œDfM>uZtkcۚ/z_N99k[-Z SFĤ:yp^[kcçۚ/z^7v *j(-9Aʡk;5Y{@3!6Ko*lA ?=. [:Շ`OKX `2PRlXt\7&D/P†dI]I&\R[TA(}굿*(vGDe _2kiaTTTU'ȿ+8l؏v%"@V_,ZX4<]6l]oW:w*QSI ͉|PF#_}w-I?ĵb/BŠ [n *K@jEejJHJ < :Ԩ-Bz\Q Ά[6~pjqKS8mAQ *}_}WUEӟ*zi_?1YyuTřK5̀JP*wRu[iJR%L :ZXx>}NFҋ-ztko2) $/!Lc*FKJ)Y'3jVKw [B0Tms_U6$#^ۄÞ⒣qK;!+!df'-ZpÚf+IRA IQB9[觕_/m؄k^+_)j 6mA_9#Hyź `h3-6~gVJ% Jzd0$u#zybQn%֐/i 6>U aхfQ=C)JP@r?Wߘ8WK¨9 _!_j)J)J%rkk¥b[Fcc.IPtm;5ֶrkj>Ly 6~!._:Eim-j]dq\b;I[Snj/6gݥ&בy>%'1-=Un p{EuQ F"xHQBZqXRZL;mIn&h\KN"Y"q.p͌ okr7L>-5#=K!|8J`nbE.!!Gv4T6%.|e7E^V$+^mHc{O6zqKiJ߅ &UU[9p[63-vVR((1W?LcAuimER֣`$7rOPh0"yc}lx^NrHaZ3YXTPW8_ ~5x;_ _ϔMZ̏ϬYTUN5IQŰR,dt5ҽ(0?7̏ϬYTR9[AR?xi%')W&+9q[IPg#r nt-i.(X~+/hI_h;J=Z$A_zUS*'J>z~ږy*RS\kyʤA}3)7+mt?er)B)C-.  2$]i\;9)\ƒ$AϰGd:xL!N Y PU/O6Ns[g md,fI:reIv5f ,<<2Yp,&"n5VODb1%ŷ iGXu6A7$HUvwʁ_>P L\Vdt[]>2j}DZ\Z[cd[[ԡ4Zⳇ䴭/.#>Qۗ'mKrKgN):jF]O?p6?Bp$gY12V1N\ ┾[u2%H\~O 9 :fb,8&⑸a-r^|p)\M* KxbVUƖ3LF!KÛ$W1:5ycrtkLd 4e;'MzFsf ?%md \5֚{ʁk~~/hqFyb; .HQ ؓvl, Vfn\3Zv_5ݜ-ÇeI+Z:km BRjl%Mȏ)+̫\ hJH '0i=N^+# ĤߔM꒛()dDēziq6#e.ͥSŻrӬU8hlOVِ4I˧5R'f1P.9!K_ZmP8k ǞRLMƉ-J|ar%e6Kcذtn.jֳNr6ɸ\b38Wha=dl$ZմVA5Di|imruQcRZ#Aq'*.5bG>|)O-%%f̡`jlL AVkN'DYa36nː\ (JOTXAB_ZYQ0+PkxIh\#*ܪWI[EZNaD ly@P%]o>u Ls,)mjj;I1F3bQXio(2f.f&-j\vOqԂIRIQ6ͦ^ۧixtND4CéKru.%^Ki Gs{ N(W.)rLPTy.kڡVq4L!Ml \aiyjtfAO%-NœB[wp6]'u]!F[4Xo n徢""2ʭғnW-p8~1248̌MJ9Ă0m,ՔD(1~*XעԬSҥbX^~FGq!q.yG>f죦iq9NFQWI+bZv ~#?eyRD-:SFk5vwvrRRW&zUQTh=h2GAkBW&z8㩍T+!Q@.\y7 bq$3($+* V6<7d j,[t|DsG+n"FqM @,@ֿ;[Va-A}(y:@7lH!Es3) NkHӘXS6*CݩVn4"YVoبkE3;r[JVD *9jRuҧ6Q٭^Җ)J)J)J@|*zPfmg~p{W}k>FoOڼÊ)ijҒGe ʒ o(s֥ZsH?%)ےBnmk}*IY(X)XHlBbA.]KSS9eѶO3AФɟ +)?s&rg4/hI_kR~l(jV^oVz/߽UO@)@:&B, Pu-(# 4- `57 df $/9OjPDfR- P i:p̃#p܃5/Υ(F !FDv5tRӇJ`%Ù`4(57 iO#iRR+82DjZBzqZHJBR, i)RB"҂7c0TmezX̠!!#RmKJW3BĵR% AQJBJaJu0!6%q!kR%Pe'-E{*JPWsJ\ҥg!M$\u"XecHN iIJ)V.,lӳPMΧCh'J֥2Ҕ( RI鰲sg(pS/ Oe=UIlqkgt^iV)AvVr/NYZQ׭{ 2d '(ME{*JPx[IX:eQIHRtPV{{?b)2J2o֝(+2e|zk+*RRW&zK{ ç&tٌEu)/<'SYɯާo399lHu'&V$yH}E.?K ! +zRw Q jZ (JkizcCr a} `#]jYX:Yep0@BT,~RH-GB:Z*}ݓMCy2}d_'8b]V^a(y/YhȐGHn hM1+1K͈8`*rE"'+ٹ'%)m6pR RAM룫1DM*)J)J@|*zPAVÕH\uoq!E*BƇCEgy/h{ ܙ I䤗QJpQ!!1 Agq"6og.a1А~gȿ~y/&6Ԋ&6ԊPմeZJM ꭘ!EHZJ̄.}ٜF $2jk{g VEDa2I=}PiV^|o֥e+ g~IG+Rw{~( USz)J)J)J)J)J)J)J)J)J)J)J)J)J)J ~#?eyzk+*x^P_-HbƩ?Agq/B$$t-p\kW{ "1ΰUfb-{W%m 1pBj$+^ZbD 11)JBB]%N-Jk^F^L YJEiki^Xw,)C&}n-4E;i[8BtK\ָңq[.ltGt-R RH%Bz֮4w8k]H^B psn27k /Hsn#Z\^tfREh6SY8g} ߥ}}im BR``#caF{ܯ+FSBƤXrOܸK8.TUźl*\/v2]`$ʷ^P{:E໇&)m* Z RA'quF ߍ-K!TB 61cN8%#TtGQH;Ŷerlb."Vw鹒U-+T5sӣS57_*7wR\: ujhnAm$4欃EtK\d=V:eQSTKe%7Zƾ?ASI#2*J:#eZR$zSw; C8\HN~ը((1W?LcA#7'u䖲hK%H{k6;ïQ-)KR:6I>K˗A2wvʈIRy[}Deć7BTJz9I:Wigtxrmuʔ]覞ܯCi"pJg-Zo/.]<^3\ +AF +yN:rd=Dίlrg$c \WЌ'Rґ>5}XyZ*e+ jV^|o6w{~+/g~IG+R~U=AުRRRRRRRRRRRRRRRRR30>pM~#?eyQrB)JP)JPA+_OX!5R奌EtX F|Z@knW&z\0ʇH)Pt^p6>xSF3K.>]J3Ɏ%JA'Q}4 =Z`;픋d VRoFG&[n| ;QUjn FLisezJ&-tJRRRRT~_§1LaFDD4,j=@|(36fDnS?_?5| ׵yVL}+X†+V]|o.S nO%!.]tETB TQEZ޻uvX߫A!j$m˪bՠPa&n?pjBB %sBjW&*Фɟ HҬ%~߁J/W$Y{;J=Z엥2SR!NڜHVM.+c$L XyξI+nB8Ty\d!!w&WF!E*lKpcqCPyx+XysDXXuiO#b]o PSؗilK4P.7ؗi?;E8*#b]o .7~(vqCTFĻO#b]o P}ClK46%`MWX{#b]o .7~,zZTŅv2~ylK46%`"KYm[sSqC|w&FĻL ӊ}ClK46%`MWCPyxMr"ʷmJCkq *J¬`mLһђmqwnPu RHmz] xsOv[O7wiA&XVWtwM}aؚi]_X~f5&CWtwM}a&CWtwM}a&CWtwM}a&CWtwM}a&1}+k^B\8[JP訒ooU=*~YeJ:{\$Uv /UttPAE3g]%(9C /UtF;ӂDԀN$Hw^" ҒxWJ@6UP+/hI_kR~$XD#͡nP|sbh4iYT{U}jh4YT{U}jh4Yko.h*($~Q"sz3,9\#SR*jԤJuZ4/c[O¥4Í)JhB|W!1 mPyz]$ׂA$e~cY{O)*:cF'W  7ͨ]aŲa 6H HiTD:;mV>Xn4ħC1W)JFmЕ|Ux6 ְ:e (Z= i^ѳ8kXܜ RZB#WéW\ ,<SIF[4 P8\b-ѕ%Xf#^bVљZS3c!ZYfP:iIbIb3l2qoP" 8{P̴()sAMDm-FLRZ mJmЌô[ZcT|S"%K Fv eŤkfڬ-lQTr#)G?[K-,BC!7r$7VʾHڼE.2u(RnJʺD,T K E߹|n=u D`IqF!S6 :e̥zKlNqٱ-IJ|w[k k;`T`\_3n7?§Z͛5u-{)nv>=HaTTDBTIIIuڕ`?t5&2 3)oPJJ̈́:NVՎJ׶ `SCְ┖JjT؄ǣNf;E(hSpnBV͔}+:%]WqᐝuرeǍRb ͊ ": \@"Б5=K Bo>F7M$(]:f$bo\KqݭVDRFd`hoU)(7Hu}F珘+tZF[<WN W֑9Pj)nw]SZZJ{4NB{iqT-!M Q(qm))u9ta^fчG^/!A@6 ċ i5,NV'U9 7%)9tPy{Hf@/}9wjAM֐yCsj> ,7t5ĐҚx!!Bz-|8Ux…%VBIRP^%m&+ ̉2TYaF@e=c90"K%j~9~I]9z3P ? E}zTG6iżIq mJ*6H{ɍ#gyRĒBԓ)'b,G܄trZ# K,ǎFK\_OU]b;CtYRRD sA zy[U*YF:d8|A#M[.+>УyJoW(?\IT(yHݩMovJ397c0jxK9}sN(*(qT9u!p6XVp[m}iւE1`)2QH!)Km)jpI$謙MşeqZT6;(YI utam:0mo^څܦL&iZkwA͛0ސi5)um aTUl+/ a>bZK@V2HQܐSVN{⛹P"ѥzg #2 7ȱ>@brLמ*m(m+Vp.|#;Q;)C.>akGsdV!a|HDF赖j!!|]wz,H|dꂎ쒛\cgGuFT@/dF*V1Lf Cm,Y) "0U$ISmk8S6zt6݄ =JBŁI!'M[͐$$ѪC2:^a9Xn ;o6}EC*me 81[;Q[R'lT9zZq1k9MGFm-ldQNR-}@0 A$ex8; |s W FS [l j6? e,3!E!+$ k˛Opa9cv%8҂utVT{+aXC G"0PQhq?W@w 9\afNcWil|ܧF9[gA-*.%YA-T?@s~Sq,ت؋͹ \?e3JRRRR٥)Z R R R R R R R R R R R R R R R R R R R R R R R R R R R R R R Ruimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/import-by-location.jpg0000644000175000017500000022761111665471332031206 0ustar drazzibdrazzibJFIF``LEAD Technologies Inc. V1.01  }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzw!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzt ?P@P@P@P@P@P@P@P@P@P@P@P@q|XFټ^kw:ږgk,W% <>,Ew:m5鷰 ep8N CӕVEғ έ8PZ~ڭ8)SRSp*UW-JF>~{za4*Qjڗ?IB|'y%όuL{hx-=xY/[+sc]ƭLY!RR^֭J1Tpqm,F (])8y#Q&LwK?UJ~j.U ȷ״sS[NumFȹ_?t&">˙S9Վ֖OhQ^Pږ&|NQ/rT-%VxFnzh4՝[[S^P@P@P@ D9%$iNE, 8PN&ZZeJ%Rr|\۲M&DPN9F+EvJjxE|CG4_Jn-էj6\}(̷77]uV*kU֏%j'(7+Ÿ5kfe Ƥy{5[4ѩY5"U,B;aFN@YPIjg5NM ɨS'\m8ڊm]mvKv+EYZ_ۥp^[Aw _Xwk,kwV]*A 0)$hTk8:S98AFqv|$J2qkT"-5ut4v٤ijj #<Śɳ3jZtI;MײI!)U\uCVg{$Þ#U>#׼[7>+t}rS>kjX.rR:4 QbNXa+WFE,|,^0WCS 9vJ]՟6"5pJZKᾯ<5H10F?5<׍={aO |Lsϭ;a? F/~O𽏉/o7XKKbJTxH^-5էE*xQŪtgש \;x7 ѡƊ\4kKFP[/cU~ ֮ѫהO:8dtZW%9MS7P 71/E5Ox5/wNV/: [1t>e_R >)RXB*\<0*7cq|لʜaN* `cs PFRB_ Z Ta[ªX9aa^UiBT'R#=ҔS0ՕyT*9TR9Z+TU]_hWJ> 5fhY]iw7I.K~4C_h]ֺ?n,ǵk8eUюaKqIʪYcd/:8E:=2pS:r=Yeƪ\`BXJ1KRN^e:ҧT霏'4k |#KxᾧuŧC,1h>ֵ= S_V&MX2 hOR=cKKZn03*TZ1*`:t19n \{l UQ}_ V"4ZJv RV qrV g^ ]]?/㿈z.eGU]]qih?=[/:9<]B%Xƫc}6Em%rVѧ%,4oiN5XNZ ل*ᚔg*TWҥR;՞R9E?dጆaKF*GPFsUUZk_?>]-KHV5x|m +{^'b~URPԣ,1yz1W/VZ0}[J؟mUeEFտf{OjK 6:=_ Lh^P>kRܶ&}RG$p)H䜾40r'P,$&St厴3VmէBPU|8{#Q{KHoڮS:o-5 Q_z⮭XZi5[N< [|+_.53E8d؉sVJ*a5!MjRl64B%azcUC8bZ^c0xodڦ/+zwf?fcItY<=RPOCiwont3-:8y5QȯN\qUh(2K*QVtҩ*Z{5,$yi#o:U)ԧ /pYP r:oiwwH[SvֽXS̱FWq fR*!ya1^ c'A9l'0PS,4ժ,Ps+b2zt-$]Κ~r}Jյ-AݫI=5X8G tBJ8\m\/*b𸬆rޭIG s]zPV1(a03J):*]#N>JPӧT0uXץ.YSiB*PhS\,Ҵc)R[ <(źχ4㰓@D|{Mcfngk{dVO=̑2cFg>i7Ta_3̫`ƌ0:tƅ>Z1=qGR_UZz4r^N}fTN9S)[d^| м/|9xV'-x7qmj׺_[iuBxgJ|ASQGZT^uc'KVK쨪*0| KW,>gByak =yGݭ);>762mj_R=3>7t ]KéXXiWUz&-eh"G49"%l J-*5e Dj_OEAa)UYR1QNlUSTIެ#'K$TppR)r/hӬsqjJ4W ~xĞ)𖒷V\W C&%4/7ڜQcQmXnd:u*'.^ƞYӄ 7Qs6L:\ؗ:rJ uW*¢r"N9=lV/.)UTQqtaBjSRJ^ss/g4=;7\]?<;WxkúWɪ6&[ZuӴ-&I>>70I%ĸֆqzTU:gGQʨsFJ}?b-IJg5N ʚry3+)cV8ci U$?g]Kh4/ o⯁ZX#Y\jznKMm NЮfbiJj[#/ VqVcEU0uq̗?ugRiRoV4<&?[4*EAaN Ua)ξ[Jp8P']X_~&kX\|Bοw|3_ |DOD/=:m)LVPkv5,QRR񕿱8U-8N/E0V;(o*SC MTGB C bXeN5a>MU<_5֋kV}ᇈ|kx@_xi1aqfq1tcN1UKO:!VZxUB_XR玣N8%J9|RJ 4kJV'g|Mu:Fjwz#xT%>pkͨCEaRoIyGՙJ\^qWAR\T`VhҫN[,#<y>[?͓RX}cSXYXJ|DsQpعb=MB&Vk+;{ke//;}3KΒ(RkJ$#i4PȎ*K~ +KcMܯxW-ijφ.54=6Xt#Z5k FIMWN֩uIs쒿ĒoFem-oO ?7|#ccēcL毨bM=&WԮ1EmoNY,jIZѕq:\4RNO*NRj)um%BPRpJcܛGOȵ费/0kjshi>=]F-bYKVu$$h ݤQ)B=N?itV&\G䠫UWhs4e$ƆtVtNu#O8Ji8ŵNUΩVn-SEm.w&{ -mn H8$pQ)',TqsB YoJ*HTr*P'~Y&s9WʃokWUXʝCl?:ŭNLmuqw[ǩϧ=Zl]HHcNX׻mX[?qu9n7Ex * z2TwHC,Go1x_~dcw4-:KdAzƒDݽn:uѥN'SFsRTaK;h)`Qpn2SvnI:PjRMJph>d雱|{g$0|hx3%/ yRO mQaSl_ xO겜iƷIU>9EF)NQI6naW_U=MTpHJVQiL~(j$-uDu]umŷ:xH:\* )HJҝ(iJ'8I]+QjQkIEMBggQIFRv,ZjIꚳ?Fk:B ( ( ( ( ( ( (-x -nk]2-`WQT3gypxxF|kֲwoS$G%[]E7fuxn.+'T:e4$0H>"z'ZN9RZN^ʬRF*:R/XЛp#t8{jRZ!rզR8ե)F>! {)ᖱ<sw}Cڦ>"|\֎kD0k~8ѴBm7VWV3w>ZW%$2S:tPSc)WWR"ÿc(acFpK ҭ-VWhQA.4q%MRrOʪV_ 'ZnOiix\ Mp\~i~|O_S[va}oKX>͕j.uqrRY)֭)T^JR j4 *NJ:8<64)Ӆ\.2%VnuBFK QC5=VOnC4 AkZ۲* g-;ΙOi ҵMƶ+5BWx~YV[HTmr&%)?f](ʌj){9ӔfpǹRRrzdf9_?M'o7|+ 'KӴkZ5]B#֎sJ1$:T?hךm hSՕEc ƋiSX FٺLFtFWVXN:xyaR+UJiVFRNgV)Օz?uRz7 +^_Aއh' h%7q|&a?PO^jdӭ#Y,y\BF*.UhUVU_=,62<18u*Jl.""' Z L+UEJXL/o SGke[[_9JEN++{Bx7W} JigteNɽ՟{5 򷦺VIN6xGW4 xYЯdw_ !ziM.Tl^)QG*1:FQ~NU5WXVO? _V YO_\_LN Cq"wgS/wUI^_7C?3h^_syW~ou l|ݾͽ-O]DGE'[I5OygѰ?~[m-s(2qm~B>tw 1Zhdqyt-j_+UڱyWc~ʞWtU*'Ike]2REy w ~ȵ^ҧ+.0|Mk:eo>ԼCh|7hzrgnڶZ٬w!T$A="_I(AJ|iݮi4QWvOM )PZNhʬ q(JIڅ:q-Rj)ǴߌsX^C^cm? ZG<5x+3A/euOis{==e)ΞXfi\a_70ٍ|gNN*t+)F GT $Z6pJ7JM^19RS݋K{!E~ƗK|o(n/֡%oV,(7UJri`MX{aUjNN"J6_R崿VZssPXkӚ4ʟZhQx%Ϋ` EЦ6K{iuunږ%e/RJ.9Ru]%98E'Qt:b\nb NR=i]ڪvҩk;U+iVqW|-7ďCr-KDT0~-4/ 8ڈ5 ),.Iි6YJu1 :k'υt Mb"%UG3vRӜ#Gshb PTF:r?gQ:ppmJi7ZW'U|C :~9:-mPjMkjĚKg lj?g[ oYML,"ieX,> F6aG׫tZ!ӣ(R%StRY5 ѫn0k %T㋔2u#FЩUTe W)a.S> 74OG֧Xtρ 5j'ig,TE2XdpR_=tS{ 5h:LPxx7ҕ:)(QT0*q!b+sT֎2UKK.e_Zx uxo^?qiZ3#n?п ׮onk ֵKNid(4Ya\I\Nf% KyhZmؽżMl6XRѡʏk5jJEjS=T=5W7XL=<TFZj)גRNf% *thϟ4Ք**q*|HǕjx+gN_Iu'rOGc{'Rsᄷ|ԅ;>98MnXr4m+ee7T+}n^}_XȣF\Υ5XH[; о(x_> i: ƾtq;=摥&Kw{uArYt=Ws#Y2a*1Tia)P*P֥yN;PjNzTqTj%^0R'hsX: U._Aj ( ( ( ( ( ( (<K<y.{x`kY.wi$1AoߺinhFfzv/%>Kҗ̙]'m,/+bo#V:) Zq+5o|s-Pe~UHg_*~k7WNQ 5| 5?K>תbvzÏ ߋ/k:~He3(( :MZyo E.˟37>oW~ۨLwcGmn~-j$M,jV-$̐kX檡|3-h+kٗf{oenhy?v-n]@ȲdY`9Vhj@DјEft1jR}t~}/nUb՗>g|do}ODog'4 ּS3L5|Vt=q<[ZcKk,7z5I4JT*byeD?gN.qK -)TSN ʟ3XPbuSV4mPiwir"F<[1Rbڔ勢,}aR)U `8B|DYOJXʒf(Jㄨ֣*Va0،V3fq#تqk 5na 7|Y?z_mM ¿j*x|K RZ[ಬ:N4Xʕ3O'_ai)UITG/us3ZX/j0j0:Qvj /M֩6ծ;T:f^ miEi$Y Vz)'x>qmť.J\Znt{^fޖ֪4;k]#WM--W(Cq'(Kᖷy||D.H-n~_N};P@dPKY0lh'`EM&`u)tJЭBu9o ԱXj>UR"x֦圤uJ3j.rJa(*VU:BV((( ( ( ( ( ( ( (8_멚u0+Y!W+GJWIa@EH?7KΧ_";?YL ('N}漾n'V=gBeK<#Mϛ߶}myz[ZGj2u;_q! |cOtxHֺf<3mS~ ?'跲Nsk?Y5~~5U_&?C?xrHlVmC[էU{kS# 6"x ,<28Ql/tay)KE4XHF<9K'J+业UWה:աVtT9*uiKNl Q煍MPkѽ%(>M ( ( ( ( ( ( ( (uSO±E/hxR k1,T?T~.Կ]|_%"#ꠠ2t7kuhcFt-_+Ժ.|34o_n1~Omיi赪y~xMHFiGKKOk6o}CwjZhͧ]06j7>i𦺧 ~]F>-B&kI5/n4Ns $ֺջIo4HiadԢ!CpxZ5}WS<i|h|Ce% 5Ҭ2]%Jli:uaW8<W]:4JiBkRRӇէyJVC F:N51XW;Feͮo6u'=xs^ 4-3]0zkadv^#[r"u@lf3xV* b(VmaF*S*f)R^X 0Z=ꑧR(B\S5rMI&> z}Uh~zb,VS:zXF7 Upp^Pjjb+SuFGςdៈ6tx_>*x+~^kG5s= BW,b.Xt˛⻾2SGur=LUYfYv-cԫ.l k:2'aVZ<11SNXlNEºX*j)(\,^%G0ſk:2P&4gF@P@P@P@P@P@P@P@p6vA.S5aV(C~%P V!Cz&%€=o뵝O$Dv~ҙTPN&y|N {<7΅yڗ_eϙy^F7+m&;v6M?WuP/oZw^(t "h_ iiwFTz;_OˡhڽŨZ#M{i=ƷweƙNaXdQi- M,,:\]Zޖ={<\J?>)nwX,5 xDmxV'#=.5vq`Jds3##R+ ؄ԩRJYJOu&9'NT"2:p%:꿶觭Uc-!sk.V^.÷^/v:5-#x>_GRJ֣M 2ʰ4Q4ժ,DyN~jUr'e8м[^ֵ*HE$l?$-*C↔k?y-)UV͋Ô-int{^fޖ֪ůڿg]N|A,_S3Ķ#>,ŏ ?T%߈-4I<;{5-솺SrEZMz_MUWI74텸՛Pin:-.mqu +Zo᷉^h/-Ќ0rʫ<;Q8~R:*Btbc(V:i6ٗg5_hXD^ յi]~>,|}wi H7IF*UV _[_՗I_ U.GXj'`ԫSScg+:s دIc)8<%<3 WLfO(a)W׽'c j^|ORڞ⏈|XZ,|bo ulvhźW<-\]X%֗y3s;骄Pr4T]dk<7,6A:+ VR*xz|axbk3Wa'81iS8|.uasN~~J+.v+)xyR€ ( ( ( ( ( ( (8_멚u0+Y!W+GJWIa@EH?7KΧ_";?YL ('N}漾n'V=gBeK<#Mϛ߶}myz[ZGx|+}fJ5i >Vwbg :]`M5{Io*tԌZϟfS]S}?.YjjD5 Y闷fa9Iak]Fݤx$h 4HQqvkzZ}s+gXǎcP|+i-> ԼumLѵ8M_0|Dҵ #R zV-fI[a*~ZuO4ƼqݕWӜ8n.ϒj"#UiJ;>zsQh|T梜hYԾ5|otM3XI|K'<9^<-iuֶ7-Kncěbr*U^.SP(oNڔF EI"2qђ 'XӡVQ|ѧU~ru6;q ~; Po%|>Ӽ5a|A>}ޟ +Mׄu>mmytqU)^%Ԍ(t6kRGZ"΍xX5EКa*/j.U)Hʛ=:vgU%h|Ҍ(<#qK^[x^%Ҵ6%YuO=ຎxtmNA*(JlZ-ObibaFuՒ:tjQ(MĥSRӜ]RNT\hVB4G^Jz> _xv?^xJRѮQi Wtk*[Wk8u+}+6[ge΢?T_U^K _BiS^ 7>.,תbX,(ȩ]~YKDGg/)AA@doחdz|Z,Wu\gi|߲Bc7o=3oKt_kU W[jGU$ZE׀hO/5+}g~%K [wƖNk {;+w^Σx7ٿC&iwg摠l-žچOgv֧Y|GAisomu+mD\Yyeqei4xG(j¹v}RN1Qz[O.X5_zvkztm|'k/ }"O-6ι_6'n~Lds|Lԩ(\[<:f7WVYv)΋_k7 qngMa)0ʔRTquk8s× JП哧VIiR9W_W%bW+y/uqBxǓx&<VKm;RO mrMcZХO<^ hҫpO GCY΅xG)ex:4ҎhX}v9X:ㅩO K/V N9(p{KORT7;?&G_ i }WÚg4C[?k??cQXWrХW]{J79Ql>'2\=qu*XXL5JT4Z:2Xl.> c18biՌhaOW-֎S[x{>oŸ> }n? xwKNދ=o_^"ό-Cs4xRIwqmjQerK4K{L$O.%*\6 K:bW 9*~= 8T0q*}kN?yʭ:{)8aEʮ#R^5V60}CPdP@P@P@P@P@P@Paaq?]ru3]Nb<=7_ hYR>תbX,(ȩ]~YKDGg/)AA@doחdz|Z,Wu\gi|߲Bc7o=3oKt_kUd4|7V=mе|/RX+ԱeO+|GWs&WzB $t-_74:O;O~}vwy:U|&}ҥ#Wŏ;Zuk62xLC:dKm\˩Gwi6yZY{+Ei 2E}gCݩNڴCYPnfG cST>U^JSC.zҞ"yYj\Jf)bkpSu+{lU):K Ez<h߆'&|9>'5y {/xv?<wn}RskCkhܩ3a_BFZ*Tԍ9F%&ZcPV ЕZ~֕89FU*S^!Bq$qv>/&z)[ äxZ#Vy(9W8t vG{A*HseGX^Œ59ӏӆJ(ӆaЌ19JIbh pS%(:}NhN(HN sFIRVš>0|.?Z|@υ4=NfHt_Pͧ*St<5Zn8yݍyGѓ+95+cJƜEε%QyV\ )$h_ cTFn~!xD'eMA4-H]?\:Ï0#F?R)W 2uhJ.eV':U9y'JQn1mai*{H,-9է*F {xJ#: 63L~%xó#-t/e="K]K]B7iT f[RT2B7J<>:jr+VũWan1W5Ѧ<4}*ҫON41j .*Tʬce'N+RukNߦE OqxJq5;EANF\O/Ok??.|5o ZI>t >4-EӴχ$:\7P g!}qytεLVZ*V|VJ#IUdTiY`ghB2_/o8)Sc2U?iVDa8sJ& :ZUz\G(R:WM}^|]N< cc}g$gO>=k#SD0O-Σ7 l5]>k _MCCKTm(oayvs[_UiPi𸚕ҧV>OcJU:,,E^ZX6IœN< L-jzTNQS\#֡6Q_ K@_R^x; Ƒq G< 47b~Vt۷HVV<\qX ҩAg<ʕ*=/`¶>*ƶ'֌K fu~)FJ*«p5TV*%)@Sëֿ>~<'itO~*>Ӽ)~/{v^km?:\@SytJRbkad6; `𑬽9kRO_ڳ'GJo{Yej4%SNywXJ<uJxܣV aJ Mc⏈Y~=j ᾷMǂh7'~/xUJ [*u宫gYҖKd/٥H%]` d8EFRԱ~K^#GRy>/QczDt+US:2̷-IƕMJYKS[΍(RT+N!eQ(ON3cgo3G>.~,Z6XHM *dDQmF9nc*h䋅,Dg D˞3O 2iOfqxRx2Wh`jRƌs )FQUb98lT6xy~xX֡UGSOL> /"?' ş |C^¨~SB}Wol.5OiڷD^h4ǂR];C ½Z~ fXcuK U!𱩊ӣJy~_K7 uZ帪U!1TiFra|:] ֣S,:KwN2e Zժ*rTLF28NYfu<­*&cV*K (9FJ8m"_]6 t>מY N1`RTs#(Nyy)n4K| D>x+ok]*[0xCRm.8":Lvi_4F.Ў3VQs5dXMAF2I/)B0Z rcTһWJI4g3ȯ( ( ( ( ( (uSO±E/hxR k1,T?T~.Կ]|_%"#ꠠ2t7kuhcFt-_+Ժ.|34o_n1~Omיi赪d2yw _M?ZԾWky^gjX|߲>eMym9Z_~=j.,l-O\/ύҢ^\45 SL;4pqTctTl﻽ w4Exz+xZjQ/Śpik&j//xOïvVZx+ݛ :)м)e|<]Ay13>fۅ$DZzXX5,Mt*1wQFP:kߒҋqNҩg~UyNϒ2e-7mBMijU_o};3H3&{}#2T RH4}{2iVl b<A:άGZN&JN\2Ҍjaq0RUG9NK)(:jFҧ7URt&:MEuV-o_<7I.>_:kx6oM6qissy ݦ}2k}2RNɋC+f<*,*b:lj*ʯףBqq~y%Z*oi9#KҭO ӴKS-} JQ:q~MXIiu|-D3ǻ'RRtT'8SxN ;9+~*S~ƵL=DE'ZkQ*N8lDqǟɤm< ghZB5M~ +}f??Romkm& SGgH?٧RBpY}N>.,Z4:K :eNQ`xISjQZjfɤT(|ii:eiZjzm~ay \YXo$rG4NH&ҫRjrZ'Nqp'iFpRN-&DRJ8UR5M)Bp$8-4p>^kk? <}o oby#]_M&-QAR8/< =5Xij'}_ 5ZpjkSNujpDU!a%NQ8JUye*q6e*ck9U\|v!g|dUk=SRFmq0xGQOXxM]tJ?_͕SmJT!Ssu(^N9Βvs&'(^1qm=h%E:8ƻTe5Uꛒ>Vy=^"ͼVZ~!xG֭.z&WOȟms`k[+U}[ZujP5o N:jIE՗n6iSaF[ BiZ>҃U*tꪴ57 II}SJs(|Mmg_ko&xA:$WSǩho[Aqko,el`؉iUl^*eL7'+\yTmNQrQbT+6*N1S$qYP@P@P@P@P@}OW\]LSXo _B)Z?_T*K ?*Aa_u>/JguPPP@:t5w:1#:/j]}>gyn|7P?'{k4_ZB2u<|/զgyt-j_+ԵV<35,y>oSn2ælwɭ/UtP OcC'Yu xX{NxG\SxچhUZ̗nOiqt'NҌʯ][MzII%k_5?>7ēhQz玵_K=Im|Zmώh{xO_]qٶq ֟ ?GL2\oa 3L-0GJxG_b>JrG>{4NhRp4Nn*TӥTNF !^r/Oߍ8үNTVtB%RTʕIs~|>4|eaZ^/5Y/.o =?ž'߅Iye p'+eo=卺Ik =mzXIʬ K:97e<bJ* 4bƜjWTFeM*Ԕ[3 Tr}]{e|HRGp課V4]Jt%W'o+Zl,~k~$›{=.im>,%?J/1GfhW 0 J>IJTkQ˲o|! :50V.1Uթ&' +J*SRE ূXTjIa+RI*NB  JҫG1hAe,~' \gk<)MѢkh1)aUS*J|R7 15>|UhB E(ʌk}+Tq: RUI8ԩWVMb"~Ki5n/û #Zljx[F/ |.R<cp~^YXE*YJ)Gh!":n8lM7ЭG0*L0X-RJIՖ"#Jx5.V,uXν ѩR' J YU:1hiVXJ~ѡ[3?VǠxfמ&{axJ5yx#>o_o<=ǩ0խﴸl/5Xٽ9 Ty9]*ɪQ|5)ю"Xў"3ֲU*(WG*1G kN.Q*9ulS*HS<#N1ztq.h.maR;߆>"KKQ⸱1ҭ .`Zab9\i΅lsMcBsL;MFu<^K"VSTcj+ԣZ8Hus֤x3$$s[b]WJ xᾕ=ZdύMk#OnK=:%ͺ^E;d4d3US9BNRQ9Sri)ET8J7K8ե9ԧ 568x FII&Z4ğZk>V}~h^ |Ui+֬훯4Zoo"sۄjSN2xHJdn:tiΪOpʬ;F4679ӥF(QWR$*VF:ŹVz_7?w~n{BLJ-5k ;^K FIMYcUgFQԥ9NXx(ԧ)Z3#(N~q\m*ӳJ!CݣZ^ZRn_-O[|B;G/|1W(<XIEN*2IqӍZCu)'O T3 ;JeZIStT 5<9,ke{szimsiNЙ5[4 ,,'Sn+:b{0؉4j88ʯ'$E4R"ӔU u{MZITl_6=F[?ŶyԮ;ibIY3iµZPFYɥUq\=*vP^R$ԪQ$J2SF]ZVT!:ѡUʔcwQQQV.4u-?WçxWRφ. ZC vN,g]6|QgFJZ1:|gC sJ2`q *<=YB9֫G m;J/JguPPP@:t5w:1#:/j]}>gyn|7P?'{k4_ZB2u<|/զgyt-j_+ԵV<35,y>oSn2ælwɭ/UtP OcC'Yu xX{NxG\SxچhUZ̗nOiqt'NҌʯ][MzII%k_5?>7ēhQz玵_K=Im|Zmώvk.<f𽵫Ɠ/-k%2BST:sSmbh^>Y)aq(Ǐ7|;xº½#š_Z_v7zLdkEʢC ԍ|MZYSc=]ZW  \2gUuSb`x fJTFpRNw*PόNX;,-<\co]|_Ww^x;q&Xh~ ovY"VڼѹWdw_cNw95XjugR=6jXH8Ӈ#0<թRaiapt,GiT 4ԩ:XxK*xci``Kƿl>/;Jj)g/_?ay%#o[u&Ь`]C] b"kQ VJ2YH)c%*1Ԩa4I֠E_h)x% G] ]:Y0 6xiх :v-Ƨ,,\b:t8֪!~Dվ(k 3ᧇt-cQ7犴}'?*sL&k~⛭g``+3=JVե^*Ty!΢a9/{WR丅aVxՄ:ռђap4(40hԅ'F.MNcCRxzn NpXC8N9|-xvIkD>5Sk>-e.xcL!V<%Œ|~uiiEհ*hRKtROaqNU4RaTᨪՕuh:uMN1}^Ji''DGZ6 ( ( ( ( ( (uSO±E/hxR k1,T?T~.Կ]|_%"#ꠠ2t7kuhcFt-_+Ժ.|34o_n1~Omיi赪d2yw _M?ZԾWky^gjX|߲>eMym9Z_~=j.,l-O\/ύҢ^\45 SL;4pqTctTl﻽ w4Exz+xZjQ/Śpik&j/5|i ߈69b |iMTڌq^{$R$ !V V6#'R' RԨ$% s8ŻF(թJsԔbiju' jRs"4yzυO_~-д5o<7{=HMSDԞOӒVT \wG˥RҞtgRXb&2RZu#QtBIJK8ӇS4c 5ZUVUi5.zmN7x.xKzWk^ }&;tY_Q/.m( uY%@q'J8Ҝ:rZH)ʛIJ*'()Q4ZYƭ)Υ8TAԌd8;ŸJ2JI7Ѧbk_QtTo[BTw5LmGU"NPk8N,>ooB~97OD :xNtƔgrVUogS9Xj)[Rgp"JTjF~<ZWl]V-2"u'..EMc,|w}FXUyhٖ>Tg)ʝ(Uwi*RU'7j"5+Ճ* 4 sPI7R7,~1|1<']xZ??'+]kQgK_/^/*B_LK%zÏ ߋ/k:~He3(( :MZyo E.˟37>oW~ۨLwcGmn~-j:]悾oG/jZWy<7}Oh_^jtNd֗_~ZG|[x!쎓躅07;h;쮚zSRQ?<%_ xU Mψ1lK;xri kx^Iђ!뎊bF9a)64] Bҟ,idj%S*mUVN:87}7ͯ*ۯ KO^1K'Wii׿ 4_.+±[MN=[]ӜJ;Yty:YҧM3ɾy?hgua^r3QHr{,?5pӌp=BJbF(%!S J(S+u9SU4%GNe/o?z'~M>|/{I<9QIk'IOkl[YvntVbFex:xi~œr%F(œ)B!!:p5ZkUۜVZs9Mʤܦ&w~\&@P@P@P@P@P@xGF;Zz\cIK%Ҵm:Thmi,o.ݶgEm!MImMmys[[;OuK=^[-7Ph_2CqsIo;I4ەBo W^w,%3^ !σ&RٰgT+ihR4kIԖ?T~.Կ]|_%"#ꠠ2t7kuhcFt-_+Ժ.|34o_n1~Omיi赪d2yw _M?ZԾWky^gjX|߲>eMym9Z_~=j.,l-O\/ύҢ^\45 SL;4pqTctTl﻽ w4Exz+xZjQ/Śpik&j/5|i ߈69b |iMTڌq^{$R$ !V V6#'R' RԨ$% s8ŻF(թJsԔbiju' jRs"4|'~<|9ޙ|_u/j_GCGm+{.k'ML-ŷSu'?E:5jVJ4<Upf: Vj2udpB;RE2!lE:t*׌6ҫ ƔR4yT~ϧhS^ y4w^ :巇j|BDolfYݽ뭜YJW`px}['Z:0IeRJYUNFV(t:J/-[kJP)sEt_ kmR[M//)nRj yqsmtn\G)7V9SjYPѧ*ҧzj:SS\.,jaq0mJUS:4J+8FFҧ7QRt&:ܕZ\M{>>}sGދhХ֯jvZ>l%O yW,UF3ڋ.!Vd6ۭ<2s9ž&m)%VqRm{Jz{o~/rKϟCJjM_Mώ<1&!neWa.wOAyi-_CbTqxJUe%졈Vt)Q>H֝ju(“t\$PO (jShRj%FZucMҧ 2YM'ӔfڋLʏ糛[o`iv3=NO#R&-Wš̒q٧k Ҫ9TT-VvѨ\`RR:?+S4ڪ5]ZnPTHJCsR93|/k>hZG߂]c7֫l^V~}2X?]u%9KR4e :uE(KJ5Qj'0q`Jp^ӝ.i #*~Χd]9 걪gf 7,N8eRp ԫ%J$9MnRvQQIݒITT{r(׽mYiu[cM,5 &֟i,^uJ.#NT0)cjFQnI{IFױj-T3%)¥{cNt'W:񔓇$v7|({_|B'=S\xǞMN-{W흾.RP5Fo-ż6N'ILF>:hޫ7:8:+Y҆?*'4TGBWQ0U0VIQJoVT5%jsW+GguVgJ sPO.6hNĮj*kՍIJ BOhvtP@P@P@wnO:mև ^αi%|!;2 nZZQ4"am $vV)F*,*_P/-nlL>,^0=_J4lsGAIq[bf {[-7Obҫ){%^_'m\ڤvGx'@֟/O4'/.ECz&'aPXP|EuzNi:\uqMuw|A奴0$zC >gfyLuUDYykdyVыoXk[.o?3Nư3~UMύ=i|;#j~HMN;[<+4\ ZʖpeϊoY=`siqw\c?|Bu]?μ浵M$0lwNM{]?;y_ Vh> &[kĿ>ľHtK/pM8{Yb;yRnG(;sEjB-T G}xrwִ/M 6[ΑhZ&wb{;Zm%U%4EauK4ƌTBx4{UINPr9UPVqzpK tۜ)ғ:5}cUeJQe)FZgՔ9}NnT'gID:+驮xĆ+}M|Inl=li׺Fk|knizM⻻ wJ=2Zm{^'Xc #ù'/**!9F*u28\>VF g*'UwIptNXF)'b}vc8r҂H@,C=#YE;uY_yy})u?L&;dPđ!4N\4cҩ,e: 2ŧ)?914 iή&.)jN4)Ò(*|JAaPJ*4 Fm 0yF4ЗxO|Khk ߤK_ZxQM܈ܴnmʏdl)ѯS|$NzrBrIƽXŴHrԄ'PbJXzS6Oir&%xI? <9xVc.o}iWuֶ< WOsw Vi0Ջo᧏a0X\M**EI):qXmJ1aJx]|LӜa*Wzt.Y֩UO 콛qBѝHۖJTqSYNqSh#Ĵ0Xx7aoxVe8Ha#٭Vf.r'ҩ~ZTT_:Ju%wZvS߷3Xm7QJhP?<+?Y|[=} [Ö^W^(=7\ޝu^YiO>CqLᱩN9Z4e c5iGC{*hN~Cjv%&^С)%O NQ)R!s)Z4iFiɧp[E!|uo’ݧ6N7 }OIN/Ʒ5)x9|]iiZ@$fʥU)QC+poCԖ:^J2N2;,UaFqէO,29SuS֥NCq×>+m;xiO_j~m0xY"ݥ]jIw$(9^Rxuxm<%[?{zX5)>[ӍX+GUr)5%*p|8' eVroc:tMՔtk|!io[q4MCÞ'ڎ^*4ȮOm H؇%QRzpUkRIy=6,擃H(:tʭԕ[6oKGf.P^jb:nE9T/×>s k txE|;G_O{VO,L}姝g<ʻԢ8FTR B8UVN38aVwWEa%j])r8| )&di{Y~׬Qkj߈tCJ4_zůwuxEec[6+k\aW(dKiFKOF6)_eQ\ʌ'F-R^598{(гF#IJQBqc%ZU-R1Iͫea&|GC|AjdW'm6oxXlCxR`Ό^ӆ[ZNSg4GG Fis}',N&Uus*,lޖ\%źtz*st^_+#%ȭaj|~-i<;n5m^Gw/{w׼gK9-ʾJRR 7M;8]W)ah%.NjSƣUfJt9eGcL#!ς ѼsxO6Ok+\.=~]{_l~;3_]/SO W:>ΓrR,?oRHT8ЅZU!<&IFJ4nEg8,S៹:g%OKѥNyzqPDT?ͧ#TrCb`~?ߛOF 'j9!0`~?ߛOF 'j9!0`~?ߛOF 'j9!0`~?ߛOF 'j9!0`~?ߛOF 'j9!0c##t-[֖f:>jnkt)-"ڱ\ôRFNKNv/%C 4?4[oOVS4}xv{[5^tF(I,Z^ݼ6W3itz-=-?k]Ğ:yI`|7sho-t+ e[H&H0L##4nTi(I7ӑuu&ig\xoKo($&]4C<|Gcj0[C$V$24IYw3"ʢJdj%mCv >҈+k#+# |*Gb#?k>*]-cVmn0A ^E 1FDPT_EҘ䶳_LK ⸼đ_iwWv6QjV+d{x{hݣA Ic[[KƢXeMKS~MR>dto%վ"+>u款-\q7ĸ{ku+Ax\;7ZD*^eZ]rzy~$Qfot]:Kko E&!B.ƹ  ӥ}_s({[o)~h?&R鷙wKUdLo9q~*^9q?1Q-`?&T{a 08C67@A~Oy~"L?{ t/$T{!?&Pۦ{|!ngq Мc3~zgxy )}~Hʿݨ;W]V W]V W]V W]V W]V W]V W]V W]V W]V W]V wKu_9;q&?Lh|К~Gx+^ӾuJO [!Lj:,u^FӴ߲]>hmso6kC<һI;K~TC'kߴl\Fma`J.(el۶_* B*'A_z|Lw"9 t{P@.xu+I|AkPӵok[XjJ7Hm>OM"K~Te%Zﭺ+WԽo9o>&/OG'/-Z߶KJJWJѻrWZ+4]Fo箱Ζɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.Ceɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.Ceɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.Ceɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.Ceɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.Ceɇ$/ Fo箱ΖO_&/?Z/:Z>>rKPfzYhha.NBZme+Kߌ<ˋ{ -.+2van Q KT;7fŻ۾wkZKK{Xv%o?D«Zy} OP«4&e cW4i?L->C/ hZ}ڇ&^&-_ѧ0/ LM@[*O/ai_jx?UF_s/?27l<Ʌ_eoU y} OP«4&e cW4i?L->JzWOҵ\i֟}n|],"{;6$u)MY8Z}ڜ躼><72+K+g%dZҊIY(蕥o.Yv_j1?}"I5R[W[-Oo}c,_ `Iky˙:K[}5_oA%/{:߶_нiV6Ky*"lz )`OjMu^]5ݜ[[ɨ,0YhzF]>+18@<q6I/˫~})^v]Ԋ %|9ҼWc=O |s$2i VgF;3[n/PIVr+w nv6 -WZTCB*|ys7pis%IwVB~y}F|=9U{(Gᗉ|Ix7ß| Fh+x4۔;B[Iy',f(NxVM)AJM5zװ'5װ&aSܛn(VmiY|  ( ( ( ( ( ( ( ( ( ( (A,^ z_>3>!x5 V~=V#վTg" ӆZXl5 =m1]%o[ph%<R7ݡ_RU֫x9b"=Ζb6&(0J(e-0ʮ"4v+z~#ZuOͪGsU,|+x^%/|yk~6]oVğ-Z써.l%4+6k(žY(+d9~ kⰘX<)VZrZeL1 0N((OXԭg5ͨS6Tѣ,dr8ц2#5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (C^⯉{OŸq {F[<>[3{,6P,j&)UP*U+Tl= DX0_l˿7 ?qH€wA?,[/Úo5l>م)B4s Bg*s.-Q ._9:LOuV_q㽅ltcO*bapwMscT~_ #A᥂i Ҏc ↫]kþן5-['/_ ||kR.XU(TTsz隦E,+5Yn*cmYF"իUGNќFCH5Z/_<eQzi-;._>3gqo ]K_=bӭ}6:En50l41IQ̳8tYU8o/`*i2N&U ά^ʨX ]xxaYeXuaTgGF=i:XjUkS^aR!RO?f2}>+9ajt|Ho77?Z%_o-%%֋w|%]S 60YzJq+G)Ӎ,;-~zz؊U'VmѡNn窵**IPFupRRGRVу\ԧ Ez!:**\՟.RP\x5~(xZ[Oh ӵ};'^tmb$'Qy[EgoU˝J# eRwMaNN5W]HT/m*N}'zu8JC*BPU=Xj4GTӊ5{⇎|Qs'ᮿ K :=N4 ;௃uhms^*cŶ߻NX DT#<$rUץ^s"8ai)Thʅ%֌]BQ4̟%B?5RMוiF"#xxPiOCDC^:T,ҴZ|79>kVi xo x6K5-.+Y;=;ԧcj%ѤX,eB?YB8l\ [b*}OӌIf0fMζ^iMx5 tc0&.8\M7>' BCJxh?~KZ5 x>?]W@-- ,RG5iZs?> $E'#s /nmKFU݌BcxBf6','ɛަ =Jj5rF8?fFn3xZnJ<*9)B^* EVu)Yk}{7FQ]7?ll?S\f mlf;QÆqזz@P@P@P@P@P@P@P@;i|'O> Ƈ]IdžM;R/W׀ iՏ9p61?'xmDw}r?mXbO? h [П??*??ˀc>>/hoT',~Cl/ }oB|_DOXG._ 'ͥ[Onew|ZZY,^8k)b݂ ȇ bV3 3L4U(ՊeMu 4O ɥ(J3i3J97 Zz9F.hN5 8IJ/XfOf"ү>"hzfi9p61?'xmDw}r?mXbOv|Y&xGk?<=ɧ3Q gW kZoCDְo( ^~:eC FUYԄjFC IB*)n1)IqW*QwYq8%UiP s9M*2M^u)g^)vטzA@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@yψY-T,X O׼WX5;>Y{k+Ҵ OOK Os70;J J-Ԕjti8F^=JSTZsr+*jQƜcAԭUINї$)j2NOB1vۺZz^M?_>:4-ZS}>+31j&6-Oʓu:4'CXIT(¤*(.g b8IEiF\ojUSj.TMөri%zsFR |@ϋh:kW]ăT=cofu5V6"SkE_g_I> )r N<ҕ UZ$jRUiէ9ҩUZUpe% 24xFRPxOkO-mu]6o'sqTi-aaV8FQ j;_bj- gW(ŏܧVҝ,y wJ*7dN-ҼOWKi8MXP4ȧ VDH/"E8s߯1R*yr)4$N8ۣ\Y5${::C9׀WH]g|[6%>o^Y:β[[KqX9g֧>?j["VwmF# sJgrFqZgn,$-ic(ZR#w9JtQUcJ)]3Ě.>Uqm;QqE4eѿ4qê tסW Zy+P8>YA^-٫]63N5#xݫ٭b^٦JȰ ( ( ( ( ( ( ( ( (<#M~] 3%|U_-־!M_UӼA5;=oQ"5 m~!\MwݜGZСubkFOHZi-kw/S ':tQTrQ`w.T3O)E[/hԢT7N1tNnS^2\;|ϫ|0׾ zw>_KUaWԼ;ICQe}QLYmN `M;ǭS*R%gjך8^{̰5iTsx|NSԖOwۺX˚iVTkNJiNu#j2sRPeE[/|旯ڬ5|$i}O0n-V4ò_jZơ'O弒$խ<%\9K zn*%NICr(Z0!c'SS' iNHVHS*7*K AKC U҆x5AG9R5SBԭ ^˅u}O?|O Q\TXjZ^Ɔ[RPès,HBP&8iUh҅Zx:__Xx_b)q)+~ y6^ּu-Y./Yeko ixQbaӧUc6/'*`',2S+S}hY}Jx\^:rNcG,ЮQjOS4U$*vamrImijW+ 1rTۣ8 fSRR99ORQX ujR~5B3-"^Fo_K.u(iBN(K*_>*ϯ.o_Xxo*ĺkmJ姎4xUk߉w!{Z?]i Ν@ܵY_0:ng Y*NIRlXztZRRyV*p՟yeu* jJ|M,՚tB(U*b [i<h"tٶ=NG7o4 v jr?`(ͭXa_EAe|TxXzf6$i uD֦ k+߳ ^<RE4Wk{-W} ׳**4i*G QF3BGNJta% P9R`_4yO E(C՚t5ܱ4.({*UeB)j@( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (u?k:׈mQFCԼMa\b<7"'>~Z\iմҥ ^uV|Tc⥈xӧ)8UZiAS1ZuyScV] UpN Rфis5RNpJFe.{OSM5&ѵBƾ5::ܺa. ѵ@ w)tHn;xvA+N0)Eg}z 4jPSS9GڼZ%/m9Rj<7%фq0aYXhAnpԡ(pjpuRWk!/ZЭ2_ܓaVUXS*ʓS# Z8=M$:_/ jxhJP*{!9PjYF IhxZ"u//'8VKOx;i{^VX nUJVs|Jq+p{ O]Kc6_{5Y5b5xYH0S!: N骱IRrV0W燯4\ՍNj8Jp:8ƍJiB)՜e'QVIE ҌMí{z4i7~)׉𾷤'"]Lxu+)Qn4k{)nIn70BtIciUҥVqLl3weEPjrK$TV*SҴe5HגR8FptԹyT%7RSRmqO n-is]x^@,?/4ۍb-Q!LKY#̢?VSVTiWJs!RSpK UA?i8žIZ9_Jv|ݪJӇvW%*hJƍ"Ҭ5nj^zƍ}kZ BY ),2:0+Itڌ(7)&, $dfP*&3e(R'Pe-(4ѥPXP@P@P@P@P@P@P@P@zK+ƚ?$/#_V^k6:EWq_Z֟SSP1)qS:N*NNpZYe B-)Fii̥(2l.a噖|WSrj)NmΤ(Sjro{E<=S ~ê{°~$l&ijZ}IH4gİb\H`H< "YdA99B(Mpsi{J*T}ߊNO+aip\,ynWGN'RqquZn)FuoΔ:QI_ WKڶ7V[?kZu^| ~ۦ_xNu4K}GQcԯ[61IԣeUj_2̺|٦kG1Qϙ1T' ^*Q(R~pB'%Eʪ^I_.eԪRm:Tk5/+ S>*֓ϫ~y_?t[X״߇6x>N0m Tʮg֥ SK6BUg:X_ JmX](RY*Rq qS|Sq'Vَ+5SgZSj|̩~Jk-'V~>1뻍W]ӮI?~:?É-#u DcG hN%T2/4ʱ9.%SP%Ɲ =ӥ72&i1T1X{.GƤ 9< G *<++eєiJ/I'ExSz5,kwi:6+ [> Q%Я틽3Gv&DЊfjWB8a)aCUF5!IbP-ܢ-Y_x\StV4%kf21 ݲiK~>|x;躮G?x+6%oU۵qVg cOh}^dg],!:u*)k`ssIR+ƕjpS,rԂf MM<.'ʝ ]ś[5h<'[j^ѠдO4xG]=>h,A]7gg.amܛMa*wow(SVXnf{jym~Ɲ;M/uĐk^!ZM#l#i}|ElVWoo$ -0S ѣ)`biaQ:1Xy6-7B WˈKOz5U Uo8Tu{j2,ѩ jԌeCjj=3:wFռ05i7ĽN/N$վ!;pR-;VJ.:ǚb9iUE{WR5'ɇ_/}9֫:RX|6 :8,Rqx؄gs{IMSwwmIA@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@Yg'U_PmOMwO|Eլo~ZY_^Լ5Ki*mFޤmsgn< .aT:U9%[cV*7O 8_qoRI}:89v&!R>xJMO ۞K1mkmMs|A^ZևË4ꖾ|PmnSuk|+ÚI>; /tա>9F\:W^ Jө k'a?mB\#BsxgeN[?e5xS-dڹuz6,#J{4m.oֹo,le̸[KycdB P3>{k}=_g{s*䕇Sn1)9(qM64ތ-u oK60.|mm8^eU2cdXJDN|_ Iҟ+U:sR'*2q٥%xJKXh\;]B[,ņ 3˧_岾'f6WwB?w *i^ϟKᗳ:S{>JNvjBpvZCdFN;4IkZ (ơae=Ωq%oqs 7qZ\ka wp6ww AbBD\W4"Jժq:rB3JTSwSgJ1sJҳ[;l\@P@P )SZ 2Ym-羱Y F+e@+roc'˞U}rߒVuMs84Zz2 9 ƾ :og)JFhZ/{Mw(ҵ+p ʖ<|*=5;E`eN8eaԜ[7Ӝ'&hqj2M҄,c*~2KNSw(J*-$𗍼14ѣ kWĽ"k7 [hfB@ 3ԧS9BNN-)JTܠJQSn(1NrN#)iN1rqRNn-I'fZ4t@P@P@P@P@P@P@|Y|e2_wk~q-a隬s}}&+j:O5&3_')V'isㆮ(O.xe6|Ę>`PiC|lSR'>Hp]5XOx~07Mc,$ڶgZ Jth:-akncmhᴅ\bF&}y|9)+ETNiiJYNUie1s qz_8⦳q6k*Ꭵ /[H^z0GiCƕ-5 z[uE+ŻOM(RǪelGY%qhFK}FױBJ5]Y'+ĶRO ˉO>.O7w>⻻hu/xSW?8Ѯ/YEՋ㇂úZx:qQ3B4/:xP'RjRUixzRhFN U8*Z,<'m U<=I{ϊ?4 ůO~Ş*UOĶx;W*=>]7G׏mk6EPдFHIKk+R<54?u:fVZJ ҡׄkMVafq-}zJB5FJ8{wSjpS>&{Ɵt_x_ Px_ׁ5 ~Y׾<׎<xd$עB")ui$kl/PWguGFNt#Zgp<;uGYRXIK Z8S6R:rL4"*T'B:xεJxCϏ=ោǟ>1}ݎcχzcQQ)^^‡LK|%k?s=ƝjXԆa]2La)T!^[P`_RUaW N|:1eaQNzXʖ.rhTM4nO/QTT0o >[=Szݶ jh~]iRj&rFSi9atrRiT [ NVW0uqrpAWiWr-ԪU᧘ӣFִecIkp ~ Yb!xHմ;}o>55_xEޱ6mdc$f53b&Uoi^St_/%(BT+Ui4)Wokzʼn x񇄣n|'-ljͪx";t[+];ŚD\M++϶X|8j0SSN8rsr%u]RTƽ:uN$7 FpJқFJ .iʭV9JO kTFm?Wמ#|Go>)Oi^?"'un$![Bk% <%U,ե(Sʧ}nt*cQUԌ__' ':qc=?+[3 *}>*ax6t x+<4}:=~%߅5^'6>2o M}uxPg0(c8QR:yF" 8ViTM<=2ƺ_\Ci΅ تxЗ˖U^LT,<Þ>Ƥ]@k~]H: Ϭ>r-1G 阄HUT 1G>Z;ߞ$ JZi#,5gOm/z1HP^2TyyCmɶ*7 ( ( ( ( ( (<>j[lu/ZB_zqg|\icR5;gV4_ZXTx̹ xJ'9Д)M-O?7 yD99jsPx<ӓQWoBݧýT5uơ/(|KmΕ^äxŷk;e/e[53'NZU(apd.tvee+7{O/RNu:-TPZp$);Xk ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (K xe8$DAH\Ro7]<=2+IiCK!?kGc틟Jaw#Oq˪=/#Oq˪=/#Oq˪=/#Oq˪=/#Oq˪=/#Oq˪=/#Oq˪=/ jʌcTW`8C'ycc%o_ F$Wmwh|TU<T迻Ͷt/|%Yéͩ|=ڄuͼcIW ^ V&rRcr,&ֵQ,pa}L\$/zbbΎXեcŜB*UȔ")Sm6B/,g *RqS*u'sJ;E7˪Nx^ƨa qKkvKge춷Ou*^4֖I0s>q+ .+QJX)µm}Fi{7%N򨛇,c$.{5x6:kNomxF|r1.WNkMuArEmq[(bB]搠S$1.zegj^.YJi)Ij)F2)$״Q1oޒKKY;E5ԔPHؿ o _L_>dqx}½֌e撶_ረCul8?CW/~.|ClS<-|GxA]>Ӡω|Wh˵$SiT+:[I b1JʪԧTB:R#r' XJtk5kuOb=Zӥ{GN51XUZ J51_V/m>9߀!]gUԯ/Ai^7O iGPI?glXX74[KQyo1iqO G[RucQ:Sa!*ץNuX 28(K%5:YaZ T[٪q8SSPQ(S[У?k]o]'5/j>9kO'xY>P͕߈tcK9[V ` R1Ɩ3B)$YUI%6&R Yb"hUB 8g*+ףBo Ml4߳UJN=J"  jwZѯ~5м%_:e֙ Qӭ~+5/s_|A9W?z%//k{H5|%Bpx2FB.jt!OCNx4ga=`ۺxɆX5K.ERj4ĺ*TKTX K/X?kƙo /߇|KǢ ⏋ZN}i>,д-FMHh{{w1۰X! <!^כ2r*UrL=ZЧ:U(´ rR_Xp^2su\qsTE8.gqRR|IKo=\Wc[?%x'mtf4 .~ʿj^ak=  ( ( ( ( ( ( z<}Qg{;DQghU@$JKݒ->Gl"]U4o?ْ)%VB+o+Aޑ+?=@$Y_xWT6ڮ,;vj иkk洹2M ȄeXB2Ӄ\[(%xBI;J%xIRViZ=SM;4d%iE5BX2s_ ˯=Fmi'&Ҽ9^rH4 2? 7P_Z h6NȯeR8,zPI=( -omYO6B0lG`Evjilmo->`')|+O<!Ѽ?i߅'ΙAqkiB)Lae$)?abxf+ _N*s Biԃ]('xI ~ aqX\FFJUjӥ8N8Irgk5mG4O* -/W:a?&s^-=E(P$GC/5:;7V+چY^ Ů[][MKѺ,)R~6(KҩNN2.J'RP%zpTթ \s1OO*uʕHNpNVg PMFQn# #%y*=e:ߴ%ivچ_ͬx@DcmSj6TU1u-\*nT+Ɩ")J1Tj*N|3ӋIN1rS,jTueQHU٘W>f$ղI<)<0m帤tPlO)ɞΗZ^Y[|em%Ɵw^Mm(ڴ-_OUa+^>g(Ri8|YJ:j*BQm66ʓXNk8ucttէ+;5NqFz5yP@P@P@P@P@P@P@P@P@Ol~ wv*]\*Hc˶;utYvmD]]>{?w_/E`}|/.Yv6?ן7E` ,h_e7ǭLLqdX?B$^Wy,,ĞyX6( ( ( ( ( ( ( ( ( ( ( (?uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image058.jpg0000644000175000017500000004714611665471332027000 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;y"P !1RU"AQTat234S#dqr$5BCs6bDcu+!1AQaq"2( ?ٱSQī$47'} Xo x0Kp@D[i3}5\E/~kf!EKbd Kwsӽ}\{.pϸ'Xj?w1hˏ͇I<7VF\ 3eO:F2]{n6 J<ǵvShQ D5Y"nnI&]|U8j#|G({#<9ZF˷VTXػ0nxbaYY"Y򛑨nPSggryAO"-hc+;; `Y41AO?Vvw, +;;DM ~PSggryAO"&?()< CYܞPSggrȉ `O()dD?Vvw'Yܲ"hc+;; `Y4*1q8R5FHg,JּwLzfq{tX5xnJIS6e{\l7{6]Cf\zDtS׻(B*[GG5K-7<鰺~G3~#J@I#tH; CKvܐ񰝫D0 ev%5>K4 l$_h?aw (YKSBYHj$ s(gv" D% W9xC ORzF'äi]#b n[\F#s=6FhaZeֺCh'i7z,BGOU A@3~7n;EVcEmeLtUJwdfּa!SHBisA󁍠 o9,xHH 8GQDncɷx_׶S T f#T5AݻMجpJ2m0&@@/};n_Hصv)c jF<ٮf};WËald:fvmvTa{`nHuisl.67(w*hLSE4sI v R7;%sQQQ#jalm/V4m7D\O^kx2vXn~È "ÕvQq 꺧ث`QKG$R:i2=9Il7p%d<:vFݛ\/p667 ͯzv_Ɋ+A84rTT&o4,{"[(pۤޒFô[rafԜb@Ce5,6TC%m;*ҴHhmwSa#II3`DscD3h&]<JXck[a NGAqNmcQ{.?Dڂ1 WW5y"ٲGKG] FjJX4mɭk\HcqblT!o9Ps$kI#%6]smQ'5$4lR=c]IYplv*h`P`-~ p؝4U1hc$t۶}"Tb`75S sq okA6OM(0gD "\ӲVyo vD\Hʷ-:ν݊s\ZE*;m3eGn~m;J,*R!dn-H') GW3rb?l¾9+/]0It\!WJ|Um &!L`o0n6+S[XHEy~ a.i]MzT~u,=3ti{i{Z;-n騵zDf|.iA-خ/$a:.zӿF浌u4ncIݖlȴ+=-zSA$\0,ÚeUb(:,k#';?yW-ZF׈VcTPTLmL< 7gJ8Mj)bI0d4Jۉ-| St7$ZW18,(LlnWͿs{meSɇr6̏n~̎[ke65A)i7zhZV8\o}!Ҽ#,NN}}XxCG0édѹk>fX矢vm؝Lm*0)<N8aq,5+IF΅&}Fܙ3`ͼAٌbbW0MIC<6Sbsonq kQ%YcŎV>QjXn-WHᇱHi3siߥͷnV+\G⁍'0;IϿn0t*sSH`0(#^C77^ESDk}2TD 15ncݔXZ-s}qlIlv`qip=f; YQ_G=\M|dkE\7nmODDD@DDD@DDD@DDD@DDD@DDDAf\z0gL]|Uҥ~GtjZxb:x"fXFGl=a;Yt 獾\ `h-5ӽm u-6_~]oq/ϑ!N#>G؇,FŰ|G؇8%pAP2S6 . z,;VatN; sbx>G؇8% f \4lsc\nI$7Wa[4-yeؑe<_#CĜG}xI0\C `7ܨXd1 NU5ľVDn;T`iBAFݞhlG}x~|X̋b$<_#CĖ3"x>G؇8%Ȱ/ϑ!N#>G؇8%Ȱ/ϑ!N#>G؇8%Ȱ/ϑ!N#>W.^׻(BŸtN]9Z`?^ (nYcl:s˵ZB]]La lsoKqK˺ޛc諪cjbdQlcgou >F#1 rv (F(КPŃֵ׷=75ؼ/e,bH[RAť6ڼb|%Ȏ 8[PۛaMZ8Yt Z}+zw hkQw{OIRbEbltj(㦂w̠im}KNKQYxuqnPK/{ma_;QC'M Zؤ4. z,*F, 40#M?Ե3s3Fc+-)#Reb-v8\ٖ_e*6'T<>[ A}v־brWaRC>V z`5fQ*y%Fft;341و7;0C¬VWӊaRچC )9,`1v@[ NVU1ibc֛ݡmax-\z:2vhY!#M@;c}_}Z7 1GC 3%2C@k/%llY0vl2$п5E3{/i &MAI m˕ƴe%ͰITs`8J*i'hn8Έ9ٙq.$Nū[,^IMP6X=MCE>h[!_wū(q &Q#$g8f&m 66>&a=Kt}yqܹIqYO>s;i+d,aq#-~c(#Œ~/KH#+^2mw)~=T0L*eOrAkA ~Hn^u=<,GQ5fPց7b#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CQb#;X?0A-b>Pý5CT' N(~aޢ=ZAw}H)a_ϕ˗ |\v%pwQ]*\!Rh'e&`nHFq+v.SfulM-8{YzK@ ăwyw8vqHeCTᦖZxƶ6w:@õއݲ E hꡧwf".%;=wl*-Tc {lRK.2:ֹA;]oz-ע3 HO[XiA3`cλQs4n$em3d. Zݣͱ~P<ӷ6!V((e,/ kY{tn>oؑJ/ VFm&52vIs .ae, #<ݲs^I;ht3S6Y ݥqtng0位/Htc\'i40bPb*ʩ߆%DQѱ3: mMq%T2ZbKhmb_oHY:yc\'i40b[" 0bM&52vȈ5&52vIs ." oIs .c\'il[c\'i40b[" 0bM&52vȈ5&52vIs ." oIs .c\'il[c\'i40b[" 0bM&52vȈ5&52vIs ." oIs .c\'il[c\'i40b[" 0bM&52vȈ5&52vIs ." oIs .c\'il[c\'iCv5\׹GRK\Zr\޷Uf)evL8^4FWJF6G`zE7h*xve׽-gJ&MLihi$ln4Z-k@(g3ps:޳Bv mdDnֹͅrAx[^:B&lu8ngZ;Ҥ]gg(tvrJ8}hN3ۙ֎uҙ*u8ngZ;҅vrJgg(t^3ۙ֎8}hJY)ҩxngZ;ӌu(]gg(tvrJ8}hN3ۙ֎uҙ*u8ngZ;҅vrJgg(t^3ۙ֎8}hJY)ҩxngZ;ӌu(]gg(tvrJ8}hN3ۙ֎uҙ*u8ngZ;҅vrJgg(t^3ۙ֎8}hJy)ҩxngZ;ӌu(]gg(tvrJ8}hN3ۙ֎uҙ*u8ngZ;҅vrJgg(tf1ጬk`$ |#vrJgg(tjyg閧zނ~vrJl'G5 @SX;-O, ,X\g\I;I>S(c6ll]q9jyg;};,Mss_(uDGW3rb?l¾9+/]pIt\!V5̠HpdqD|;vҫwQJŢsiiaI>Bd\6.@ټ,OkB<:z 4cKM^s6ڕ8qGLi*+T ]ĽowoQjYBMQD&Vh- qmbl l.m+zjA8ḭlme_\2 9[ ǃmXFidsg<::%Kbhiէ傃dXԺDbABX4-;wgHۊ-9x%c" ְX8؀]ح#Ʌ ijic2O6`hoyhM[N8UD$6mϰOfU"`O?gx8yXpvӺ s[3AuS{7ܰN+{690` GtRP-l3G1ݥl,77B'j]K,mu0{cc=wmE\<ܾ##mF2n¡n(&2@".mA 8/<2G,K Ic求.N0jfPXʸbuKmfNi٭iF`YR!EdpSRM fh?IpsĩW6 rt#Hnm*?K!C#+r1a_ϕ˗$. ?K{*b{QD@DDH9lvWJŎA\:OzkzIPq ^ doC~F66'BOWL :w\ # 䞡{\:Oz%MRݻ]mrOP=I'@h0f'I|)&yyMͬ.=jLt0G< dJ=$8 䞡{\:Oz8X \2ݦKپI=k&?{$ޚ䞡{׃,MEYGlf]l[-Og2۟}He-Og,s_MP4dpJ_#yDN m;uSs&t*D򁝲oMC}&[Z y2xxRƩGyTU}tht;ryE'nk?+`q_-Og|olQ:B~pm|Q tq:yh)^cmoUI[ ꙈGBZLc4wyFޅWv5UNvPi>mhsqI"AIE[I+$jh$|?h >kH]6YLN{$$t-ui2l1L?y2xxTz UB)+Jɣ$nlyYuo+89#%ě *KbS#FUIU] zjrYa-p ips}m m=}u4-Xtlh`ez3a8"$sK4@Ͳ:B_~1 ,TEƯ)f86g$:  .mao}#Fʼnuk`u(|qeq6{$O[g-Og8)P 0#JS]mxUsI.(OHѳM#Ip|s|ep..&[Z y2xxV+zɖ'ֳžL1>,{Eɖ'ֳžL1>&[Z y2xxRǴ^VZ$/-|eUQG (L艑Klsol;1 *!56YDW.^#+rE~GtpwQ],Oj""R}谬ԟig(5Mši1vD*;=a~sp@vj**q:Pta,V&L.hWJ>0?j)|8ɫPcͯfA~ X)s~uerTT4c^1r56 3j(3E<岺i]#ֺ%6E#ߧDDQDD@DD (jkQuq#b}|y˙IuY߰b@\pN`:]3,ik@[%q|A UuDs 6@쭵Khs}}b9ia {$sZblecx!U׌dAInȤeC6y`HD2ůeqơ|^gTT,62.kĴVMQK l l54h>;UãS2R,!cm6m7?5>eGޭ&Nܗ'HAS|'h5Odkɓw%;P;u4n cG<`stUn.8:) b?l¾9+/]Cf\zK?^ T׻(B'@DDD@Y>XVjO);1UL],oҵFcq $a0Veh`- ^#4""+쨈(GN=]vPՊyw#}w sum5N T50W<0ҽBb_70hrV[h~Wa`2%1$Źrpf r>]Ʀ+-L[;_lw- b'isk͊,;LǾ'GEN cQNQ>:9!5\\q;w-VDEDDD@DDD@DDD@US}|Uj?~?cYG,h0T\{Þn?!>cHBKCM,."II/sn>6I8')}oįh#)Z>3˞I'$F^R247u~4t/H+q~edq~ed#+r1a_ϕ˗$. ?K{*Ү gT?$l͉$`I$I]3"AbQ:Jg<;#$Nuk#ahAY,lsـ^װ(=%]<3d17K`\pRUC]KM9s]sI TfK?aY>PY""?UM1U -|K&M,h6 4>?]'zy꧷H6| M7߼Y;ɚeX<8_3zUL,tIެ3zS;GwadFd{K\lwoU㉊ GW3rb?l¾9+/]pIt\!R5xd3I4.2! qQ0wQ].yvӤxYI@(haV/lMk 'OhPVbc\Kzp 7.A6ܑ#D*fA<:iIWZ $mi[X'{ &;ij $lCn}ŷV vTV7TaJ@6qFLI4<;D8\- /4ԶVJ&sm^ lS)ँ 128֏P`YAfK?aY>PY""?UM1U9-1tN .vi <}BYYU >%N8HƁn2#A1ٱ%p{(p~f-m݆Dmm-m8};}Y;D}|'h ^6[i2J H}|_$/ѹٞ4|keZ-}%G>eGޚ'̲v|[ z[W7vmaufj׺7ao#fa Af\z0g\]|Uҥ~Gt=" ""I~?³R}蠲DE쨈 oUT_'XZYߘRrd~?cArdx92tŴS#qoڷ*%p($xmɓw%;E#XFx|ҽV2(LQZФ*o6Y |\u GW3r .{*R?^ XDEfK?aY>PY""?UM1U9ƣa0b%)dɰe`fgA9ik }+tۇJ=6?ğvRIޞL,t'卅6nK\$IEɚeP|IPT\}A&jk>$QBSqę}>ME 5OfA5,>P|IP;fn>ME 5OfA5,>P|IPT\}A&jk>$QBSqę}>ME 5OfA5,>P|KDPSK0&9t$^,QEK=B~#%>uĮ.~Ӵ in?;S< FѼEv;hPȱz.$\acoܚSrhH5Qަ?z{Бk~M=ɨ~7&sϤnHDю^($te6[~^ަ?z{M"Fɭ~7&ܚ5Mo}Cǹ5ަ4$k~߿(SrjM=ɡ#[dG?z{PoWBFɭ~7&ܚ5X*4u-$Po_[B9 4XM ܃Ե)/6ѳ8`:ܮC@ԬmDYNP7 Pqm,3MN -&ɷooHnکAk6mhP # eeT,dT|;K#i|'hY"_Nzk2#VH_Nzk2#VH؍{v[Lr9f띀D1a_ϕ˗ |\u%pwQ]*\!WKڈ""" """ """ """ """ """ """ """ """ """ """ ""0gP~م|s>W.^`wQ]*\!WKs"" b?l¾9+/]Cf\zK?^ T׻(B'@DDD@DDD@DDD@DDD@DDD@DDDA1jih%+jFItkD2ICs07WO3L p Q[I!5<2+$J?xg?S 'BMOoX4\l"TI?*+{2Z|ۯo4Zn{??xg?^ψU։c~R| f-s9oxMu<2&&OdJfı|?VSYCWs1Q>2ѽgllb,nl+R/̫m?e@x92t:Grƈ2^L#/&Nܨyꢂ5s% ׶\' 1ؚcJ s|h׃c{m rdx92tEz2φGұ9Ɔdnћeb%0 <8ul$FXܷptq9 ۺ=;rdʗ^홀ئ: b N]ղC%;(إU+Y8]RUm%P{~م|s>W.^#+rE~GtpwQ],Oj""sY`q kk$`PkX [2)4+-uA?W}GAw{T=`MvڡUBƞAw٪Tx[6UO%=D#K^ǽ8 ;(,+|sy96iAw٪Tx>5W lZ,Q^'h봞X'|j4UBƛz'Ci=*O ;_*>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"[  !1"AQT#2345SaqsRUVrBu$6CbceDEd%&tf*!1AaQq"B( ?-l )ֵm'*gP%28IvO_5>tDTw&r'x ;d0UXf."SozY :Wn Ҵ I)Ʊk$}Ulmz`//kx$g8JR3h!J7pn<+a(L溵$%iä bQXdžȧGgEj"O)ңE+ZVu%.(':G8T ^-Kl+K@,܄`uU>ȧGgEh|=K͈L6ui q'Omڃ i.""HDK͡s)um7G>Ȯfdّ'H먐Yn)BJJq~|qV]jq:6ì5+^JㄔT#tv~ dVteq\mۡ&2RBII)9RTYƽܤ2c&8yBխ(9  8Po:;?)$}\K/GAo\VU:clFڬwƞXnC u$8ZKRNUI8n;?)$}\I`cd58yۘӍ{` `quHZZj8 oI+ʐs' GgE:;?*Ca-`-.2jA)*עD%0*uYY[Δw#3D#tv~ dW5 Ww&̊%V0F`whW{"f J 8PsՎ:7o;?)$}\rS!8p(RJOp6ՙCpi9RրVFyJI?/~z;?)$}Z8,SDV|XABNYb ':OgŊt( ϋQ<*zPAТx+>,SDV|XABNYb ':OgŊt( ϋQ<*zPAТx+>,SDV|XAa Sn-  HĐ־d-HRr TRF`i؋g%>j-0iԔ$>S#Tc]ljhKa`KtCqH,onGpW`\HL\,@R:4C}8ʛ p5iϕk㻡cJtҫ}{V2f2ʂgBz)*&&}iQxf n<,!4QVqDjٙq%ئtP(E ~p*ŌQC-ukG1- trF81Տ썓[=RRzBr'};mݯSp>"eR cF5`D8iTiZȶK\h0H I*  HΨ!2!<ʑHNT$umGoȁ=ǝ, TJjmc$ŠI[(  Rq;|u2lbt)RwrQ ?sKȊ03Ow|w+֮VğAlHS8t=qVbnC+75'#ZmЕ-,sYi|xձt-6S*$7fTS$L12^~۬uw+ 6_X@Ԯ+ÌhQ! `01 _,ٍ>+ mlI `2q7VjYS:,>\ƋtGV;c{5nžS0mR=_߬4Ym[CRWQt9EE%%@d2xp2ڜ)ouvҍ_^$]/u+r78Ԯ e0⢭ uVv߶7je嘱),~*w]_hoUGi 덲 g# ; pF*=Hȕ1PRD ާ-]*P S"gu!lˌn-()lۼ:푔nSkq.UN~}ۊs:K`)Yr{CPrf8ӔRG;3[4RL4$Kl)ZB$ﲇ޸#8߸imZҹ IJv܂vT(aL0cJwv}K>my5S{cs& iDơ*ddy:`;9;xgۜ] "\9q Gz կ:ucqUS"6)I#{w{V#RAsjH |am)w^A;+=k%m-1SԥG#nJc0[:n7_ֹ-j9Qdl`罊D4Q324 Ojs8;F`-Sh@$g2TX!mG*Rrl.YpW)A ^Vu'4n FR҃Iӧooj͘IK l6Vϣ3ӣ3kN q-H9IRA)?z^- 魟Fg?yFg?y zV$,U{|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3cbxS>0S|`3?:3?=6'3:lO g ˣ3ӣ3sWU˓mIZN0Rr•ݮ}AJ[  юih>Ru{,j%)Mhӭ e_%0Q2nj]mY-̺ q߭c-'R%qMz̈A{EQVAB+)Pk. ڒIjކoRT 2w뱖c-'H62*hs Ib^s_huE&;*TntxCRAAgw 8 㹝[7O o56mppR\IlƛXZdd!m 7@ wU>{4oHhARQ};f[7O o5,rXpK\!a kᛈDXjD˫Rԕ Fu9t]c-'N[7O8֛žeQߐ,$%8) NG7ۚBҷV uz Hzc-'N[7Otk \7 6z)Ą J{b\#s[/P!P(OcѧqCIS8xrj#BC2㍽ $ 8no=CV38zU2Ɋkrp8$I# 90F}{o21R|ecxcԋVh%dOpuz~j%}nfJr@C#AecxIRp᫲%/[P@eiЄHJ) +9?ke严 0kl請N[7O o5/8(|'*$y5%XZd_h6ЄRF7@ wUKۉ1T5 ċx RTum]c-'N[7O,ӥ^OLD:ۉ!(p (jV N&)p]HKFK ##mo]c-'N[7O~4I"8a曎g5E*q9 +$j1* ik,_ 9 R RHӾ۹21R|ecx3c܈s-[XA;6N6˃GWo)>jv21R|gscm*c-'N[7O4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJIS楊4݌ o5;o)>jXJ c--!FJHWit4Z&5#1o{x)^{c-'KiWo)>jv21R|Ա\=ݮ}AJÇ}O>謸c8zlriX#vxwޤˉ!?Ċ1[2r;jϋI_]ǧY%6 ?RF>S+s&dZ漈ONv&p6{&T6җ>RF۔~OdI؞J3*l-!C&:͑bقNO$2I:0~:G1 &C Ӎrm<3- YqT:/*9~MR6T7T\aNڱQ8$ozD %Ƥ!p":9$wpG M'd B̸5h۹pbK\C԰NAOvzcL31i)'#8 s˺_ۮ sfZJqmv9R U!ZxV'Ň>2SV.a%FOPLn][g.%o{%Nv|TŦ┥E)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP-)J)J)J)J)J)J)J ?z7iނ Дk(~?ީ0kWXZGӞ۷2?S5,f<0r$CeŒq-C9V\:ݭb)֐wsnNk ;}߿mE*D|?"#1޽e̚emJm)CJNNAD4-%@!*{ZJ.! Iw!(RqiӷtR-6♘kg$uΒRO\=ݮ}AJz+kZ?( DwY!. ׂ1X= ԕ,,)9CG^3GxT-TR_G'~7*M!iҔ$%#UgJ"O\z-]j[@EkJ2TAVK)P|> .s Uԟ}[ZpIG5cp)S!qvK%!_r?䛴Mn3st'v=6(.R{z㻼E[\5mț CAqr"حWZ)e֜mj^04)I?fj\4\ѭfD7;P!#G}ɐ.e,c:C BF2w#HQ3ZW1/0ycQfzmN@$cmsܩ!ykMic%R:VHV)'F)ܕ;ێ䄯Sk!}$ 8ͫ۽CB[.:ˁd ZH5&j,7TX 2&ܻQ#67LSH_j AFIإx={(&HYu(.2 )) TeJc~,,yR%*PR\-;R͢fɐJ)KB30 'ͻ>JTwAJ gʸk/^wT;#}I%KPZNcW'koؖrR!bVʂwJCIDzIgjA|%(*3!]^B@d|1|ۻTE;aoeX{]0^JAlֺB2g]"t1:bIJ4jF7*~FVq^'i誔92L@M#8VE~,ė"TYLfw[ˉwBF)viZWβQ)hoʊ%e|}Nm)I+JJTۊA߯Sz6cJY8M"::cUIWy׾ 2Gl)p"o={:JRB1S͕(A5V-Ǎa"q2  %Aܜp׵GJ[SjѨxN: Q8zk%m>!I]#ؗ ZWVO] Bq |7%Nn!+G_jI$nN*퓩%C## W^ 3DŶR_q+I@8` WK=O=&blFT0^JqGuVTFx槆cQ{|qm^C0`MJcsڕ6Tq׶.YD+&qKiJwoiVsv9D~,QKC=ۊV֏`sX_&ȫĦܮ2)1ҷeY@PwS{mLvkS&ǖR pA AHke(9k>9t򒢥(YVΕ"+NrgupkGRvy*Ç}O>譭jwޤyEfi:1B~|_gWW{M[>VߒG-((줒Rz8J_Sh.D+A|O犯 ?z.+@L'Lԭ O(1gBSRFJ'8NҬA^T{GxSjB^mkKa„i9±88?d#Dvn6TXKj@H\Qc#PKyh52<)dP=aA ˚XǏa4ImDR0SniSSVF>{"/!(R%$ NVVC'z lf;whKz@-B ؃p%B ȳnCL<24V ;W{Uw.#n-UnQK$3 V)aG*8JIڮnj{PN7'9#c W{ٟe޽Cd,{9QT!}%YQ8G=Մ\`}#xIHl }ڂeGxKZmCB#cH@ d5 -ȏ%)L:dCcPe?|O.fx׌297y!p;{mZݶ\]mnZI.-?:A?dRWޟUSqJ>46HIJd@v8;c+[FqW.K%ťk @;Z[Y>.ib(1u>+u(ij3Nv=GVS* ZxIFVpcS{Uu_ljBO=Ƴ!;0 L@dr- ֒=,.˝ ϳU$?;7XN=%D:drFq5~gꬩA~#^ҔA/+'[l.0ًFaF<BF5콚P}\Aeɼ@sJ/=Y=պhlĺ) +1*}MVq`c no~kr 7#K g$fWqV-섐Soi3&EњiT/6 Gm{; WC6xDK:Җe6 +6qW{~'nelɓ! ZJikTTV2=\;"Ka䠶H %INXw}R178fDh>nwE7> R[+]jBR2W]s%ס2wAWHmA"T!ڶT 5$eoqOrP\;lNqߨZY\ {LQ'+}vޥƾT(q\(VN$-)4Ž:C. -!zCHLsd$8{S7oC J-Q@uq׸ګ#lCT^`*2TP%@d8궚Ù]1p" u Dm+p$-,JP0Nkjjx5'.q:옮%i+`J+aT0)N2^/k׀'bsVW h0z`qZL2à%!DNGܩr]2WrCQ-)<қ\Oǧ'5rmSo)ind$6ڴ(VRH}~:jΡJLHlp3}Սg8յ7^ QB2Z{PԜG:vX̴kĈ&ޛjbaQNS';oܪ5.0^-VҷN$ %aC ߹ĐbX!'J 7 lp03{&j1p 8y*q)8ŠA7bYO#TW$˵IԠ%l]\]PBНhҐ RBR:RxDiۊKm[UBT9@ҧ3y޻W.gov|dLq:O$8NrF5W;25Q!g*F;:40o2譭A\^zK!0У= D!8%#$)X5kңŀPn;mp)íB;]DޮX č:3O2J\%JBJN`uv^9-cve8m* ZP5m% `՛9k,;S@҂3"PX@[eAC4ڽlɋ-JRIZR}ౌAl6U]ɧeo5 ʎߎRQ!w9DrV [@8I8 ̗k>F:u -0ԕ`);74}Zf5e⥩ 09)$s|UB3TW&Ġr>Qj#pWey8ގcm $%+H[xI,SnrXa&QdHҐ((^)Px扨;g..)[LZRPQ_,J_}?s 0T%ML4Ss!K$:!+A'::LVDSvYZRS A9#j25 sNIBJNq2J\MңuIJ Iʲs6'KA q7.6)nJp֑ӌ oqˍpc)ZDu i 9l8w^J(UDf9lҐ8B6; G?:L"DH}J).))1L,S"TDrTi ֥$@^s>xj{׵ΕQ%8ݤ,)Hm) A9#lגo]CU;2Tjzۉ[O`-\gdV%H$m)VJsK¤5 lKJRJTUܫKav>$mW6eW)E)>S묥$͵4^(#N3TQ.K&֗u)Ɯt6T[ZJHr՛see=@2Vu2G#l᫴&ZS v#νXpi( х[$cY)f\L!!MoOZ߫>&G ԙL %3N LJs,ӮCaԾ'$(a*4}{`վpȥZ4$@u$sg0j8Snm[e%ĆQBWMNÊ1nrAQZ*YZ gJJS%DrF7PԨ-.I _-:Ydlj4dt )O1kRs5sǵ -TN$* =z;=x0t:(/:X$P:Ƴ8M& ^jLɖm֔Oh)Q8ߩj|tot2Hp_,2akk[RZl%-Zy:xN̳ŒeD6%벴{TTc3-sm(q*N)8Ignuͬ˪rxm483 î<%Ag*(hV@B$o-s3-خZ˨RJH$u))V2 H$?h?r8jrfr|HPo\Ruk#0=c} e[BI+@V9D#?Zp.IAZH^sW^[Ү6v1o+C)ueպN|;~$TN|;~$UU!ZF`-:SImcQH$ z%p_!ͽ o2$)Hۘ;ǫ5N|;~$TN|;~$UbjlڕD3{35>wSA*QpjΣP߽gnMjDqHSRn)!-BTF"]H[hKA-_t>}*ʣG|@E VmvWv.߬GqN % JV6 >}*t>}*F9sϻ [$%Ǘة`(:um;7sz˲O Ƿ wt%%ĭD` ;ҜvIҜvI9p3t > Zal$[2NH?b1{z O)hB*$b)χoğJtuңdJGr[cWsOoh\MO B.{u)-M$HIzɫba,YOKt+(RJ@QΔ3ߥ9S9UjiX..RDLfZ+R_mM:HP:כdZm[ $B\[aKJXH’ lqpkN|;~$U^eء-dQԠ3컕#.W ܭnKZ: WP|]uELGe9%7iBIԂ{E{\st'ҧJs'Ҧ˜thdF ?!k%zB\HFG=>ZbK3˕ak7IJmČsR4๜޷)χoğJ)χoğJSRL[*TtNr59hዌ[w )p~ZT:p1;lOSfVZ>1RSBrn<8WfSIvdƤBޮXo RӅ'%22FAߪp2É$BU @X@'.!(Zq )R0Sk\d9%椠Jƕa 96mYn]n,k)4!;ߧ[G-6veї j@n\JSJ0;vmme LhKRnud `{H9)JP|> .s Uԟ}[ZpIG58z*ӝe,BiQ@V2Fpr8>ܸqSЀ ׆ qR=vWc9_Z{P˙pe_[)k2\\uau5g`sU֕0\ SkR_%X.kV@Gا1i6x(eMr%>i!)oV9)qclCa)rp6PU^.k5*Xu!r;'N9]sxY3[컪y S# N@0wf1N.{7%<}i+ mAX!)Flծ0d--L{S*_j՝ oz늸ƜL9Ⱦ>g[K-A{.5a k#}~;s6ѫƾ*ln3j̴OۤISRywR%U`gn*Z[CuxJ(ulBV0FI5ʰۺl//tdOo-iQńܝCwWAL7CbV@'IMNsO O)HnKKi%Z_V7b=Ȯ4ZvN7yi+Vʶ%m1&J&=5KRTTydhc*~'X -Il35G Kn gDqZ(!)тvUz |0ѡhQ'{M;pcCuD7#m, J,8Bʈ74V3tϽѣh\J'*^Rτ(#R'9#99MG s*  >3Ը=࿸JRk^q菺*Ch)Vl 4NV7w&Kϩ0;_}B\[lK$((+FGYkQx)l-j!m [e+*ׅ[`u+]`2&c$ +ts;ea)9=@V· cɍ̙/)jrGlVj #$g+/S:;]oAҳ4`I߻V4!!0;yJJH QpIGWԟ}[Z 0gON{֏J{tq55<<x^p~4zU=(+6Hi.6JP$>{֏J<<9x#Z=*P \yF-TM wD_~sGzU5(+-\šk)%'dvlHk>{֏J<<9x#Z=*GzUS!8(A( KBBS Ԥ W<MJyx#Z=*sGzU5(!1[#Y*)pOpU5BFUoݵpPbDu%`%@cl BmM(d{Ux}1nJVvJBĩQIڲ=sc_.\3+df%ks8Ki_.\xGG>T),Ȉ l) mluWAAZB>i>JB>i>J JP)JP)JP)JP)JP)JP)JP)JP)JP)JPC ,||)7(7)ڕ-/w#)20RA m]{O+_e]nlěoo-^ӄ:#Pcn?͋ۉzϙĿ\3NgWsQMl]OӦ6.n'>gWs9K^%4mb^3L/BsRM<Խ";-R퐮Wq/{_?վ>ZL\\밥RvTTN X>G_rqJRWvy)pkGR8wޤ֫}O>譭A 'GMMP~t} R R R R R R R R RѾtVԋl[G7Ο~%{#F{TK%K @嗒.)IFa]usxqNC*$T pjId`c~]M^'%..!LdAZmѕ9;푹 [ϱ|kp2i#R Oldvg#j7. DKMˇ%~&8Zz+"#\aIVHNRpX;TȩתKCCcY{զUկUu^f1,c =i?TsAJ덳okJuܸms V΍!ˑ$8?UuZB>i>JB>i>J JP)JP)JP)JP)JP)JP)JP)JP)JP)JPC ,||$j!{O4ޭ6h17,7"RQIAr˳ B39*zE%Ŕ%P [ 9Pάj֭N^nc+4upkGRvy*Ç}O>譭jwޤ~t} 'GMM@)@)A-)J)J)J)J)J)J)J_:~;Vwҵ5oR?ѾtVԋlA)TS?5>-U+ur(QH I7$ v QL׺xק)OT4 ´Gzuu)%$GmՒ{)OE3^^( n~6 0ͩ0(RV'q7HA/+8^c A/+8^c䠚0'ZhKp 8Kj(B5{U[X^cm 3ԀJ'Gg=QL׺x׬:JSͼZG5I$c=^ RJ($(I!88>uf =QL׺xק)O@a'SyH)3N?vJԐU{ԠE3^^.&P0Cv#Z[* (B P#Jݪ5%E-a@g9cu #R:{ϣ)K\jjn&RRRRRRRRROUjHv Uۣ|mB~-@ LHleYڂ-@Y/  |gi=ZSp'wlmWtvP'PP=h%J: .k QYܓ :G~wwKZ{{,]xmeZNSp'wԱoqw-tuX®K֋.P“wrZRJ8Rwtuh>K X+>K X(&)@)@)@)@)@)@)@)@)@)A /pIW;LjQ .q׼HB 4%kpͶLNi* wd2$$(XҔA5-%D(` g8e.i[,6TZs#W-w/)nի`ҷVTjZԢRFpBvKmĩ Ɔh`| ߧKwl=J[&f_icl :꒔*Wj;;s}?R ٗZlô6"}kzC-jҔj'إ#P])A󫇻\<{ϣ)Tv;R~QEmkUþ'tV֠n&X?:>jj)J)J)J)J)J)J)J)J)J_:~W_EGjOUjHv TʒKYzJRu}1A [Z0ǬwGw^kA8A (8\VॷyťDFTNg$ N:䡚3eew4ӑR*-Y'szz1-V2H)k= =%G|HYcnYy:y]# ҕA!V8ʬo@RJ8;jW(RV¥{7ċ] s6E!Y 4%a!Y 4%ԥ(?-)J)J)J)J)J)J)J)J)Ja{Oa{ORRRRݮ}AJ\=;?(z+kPBǷIST,{tq55/to?qU{g7#83NSdgNFZ,yz}Vӭ[ZBTAu{Ԣvd\GZ-5IqIp c8t3EqkG췿ӱ\GZ-5IcM{q'`=YWV~{;3USeI:{&V -ɫ7ΰqlSj$:PnW-nY $MSO~s朗GpՂ5q߮!Y 4%a!Y 4%ԥ((((((((?-)J)Ja{Oa{ORRRRݮ}AJ\=;?(z+kPBǷIST,{tq55/to?qU/"#5Vn*q47-vd0^id JR'abGXU5ϸjW{ϳzǦ6.n'!∞:Iq:269;>Yq 2=xԥ󃂽Xtۏ:mb^thmqR ߬ۏ:mb^6g|"G\ݽ \M[ycDž!.J:RmŞ׊* }/pIV}/pIPMJRJRJRJRJRJRJRJRJRJR^c䩪^c䩨((((?.s R> QpIGWԟ}[Z=OΏcۤ(((((((((!ۣ|ڸrqa(S":JJ1EZۣ|_᪂/Rwd{ǙĿ\3SKBܸhH .(<DzHk+) l$A$䓃8Ki_.PʛRm AHF9cmjoJ @v?⠏Ŀ\3NgWsKĎ]t)n66ZARkA~:?U6AP"#5);C]s6E!Y 4%a!Y 4%ԥ((((((((((!>i>J>i>JJRJRJRJRWvy)pkGR8wޤ֫}O>譭A 'GMMP~t} R R R R-)J)J)J)J)J_:~W_EGjOUMAɿĜ.RGNsV3򪃉h "e V521w0+[|C̱neJ UWz .s Uԟ}[ZpIG!cۤKu6`8XSd`;^PMJLgJe|3>(TR+GҦ_ ϊ>Ԩtf|QW3⏥A5*2}*iPMJLgJe|3>(TR+GҦ_ ϊ>Ԩtf|QW3⏥A5*2}*iPMJLgJe|3>(T7Ο伧[SCjՄFv#{=-)J)J)J }/pIV}/pIPMJRJRJRJRJRJRJRJRJRJR^c䩪^c䩨((((>upkGRvy*Ç}O>譭jwޤY|Dym9 īZR[* (d7G <& !QmhqmZ]΅ANJ;d ^m V&/Xu,ŘϊvK}1P9RR:;:7yvv b׫ c ?m̦% oKܿd;Eꩬ<=.wL}Tm)S c~kViyq]-qHm+Q< I(V1MM=޻ϜV/O=Fr4*`GX\^ʊ҂\}2PUk~_n7n%jJ rT1$!GFnm]rdE2RHF ܰsa8v3GlŭieHDPڜdyNRwUov E%m!ZT)#}Q=ӵp 3Tg=!=4Î; 'HVlǘ˧C}lȄMFc;+T~b8! \DR(% V4Cc6pWQ j3W =ҕla0ym8槊\ HRBAl+OlRoHo_*K% :ËiG8qUY!.mn.KELTCDugBx!"iWPR4)Crv;Vem^B҉-@Wl#m@gvB2#e: ִR?_rik%[u5] e %Rj^vtR+^Y\T^[Kͷ5ӯH}zҠuk{[NZ䭵:ZZ$;nbgZ*}/pIV}/pIPMJRJRJR-)J)J)J)J)J)J)Ja{Oa{ORRRRݮ}AJ\=;?(z+kP)T߼Z⼦$\2q>m=ꏳ_YGqWD⛮Ϸm\bZ`+ I$;Wb&mc~p -(,Qmrzle\=.*}<쒹n-T޽bj ;jo5Q\9"w^hڛ,òQ$wj\u.%j!kʝeIBR\g^rFw{DtGSђ#6Kl-Jư?Y w6HO!:jUcY{a&+ֱFzk̅q.Ӳi JXA*GNJ`3]#!6Jo*; ((#q߯n5Ң3u[|]/84XRA98VUNj(N!M6rRn Q.7׋_ut}~Q{-m'T[T쭻_={KZUS{%c,ҫvFG׽>*6'3zd_ gtRQ)XfРHg{kQt9"~ЯyttR֏]{={J#^V{O{OjR R R R R R R R R R/pIT /pIT R R R R:{ϣ)K\MB\L48R9Hӣ#R'F#MZe ThBsJZ X-Mp4%Y4)ҋ] q)H k>& W2YXȐѨ\qƴ%BB0S# ڵ%͇Od^!,Gq0erq:˪osچ\8#ƥfmiIQD XO.+RXm<+RFATra@*mo/]]N5Bsܮz܉3'BKMK,2AoH_)'VK:8FyTW8~dNjO1_$ZTSX;$qVfHy-aíN1o?q'A, WvPy18Q!9AQ %5w6.oQQ)eIj9Q\$GVԌ˽:ZRX-J[Ipx}QR|ŹިO'srѫ<޾>˹VbB\{"ܸ(m冴4`RrWbtz/cŏ5sf'=!K sW2JsOUi"&"jR}ܴusC,vX*m)I³DAxX i,. ))8$|x?QIFx #I.Bd%!AN%^I IPscau>g2{p-I7ђ>N"RTc2>+ȃ.+RXeЮ^22Q>ۭ1w72޴C,*ʃ[6#'};lK[F&Izt%BXR2^5#i>J>i>JJRJRJRJRWvy)pkGR8wޤ֫}O>譭@)@)@)@)@)@)@f$#WMZGmkKpHjB25;T'AmC--;qgA#{vgEC=NxФhO1V鏰R9 6ۯ`P1Y-T]XZ1 lI@!)אG,I=g ΋ ztVɱm7=:!UI 3{^uu >n8:SiJu+=g9w4uٟO;3!BKJ΋ ztRYUR((5ӌ|xٲf9q9 6T)AYH$uDp.qq^%JԵT8ԣM@TD_- ֆRNsK NXSG l$vRXf;3!Bf~t]n2Zu2 & m:+ 2qd#VhsR p-I$(%jl%D` =[afc90 ;q6|{%)j%@AFלm{ ֡!o8ܐH(Z']JQGfN,/ [ BR9(XC p$8{9TRoʬr:"HDD <%6 N~{Kgoݹ&SycNҹ)$ӒJF߇mSsj(]"Ԉ쥴s$ *+ʮ)J)J-)J }/pIV}/pIPMJRJRJRJRJRJRJRJRJRJR^c䩪^c䩨((((>upkGRvy*Ç}O>譭jwޤ VaהÚ@) )='nKLm-JBTJGh7_5=i>JB@DuĠj H2{Eʕ[~< {b (X% Cn{UU^9JhZUOmzt ϶=U^9JhZUOmzt ϶=U^9JhZUOmzs r+IPN 8GET TګBzT UC--էBJsE(ZUL HW@xdghݎʞvBTu$wNƠX*jX*j)J)J)J)J\=ݮ}AJz+kZ?(,{tq55VJiXZIO#YGzTR}hsP-*{֏J<Ԩyx#Z=*sGzTR}hsPMJ=ҧ={GA5*{֏J<Ԩyx#Z=*sGzTR}hsPMJ=ҧ={GA5*{֏J<Ԩyx#Z=*sGzTR}hsPMJ=ҧ={GA5BǷIN{֏JK &\ sH+%#Dw}MihD J3sI*ߺH@7z)KuJY;w󓜝Nv{5-IJ-H$ y#rrOWtko/LdP.#nJiEQ7_G7_GE:H=hh˜H|}3Nt}}CYt t `^"$Uu4xNu4xL $Sn)n){CkTU^u4xY9F TwraΑN}ΑN}*ϖ*K?MOΑN})]"LG'ڑRN21&,L@ہM8_1')jgr1u InR9 C$G\zB6JׂH;׆HZ:RBU zXFX*j2VP% |xk RRRRݮ}AJ\=;?(Nb5t)]ò;~P]RN߫Ӳ;~AvK;~NDU.DxoIo4T-z4N߫]RN߫Ӳ;~AvK;~NDU.DyوZu;2! Ԫ]{w=vZ'}h.ҩvZ'}ihWsѠ-*ew]F{w= ]{w=vZ'}h.ҩvZ'}ihWsѠJhWsѧew]F*o!7;~AvK;~ND Vb]{w=vZ'}h.ҩvZ'}ihWsѠJo2:qz5ew]F*ew]F{w= ]{w=vZ'}h.ҩvZ'}ihWsѠJوZu;2!;~AvK;~NDU.D;-z4iUF)/^)'aVh((C&S1<iPTI=@wK;~NDU.D;-z4iT-z4N߫pvy)pkGRm'`HgV ; 9˒"l!IA.g_Ru1xeIxae(u!gNl'~7MDmd vJSБZ)1tQ%,6KiJР#(gz6e+bAE-zJRRIWP(k;퐒>=wBuc[I;v l5(׬ؖĂwR_A ʽob@6Qp걂5"9K.;>(e}lo[uo9 ~TVo Ǜlm\(AjKƠ^l AފFI~* $>AFJ VVF7 cz4ŋ!ˡ.2$J(WZ;mWjMz̒^HϮ(cUX<[rAN,l%#pY D XmNa. !++g$qVDmNts"!!:P^;UIGl1;Qq+3X)0GٓVdp)equIu:%Mrd ?N{ƬLU!2K8td8SǖtK~2K q($ ,[q9܂.eH[nҐA:Pd Gq< vRwE7eyAѨnIqՍed\^K4zԐTUi$ lznqK\&pka*a8pS?^7*TR$G.@RH9 Ek}M*tJR'sPH!I(ь!I˘GU9\U "smIѥZ+pU28\6G4냻w7"ԥWHџH)3'e GoHv&bJTJ!IZj)}'qDgbǣM!RR6JA PQIΐqom_2#}()td*87 ZpƧfͱ eǁ}$@%t$d8pvF$I2_"@B\yQ $ Nqְ!ȝm{*q*HOVվOY*履7tZ_UZ\)RueIBtFGJoQImX\b.޵r=VIp;P;Ճ⏢ jlQ%Ƌ N% T0u!D`㮦q$  cNssc9۫GdsDl60pBBdnw m AzkC)sAI(B~hOF?& 5v#FI֮ glթ|Q4d!XhJTJԬ [͑pt0Z 4*FPH:S\<(H[oK@B P'#~Bqsv'vF#Ġ .4( T'1׵dnF.Ck (R%$`i#)9ii>ַ9JAPԓbGwޤ6JL!Y*q씁pp:vڜ-aO%% BI#bEG2M둁m\f l^ҝQPJBB$cFB TRd2Tc:%L&Ƀ$#c%hBT$䃌4'n1m%mւJ gI]bGqjLa+e2^- <Ƣ ^CٔKᆔ.4mF@H QѨdgW)tvn2$0ixoJU  a^|yGQ<^XzLKOscV_|mx\19zOS}bqR/ys5[;|+ni-imI(BT4O/8gWlXrE3oAm8W0 SltH}\ejRlpVV / +S@-#-.;- DV7b$ۼ !Ԓ9x;bGV٫y̟K̍6[RctxcJ)ni;mm &k u?z*6&ڸjyJd%EH8@ܞ5*&f*B#ŐE =`V~1Z+cW-=!iJPYqh!I ۯqh%"tVґR)X9I Ռ`j6UyFeJRdugcjgkbC)M$$$YD73 Ê)NOoA(>1oDYR]mM$ T$NYOeS.S$:RR'|e;7r[~}VI`˛q̊*% (t2'BuUb{Cmu Z p%$d:aS .A(n/Dt&BHkNWX#p@$¼SL6㯗#":Ե,( K*بo* mv͵}h@Cj$vT7w Gz =J*ZIr$vlج-PCe 9STj69AzGÏ<RHm Rˉw[`mV|E:5ʈCqPbfiq>)ےHJаF[H$;ՙPRHpy)彔%%i8DZP'<5ʬSL6㯗#":Ե,( K*بvӞ2#@xEn )m[rw#_)ԫb!:tPG+JAP'aX P [CD! !aZPR2FѷĻ?}2 d 6j;ÙFWPpɖ0Ts+ikҝ[[! p:YW%r@)9-+Zt:aiJRRs R> AgIBBR{!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJd%|/5;!+yJ;!+y _ #JUJ_jvBWRJ_jvBWRJ_jvBWRJ_jvBWRJ_jvBWRJ_jvBWRJ_jvBWR8YZTz)Juimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image072.jpg0000644000175000017500000004035111665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0t"T !1TRS"5AQq2a#34BUs$cr%6t&Cbu)!1AQa"q( ?뎍l2Sk]lI '`\"g \X?Er*"3A=/ dQpRopMŊ6 RDu4RsW ʴ))q߭#e5%g3ؑ{)Hʇ1AzD.:T3urA߶?63A#jH" M-˯0q8<=nN+p'8Q) ܛ=`HLg1h}K HHQV춽R.c"$Fc6TPim%[Y"+2IѶjCL6@}1/ 3&F2NwOhטӰy"ΈJʚ a7pg#: Dd!htwz^f9.gm r^-OIERhZ!%H@*ѝSU:(3|gm;EѴ둞)+3tAB ַ̚/@`FHlHލgWccO J >þ9/ d)Ň j*| , mTE2,ZT[q!IKp!muZש8 7.$in䤩a;bwf TjuUb^:^K-{$\+OVgi34MPJ+Í%MIMYyCԡ ;*bqLj;5fz5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy6gbqLj;5fz5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYy5؜S=Z=MYymSN%`6o4 a'&K'Q%,rIgF8_BdP7*ݛGb%p[b9DmLI!j[ZNcuk6YC# Bߌ˪F?'­\eD+[!]ˁC)`9$qfFzKdSOkp9cvI6a n>"hWy9 HA){J 별MEE'vZ.uOۮ}^^49sqfNlݒ|)Kn]=hBu {4`n~g1 2(BCң*)M?o6Kf2{+?'œه1$Rb<-*p\ {U`_?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'œه1$RUlݒ|)͘O,Q^?'¼ e(BT쥊t2a?տi /KҬ3 }e(HcvI/~~4u)F$!!)MXsJO}"yG~rP,ҭD_N?q)XCRq:,j1k cb Zam6-i?vQb (yl:tM$\Yc$ =PkOԐ?M5)3IěVJҎtJi=0ioD0iNȚQm}D,ppR$e5 MTy:X\J+Ȍ2ُ 9qeR99"Vp*jXzRVI+ m>yn1Q&+RYuֲ!v6c-R%C1e}1R 7վVas'ПK@\?Vhvnm3wz::j7YS-^cl=e~3%WlJ8{wqI",^4Z47b,@/:4bba;86#K69l j_;W)аYp pJ4|IKo"֛z+*ZN]CLGxmJҗa}gj7NS&0fK$BzKl b=ei\DYqqInawhi2} "Sߗ[J]aS#'=/4rܔH>Za7t4 ηK( ZK/D maJ!WirbES:ۅBSoٲZr8E1&lboA4tgFҒ;TJo*>ߕ}dzJex8^)-\mҦR/:e-ae]&Fư2ĦÈ,@>=q4JRJRJRJRJRJRJRJRJRjFjFGMU'>ZU'>Zr#)1%iV̇AJqȼWaXIZ_Q9s`T)&DXˍJZ "TxL q !kzHQJJHg!p)0WK h`[h X*.߾roWG'?=5#y$(lʒ%?3Cn9$¢ŝ=i SjX.Ѹ[w9ܮOWsji[~2Ć?paL:b ~$&RC[ѭMH#~rWn~sjNz~'qH.6Gb+1ȍ8ލnH[l V@gZÔ KHk'11 (e^x_t0榩lOsb!B"hn-I En}~ʑ@a136sU",(Rܓo]_%pST<sW~Mr\vFaq9oIPb*)@aKi䶴gin JJHa^\ UDc"`a%OŸIOݐ&էp_M-\dNbl6 ꕷ;-;pb"<aohhaovӳu9-ξe'@GͼFk?_yy+Ru)YoeY%1d72hT|(7>m߻XG 'Ԝ7l\Sq!B&j[ ClP Mv7!pVt*:2gSYR)Aٚ$lrwp^\0fR)lT$ 6vsZ$;)(BBӱѹ?glݿn~pa&#'c 'bwk /x1a7Qm?6*p']*dWdm@ae6|y%;kq!+H9HaIq[ [|PaM̘w5xW Xjt\EkΥe;}ձ1,.n-ЧH*#͇W~<j95*4?ƯLL*uɔ[buJR$ U4T H!d>ubu?>4-*7|kPXWcu5,M8YBʧ! uF:漸VRK`$.lēj v==Rh܉Pz~e ω)ω*O}"k+O}"j oXPWr^qoU[-^X;RTM7,NNPa\̐hDU> @w{*TBV/6;u[ŬΜW6؊d!J,JHPʗ YҭPYS9I37n6"܅Ӑ&Nu!JUle=- mJ -w+8B%P4N𬠛(f6mT9X!1.SG wq.Rޕl(p>#&w?X.q8Ip6짐ٚeYYQt{7kcQq=OJHfj@AZ-]m*~w*14cXzGViRNbE3o&'fͰA*„Y -KBPBȒ)2_E;'-B?(:%9HOz$fb+G$13#K b˚يBF[ZJН9CJ)s][IyKBRBJ ) )BR͗5&6+1xˏ.49l$A˖)Df& 蔤cԜLTN[fb%Z*a:*Y&)b^B^LEciA)I(.VulHܠMoR)cW0^^Gf5%2c) d nBmフLRtlBW&yi(ӊSi!. vRK.eҕɆ]yuJd "B/pjĘZ\,qJFìhˮ{.iHjge>1cbJ\MJn.mAIϰnWQA\'WlmR^ŒDf݌nRmR8 XxJ11Ĉ0Jzਧ(z@s7RGSdCYJO'˾yB菼X䭸B P(}Id}R|y!N(rlGJN L)W-86FM?dƘU)jmSPl lշ]*bMS&cIr"B'Ji RRLrJH , tܙ!!!j+e%H9T,Ԧ*)J)JSU7'}TEjW'}TEj#bo.bIėq%h\ĝɍș),2eDZ9k/YhUp>>k6={ؔ61{%keL&٬wljXҙu@Z{*)#o #Øc0YVFkʙ+9ZkW[kkZܓUNO*%J$(%ErtdnlmiJ51#<ߑ!LF ܄IKo-Am)(F'?\1jtyiq)m0 Aw9͗ 3`[$H7ZG栋ʙ!ɩ *KpҴ[l!_Huy5 رHNGeĨfMفm'ݾ)qE2Z,))JF(Iȝ[as83Iu#HS %A!5mmNaTl)RUF6BPWjlf1%MPIT7I-=**jT:}S[ob Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob Pm^WMm݊(&C{_5/v+-*m݊){_Ԩu/v+E~Rدš}PMJ[ob km^WA5*m݊){_Ԩu/v+E~ȫW>ST1/$.6*$l55 ω)ω*O}"k+O}"j OXc`ƒ-HIHٕܜvgXbS#vKi Hy)ZJ![6TxlTbgѰKD*g)RO}aMT^.%I2R$ΑRZʂ?#*ؑilbazK#QNfSkbl)Z %&S`:A QP~Xj$fu& ST]KPX%J,!DqS'.T,aH,)J *YH*؍EHXәʌ2ּN* :-R }vmTuIčHPR,s{Al}sI-a\x[iaeŇSĀS}X&0b-3!ⰨI!Y $ȶQpwF|1xDp Q{!)BP@" 8\zqˌ! oۼmӇҡVE!EBlw Zٺ}ZF{2;?=]X%IX-oݶÒ0FN=t , oV]5Lѱ0&!d;HHj)^ǟ رRRu-Am$R tRUcr" ȧEVkmzV'ɤ4㪝ŗ Mmb᜕ěœ6ZBPb/VMFXׅ`+r$hWȥImPA.ccseg0T:0 &-*ioDXm8I 5GG͛u]E(K-v:T#H)m v k#%ӇL:SκPsIK]֠N¢=(IzQU`#N)I &lMm77fa|B]b+qΰM}岁(l-@ڋrzV1Ymi)HY oelm;'i&BK9liB]oƋf:!r4}z7 aWPMR1YMRiC$BYM|F 6S/*HBm[}pe)s%aԧm+#0ITXqM7oF2J#E^+d›-!MHVTW QsVm[scmPBY'7>Y  L5N" &bJu8@m#xVvz;ʐCF w0klɼ^#1@q,Wyn8@)JrYCwE_6p6FF pؐ6Wm|oasNg#%H.!;6h\LJ%F b”Xք<{8:QD%-p+Rr-olϪ_cC&YZ[eTy8 &nLUI7Up(S)TA9 FubL;n薘'|_}m#hj3W tqgr~lV$6DsDӍy*m#o*("N#2,g%F#*LvWmobrZY.C$)D7m6FmuƆԤNƅONB3 Pb^TԨ!b^TԠS3يjqxf{1SRN/ f)MJu83=g5()#-ol{[&ѣ76+Ĕ)@/*M[y;ERT2k6-aI `TW7Wjhp\Ҙ\Ҩ;G+V;G+VRRRT3ʦf1%ԥ(((?-)J)J)J)J)J)J)J)J)J)J)J)J)J 9gE'2jG VVbX~ȂޚVjF&?W>'4?W>'4:nN?լN?ը((( /d__A5)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J ma5H@I/'0MVfkYy@FY8L֮|OiL֮|OiT'}TEjW'}TEj)JP)JP)JP*__ST2U Kjn Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob Pm^WMm݊(&C{_5/v+𠚕E~د‚jT:}S[ob @S@+-"ux㎺׵op?J ib+4&½\_QZ4pҋ(YJ`Acmf8L֮|OiL֮|OiTtܝR~#m fN?ը+kN J Ӽ2);/¬҂ kN4;/šӼ2*(+kN J Ӽ2);/¬҂ kN4;/šӼ2*(+kN J Ӽ2);/¬҂ kN4;/šӼ2*(+kN J Ӽ2);/¬҂ kN4 kN4;/šӼ2*(+kN J Ӽ2);/¬҂ kN4;/šӼ2*(+CP:&wURjFjFGMU'>ZU'>Vbv B"v9lr,͠TJP)JP)PyQ>*m,^gc؄؉YU h]{h: VW)+{5e}2r:hu%*P1ﰰ[wWt֧ZM)lIL>ͤ!Zk8,U$Ҙ+*@7)Aj!aDdq]9{ T5J v)& \_p#n;+JiNplM#SS01)(~;PЕIm b5t'G%J ϤkUΑ:!PM "4ei)w.a6"F6ÜbzD,` n2Fk Ӳ2*$ܔ*1F.6:˷!MVVS`2*'woΑ?xӝ"uCƑq9٩OYSw*R MA݂֮FY?h'Z>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; J"R !1RU"2AQt36Sacq#5BTs$4r&Wbdfu*!1AaQ"q2( ?nM\ p $>8' O+.1хSh$$5&}0*# eH?VvYhBkڴ"@H@H.dgY^Oٟ7}K<7)qn -;Uf|e^8=Sk8eBP5z 9ܣUk.v8aQcɊHZ6*POHZֈ"9^r8=SiLQLC*wo8)N @B u@nԦ.&CmEI )ݪG\sDNGcHk Bn`k$ g*si#.N!i#IY%G q}q45mLQ#1F9V丶YZ$Q3x cy)41ssIT\RS7jS1ۑNGcJvm\'BT yF@$>e-9aJIdRIΦFi87;/4pz?,}8\?n;) {QwpHmߥvm[K6]#UG qHu3ACLQ#1FmT4}e.aNd5T6s Iȼ7M,%R"D|/Ttͭ'k[r8=SiLQKӥ=%%)ymkwoI^^&؊-#)(PQJV`p'wS4,>NGcS)Q0=!%jeVkc~r ENv\-6c2$W.,JJ\'8 g3hDGc95NJum,F*B)*lI vsiɋn p^2bãW]!@}fZ^Gc95_7IDzci;OMP3 ~Z:C*W'6qS%  jyr?kW3=ӑNGcR4 im05ai,#$G<*I\cԵu ' H\告?opz?ӑ_6 ķ?i~!BK73 ~>ͨ4pz? WD>ELQ#1Fy'N@S0pz?ӑW] WDQr8=SiLQ@S+}T(4pz? WD󐫢}T(\ne82Pin njHc*=uHqok4Z@n`î#dk R6|1D==>Z%8%FqTփI8pF tsNbqLBZj#7m҆.l,)wGnz-,ΩN1ƴcǞnF :3Mذ#):yI!6V1S aFP“+kJ[dôڃpC U 18rֆE={sh4$83kQJLޣբ 9jL5 uW!=Z8)H('tt}1\uF⭠җ灘}!g $q^)S`jwJ\ ;iL{}LU^^ĺcm9|1㍿ :;ZU冗aNR"vZHij|m0`xᾬmbfTphJt,:Vxwµ ƻJ3g&Tĥ/` N00kN"6rǏҳ9DEu%۵;Il!dN^s#.ω7&%),( PPqn Y- ZCeC)5e0̇hJ,珄w֧{L83bXq\d% qPKIOH6b*K2CՎՓ޹ѓ^.]k,l9SeI NSmQq1K.iLr#RbInC?y4j&lX{.U%6ڸY犎7^ť7m5 DP J>"X²feiEvY,]U&[ZN6*^Nep9rҋ+3Xw9:u2&̰5X.I"B|$VʮQ.Q?G+? -)>YW~\}-|nKK^4[$JJRьJ!)HTz%z/qUuuzeĶRmJNR#͔1o+wjaZ0PҸ9ZPB3^ wM̡)IA" ;P9>6x4y[ZuԄʆ]''8xZum,l}W9+SIV౬UFBƓYO-4in_BҠ<:'R\FtiZ\wRJĂwN.ڐai™HqTBr%8`[ݒM/i 8 HHNw; r@ݿypγ[u >'w[U G%%%Ja/pNswUw|+Cҝ>^ZZBZ QxJJy5Jq@t:T6<8'esia! p̄/Y`kyԆfE@bK.6@B²gU[ˊɳS)Qf(_8I`k!;sd6eKNZ-)Xm8ٰ2R/b/VCoƍvI+mjRAd q oenZ: *Aͷ ̹̘)0am8]*R 9 'ꠃkO#*tonJRJT!+P~jrnj{v'DǓu<9]nrˍ 6dʐ"D5QA*%^NF71RbO`%S*: 0 xV0n eE!*(˻HLfqRZ6Knc%aFYs‰r%rZ[д FAwctqɆbPaiCEr xK$9K!J$ Ca$,)ӖlXS5hSv%Tޭꌕ))X ~*TK)cKJsbWx5g12CL6"Y 6A w7$p-l6W%֪`Ǐ<b@H')|U;VJTd>ܲ 7(#"zo򢛬%r/HAq<5TgѶnPH۵!kucl\Ju Ndv:*-j5ll +Zed '$q\vc>[$[npNN>ڱ#@ΒY΍53eM<%iAâ5}Hkf"oTd^PJu~*th)m1Ғkxbwtӈ1RHP%)K1&$ڿiAejB\jHImiJT R R R~ -?[G֭YW~\}-|NKK^MYV1n)JRRRRRRRRRRRRRRR~ ?G/o$գDmT-.(H*8ޯ?RtLxzg%> 8R2$j$92ސ4[;WW%YW~\}-|שiO梼ntz|ށ Ui)kí5Ra]qZpc'ݬbRQyvBOesYQyvBOesA*Iwi t$W;QyvBOesA*Iwi t$W;QyvBOesA*Iwi t$W;QyvBOesA*Iwi t$W;QyvBOesA*Iwi t$W;QyvBOesA*Iwi t$W;QyvBOesAZT^pc'ݧ81Г\JE:{+s =eqcJSnW8z7ɛQۻ# t$W;:{+ڷ0#|u7ɛQۻ# t$W;:{+ڹgn0>N@ޤo>qxןK(iE*9uI>:OwFN:{+ p-S$y 2u#;s ` qÂpΛz~J~V5ߤKw5ZK1ln(|>3 HHyzp$WC ]U-WUJR)3ɒڝy2!9QW8Bpئy-%֗JANFb•iB\ӑiB\ĚTnE] gsNE] gsKiQt-9t-,IFZEж{W;ZEж{W;&iB\ӑiB\ĚTnE] gsNE] gsKiQt-9t-,IFZEж{W;ZEж{W;&iB\ӑiB\ĚTnE] gs]cĻ%©܍--J'K)] j@VIioF+ѿmQJoFFh9ҺmQ [׉`%P֢GsPq_Zן~\}-|נ_T~bkH.>k~:BƔ8)SjP:az?pլKgѮө(ZrFA±cFiS,IL9Mm E[~QIFDcW5RSjB6u8Ҕg|$@8<21ZRԄ+] iնFFΏv+qճu ujQJP:ēe>]¡ MqP6]I%.)BCQA h]L}І61^TЬ:Yx5Ke{F^ [V3T|jmS#kl8ԟ!##sHr/*77^.ӯO&;/%!Ej~r-$Hi2*mnuF87d>Y :\ƙK%D!ejc$h0Y1ԠR-gXIY:YJp``J5"Twm)e,46imHiJd{mmKV-$d PG13j lrBu2˚ T-Ⲧc5mKJZZ28 Տ#Ʒ{MTm!-,qvkmD)K1'$:q\@HJm+ NO|(rZrYC@p~]a&f#i~Rna) lZ#.,q naO~ue[&Qt-vD[ [[?v+JmM`e, <(f,ۚ-WHv$eF\ͻjZ+HBRBuBuVwn r]QoB2Ҥ-FIVNJ9NlMm.|vj},mԴ+8V;'㊎җSNN2rrRp14󳌭kr %N:5w^3iǎvmp[em 7}k0-؁ >u!$rq K9֔"%vuH\v65AkU$¼jt[YCφm+fHH FV| ~[ o|NF$$_kq˜mRm؞qW&'MvpV억Qj[a *7!#]HeMaE+hqsY PX7o%TJHNVuNϟ'Pٲ١-[V2!X (n# &fܝa3i+q8HJuPj)I*JVS<߭i-3#/ZkH[iTJr2*6? qP8RY?񮫁h\d.5?JS.TQʊOI98V-!h;.3h> ʒ0 CjIfq惞.̏ѶIp+|V+MIR\%vn$0V#ćk ,d6% e $(@>zϣI.s1fV]%Aa`$ mAxv 3$z3 kfshB\gG'ERQo,K`3%jmknt1oiqdQ)@Ʃǜjy<իsEi-|Nj-bvhP-KܡoH54K\)ɉ ,wYBN珞<ڀPhyOC?Sa4.t!=ɭ/;tv|dr]m)T U&%lJ"Cxu6#5cuU7xIPK/z:Մ |*,}Cr\An:s8xW2a,Ij%eĶP`yWkt+FNz'79Fu'AuKe4ZA%Nv!AGPv27zt#!8IJ)uÏr߻uL)ܼ+FWͭe|Gb˜ͽm)+( oQeU_ܿg]ck mQaI)kFOx C˒RVpRrTw++_ Myu~}^5uTWC ]V'u)JT R R R Tn:#:[[k\[G*G1;,vq;^7؇zL6R,X#ν(Brp2J7TX˄HˉCJ/WNc}wc+1;U3 } aIR\D)$pT{]S+5+UK >bR߯CK\y׍!ާ1;Աڕǘxbs߯CK\y׍!ޯ-76RUI8I,Iq;^7؇zwRjWc}ww~o,vq;^7؇z1k䫒dp 㜚XHҵyDvήX3\y}~2}~gWE)TR>hut_b9}~2-]ا].':٠'?+(+WV15ߤKw5++_ %kjf+az?pՔvd:0VD(Ҥ%JCHo]CnJ^d|w)$y*Go[i,JnuJ_2uQoiӲY\ɏ\fM3s!>P>(b>GaYi)S΢'Hۃ &; kvCZaem,mސ5=H 1@Vۖ7\dhSiVU* cG?ºay6dMeSv@J@IBX<E1ݚ*Pd< y)qC#Q3cT˒ 'eXqӂЕx);m9c}!Tåx'[HGS7A"7NXH#,o?¾]#Xp>7Ah)JP)JP)JPW_T~bkH.>k/WV15ߤKw5Koaz?pR~}^5uXԥ)P)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JPW_T~bkH.>k/WV15ߤKw5Koaz?pR~}^5uXԥ)P)JP)JP)JP)JP)JP)JP)JPR)@)@)@)@)@)@)@)@)@)A]R? [@_Zן~\}-|L -WUKaz?pbwR@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)A]R? [@_Zן~\}-|L -zf?/W_UMWU[$w>кR=υ6q'𮔠=υ6q'𮔠=υ6q'𮔠=υ6q'𮔠=υ6q'𮔠I|)=υthsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPsĞ›_WJPU\ֵ,lOZަV_~\}-|נ_T~bkH.>kG6+ ?j̱s>Ea /U\9]2EXS,t\s>[ЈZRV#xg:.z™c|+S3n,6fRPZNߨpTF2&38TJsm-ݛ(H+Ng;,5yc|):.z²soӭh 댸2\Q[A*+%IߌgLpRJ>P}BX :R#(-J fT o=Ahv7}_c|+~::.z™c|*,l6mkq 8ʀbN6j)i; IR8~ c|):.z¡.K%PB` wn5սeD%'Qw}2EXS,t\pi5pA)>Q_t2EXTr̷eMT $2jUVrSAtfqUə|5q8|v.ߔwIsE9\QVU%vj]jՍۼAƂ%wIsEVI&:5?15-:jHZT$p'#;j*tpm#%I-@t'9ܕ$* Gg?S%5SsYhZ` TPwIsECnkdc<)dζX9knWՖ了Gy z5B)q:.zG *A,t\2EXU]YiN:[D( XIPϔPQGdI.(DirwY[Ru\py#8,t\2EXVQ-"+Y#g k-* 6gAY俗Gb[)I '8lFX e+˝oA~ |RZp.6H#$`ڊ:eNL&B u:((?5Z++_ MyuX~q~ W5O|r)Z"j긤A/ϩs9ޮs 01>Q\w~.v;\φR  *@;4W l.-pTB0@#W1]>O>z'Rhs@kGlisjunī R*ܔ2!V`yI'&}K>O>z*uǾ+\w,ԩ*KN$$9F|jk~O>z'RhsTOZMU%: ʒUny@c\+q .j䥢9<3T/ϩs9ާgԹPO3 BN$c;ϐ¾RBNY$17y\w~.v;[)HRaJ?l;C|}KVrSOϩs9ީQ!GڛZ**I>aAG%FoDh\lGV'LATh m B"IJR0=W  [}HHC.KimEz` =W |ݥPߠvE"2Jb(dmT~'öX`8#k7)K# QH V7 wi_$wGvBG~";} K%G]ylOޙ>AҿH+5|'LAYPVA wi_$wӣ]S!8 G<<G *Pyk9'nz>O>ztʎK8UC 1j JH!LyO'Kz5\w~.v;ulofSQZrDG9R%QԲImnMdr@?l;C|}K7,6N֚qN!AIquC )*Q8J2wUV}K>O>zʫUBW|}Kvj vN)[OTWV15ߤKw5++_ %Q o.CoAPQqSOR\{z8KOz'.^=T[9OR\{=IriWҙ z8KOz'.^=S!oP=IriSd%٧^_Jd-'.^=s{4LCd%٧Nqԗ/fy})s{42zޯ/2qԗ/f9OR\{Bޡ2zާ8KOz[9OR\{=IriWҙ z8KOz'.^=S!oP=IriSd%٧^_Jd-'.^=s{4LCd%٧Nqԗ/fy})s{42zޯ/2qԗ/f9OR\{Bޡ2zާ8KOz[9OR\{=IriWҙ z8KOz'.^=S!oF2t3<)N -O =Aj"uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image010.jpg0000644000175000017500000006161711665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;a"T  !1Q"ATSaq24Rcr#35UBs$6VbtჳCEdu$!A1aQq( ?VqƔ󎔤2Y"D8((Vܖ+Dh7+AcVB"[qRHH ;51XJF V$lBi JTA:poq䉩ia=W)p#2/^ iQgdO:dj"%V $5+ruڶ% eY7o#+a *Pyض(\ ਁ`{/T ]rS%%MHRB`S{*-{j JHPmAT?sfP))߻[N*8l (YoڛhoP5.-+WV}K9HQ&p:.nߢGS6$n/JJ[)y! Sa0 ׷DM[jCeeSush-l}fqmN:J5 20?oȴυBzJSyHjڂ/bw]^$`\2YShs&emB gm 7"=Yi 6qTIJJmlӨ.Uu&[F,bS.)D,#0 -+ x,&28q6+y,uvږ_uTaC,4S*Vu)cZu[ñӐLs*Pч[ &Jۭw`ߢGWQ:ВBnSMl؜yKv}+\=NӲیV Ò Q AF[m!7؅@ J$`k yvz!\Ϥ-{_[_K$/I,2FVI{ ޭd)S-[& #wv"*yn׀SFxMJi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRi摻^SRmG!TY)$׈a;.kC!VfH#C#u.OmA6 QrEz[ͽ [&*LKSB'q'Kƍ!!--ҝI-M3c }** l9]n4 ՃӡP4%KyL$i ޒ.>//8smaK 2s*sS|(>ŴqО*Ua/ S5$Y(ٸJ,\o^ʌnBq6B+.pc*6E:Q78*تdt&N4:}e+ǜd(H:04 PrjDA":>K/t霨N4nqOXҦ}&qB[Rzڤ[vOv΅:qGIaDE$4\o)uen,$׆ HЖ qsV%͑d X2e "9-0lHP]Gۭ)M.Z;ZBqЄJUkk ~`!- ʐ.e b#81gfYMÊSS$[y>L@GymMR@*CP BG6cxgיּX pw]u89[:r8Z\\F<æ%1*$‘k>6jBVm{aR&c–<)B6R[Q}?g;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zv*Տ X𠫳Sg;ӷV<)c‚woMN߂X 9ޝ6s;~ c–<(*zvBjT_E_JPv4(ጭZP֯td׆T3~ZHS ӮqL%FAxiѐ{^Rk" O2=KhڥdG[L&RQW'{o V4=կ r9WD3F[) J"wks !-:I9R o&Zӣ V5~SbV]eJͭņڭwFAxiѐ{^yI&f2ԘOh VeRUTSő/Q[Aѐ{^61Z\yQ̑ Õ)YWB FTh$b3C,)9rd(r\Rn;!ӧ֐GeI;EaFdy/'h˵>Ubᬕ.C ;Kyb;A@P1 ob58FD;- S*,Eʹc9H n; ˄@ܸU.i1I}d׆]ʘ*122+*6 eh7󱣷}qŤfORz*mpٲRTu0((qkhZ̏:OڸPQW{*6.f.ũEJZi'SV@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)A'-ۀ(.롨' HqD 3&Ǭn7unҌy-ke$,؂l ؓu>n{@zUkT3E4 BIUy0{RGogZ5gRcg }-J o5W 8Y GPٺΕ:s AV7TX3v*2KCRVx iӫ~}'bQ9I̓r:F6Dw.X }J-lGJVNj.OUKR9Qq9Q+oobsl"Ko2o{kb ͵2J/j%& 流ڿ4bNTPwl@VkXOfTc2K2츑2 m6RkDfv?:*D5*o cDrN@* 6uMŪ1Y?y=6P1_(Tt N_c&0Duu!g(vm\[M%:}s=lʔ/kn^U%W3SK9Ps"!}UQJR R R R R R R R R R R R R R R0uQTZ% `s^0\{yJ6b3y]]=wPnR\z{\81G05q]C@e+;mUeI!٩DXΈ*.H)qm}xԳt\~[c"cmIH2V 3\O_@(ؤL>RczHTG~v?.ۂ DZqww3嫠D}{(c> JZu<%Y t*q™r\Hm"|B{"S{ 㺬O29;W' Zj&u{wTY,0yʂ-%KP*qj/z ĩQ6LODk+Sm )M%ߥҿ?^|9Mi6ÙRRnVYĢ-É-繰I͸iqI_p_Bm_xJSE[kT,~k[o$fI}aYmJR(((((^Uy0{JUeXě.ϡ1D+ɟ՛U *ܤ%.e x9'^X9WfQV׈c /-5Ţl="2΢P}nL{K[Bs tR8y9r&['__s(RPcXGVn<$l9]7rRb;Ȱ])jP@ ]tn([5!17vU}b>MW$RI!@ndׯ2ʒP%8y̡Yt:Zm=JZb睢W76'loo㺢e ȖCCW%i}l=u yU!Ji=EH됬7WK҇4ԬǓ͕q2Uⱌi h~Kmrʮ+e8ji:Kқrh>XHycP:sʢN]sh ģ,um!(Je ,ҽXlyHT).$֢FC{U6ʊ[(p.56+6.3= [$4)6RJMȰTh^*d`HHa)#b'r#bC 솂ێOXlOjScD FiƃS=I( ˺ٮ==ſc'N{O³DBVBP M-{7aRJR$qۥ6&H*;>ʴ6y) ~%? 1O#)VQU6[YL[SMJ O3F >"6)6Aw2 k ?C)Ww~O°#-3b)m<RBVF']{|.\ˌ@,-UrP;Qw??b^d8R>v(-=RʉOˌp8¹ 7WWCd߾5!4yNs?p±rL K [C7*)$fׅr@C,\%(wV7VTa&r7$'N䫓 1 m-*)߮OP]o'Ѻ;Gœ**Rbqr&Ciq҄پ:f.A7T&grhi]yS*ts^$Ə:pkURg%׃)΢. hNM{m'0Wݬ5_s/9V0%6S*V[5rsV%3.I QRSpHK?æA[ D TV<7s+NbNYa vaiʬQaUy0{UjJUe_qim)$oCPϲ*6Prd}\en ył[)+>=u;Y-\ZP"B;6[^rֹꤑbuoyȶ+"ŔvP(fA,m\ .riQfP(fǒ̤)l0J+4qGO.5AJRJRJRJRN4'\}IKI*+*m8[;in)H*$ >GUl=M6=i1Y.ڝؔLKe.Uw]M7&X u@O?&h a¬V9OZ_iNK9A׵pL2ĈL:BFҽ9@uSVP[U.VV ua8r* %jp+V- keXۭRob ׺ Rp0lPol(fKl H۲Uc Se#@~7@h[69xZRT3$ ނl2%ʵ374^[f{\C>ʷ+*7Jqboaxۏx /5 :ojy7&C q&@ҵlk1H6a%.n-J+u33iVfbOtcJ2rU%&!#e:VX )7u|C 2d6Km천yz4GrX mg,[ K_`سR^ՙIuUG%$6 a)sNew}CQ9Jj.4 6^P!#/Q:uR1RfZp#.K aIqD%YlVH%Hof8RѦ\YդaxhJ k{;qXAȌJjX˕ \^oDႨ=+͐]`7Q=wZ4s@HpGi kqEg(6F]V6R~TbbBiMT$6ewxN;-W*͵Iq *4e.fP:[p:߲7ʙTa!xfVY@ [r4:?tJƘDF$aqJRI.uc'dBvaf:ݥ=U # R2\R6Nה.?8:NtIbT%9\J U*?慹rA"D̥#"RPTVK8eRe_015%njK'6[8RHiծ$L/4##AM1ˎqT!l8ITk,؍-01IJٲ}a#6 BTGa7:]GGd惑Qab-i @y)ڸRWp^\Wܡj3D ICB N㭵"$zdy9\j:8Ө-d̢Zt(0Õ9`6#f,HAVa`WaGG"d8F9Uo4$aDdbS aE:Rt<IK[5IsFq /Đ.NPNVWKy@I#R;1!0fM.H}lHV *-zğV# ^$!Vթf[[Ԩ8hw*CDZe8/]r6<NQ#nAK^鵮WeJcjtyNm?*$jS$v])@`5b`~JR *ܯ?}nWT/9VCqmb9YCIZЄ)] 6 #V%' ?Fnpa߾189>BeR CHЛqxܦ%re*w;YR-(g T׮!ڽ/Ci:!iJ#kt6JS`yQj\L6 [@hvaii* ^ "/&+)qHٕ~zj6<øtvLl0(ghsXv#-츯nlC^~r2~VUT6Ă ZDa^fJwKI'xNު㘓NƌΝR'Zm9Ų[oS.>4]ARR$0RTM_Ҹ׉5=GJg2h7d ٗu˜A[L!9)zriD?y %6 +nrǕ+ O_J@BԀw/z}0ⅸc2.ifmqoe$zc 2+,0!4AX$/: bAҲѵ]m1)G :0Ԭ]9wnޅXX| Vq_ !B Ad+ !bvbޏiOU!}Dq ƱxXf )d:aH9z7A3 HR󨖑7뾥L8KyR:rЄ-< q ?3SDdBH9JES[ )BIYQhN:]V՛m?4mƓgPPR{.5f#J.!@lAQy(_J2qt6Nze0ےm)I>֭ b$drI}Hr6#"½RiZB 8|(El4VIQCIM{ 籼*s)pkup6zI;j,W>;,m#5nA' ІЈ1Riԉn*JPʀ$ >D~Sts`((RBRz+cưد.4T!VBHմH#yU;+Fi*@:`u) %1K7S6r#Lvq7/,6˫GQؒ{j#b*N$ISS`қUHяWp>5QhV\l "p\bc:A)9,QrTky,IYiDvB|uT&~A=An8uh5QGp/'+)u* al$)!Dj4 A B(3GT?E9Y풀!9`obr> RUu9KXc2ʌ+K Oʌ+K LGQ%!'hr{B_ʌ+K Oʌ+K ^{jT,luy􏾔<;m * 7ԭt-.!+ATv y=«g[P@[ST3)hZR8+<ň[U4vi`7UO?lՊ9&"Bd!%ĥ'=JE*T5^-[!o]m5R8`)!–+Hm-kU,e(Uy.sRmplojRN'ö-"Kn-$Yy&\"e I {PszTtjX[*ߕVLgTD^YK>lE`:Z-i.|9`[lBzkZهxS;5CO$^T*:\W A׭շgfw됱H/!Mj9:pUm_}\u6W;KT6W;MTT6W;MP_P}\u6W;A~gdIuֶJv+*ѡVW;U݋ EbnEƨ0|G Ok-BEm溬;lo*p.( Ř}֫Mt*)J)JW^RGogV_wSPϲ* %FSK#wRҁJRJRJRJRJA$ aҔ   , Jb Y) jJ)J)J)J)J)J|)I \nRRTL?-DAΛ)gs-x حAV.Tӧp=jn#fD8KQieOEe|,O^y(;W?TV/+%|#g#sPw3R +Ԡ]Jgl?Nҿ Us~Sៅs؎79LmZ%)J5IN*AAX2Pƅ"@b͜ʒm|#:_Xqz^{mZ15%'27']'횱A%0V[$/n'CoUM"y[>K8kmzK+hPPD5.vB. ƵA)+.2s*#rAUuRg%,5ZڥMm,-n=ͿՊ x(boUnz'4|Af[9{(YV|Nz'4iU{(ӞUnz'4|Af⎭&c++%C zD6 G?M?-FS*\q-DI ?'MMXW_H sVrToCeJSةWꨛ_geQFڸӣO\[j^j>#'^:,jYAo ԝAFڸז[~7%[qΒjP]]͔kUw^`78weTW^Q?U6WETT3rljR R R R R R R R Rgyhj&H EbM1N~lai)AIꏙrw.E˔ҔRRRRT3ːDeeM8ok&쩪3]8 m r٥ "`4g½lĿwZ : (n~RqiH#ukuQ_ӧ;KN Jݭ濰Rѵ7XXڃ'f%Vp`1~\-gS HQ 5QP*q%&n!jV9Q?wyET W^Q?U6WETT3rljR R R R R R R R R Rgyhj&H iT&N#cw(VGV7}_'lCE+'!|ԬʾO؇~U?4PkR+9<'KJJ"!V*?ПjIvM\! V'*K A +ґmMn>Ao$;+[o_.[HZ}ut(0[KY_w*68A7[R]RfFB﮲ ?}V*= *Pϲ*e[e}TRRRRRRRRRRRgyhj&H Grp)6ՙ wdZPum 9Ž}>)'o3c+Mğ]QqI)EMbbʺe֔rk,C>Ѩ"#ҵ埍2ygR҂,=+^Y,Jז~5-("#ҵ埍2ygR҂,=+^Y,Jז~5-("#ҵ埍2ygR҂,=+^Y,Jז~5-("#ҵ埍2yg\ OǙpĆÁe^8}h6ygL=+^Y>Ʋ+.l拵k~}|oY,iGk?8}kM(+L&sPRs_rknZƙdzVc# է87?AGk?eZƱ?pZsῃs9dzVY,kTPG+ Qe8/$OUnxɄ[J,Jז~4#ҵ埍KJygL=+^YԴ,Jז~4#ҵ埍KJygL=+^YԴ,Jז~4#ҵ埍KJyg_ZmHV-Y?RRn+¥b$WrBB$)e#"9i7D/z0fRT)($0nUV2* jq$ۮT}8FE-71*[̀^Nlt E\li.4Q h}2BroS.3NyjP[6@BkֿmhRJFm}(s#ό1\4_׭bHW[$-uI-kIne14I)ijJR2h٪\a\XҝuBwph٪OϗA2ڊnCn bjRԮŵ7*g%@bd(1ֱmjE֯[`VJ @xjޕ&_enK@*R MIX$xs؃XQ$K˱]re)RV)f~`Պ?}P~JR +F +FRRRRRR?X*W4uO9c; X$%[=WC `Abr0iRt^c zb&$T.7DTRXs6[N}s&Q&w*na\+w1KyN=,MY܏Ҋ¼t `2aS|8m[0]{۫m攩+s"JFKm ')쯈nBS/}z0qo¼W2ɮԜ\}W&8,%@rMc zs ^SA8,J׸ /L?(y8V?"+ZͩˤGVyFX͛dQ~6%)A812NJRivBRJ !W8W;6*ߥ}cַGBz[Ԡc߳=_үxá=_ҭPsRaH> ̭9fْEE뮂+E m I#-(*3' d ̝iv(>HA=*=>ݟL߈PIJnϦo)g7R۳ mfBv}3~!A%*=>ݟL߈PIJnϦo)g7R۳ mfBv}3~!A%*=>ݟL߈PIJnϦo)g7e߳YE1Oe )Wu S N)!6V Mh3_mk~BB@K @e?mGt7ԕ1'}86.M:OoNn-j($kŇ*w1o1ؿ~KLx:R[(@ RI:o^`Պ?}P~JR +FyGmͦk_ڈWzR/*T)TR/*S"oU>J8U-).wvP[)@)@*ITwPMJґ~W)||(.R_UJE%_ })||(qX\l>_ c@ AH[ArO"o:R/*P\SH[NJ)TR/*S"oU>JH[ArI8E$)*pU)||(?O"o:R/*P\SH[NJ)TR/*WDP.{hʾiTR/*S"oU>JH[ArO"o|hn*P]SH[NJ)TR/*S"oћSmXRl UADP.{hʾ"oA>l U^JH[AkfO6}W"o:R/||(-l SfOV" pC*S"oA>l U^JH[AkfO6}Pb. ^2}H[AkfO6}W"o:R/*PZٷͿuUH[NJmo'UzR/*S"oA>l U^JH[AkfO6}W"o:R/*PZ٣'^JE%_ t_UJґ~W)||(.R_UJE%_ ^H[P#Ӵ̤]JR~C66ڞ"$ث]=Utc!;!<'6MH$ AJQcVcbQ ,;l7jiin%%'҃5Sb/I[M%;}YxcRШ¶s5iʥE8mG9<%֛RPa.mI^pIoq_?/lTT<,Of+f(sh27 ^# Cn;֖T}d h*OBL(rgTRBRЫPO֠ox׵p%THnšIHNl.";hZb'6K\N\X#Va,(A5;B+ia-s*^9 R.:ofZFPhOmq4 (ہ`gk^*$+`"29Kuf#(P5D؍5@)$:eE-¥BlHVri$V$ ka.()qYRA9+ٓimYMcB8V'rOiSMMj)]칑PI9ӝXNiaV =]bhO.Wʤ%NU`Awf鷦MY5P@P@P@$HcYFDRpk:թկV\BU'+7ENM$ݒmMJN bZd얯Zg4]':-4}sM&Zvmݕh^kˑOq'"u)(Frɩ$w{%P@P@P@P@P@P@P@P@P@P@P@P@P@<SP!)U\uCVg{$Þ#U>#׼[7>+t}rS>kjX.rR:4 QbNXa+WFE,|,^0WCS 9vJ]՟6"5pJZKᾯ<5H10F?5<׍={aO |Lsϭ;a? F/~O𽏉/o7XKKbJTxH^-5էE*xQŪtgש \;x7 ѡƊ\4kKFP[/cU~ ֮ѫהO:8dtZW%9MS7P 71/E5Ox5/wNV/: [1t>e_R >)RXB*\<0*7cq|لʜaN* `cs PFRB_ Z Ta[ªX9aa^UiBT'R#=ҔS0ՕyT*9TR9Z+TU]_hWJ> 5fhY]iw7I.K~4C_h]ֺ?n,ǵk8eUюaKqIʪYcd/:8E:=2pS:r=Yeƪ\`BXJ1KRN^e:ҧT霏'4k |#KxᾧuŧC,1h>ֵ= S_V&MX2 hOR=cKKZn03*TZ1*`:t19n \{l UQ}_ V"4ZJv RV qrV g^ ]]?/㿈z.eGU]]qih?=[/:9<]B%Xƫc}6Em%rVѧ%,4oiN5XNZ ل*ᚔg*TWҥR;՞R9E?dጆaKF*GPFsUUZk_?>]-KHV5x|m +{^'b~URPԣ,1yz1W/VZ0}[J؟mUeEFտf{OjK 6:=_ Lh^P>kRܶ&}RG$p)H䜾40r'P,$&St厴3VmէBPU|8{#Q{KHoڮS:o-5 Q_z⮭XZi5[N< [|+_.53E8d؉sVJ*a5!MjRl64B%azcUC8bZ^c0xodڦ/+zwf?fcItY<=RPOCiwont3-:8y5QȯN\qUh(2K*QVtҩ*Z{5,$yi#o:U)ԧ /pYP r:oiwwH[SvֽXS̱FWq fR*!ya1^ c'A9l'0PS,4ժ,Ps+b2zt-$]Κ~r}Jյ-AݫI=5X8G tBJ8\m\/*b𸬆rޭIG s]zPV1(a03J):*]#N>JPӧT0uXץ.YSiB*PhS\,Ҵc)R[ <(źχ4㰓@D|{Mcfngk{dVO=̑2cFg>i7Ta_3̫`ƌ0:tƅ>Z1=qGR_UZz4r^N}fTN9S)[d^| м/|9xV'-x7qmj׺_[iuBxgJ|ASQGZT^uc'KVK쨪*0| KW,>gByak =yGݭ);>762mj_R=3>7t ]KéXXiWUz&-eh"G49"%l J-*5e Dj_OEAa)UYR1QNlUSTIެ#'K$TppR)r/hӬsqjJ4W ~xĞ)𖒷V\W C&%4/7ڜQcQmXnd:u*'.^ƞYӄ 7Qs6L:\ؗ:rJ uW*¢r"N9=lV/.)UTQqtaBjSRJ^ss/g4=;7\]?<;WxkúWɪ6&[ZuӴ-&I>>70I%ĸֆqzTU:gGQʨsFJ}?b-IJg5N ʚry3+)cV8ci U$?g]Kh4/ o⯁ZX#Y\jznKMm NЮfbiJj[#/ VqVcEU0uq̗?ugRiRoV4<&?[4*EAaN Ua)ξ[Jp8P']X_~&kX\|Bοw|3_ |DOD/=:m)LVPkv5,QRR񕿱8U-8N/E0V;(o*SC MTGB C bXeN5a>MU<_5֋kV}ᇈ|kx@_xi1aqfq1tcN1UKO:!VZxUB_XR玣N8%J9|RJ 4kJV'g|Mu:Fjwz#xT%>pkͨCEaRoIyGՙJ\^qWAR\T`VhҫN[,#<y>[?͓RX}cSXYXJ|DsQpعb=G[Kb!$XE]-h[JVWNqhKܕגiRhE{ xS z(mϝh2o;y?N&W5χu]s୓Z$&Kol~j=jʫ>s:gS:.()u!/aR(fRxDJH5Iԥ7 upk›RM*UJpJ6)\Ԟ 'QHƼW紛|YU?>'Ma-|-;".|JLLPCmY&}Kޙ+ϳߩ?Y^3PJ0𕲜&VqxZ*Fx7^ oK,L+kkǮ?ӼU/|OuAjg}Eu߫iAƾzuy6a02:NT:9jUa=ԝ7q_%[ ,VbrF5yCħ5JTpգRE "tǍCş 5icE'k:Khڶ{U|e|!捨C[òj"{F{W}LTcu^\GcJ2*g_FS˫ᣒƊ 5J*.M˲7*eqs_fzT(֎'T8jXz K~G:$?o5M[-s%~Q.}?CeԵoflm8Pf1˹%ə- +OiKu[?Mѕ)g|ךqO g FqoB<M?3lj)e+/0xQ߈z.<)2~*CBxwCz.uMo>(sxlM I-UYi֐a zxyU_RJ)Q:ٕYO1%IJ_lͷJ󥇌*Q,<#jL<4aHbb//m|?/LqH|Ma  > I ]Bgc^ͼL"j.+/Xg67 :O4RrN9Tي)WRԡ,>cEIeXWJцXz87R3YL,'8֩V|DЯ9_|Ivk>$]6Z7A7[wYWaX^A`&\iRNTcEug9'fVrpK&XbO8=|]lM:4R|%iWJ1^ʥ_cRxX(FxZ8i֮}ek SQŇtY5xs71ӼIo @ 댚]Ǒ{m ͽգOB/ ]fXBN6.7ldm߳晥xό%O8}c|:[|pm4Y/ ;,+iaF,^K*G %,ӡJ)`*bҎ*qʘ:tiUJC=Z\VjUtjì5L% l9WXP|FW O^S,o>/^x6kOz?h;gY<+=4=Oÿ㣦6v{gM;tF=B[qU* }<߆(c*xn8ޥ\S_ [ UVzrxYc^,UZUƏ xgB= xFA.>^G]Ocq :⶷M;%&_ i[Au \g<:yƳRtJtqqZkέ*]LΤk.K',5uZyBJ10\H~^\x2XԖ &.az\_dEnX5ɦc״?j!Ν㙯?E^ ;Ǚwάa9rBBVPj%<'ySF60}XRʟ%**7S6rӍXG39n<`eLei&z#zo~Оl|q[_U~YhvZ47s\wF/+VT9{YJU>/q1s;GF9ҫjqJu0uңbrXQ#8ag*Y~XNj1X/kcKχ{7VӾ|G݆|wJzXK8хTNzMh|]>,ڟ D>~f`NSoxz&{]&(t顶,>@%7y{8G++b3JV&S:/ C¬{XbaxJn5/g`j*؊u9eib>,D0qǬUx2k^mԭ<.6A,GW>(x6>!Kx'^dg[[]F=wx{~{x Vk; +[M65+ӭ>Vy rF)#R ΤӍL=j,' *ibL=8 05UZx7N%8EQ&R*(WTq?.h?!yh߲޿qiOC4|U[-,𽾞ڎu /s5ci†31].Lωha\{J_U nK;Ӎ Jx<aS 'Ue*9Ы8J3\.sz̥(%<=ZiakcV'N&M)Y|QzC Wúc4sh~#|IGÛŴfhZNoNΨ XhsМsʯ5 xʖ"UiJ1̪|M 5\,y*MUzfmVP|o$p,🋴_]x,׀l;ɨ>O tײzW*_VPRܹbgNF18_e:U0Kj?/>(NR:J9F R8_ƴ'G^TjY{hў*]VJx*!e,鋤t֋xX_k[Qoi| y'MPY4{BNJKow^GY% SAӪ*aaUʮ?M/05TecZ9իSfq(ZT<%*Z8QҎ*)yWqSO8΁OIѨkr|mоA?x_Nֿe|4ѯt} .&CC+73xSC*׌5)V:#4BX'%VtTk`kTOjVZԨFu)SV]:0Thʊx$4ε+K ^y'Ʒ~uOKC'Ե ~,m#:_O^o&.|6>!b;Y~%W.Pq¼Drya,d+O05aS ά+ӫ:qJ:2gB:/.ha3J0k~3煩Y`7Ace xoMTscS߁pj +ox\1j(<χzŊ5 Q5?Mc]xQ//ng'eRTN_VNJ IT*g^|jaNW9QqpԤFpMs{ЌU*SSt&Ftn ( (>eǤj|Fд_ ĺ2ږ,<-͸q *kuir"L=Ar鵴ß x?u=sguˍ:x.%܋?Y{{Lp{h͞>԰.wf?RڱoHrYىOρdιhK7*?aVF@lmM,RZ5)#~#.Q`_+0!P&Ԩꢕ-nXh'm4΃_?緅+P->|7iRQm\[x!ugM}P}j/E#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>G1 JR)S-\O)T$Ydv#3I=OtV_kVY.ğb=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/"#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i K>#{xWRφ?Aiyؾ$o VZ9ݧ/H-/ ď_ ?KG>b=+Z)hvܿ _?緅+P-n$}Gj r|HCsO_Z^A/¿|7i KSZ#ӯ<=iqɪI WǨ_=7Vu F3֤wba5?ee7ndN_KöVsz47wL!O!h<%ba's%=6Zǧ_æDωfn4"j탨\&tSyqiqW8N{-N:%ޭk:ItcYzÏ ߋ/k:~He3Nf KWεv>}q*\O KʛEI|^e%ة&yAե\O/uǝie~]zk=?%-;y=?-w巊R |&"+ԢuphAf~"|8woԯ>"G> _^^7]s&ővnGТm`ӏv َ}6Cu̧O Q`G EФ|Z,GS0ḛ+Gtٖ25ᅅL&"XLeJ:RTҡ˦u(9/ j> ?yZ^厣k&þ|iD&apY\E@+O4Ll.]MKTBl„*թT9b'JUoe:5Ba(bIV^Fԡ,tq5GOJY_54㊕HoRk |}|>h_>7iwl-Yk?|;"ύ?Bo&m<%jlR+lq474ƿi:%"fhѴԧsѫU}^0{j ҄P-SxZrl$u+b89br(nw) jbU3_U)fK+WW)sԯ^9sTdMaѣԞ"15% /gQ8:zRFXZuUJm0֌}XV4G5PH:t j_MT&جBO,T* *e0^\vJqmS,aL=IOX^!#F5c xN< >oSgu5}kWDv%Ěs][-д0Z2V|LmYzJ5IRjxJu֕ԝ?oZ1Ic9T٪t%Y0u*B++tOjԣYզB֤dN?c1P@P@P@P@P@P@P@P@P@$| 4S_5~8Ծ x[>*<)N-cSjv·VqV:>K5OwcT+RѯJXs{f~r,=cKR*ja<tզcE:4GВtcJ&uhJ,W֡b9W N|u7 u񟈼:jϪxfZ_|/m:u {fĆ>^u_ya`:53% X*X<غ[#V?gSg؊:JpiN4:GԔbOՄ*ʱ`14Q*X'm6Z[Kwcj̸#]^]J\ _aV妝%Ӿ"]{ f-Ǚ͗Ulg\*,ThJ#׌t}fj4ظ *gaC/F1ׅ jcVj^5! y`8:[E{w'@V7?_ú$>3L[]y|ǠkO76y5l>$GBWK_ۍn0p­G첸aԍjuT!ЯUkalgCa'MT>lүVAQB WX6:/04#OR/[ b UВ9]E҄NuӣIc &' 񃧉}s⽄$VXx+NO;߆%ma~.a]*˳qu%^=kK|2𵬊S(α ^xqX|n#u|X> J4RA1r¶#跆BxTo/Ư\K|I{9/fS_W5 x[^W՗_K{ LiR[/`\N)UaugժS4)֡q+J5yաqTغhСТ0*1aFS:8J񡃊`spk~2|]ǧ~7Zux7,$e/Ac$SzmVѽv-wqgS)ͱFZ򼾲N*ٞI syТa %60*4>jHbhajSt,ƅ:- ΅9URl=lubAQo񑩅W?xőxۿV^i+|'um|It>DiO{P:UkFY%Fto4kb(νJRʨ)TTueK-xBYJwRdy}((TSFhҬЬ)Tغt*ԟGe'<7Mg+M_ VmCo8'REvIly~:S(T9Wha|82 q1K_RXgєb<%i7J^ 5TcZ~ɪPJQ(FZ|<_wu^ G!a?wŸO_[Ux>JHepnm^<b8ᩩbs,#׎]B8x%<GWJ4˾Xb`Wˣ)0S SMw.Ta^o\eNUܺ!SĞмOE.t85xC^kMֿ/|KC4м7 7w6 ellN]\ڿ?S?+xG ~<%A:N ~x#ĺ.|U|xu æi'IJ~gԖMPǢyHK0 ~)ƞbS0˧:u*|ZN5e GO7<=8VFC WVqr|EQ ^-{<5XEh;w+h ej.IW tŭi;~xN^Mռ;JN'9Ei "tKShQэLf4iU*t0r<]ǪTt:Vu)0ԫWb SR*.rJs ԫJ:pXE8 |l>)i?lu~)m|1š=}DgOw7B KHR2]\ܼQXz.J":*hN*èaS󻯎tk^_ j;xBE="^VOxnO2xFQ[[+//o[>֓Ōo.# ҅ iG.Hq93Zn\RN1tU\pc2XfPEGmG_YzÏ ߋ/k:~He3פt-j_7FO;/f~n7y:~nU<򞐗K'ӽo zZ55RLӠ.ht(u[[++J;H#/,/%.15ŭ#DM_,%QqZEՔ)ҕFѥMXE!ޮp{.NN1}"ܜVͻ\⽶ԢOcl%lz2^ .:Kd%RYW2ĚoΡpf /e߳)R#, YF6O F*prnJrUUTzxq4b#{WNHFK>|4:]~/ k:oxš:>-L^ WO5=aW,gS)Jl>&F n(%-SN)GN0TRAQTjkGRUqBYӝZѕV%9JPn-j .c7_ ~\x1:Ge׵cWL7zط7~ۙdeK|yNU3xu*TvX#VkԎ*1ĩyb#D)%9BS\ҧJZP5N-*p.Xχ>!ZAsxXZ ,H7^[m&(-!~#y&kz18lC ak!S:XLqx,RJUkY SP*xlpaKR^bjJI80Ҋe="P)o<#/<#]hi~YV>(xL}C/-QḦui5kUƨuUJ2}[<]IB^تZIV/yePYU%J^rPS檚mgK=_txk᷃vğS"FnKɢ|CM6Sega}5Fz،\L爣[ <(C׭JJqEᓝ9;`xkʵJxЫGㆍeF8TZyϖstJr քJQr | 5V[+xÚ|'>+Ӵo elbEګGgX٣9T0"نd+UJ1*kAR*GcE)(8 sU!ƳषIjRrIu߂Oo_? Cz wբּMt#e]K]O[T\,2B@T…PNSF"81aW8ԄRJ51U! ^qJ)kWҡF5J8kZG{ΖSJ٨?ox8ً i?d>M~4#[>jrw'XbǦuTԫ9׎+ʤ'QcyaSmb)Ӈ/yig\"YҬ ծ:MQn&hQ˾C&`F)B$NV]׬lV*Ү&OG)qO٤£N*?ʣN1JւQZ$C ( ( ( ( ( ( ( ( (m|)kO_m~!__~WuhKw∴ԮVk[i,%Pm!J' J F)FhժՍjjЩҭQMINU$§|$:'NJT!*SNP)Q)Jj !_x2%-*Z^Yin'u7Z4=6;6It-fLOlLªMX[(Z5h0հ8=hUSJ8#+MS9N ;.xW1n\N(Zqdaޗ/F i+KR];]GPp_\0N"+WR5#*2EBQu e(MF:qZ8+b!%(Ԃ娥^Y)I5 ;rU~}Ꮔ7lSx-ُ؟MPuy]YK4W77r'frԭV=rQi{mJaIDZiƋ-(CRokFbK WaaiCJ(YaQN^,O/m=>|3SnxSC"w~ٺDCK9}\ﴄZ(P ڥ.Gk_^+Zp8UQgSJw(rGKToޚsoV۽Gox"^-~ |<2CǑh0[xTIz'}Wk[돖tJe+]ak\Ez ѫSEx:$5 iЮ/}3MoKZZFfs&4+yj^66캭׆"vSӥF*{K ӡJeuRujӥ p8F3e&h?a&e͈kTXڣJ c֙hz6;]jO<)_MԮ-C&IQELPb XZE**)rZ#Nu!r"ceK*1vv)եNr'9;t?_m.uIS0xgƒ.?|*.u: էگVw""ɤTJ28T9! XE 0հ~ʆ;G GƔNO?1^ ׃ 0[ǭxu4abKv,p@Uھjé_ع,Eu/gڭY;ʌ~*Re^)U:N%oiԊ+M)wR+oXv_z -}ocԯo<7֔\j0u,BxW&E Rj>|OKZʒ*|tj/TRXH\,*+JNJI^㒧&=ݴ:;x&MGw|9y贫3xGP Gc-BOm4 lma U^!?~s:NT:RYҔΥIA97T<x<+ŖŎ Bk\ξm; YKHkdJέyQEH/FwRxZ|JPF5ť%NUn MIaC Zu~B"jPGM5(blE /JRJ^ ςfk6 ~Ůk{0~%,G JFm^|Gkv[8nl#0ю hѽ:T+PRHШFKWBOU׎xIW/k^JY.iB*"SOܜ\=C_?S|.uKa_OROWĦ]GL ]/IҬƣ}23˷S/gO .H`^^1Uk҆#"aʫW^ڢOxrEZ5k1G ҡMQR:*WTRp,e$l|--"K4 x~vZΘuGŨj0x&fsl%$pիRRxģG:T S+副N4^rh))’9K p)Nz8l$"p*:4> PҔYM?f--jVZΣ&^iڭԭm-F(ne5 FU@ٵxPԕƜ*ʚڛ TQqN2Rמj&<|dx ouhr\XhetٶW qR*:11mWekUTIUVV)9hE,5 I`*4-)rRSKP#|.y]xDZo>xwúޗ=mI%ݍSNSŚ$mF46p)Օ_gT)8xeW)aNKh<4'*Tۤ#q~ΌR44JJܮqt x1=DKxF)g }cm:8ObhԯW߭:8N9RFXnN5b$i"AVqV5%V~EhjUg*۞%)JMW¿ x?<+MfV~=km 1[vHӭYGwO%Di҇% 2ӏ3<<:Whμ!ZThJcQ*I**ըהgRru'MsTqqsM9Jß _| œIqxº[/eƝa ޳3K,L,!%ؓ/zU5/cr4%h^ EkNi[Wu[ZS­O~i(҂5 4b*Q.ցe/??Im]0#ٛ#^CZ<_3hj|2Wƽ%t=o뵝O$Dv~ҙky:/yZN'g3yi~Ϸ?f7}lyOHKVɄ~nVyshC<+֓w}3ݗw3_a?y/ mX|z_O//Z֑o[xjƟtۿivg JHwqD z=/{m0,l~ib=ܳK(c1S`R`Ɣpp8ў61ѕ |;3] 3R *utO B5Z\J)ԡĝ ,eC _ԅ RzkFgBi㉅Z0~sx{_HW~!hW|w/Gxnš7-f\>=K+&voiw^yF71Ua3V^, xJ7GPGO)U׶t(J%[CS*S&B%ԥ3Kc{OmkBqE m1t"sԾ3 O&U(N-8`Za*bV'Z\*xFqX:tqz Wyu,JjᧅWJp*8JafD,?h'x6_AusA> L4?7]'~֩R{HֿPɬw̻ԵxaJe8l-^XV[3\&Q ,*3 fy~" ** z%*kQ{ PG]x`+֥=xaˡJʅ )gGO>x5|!iޥt[Z+_)d۪Ԉnee!;9`}fʧJu**ELNPq"[4BsjET!RjEI^"VrN){5R!ȥ+,xsUOoxm<[oo+𦈚4D{/oo:m4Vw^/Т`ad,/X\f:&!Vu# /&NJ%R"xVt^. RٸH)tL5*  gQZXB49+ө i*38XW~5xCI x+ztMT1x;H}"h^ݽm~;=ӆ!bk*xU0yN/U!J)`Wfu'M)Λ`]gre Opk(΋m8|eW-S͖LuKO~>f{4Ki;EL?lZQ5knF VֳÇia1g kY]uUeu^iYֆ.`M+sܞ&a*L,')piuF}N"UpO x'|B <9'sE\<on[_@Hd_V%Ԯ ҍ֯XuK0Xjuc jRS8*{*obeºuSW NIab-zX| '^7h4ܦx:8ΚúQҕ GUE)4O<:>6ռSC2_yo k Y__6-!x4RxcᖃNK%o&3A4O#l]T1y񧄼! JM3Ǟ'֯GI/A  㿌l<-s(=iD s2<>_J2YN_KV?WާB*4!SY~9AWtG2 :j6?QӧFPUg:)Un ?N*ӖTq<_>?h /u&=s}Ik x"¿k6Ǐn$KZh%Qt&`*G3mb0XU8S>5t9WK\4qzV]Ztʴ#Ac%,cGFa*a#= PFoJJTLz5[;S>6SA]~R5km'P %.uDxMi:NJm}sbkKz5.:&XSq9.B*0l9>ƥ|7jl(ӝ 는pX)ҡ8JX,r5xT4xZPXZNKRƄ7FS?^{7X~F$<Z߇Qhv>qDxF_k:l\A_BQX;X_ycؚRrZyU],<(Ƶ UWoSb_"QN\p1MQ:pjj^ׅOiJXiR_֯?|gOx7_A,ikNwIo4/^zItۉK J 6kz {-K1Xf[Fqؗ y^W[ (XWKa+N/,+btPlM_xip1a^ Xƺ8~CoNT~5i;⟁~L__k0x9KDռ=xĺ-i??w-V񵍳EEGy/$/9b05}\<3øT c0U9RjjrT]ztB8T^_:8 VmjOAN.,ԔYn3PK 09F7S3KgCeix;?|2)GKt<mVMjb;Qk{yV)Χ3,]xpLai^ 2IFxTk{yRT\| R:JUr4kbd C ž1TR:uFgFya34^.x[X&k'>mGKsoWQJg_ i1[-[99JbpjEܨ{N7>Mևqc:'/?궚!,iW|Aa HOx*xpU*VcyM,6*qi$(c08~ax~_Me:- O~1Z6V#4Q 8E8wYiQ,ejYjt턌Ԯz.k ./Y౼> rގ> -__N𽾈ֽ xľ"ҵ:3i1m,S3ڹCxZxL0V_)V[b2Xu!AgS븊 ֯N1x*YUx|>.k N6(ʢ :T0,|kVSJ8iJ||c¾4:t-wcL=?Ztn.{R\[MEqڽva[w*ZՕ'2Q,d NUu)O#sRR=?4N2_jIuf叶QEB*_WnTUuv'9~1hWKB8'PFg}c]y|6qaM6z>q{׼amCKjeAJ95;z|ER:S0У7Yӫ0N3U,q4ZftPzxlab9a v2j4^*#^1ЭRbVv_[㥵GK׀ɦ Y[jZl7jz߆bO&].?}yog ͈˰JT1YY}JFa`FR1߈.o_Iiok w.$1u',_7V\+:8SEjס*ԧNU!WSJ6SBҖ (F UqԹ 1]>ybXQ ۯ xĞ ՁGVL5cEf11Im##~Jv^R3Ug.I)B3'O:%R-*uU:nq EEӝOg(M(788NPS?yoU)KPB3_ YgOCi⯍s_ۯ_~2xMo)𥦡 _ 5AΡ2|3SVTlN9&bJ3XG6*"WRS*T(VFOgO S QgJ.Y/ᅅVU^YƎ"5RTV>ok*u8]\xSD ߌ^ߎW쩭7wí'~0T ϊj~ ִYti#\ 7M:UׅOd5+J*s <6>4帘/FxjxjSΆUk%:rVX:9X ZѨqXuFZpZ:'nckV>w +ĺx^ix\l|Isj0V6/PHfQ6W62N:U6* ,m:5aҥA:.xLiVj2ayFuP'ˈeӔjb*p5,6#45:G7U:SbQuCؿaNxw*r5{V^;nF&ZlO r jP#.G4=p'y~0Ow:/s SL4M#S[κFj7v(buNkKeVY9WY ϗ͸/U)S*PO NZң:F1,qg*5NHi~%𧀾6jq|@Uַg|Uzx |S6[k¦|'/n/u%|jR\ʨVף^4Gca<41pVXz8Ɩ=J*T0%êx$;Mb38u(,iZ%`, 4{LЕ*XCGBr,"_oY|?x:t>xž:'Øo|=T^ _Uu? qq |$9,.tjgJTTyuG< F ~Φ2ϱitXx4iTu-P!S(Ŭ5 NUcqbisTx~ΕIaja>Fp-x4߉M mxwþt?U|Nm׆`Տq;+5iF0*vyV<:F2Yp zpUTbӫC sC*x!e0ɹ`xQ^jy+FUU\qX\M ѧVq~O'OGCռS _?Ooᇃ4ڿtH|g>?@>Ax#ğnmj2|H횄g`CZeqթC^xoB5jrԯ(erU\#u12" 9s9(~ΊITKI3'E%ScNj]꺾4/ ><`~τJ ψ9{+WF/:^yRXJ.lVC}_ *<Ά/4UNV|٥^"MӂЅziЯ3T8luZ_S`hGUž.<^ .J%r VaG2|McO*`0*/j^>/^[Zů|e:W]R[ k'<9h>ҬbcKZ/RӥSYoZG˲sG5dnc%r΅H3Ўen%= )es X ,&uէ<,dOӴ2oԴ/ 'oYuIߎ<}a ^I ?ԧ?,{ZT#BSc)TLy}eBG,U<:ERJ5-K|mL.aRTh}SլJԦf?Y u[ӆ[ sb z0p!#S Ư/"7?F5? W>"Ok,=Gm5_|<&5{3UuL-(J",4hQzQaR])ʖZ„!Oy,.iS_Y|0gk,UF+FSa4<.?q.\½48ʜu?C⧉< xᮋi<]u/_5?pk&֚~&^ixoomQYt4EVqy}8lf8갨acl U}_9M T01&S ,E|.)ZQAK ZZjzUOoiPaj_?R?_xgF<]-SC?]ԮiV73jmXuFl:35LN5cV9n?RN#NRa^&2>K-n)V" r2B4*4' Nz;&jJTc2&^U$~jr,SfN;K}~W<A9 xK:tA2Gu?\VLN- ϩ,EjaS<2Ч)N4aKOtU",:kR6"nxzpR . 6/i*BZxj&8xW *PxZIo<˯v㟆v_7^ h K'Nm_xG3 VQSҴ[uw:؈8dQ5 .x Uڒ'[ :+g2=Upbq9fⰹEIbhV1_[:vq+ JQ1\72Kd/xG?oÝ/K,i}/¿tL AaudzŪɨ]}Tc[)yF?Ou40TAtyjh,$q*9}i(JTS0Td*SxLt^>YFUiԔTmB">=gm_ន^@:ggw#./'t>>Q爮=Z/o|w8޽aixw]ԕ4@O4s9EN78£& ?YhҫBU`Nyel5TJuVSaV: U\(gKVLtq'@٦|R~ Sok^c 4{]OEΟ#Z(oma6a-.dxK 2]zxT( VtnaJNrTq2XxMOZXզRQEZ|krEVtTE[НnUPBw_>/Ũ~;ּ ~w~2{|D!#C$)|H-^4w^Ь<\]^ms~!K{ i~&"pؚ5)b)³fOb8 ^HںaG7^FZشyf_t/dzKm2zÏ ߋ/k:~He3פt-j_7FO;/f~n7y:~nU<򞐗K'ӽo zZ55p~)Wǀ_6Z>x{gxo-4CVӧuA$PHF F1~B*3}5[N}m>ZSVT5*%9ɷ9:Bs 'xFojS~ʝ߳߹li/|9-ֱ}oe&=b!kSWZ:ֳ䪡WVYCZtR8աS 38S Qx9BIXWb:VIrZ,TdJNVԠdSwY5fz¢ |#SQj ccp. ߇ЇU6HmŽub3a&XAUaԂIBάm{(Ԟ:rFRM҃^ΟRQYE$ީ$d /|a O٭%hz:ާڏ.m}2KA=ַ,rAkoxRh崥ԖWVPqF֜A1!*j.{-ZՅZԫRxpXTI#KC FNQC mҌ!J_Q\BMWCX/9tmR;=#ORҤm:lMXiwn~;l̏6~ p›RՌ(R4=j,]\ִGz3Pc*\М!hεJQue{U$)š8KLUSjm? LڔvWdzIvoNuKE0A]D˸_hթ j*J4PRj 5] UvQ,.IZoA>\F5kTU^RIJ%9nT[oSߚX>|a'>[&x,4t7Q\0ѪFe- ڹ"02JUy"8ԬN8BRm r6RX 永xQ9hJSJє I)r;YI|1l'l|3𾖺'\O;ݢil>ݤiki}(wM8gaWZ5gُE&''[ާN_r!|6}SoaBq4 \k1$mkGw~%ӯ<1?m3xEgc\ivx[f]itK =Ϻ v0.3*ѧSEB8JU,D]u*nFZhb!VpRi¬e%R鹸B3MJ0Q)9.g|O |,c t'ß*5ԑ-%rYm9tHt}:oHM ΗhehiRRFXjupR6M҄%xq+8X^I'Z)TuyO)Zc_> >4ӵ^x['5}zQ5 gRҒTfIZX{ru(%FpJbh=l2U wnj(΋)E^:ʭY)RrPp:ғuiʛ(To.7\!nX=ͤx Iq*šf=c:,$w>hRa'DkU8NkB~ x\6F*QQswI.gyw|gC Iw?[_@|)-η'U[&@i{m7BJe(Y4'WERJ {cd~:/#̘ ۉD_a]FsG_Ο*rr(C6Ÿ6Z޷A/h𵷌.4YkShIEi++ƙhn2Ʀ'}J4GRx_g?k^͉N*Я]Jibh֌RRerk*k Ѕ+RʝJ\t\wy࿅^M-tGhZ|XzOG F=j n׊԰ײM%'Ur,O}3Rj <=K υwE^^?SLSN*)rU1uVnU}>eN8ǿ+LOŸ%ncԮtx͕ƣ޷}=ױxw ;e) Q"ä++RJ2TK-sKN1Ujq(D\*&Xpgք+85-3/sc[E}g:v7W>SmKIAӴw62Av2kIsr#,UY6bUjNe*e*5==&m8ХqO BN_UԍgRaQ֌j):̓%OOVӴ '|gwMAcEPwV) a5/~*OԥZ\zrH&WSWR/yMWn.JGy':teF4)N )B1.Zܩʧ58rN U%~hռ#g[|a~kNJx7Au+JgѕMfn8a0 F0 U'5Nŷq քcQu)TUVUx{/bB1{78s|' 67O_x߁4Wuƙ >9}' L^!'ER["Kya=jN1S,43Ju%MSn%*N*ӫBYFZJөfu2*)aa75 (rJ)3'C״Sg_Job\VW:1~Žͤ:DhgRjEq{4[CkR .1TU9cZjUg?dK ; qa ~¤hlTuS{w'iۓZF*ֵK_SF9J 8|1)">/Yx "v.l!6~F[Ǜ{F\[\e%̚JN8F)B48k:RqiS:pN>9m$Zi~Ncnhk c￵oCY.o˼pn<#p8J}.-?:DZlТJV&2;8I:^iv֫X:ժUjg: ㋍:tr"4ҦtKK(J~/gȴƦVX[UTX[>xO u[=N"k"w kiDz|RK8V8JӓNէ¥,Mle*8U9 N"xV'&SUQPzˑS*^UGJ7[CN>է׬?ZkB]k6UI1[x4 9w|lpe(A҄iׂvZvUWZUשV.1|I44T`GTi0IZJ+DHa@P@P$Sg+֟ B[ݿ9Rl.i\* .X|7}Ao٭7[dz>=}FThoo:O)Z_{I_tKӎ&5ڕ8“X'R(Ӎ9>ZP,"9S!֍(FBPIF:8*PPF6Y> x^{_ |$gXݿ#>EtےC.r 5i 7[_jP^)J\>[ )AY3".W)Rq֦jQQs3߽4y4ޭ{fE'/Ù;^Ҽ[#xd+:#`NOyln%%V.,S"x8jqaTJ.xz-4ZaMJ> QVibUjN5:uOʮ:N ,I/xcD+4oE%4W 30LI4>$@䶶fK  qRxԔqF)5^TcBI*V\6# Wʖ RNuyKrOiSRs3|ҽ!ySouŶvxy=M'I׼/ƫmYu ]Bk-[zEՔY3欣U{`o ^2ihPc*XDjFmӕ;ң3r*|pVל0WewnL7tH4k]-;]_g4/ ߽Ѣt M/Li-V:Լlmu[ E*֧JxTZBX:4էJN4Rqg$M(~4+M5qS˟rחzG;ޕí3P>|=?mZv4xSA𾛩]=Z=ak 8LڠAb08TUc*.RhF[E5B1IE7ʗ+UbcV>OJSKr }JN6rwe?V Z`υ]GJ\T\>-}u=Ut˫O^x%IVEEIMԩ*eTqrB؊xyi(ӌ)UXm7BVYESrӟ4%KڬcoïKv`[hO [h0X#P"}S WX)aUO}a\e7RrX^ϕZwU'͕]TT(ʽ8R+uӒ#ZJ1QFWSI5rWޱ H<uu}5/Z _^ǩ^xn;)CaYl$$Ln|gN=%jT8_ H <\YIJTV=%OM{htw^My ]riW^gb7[F<9sahAk*۫ C~JuO}֝ ԩFuy'FZ)ӝJNrnNxyR :)Npt5iΛ%%9-g2>X|>7 x'^W,5[E>~a}vA,%/|^ ZX_Rl$pRj)ӋK8JRƆRu_LE*ԡR.jPj؊_ZKƥ JbCVm>3] ~%aKkYGڽOՄ pݮ٢GU {a%(ѣztV'ZQ?iJ34$թ4^^ֽ\=Z ^Z\ӆ"U,D4V8{/7(]ė > kL3@^YG?ie>go^Ο6\½<;bk .ץ F%,ExÕVE**j78TcUITB5NJtT¤XI#zZZExCtvI{a%z xZ;DAmt= KW`DcZuQVSJsSM9_#^jE*q\eNi)is?f+Wgxoy3jt߇> oqaKT<=MbDDhHXGrȿ)X>5c1qՖ5^֢UU/QsJuRT#B4arþhN]u(\gAwk)m{?Yux^[𶟢ˣsUKkY${hl gc'+^~,EKi]UUUUUhTj*\+MHƭ xZTQ(sRQ:G$e~hFʤhiIsʕ\+I\m#i/|%cD{,-bSb=0 E`uq51+Rѩ^Ztq1ҝY^r"4ܜkURIZ#ӣxEBOOjJԪU)շ<*JSn~0-~xVψl+xzch[>a-(Kf0;JUk>JegjxyՎ"t hѝxBFЕXƣTU*UQsկ(ΤN'w)AԨ)66r_>A ^G&^$t-_-ķ2^?5:fgY&Y^BK':_>Ck^.h)KмJ.׊ҷ4^15ۭMQZHQJ3jhA5TkS]8 ^HںaG7^FZشyf_t/dzKm2zÏ ߋ/k:~He3פt-j_7FO;/f~n7y:~nU<򞐗K'ӽo zZ5 5ݺ/Їjy~W&_ޱo5yVʟ_O_ IOí"Ķ>է>(~ Ӯ ݶ3x_4u?z? _B+4`Y-m=rg3{f#1˲U5NPckЧ8yӥU(Eq-#ax3ƚ<=m>%jgX2[jj64aSc,enp;["xb*ҪRJS2|_T_|ʆ 3 j֍U΅Hӧ aS-?>5B4 ^4Z4oZm/#ι |{V }GÒL,. 򍅑.ozcNgBY-.IZ/pn2<0?9ƞ#SlQjJ#U^MZKWJxtaRx=:R%^7z=w׆<=ommG>+wukm|f|+{6+㼋b2D烩|fRM7PY2Z4p+ᨵTf8N JT8 (tSץ0`% 4*XO [3O F&(/Upqh,.08<:*X4~_Ck3oO9SYf<,Ywjt•(p[JRfL=g4:X<.Uhf=tC #K5SZVSck9Uk(B^v:r2 3Of_O TU+aZ'=6,EV5ӆiW,1BY8Ԋ.EV䝨RjICJV>XşګP|xIߍWM4itwk_ߴߏծt h._E'+kW77X_h%ulL*BF<^MBJ,Dج]YeJZ4qTgBqɺ8j>·uE> ]OXWo^=bvmED.{Ov{-5% C12p T#$`^28(B/hRN-S7v2'KOa,4=W(ю*,,׵Qp4ZÛ-6/ꖞ'}oV~4hkvtص"kV2gIՇUc1\?盧,U3¼ҳ ]\ΛWUUQ8x~0|Oa<xrO:{xyV" Bኴ+FybpUzWslfMQNPU)R|~ORjQJ8+r%TJ"qJxa2G-HRTI`gX8{,L[eXNyfu-km4~ c–yio×}{㾝ڗ&V-!kk:f8aù-F>%f8JXi-N}U}oͧ( ^X*9`JRFjRjN(*<-~|峫:C1kMũaK,?ZcG42'~&I{ė3N3Ai}kX 2[7!,$s=k^|qYSth]J2ug̤3iaTW.C"7F^_Բs!*MԝHWnW%BxhBMx ^h^=5.?<5E&ߋtjϊ5j־+|/\0xwvVW:U/o EfX%uU[9WL?J2x P˰b!KNa1~tqU.z C/Y?FY'9`T~'B]*zx׌.|3Og^&񗄴 Oў>'ƿx{g]Kόu5kzȘZEhgRºRK UsiեVgaʏIRXUcc'JyiЍXN UZlZXLգRiV63ΟXZgN)Bաj?[MwxD)ҼGC6վ03½Jx_WSxY&햺V u+w1oEQrTC3洩{xծ~uoхJFƿcO0L֗Ծ:9f'7b*QT+bL ҅iaYqwJiJO_ߴIo~,оi7 <[[Pk? lj4?TּI|~& mq'|Djw0?j1%eZU<d =Y r?_Z~6t񜚲h?~&GQj&/&Ubv⥉ЕiZ13UTZUӔMFt*iFqd3u|ʲ+M2Kۿv8 :Z^T%)UգJ> jYs}H^0>iw ~1~Atc&jz߉~#A-4$Y\XC J+:cuJ1XNi:P, |\bKb0rl֜tzj‚ƍQNVKUaVj"){jSGJ*MRk }Of[HfXi Ls<#2|XKmУKu2^Rv(< qZhԫC3pܰQi֎b&u3h pcZn?i/*ʅɣuORե ,`^4MוJq..sk⏍t<]#EtOҵ}+도"G^5OQ?[ ݤ=#FnR3V\¼'cQ# SakQQcש a1z>ֽʰ4#PB^֬bT^[Qk+l5 їKa㏉&$+>!W/ 9i6lͫ>N9s SU_3rs`|Yהd41qPTF.:uqLu*',BG1μ)FW*uQl5*1tUyxNV->ͣhÛ7"^Oixƿ|=\}Wh$wmk;m~L.J^%|LT8_U*t%9e9fe^T(¢+-a`R+K G|(FQJo T.HqajVPq5UK,&UBrgpOKCͮ>,~xjV"n~Aqj1KGቜTiKJi׍cMмmMf |; GI]GxkAV in|X#^1d`K˩S gjì9`s)UG QqW qZ9.{%N.:0ط:<$9i®;hByS l ylNᆧ`2De^UНuaW8t|~t=[>޵n'yBj)(ҥFJ\(9޿?Ÿ>5/]j^0i׍~ֺ?~2:lH>+kw!e,l .{i&G'Ҍ&8HRZIN7QmT¥jqt,N(ϚM*XLDTJ5jeM}r0%N# W)BSiS`| ,Z?¿xk?>|5_jz 4JU|\Ӿ"$wK>cwuŸ54ꭂT3 +wXe Vpq:O֭F[R3eU<<:BL~ pZ5YƤ!UCZJldLN2t^X|W]*4xI֓Ig;g~ķ^겒XiЕ\N&J̳^z"G=iqoptu*U+ac41Rp*,>.4Jxƅ:=:|iF:.<V17Z]Y65G ^40qXc:0-cO;O&KBί/xFŗ^$w ,|$Jy_^ͼ7ŮN,4*e92H^WT)r[3!Ns:U,4]rDW%F=ZT M -JncЧU<=8eaЧ9ʶ*P ]7 -250]|j{/|{wJk#Ss/6ω:nqPUGȚm yjQ5_XJh4҄.FlEשJYUE*ʕ"]Ne(B)ST"O/E t֍U1:]E*NZH,/&_8,1O?{Q5៊(mgPj_b<^# /Rpװ8Jr *m =_cB0gfAN6"ckTkLu132Z6g&B*kOں5\UbTx2hӫO}K~n+^(d>~45g𖳮SVK}CSjgSil mkӧù]LU|6'55,Nes˨S'dg7Q5w VvTjⱹte8^JsqsW鿮ʌ+M㋌ʻS>*x趑x^2Sgox Miehaua͑՗MI[Kkx`c Q9ˡOZ8QЯ5N,_Vnx\$W |g{ßoDŽc<~I/xSEϊo.xt?:iP/OЛɪ_O6 fA8,^} rFtQNX}o+RéƵ,i&燧 ؼU(ayjю.QPrb4!?ůgcUpҥt'> xSG_(?hVAiFK4+EקJ*gFLt{g,-,UL(a~N񕡊ՌpL]ZmwuZ㻭k wGw/['K߂4? O O+kes-kbxca:P8>(';kM׫I9}:*Lf]K JQ~en5a)YV<&1`cZ4K r<օeF)wQ`t2juZ'N<KİX/}-;Tf%2_$q$~dЩ^;TK**z8ntrJj⾡Z?kyM_=צ|bt NRqxy.^6<'w/siVq{̈́+e곗6)jSMRxZxRT9Œ`k *2C [ &|e9*ZxGUA**h)G R"+<6aZx*ѩf#tI-~3kը{]GxFm|U WOJפ.P8R Rv|䈎_S:MzO'B֥|+Id;,o7?ښow[͏) t~];6ܵ^O3ZG⟅ '"c9i\hʤ:eMsZRQsJ4*7:rwf97I]8]̞֐WÒ[]kRhzc[x-N ~f1uCk1Juk՘<էN)SZ0:s9`$eqF/ӥj4%ΜFJtN5a]J J7zuVj7*/~/h?>?|7|- xYu[asj46[ }w[̏kl/;nnՌTYH(4*ʌײI*e$(8߻(YA%=5RJ-IZI!~$~?j-Vo|SzW$kz$!6,p(F[JQIexJ:Ue{W4iѝi1~#RVUXUJ*W>G UJXd.40d0h&(Ƚ|=t u+t9_SF#4-*K.Fӯ [g ǺR8cIGNRk5Z3".rKSU"Jͺ\L*XR<=(R 0hԩF\ZJs)'qW$[&u#t?ho l!m jI'*0*Xq)J!^X2U#C&))E=kMw5F2 ZVW5RMB)ӎτ | qO_ ;_&KͩGeG4>ntWTYAZBJ1&UЕXeDΤcVLEX8$MS)8ΥIEe9YMŏcC M#:~ zPZ֣׵F⏆ZNJʼBSɅZ(+WK7˪㋍i'RKBz\tW qFmOڹR{\~\6Ť^V!_@R\uMb Z˨kp#M_J#фd =J5iE6*xPM-!R<.gJ0#ѦIZ\Iyg~x~YGi];w~|*/ 4-W?_ xR]Knl<_wݭ:LG q aiFmCҴS+6ZvVfR+si.޵q޵9T2&.UhVXUVcBF1+(B#8(餔(Grҏ5JW5I+x+ v(*8|t,6%\iѠ c,%ؓUu]YVuXZwV,=ZԠ)OXrNGO˗ٺP܎vu=8|SI=ύăƷ|7tK[뒏L1}|>ik75q)ӧ# -9ө1IRJ1 U#M%ΔjՍ9$ԨҜի,JJ勍:Uw&*55i*uhJ9gM(I8Þ 5k;}2EÚ[AR^ͦi0Z‘isjzj" !mjUΕi:Ԫ|psBsFWR >*_ç!N>_gÓ%*JKY+{JӝY)NWp>Gh 𦕣C}jqiot2-KAM6-P K:=HKIbKuҬ,-r7RnxkK*ѭj^[sՔOJ՞"VTŹJJI:wu7RNnM͹?{S3DS7ޫῆgex;M$e[[ӢU}B{ki.7oMƤ`X)eV_8odr8RQmYXgTU))%.kJNlŰ 7JƵ37#l>xB-޵[c\0JѴ1 J)J(Kލ*:RPa))8EEB kQ~ƵzjIܝJ+ԧ(RKBMߞG–V1KGlt]6"I-džmX{y'V s[.!ѵz+TRxDg e9:aRtԍJ5*ҥRqjSNrNPQƝBʔRT8Tє(dO}5-NZK/ oiYϧ./Q\6:>זr/ Ӻ=L_-gA':¿)5$~+F-yJ"2~NdHFJ7t=ur\_ٮJ#hrԜv<5C[}AklҬnk_IռGLKQn<ȓBj>M[/+qTlˉ+m^W_i/eTN_wӕ(NZR58.ghYI`_x^Ki:{w4m?7xXZФzww)y"u/iz7JmuO{ +Z=SMHmVX{L[*Vէ]xb]9JYb9d}V.9jETJ9уqqQJ5)ErӜg%:jђMO eN~|=|? <NXgeaY[\A$q""vhpBr')Y6םZjI֨E*Sܜ 7c'Nºqxl$i…'”(ҧnZqS JZ<kt O!4g4rtşF{7O]h(O7{oc쾱=qۖ{ӛ9^xBܐ(C|_hɤᏂFɠEkv4O> vP-+֕Zz YIԄ'46y&ԝ$wLLSXie4~-F]>5[k^LK3w^u$)kN3|bW+WjS1cJ* Trt祽nRprWff9hKMKҭ-"͞ "Fh47N&;{ hWZ?RSKޓ~ZVZUVjyթ:&ŶIvW]:5€ ( ( (=IW>|=~ r^բ]-ߊ"WRYUm\xFA*-(*xl\jBUVV5BjWJE5%:TsW WT:2)PNW9BF..4*i6xEh:_ ]iz&entkH'൚[2M='3 5cWlTjhգVUN5(8FZ5NT8\g(,G',B^sSqlbaq:ԣGiœG_7z_m+o}Czl I/%Hnt[ h"YuAº }pfg-8VxC\HԌRv iEԂQi5뢴Rh(eR yyd$$,uV|1n >:[;/Mof?b}6{C$:ue,\*tpTeF:m{8>|I±O9F|M s-f%],Yks5jnԡB*Sj}Rg|Ez*\ujSi¤-UGM*ܣ9ʢug-Qzii[nw9O_3wWҼ?x 6GWuGmmR+%\KYҧO D4pˆ֨\[hš}gAɨ)JĪ%ku6ʞ'ӕ]'*uT*AYݚ: W_-wLƉWhKi jg`h|1awIml̖1$#R1Tѩ(iF!Rj#HƅTlG$,iΥL=IΗ:ҧ<>f{>5C6?mtX{ĚNx_UuWZ&6Z)YC[J4gYF1K2J1pYdӜ*ѥь(T؈Ԍۧ*w{QF)STf E%5NT*ᔭu8aq+F#/ Nohֺ7-[xwB6h^{ /;Eii̚^X[:uxDz^UۭONƵ,<'N*JtiիN&i¤IêQhWxj⧉?6" 6/iRcjw+7_Zf|>{ڴui> }7R{t{˃kp%Go-3@aj`qT\jЍ:kԄc6Poݍ/WX?ڬ}ڟOV9l|xB|!'O |Z\z7Vj[J4&RU*(1P)cQRo#VZ?c_фhJXxӊ )4p(Vi*45>oQ;-<#sˆ| {Ǯx2?^—0oyцsы-`FEWjRª¹obԽ+jdO*1JQzpVWS%8FcR*4jKb ~x6j^>RwZSuq ԲII\0&JY>Ν/k-j{*JԩMp,‘QJya"p)9({5'M{JWPv 6=!烢Ү?ϦB;8o- xr>9ЂUW(VixΔ뺞:R_NJgJS:%R*t%BR'jӝ78JKIJ6rZ6e> |0}oO Xk:- G}r:S gXJ^-" (:F#<IIj+BSK"0p9U&5% 5i 꾘UB]7Oԡձ+P*J){6> 隆|%gKíX:5+}9{c o]D F8J4+SQFPC,=J0Osê#B~Ҕg5.i_5 >IWS^8i%^zz*d EXiN?rqpM _Ln&>)K ?I_u2ft'J~-H|.5L>l4#̓zxwezW&]JJX*]{jU=IUhnqƪ<'Jj'u5FJ]SIݱGL.;IK+wvoh|1z@0,l:Ƶe*ꢭ'YV^E6K_XsR5g2~ |3ė/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&j7tZ_/͡;7ZLy8Gs,$ټY]Ay #\ƝU1Yz\6[]*^#eyB4as-zï xzS|W 4׼ k(->"VmWþ} 7y%.4dR6"<,n7/T:dh!WQkqXjpqQ`꧇K`1^8JiT*gS1\M*Qӆ_*Y]`qx tTh*x|9ψ]|z5AGzjEnhsnR#,Q"t僼eg**.&ԨVҵSN518zmAX1nk# ҮY ͨcU)PJq'z\Y;PJp"|ϋ?V?=;8mš"h|? iK\鷞X]xBQO V֯`nn;aqJ8ؘTYԌ0x9*!JXX9xʔ3 Jify#,?שu0(T'EibZRN0t}΄Eb!_uAp|={&|&>><{7P">']{v7)?[jKNc'eFI!W88eWpP*_Х_U<>%ԝ7K[ԧ:oweN'/Xh{;ޮ.Q'U?XYkO0:-i_O 6Zm3^5-c0שUnŸ5:xW >4|pL7h`+i x$u=ryo}!AZ ?[RJ7ZxYaY,Yav5IO Kp쩼J' N\%:%\a0z5rg:jkFJT-RaTqӅ?/|[xƆ5U E񟆟S]u uҴ}R0$D[hV\5jj̛-ΣF8R(ԣJq3,V)(8KJ2 DN$ 2eZȩRΰpXƷʰj[GK Kh:Dž-~?߇. o};U׵/#դM'Ꮘr[MCpSiu͚qs'Z*}KqS)ji[ITߛNQY~ TrUUQ,&78ol:4<%g,-VxPU)ӥx[Nj1x:5>xVӼ?Yik m{TSך-V ӆInu;_)֓ ;0N4*+)JSQ娾^dp':r/U;-w N?š<%o_>ˏ [- *%RJ* X\^3ԮN= ,6*x6 <1t80VR5¹qT(KNXjН~XT?Ś<6McuEcֆU[Qb(<>iTUd q8}|,ggV1,*t19]IBcЛRʖYOJqu*ƎidNxcLrKčVP~^|%>(3M/|gf^L>/4 ψdo CXHzֽl)I$к*d1 SϙIbg eS]W EM> '%-;JӤI5=UV (QJjjK6^E*\t2':^;(O:U:iSʣN<`IM?WVJISJ2)MJ3_x;oXx:]ϊ fH|?h"Kk tWW'>;vxK/Mk<k]F r֣Kq1YBiUgu:pT}O-8a)^XKR<-jJupiR+9a*RNӌVv<β^urB2,._NE]k_=>hzwu I|Ko:,4[aץ&l,u?VխsԸΓOW9 ƍ :|Si1tTORxPX\ |lc! `UhՆjR?Y )a+"jRlUEl5|M|+W,- QZ_3{귾* qx6Na\7f J7ػ| ʎ_Ҝ58J*p\(R J3QZiPc*xҥ5(žGV$r'ʓ)B|P/[|tſt 4i1~ i}CWz&v%Kl# avY(BNl FTR*a=/ag˫V= VW.qɖ_U)T|F. GSNrڕaNU)FmWLu.O%ڋ ^|JU)B8e k SQ4!RNNn .KU3 xz*yoa9FN\OJQUy$}q\ơ@P@P@P@P@$| 4S_5~8Ծ x[>*<)N-cSjv·VqV:>K5OwcT+RѯJXs{f~r,=cKR*ja<tզcE:4GВtcJ&uhJ,W֡b9W N|u7 u񟈼:jϪxfZ_|/m:u {fĆ>^u_ya`:53% X*X<غ[#V?gSg؊:JpiN4:GԔbOՄ*ʱ`14Q*X'm6Z[Kwcj̸#]^]J\ _aV妝%Ӿ"]{ f-Ǚ͗Ulg\*,ThJ#׌t}fj4ظ *gaC/F1ׅ jcVj^5! y`8:[E{w'@V7?_ú$>3L[]y|ǠkO76y5l>$GBWK_ۍn0p­G첸aԍjuT!ЯUkalgCa'MT>lүVAQB WX6:/04#OR/[ b UВ9]E҄NuӣIc &' 񃧉}s⽄$VXx+NO;߆%ma~.a]*˳qu%^=kK|2𵬊S(α ^xqX|n#u|X> J4RA1r¶#跆BxTo/Ư\K|I{9/fS_W5 x[^W՗_K{ LiR[/`\N)UaugժS4)֡q+J5yաqTغhСТ0*1aFS:8J񡃊`spk~2|]ǧ~7Zux7,$e/Ac$SzmVѽv-wqgS)ͱFZ򼾲N*ٞI syТa %60*4>jHbhajSt,ƅ:- ΅9URl=lubAQo񑩅W?xőxۿV^i+|'um|It>DiO{P:UkFY%Fto4kb(νJRʨ)TTueK-xBYJwRdy}((TSFhҬЬ)Tغt*ԟGe'<7Mg+M_ VmCo8'REvIly~:S(T9Wha|82 q1K_RXgєb<%i7J^ 5TcZ~ɪPJQ(FZ|<_wu^ G!a?wŸO_[Ux>JHepnm^<b8ᩩbs,#׎]B8x%<GWJ4˾Xb`Wˣ)0S SMw.Ta^o\eNUܺ!SĞмOE.t85xC^kMֿ/|KC4м7 7w6 ellN]\ڿ?S?+xG ~<%A:N ~x#ĺ.|U|xu æi'IJ~gԖMPǢyHK0 ~)ƞbS0˧:u*|ZN5e GO7<=8VFC WVqr|EQ ^-{<5XEh;w+h ej.IW tŭi;~xN^Mռ;JN'9Ei "tKShQэLf4iU*t0r<]ǪTt:Vu)0ԫWb SR*.rJs ԫJ:pXE8 |l>)i?lu~)m|1š=}DgOw7B KHR2]\ܼQXz.J":*hN*èaS󻯎tk^_ j;xBE="^VOxnO2xFQ[[+//o[>֓Ōo.# ҅ iG.Hq93Zn\RN1tU\pc2XfPEGޚFU'F>6-)ի*kЕJۜJQQЄHӓ#75xeNJ܍dwfO¾XC1jpk5+JkYUP+^ԡ:uOZjЩxӜT($,+ 1xv+Q-Nt*2S'Jq Pn2UӬUiaQ{ F)(_1{屸vKooC Qi[^d{[f|w0uVb0jAEIVTgV6jOH9P)&A/gOo)FOZ (鬢QoTJ2O0'Vl=k{oSumG6ھ%[Ԗ9 A ɷc<)B4rRjK+Pҫ(CڸѣNNQc\ʐ|MZ\=ʭXj­HjURUI8J*R$p'(СA6FEc˥O(kO_ͬx6ǩiR^r6~m D68V=ZJ8r]Iќ1sj_2*\L*VmԜ*`9Wj•9콄BQPFJ4:S8% I<{2$4'y5,4Cxg7?e hf6fGכPI?oYQ8ARӎaMP BjqZ5gǖ.IJ.IZnB1.hN}]gZ%(骒jMFv|%k&k|*m56^LJ&mJ;+2=Av7˧jO Ԯ Hjԅ5J%QH)5E;(Ԗ $7wF.u#b*TYԩ$Rn7yIu*J-)JRo~,~ 0Zinޟoז:ֵ5|2L-Z0ʵ\Dc ӝ+rIԧ txN:o܄RQY} 4TpnNY-J*~*LK|֟OT Lj;I{O kL4l_iӴ河6ʑ[H|O)vʤ1rF8z*#W':19^ D(GM$B<ӗ-/vyTM)_^ ``öEQoka/eN[di-NĝjՕZܟ;^׬{aoM~rǗrr:|\ux㳩ͩME(I|n$5ῃ]R\xgыK]AgմWѫ!N<<0aiΝHъJjQHRi(FtVi%(FEέYbV2U',\iԢ7YQMQIToSE*U!:iBI$vgm ' Y,д Jm3I 2LS^ UQ-\hy kVRNtI֥Sۜej˚2(aOiR8Ea t8F._iRUZ[VIJrۇMm2=Gg4+SH|;XjZ ihzvi_iBZN#[f!dlVs_e''z^Vofx{U۝VuR|Tn*R-U/zUI֓Qsrnmژ_j/߇Z>꯮ꚦ ɪXrk:ךkZ^~nwiַx"xZTaСogNNja$!hzը.TFJ_ZZ^sRs|ܯ&{kx>$h| h֗Z5΋2Q⿂]ԷgHÄE *n*qu))Fq\SQ.X$|#V8T :*#&58dvi5^[ j {{jO]W7^n<1oYCP%YZh4hɏHHB=+eo*u*VjjVV.wqRjjMZSVI7)ɼ_얤/c:rt*N([go .|7x4wqK+iVem0Z%.蔭ƵZxY;5[*1S1)RT9J 9j^?7**URW+MJP^ ORִ'J7Yk wn,ڗ~keEr7Jܸh{L4m^- 6p%s{Ң;U^%8R5 ¤e牦Ğ ¿؞ Ԯ5y++캴kwQJsu4D3QJ (C#8fI$EQTӧښPRFU^)T⽢WZʭUV{D=5l>u jW^SeSO}+=Gf^HYt ojzϕb'\ɷ|SV+ԣIPx?{8!%.hCjԩ)RtgOG XXW&4Z^b':u']SUiԣJs)ҧ'.hEc\5oKĺjqO-kKM*ʟe흞#b{*kІ.iJdN|NWN35)'Im+IΫC#ASJ|%Y֩ȒjR(Oe魥>hi/heZHlL.@OXza6pypZ?٤ԜԝIJ)U)7*Ҧr&Qu89UqF*0Q)J%='()$!~SS/e?WnZkԴI.KQ[ܴySN*~イi(8Rb܉%$֭Y%Zk)Riӣ$FK:TvK bz<#ᅼ^LWc@҅^'#qi5|6Ǩ bdGU>zuy(,LiJj+:gQiWJ&ZStV]*?0Q}!Z;rQԦ8(, M[Ӽ-kލj:MJAdmB꺦D5+asq$FsRŴa!I+*i`)% %0&I֩Qse-eWJsϚq{*N&i~qywh&ugBKҬt~5u]oYo^oR7qF/-4Q,WL>.Z4(V8F$麒>k/z\kzt( ( ( ( (m|)kO_m~!__~WuhKw∴ԮVk[i,%Pm!J' J F)FhժՍjjЩҭQMINU$§|$:'NJT!*SNP)Q)Jj !_x2%-*Z^Yin'u7Z4=6;6It-fLOlLªMX[(Z5h0հ8=hUSJ8#+MS9N ;.xW1n\N(Zqdaޗ/F i+KR];]GPp_\0N"+WR5#*2EBQu e(MF:qZ8+b!%(Ԃ娥^Y)I5 ;rU~}Ꮔ7lSx-ُ؟MPuy]YK4W77r'frԭV=rQi{mJaIDZiƋ-(CRokFbK WaaiCJ(YaQN^,O/m=>|3SnxSC"w~ٺDCK9}\ﴄZ(P ڥ.Gk_^+Zp8UQgSJw(rGKToޚsoV۽Gox"^-~ |<2CǑh0[xTIz'}Wk[돖tJe+]ak\Ez ѫSEx:$5 iЮ/}3MoKZZFfs&4+yj^66캭׆"vSӥF*{K ӡJeuRujӥ p8F3e&h?a&e͈kTXڣJ c֙hz6;]jO<)_MԮ-C&IQELPb XZE**)rZ#Nu!r"ceK*1vv)եNr'9;t?_m.uIS0xgƒ.?|*.u: էگVw""ɤTJ28T9! XE 0հ~ʆ;G GƔNO?1^ ׃ 0[ǭxu4abKv,p@Uھjé_ع,Eu/gڭY;ʌ~*Re^)U:N%oiԊ+M)wR+oXv_z -}ocԯo<7֔\j0u,BxW&E Rj>|OKZʒ*|tj/TRXH\,*+JNJI^㒧&=ݴ:;x&MGw|9y贫3xGP Gc-BOm4 lma U^!?~s:NT:RYҔΥIA97T<x<+ŖŎ Bk\ξm; YKHkdJέyQEH/FwRxZ|JPF5ť%NUn MIaC Zu~B"jPGM5(blE /JRJ^ ςfk6 ~Ůk{0~%,G JFm^|Gkv[8nl#0ю hѽ:T+PRHШFKWBOU׎xIW/k^JY.iB*"SOܜ\=C_?S|.uKa_OROWĦ]GL ]/IҬƣ}23˷S/gO .H`^^1Uk҆#"aʫW^ڢOxrEZ5k1G ҡMQR:*WTRp,e$l|--"K4 x~vZΘuGŨj0x&fsl%$pիRRxģG:T S+副N4^rh))’9K p)Nz8l$"p*:4> PҔYM?f--jVZΣ&^iڭԭm-F(ne5 FU@ٵxPԕƜ*ʚڛ TQqN2Rמj&<|dx ouhr\XhetٶW qR*:11mWekUTIUVV)9hE,5 I`*4-)rRSKP#|.y]xDZo>xwúޗ=mI%ݍSNSŚ$mF46p)Օ_gT)8xeW)aNKh<4'*Tۤ#q~ΌR44JJܮqt x1=DKxF)g }cm:8ObhԯW߭:8N9RFXnN5b$i"AVqV5%V~EhjUg*۞%)JMW¿ x?<+MfV~=km 1[vHӭYGwO%Di҇% 2ӏ3<<:Whμ!ZThJcQ*I**ըהgRru'MsTqqsM9Jß _| œIqxº[/eƝa ޳3K,L,!%ؓ/zU5/cr4%h^ EkNi[Wu[ZS­O~i(҂5 4b*Q.ցe/??Im]0#ٛ#^CZ<_3hj|2Wƽ%t=o뵝O$Dv~ҙky:/yZN'g3yi~Ϸ?f7}lyOHKVɄ~nVyshC<+֓w}3ݗw3_a?y/ mX|z_O//Z֑o[xjƟtۿivg JHwqD z=/{m0,l~ib=ܳK(c1S`R`Ɣpp8ў61ѕ |;3] 3R *utO B5Z\J)ԡĝ ,eC _ԅ RzkFgBi㉅Z0~sx{_HW~!hW|w/Gxnš7-f\>=K+&voiw^yF71Ua3V^, xJ7GPGO)U׶t(J%[CS*S&B%ԥ3Kc{OmkBqE m1t"sԾ3 O&U(N-8`Za*bV'Z\*xFqX:tqz Wyu,JjᧅWJp*8JafD,?h'x6_AusA> L4?7]'~֩R{HֿPɬw̻ԵxaJe8l-^XV[3\&Q ,*3 fy~" ** z%*kQ{ PG]x`+֥=xaˡJʅ )gGO>x5|!iޥt[Z+_)d۪Ԉnee!;9`}fʧJu**ELNPq"[4BsjET!RjEI^"VrN){5R!ȥ+,xsUOoxm<[oo+𦈚4D{/oo:m4Vw^/Т`ad,/X\f:&!Vu# /&NJ%R"xVt^. RٸH)tL5*  gQZXB49+ө i*38XW~5xCI x+ztMT1x;H}"h^ݽm~;=ӆ!bk*xU0yN/U!J)`Wfu'M)Λ`]gre Opk(΋m8|eW-S͖LuKO~>f{4Ki;EL?lZQ5knF VֳÇia1g kY]uUeu^iYֆ.`M+sܞ&a*L,')piuF}N"UpO x'|B <9'sE\<on[_@Hd_V%Ԯ ҍ֯XuK0Xjuc jRS8*{*obeºuSW NIab-zX| '^7h4ܦx:8ΚúQҕ GUE)4O/N[nz>Dž'xĞ{/xMC?PbŤ^#2 fmV |l50aw-xS/YOJdzPf 5JZY,ʅJ/3:>OoB1Zt0ucKUeY.K*0J/q̩닎 U5l?/h(^,>i7 ~1Zm }?L־i];55On{>h %#RJV,V.;BYʧShf,|!J#ce:^ke烣Zc< :])Ӕc+WN*pZU0ܫfF:Oz*|m/<'o Hx?ÏR׼k{#N2ho5υxz5~^!uLn#[ii+2>jʽL8OxOmsUɳ|+0QR r9:8g(Nj3lx|-@[ſ>z%.C6f℞=">'яBaoMqg8mOcQU B2t*VjU)GNS[8G VAQUF%5B*> V+mUʌµ|Axόgi._]W_|!?EYkU|Ih:i?"o I+7<,5qX5:|!̨ =Hε*8Le4(<5L-ۧc4(u }^E&%TSSx\t\cZ8R W,SαyQ:/aUWr:΍TZ2thƥJ|N*jukiUF(֥VzRRpB5a]~?+NpjZU3jѪQ*𧋎&1y5ύh~)Oj*,? u_k7w|mi3M~l"-ޯ[dInmB즒Q,V8(E`0yi*]seԨT8SX5ISz)`0]Hs*(RNJSqOҧrśJ]C=&k.[x[EwRR~)jOd7F K]/cIӎa֡,;pNjC1kJ?,=jbXz.Y2R VZ9i֕FQ:8zxhU J5U,3SPBG>9~ɪ[j>_Zgek;þ0/`oLjSᘔ>sVj:xrtra,MJ`ܪCqthՌVp/BZ|<|oIR~jExSE֬m6 в+g[ϧzPTp51Z-VR`xru1uiJxIWsKpiTtگZP&E”o 壉KRU[Q:*ʱ4Ts;N{z"IR: α7ol4[|N]3MotK>ؖ3j.wsy )W1S/MMFЅJ98E(.kW)JX8cFpN*tU9rTt]?k)EU䓇)sP@P@P@P@P@|3HKO|l%RknPm;X׾MOL_ Z_ O X0K./$=޹#PK/F)`iΎ7xhbIʬq,{JTaK TIwVf9qPX ҵcBJ2ӥXi*28ա*T_Z'*^X,E:!7~"t|<_>!i~!~-/yHsY]p)`bb ynZLeb*Ӝ*8hҨZBRQY>kVC*%ӪF8ch13*})b)V->#|Z񷃾,i|4 |!{:~ۯ h?>*m-ݏ52vWk6Ӭ uyu*apT2Zxu8e*uh0*9*N0G%qӤӧVV5'-8Ub9-CO8a_-s\bo-)¼0LWѠⰸN*>N㏏ڎx־</eGWO|_MgK \/P]ᆓXjowDNwwlx3f6]UJaer<Q*Ў'^2өըb<4Ua SX x^(UҡZNW<xԄ*a犧G 8ym|[Oh}3~mu<#|#G>'緸e5 ]-~cn5†# _R5P#BބjՊ^PЫ>fNKƝ:u/34u}|iq^|y75[L+it[|;[4rW^t2 ,]*جUUy ^i5RJEZG+ *ӡ_$fbp괾K8Ў.<]Jxl6])WBK+uJ9Ne%5 x'ϊ4Zƙa:i>,V}~K5uutt.we+է/Wp֣i`0#':߈5 hz7~j:w/~"<o[;|8w5iuzd:.Aֲ+ =Nx:,-zEa񸏩9`YOJ>|&oNkVPqĺxl'W/z*(J.3[(co ؏khO _ QĿ6O>&aq/Y& 5=O~!\j ּ-⯏oiz}_V]~.-..1Jl"j hyM= M@j6f3 UfZPEѾ>9"Xhѭ:)K*#SRS˩Օ,ヅB"Ye*yJIQNѣJ'B˨SbЫR~ ŗ>%`d7?64I]5|w73[= vj KA'aNciNSR_-hF ,)B,m|#Jb)Φ"cFQX(Qx4eRqiWC&B U*FPMui<~^4?~#_xmy%x+,6ӆ5u ~>*|IoxjmV!⻟ =*m#헚:MMzt8w]}\]*4Ҧ.aaY\V7. iNx\.#NW]7ܹQziSRyjɆ-S'MUOT4eK^:.oQ1N;o&-~Z*VXW׆y}x Su0&u67W3UPzƶS<~?!h`㸃Uю"XH(,UYr1P* >aSԩC[2ɩU)J'8  |ө)S)x |OuQ7BTL yaeFUaco<5\;VRO?AT|ME(4jRSg+OZ5>q%tfo{_h/͢׏A__e4 ?*Aa_u>/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&kUSᇎ5]7]Ï[ѭl}c>5]*:ZiO=,HČ*cvU g-8zk-TX|VkBU*J6snru)FFBu#NN'4;+g r6ٓ>_ r[ kbML{K{ũCl֦8(uf;UCܮzR֥<=jqBgNqR,Tr4(tF8YӔN)Ƭ+AVNjUE-G|]/ ;l.mFۋ{oqymgmMZ81&YQXQ<>u#B?{q?uk($'IERI+X?>_:ğ [ų[|J?uOUյ\jdT{oRX7&#iJ1, CJjF:39F11rc*B0U5jp\[*cW1 !VJU'*K eFB ۥC.>᮹>~6_ rڤvzFI{uxA[s ,XUjG b(Su&FsTQ~xxq2rTYRr˒T_Q T燲 SF9B(ҋTNt%$>xĒП| ៴ -|ٙ^mC$eFKN97 B1 ݫQjh{՟X%%('i?fT8B1ukTIS5q< ᷂k x(G.ꖋ9>`R7q"ѫR(TiF5"jRX\3|Ԍj֩RgRIJs'ԩ(,9+9I5,|2èx^[ix^Qz^XkZz(QXG[]Okp.R02xʆgIUSCN^(YC,;h+s^ EA|#|@&~▋/ [Kմ)|9-͇;IA71'HTya02 2c(ӜGFHQ*S(t _VxӫPeS&y=Z5pJt] 9S#t<Ӎ\ AXt)4p—hwuO>^^"bkˆ@g-_[[Z<^"*IF3VPJytkS )y\5< wOBzNVr*i%Y6IɹZ/ ԼQxRQƚ~^Λsckm}yg.>;~4s+RJB|8%5j#!uk)c-,bEiK(9a@ʕ9WeԫSJRQqnnf^<ؚqY]ڭ(8R8AbVĽ1{R|;=G?[BN|'^ZυM#O>:%HY pĪXF۫uʤq5/jNU^UVFIrBF~:R֝:5} O9c;E5Z{T-CEE?h.<=? |A;Sƽꉭ߇n$u{f8漳hf5wiT8te,5XWЯO$jSnBh6p)Q8Ҕ6Z5[C7V){qqu*A3qsrm^o|E[V_ x]KM kZŶ$;i+p-J y&S"85PO K\D0*acY8i΂'NF(a-(Kf0;JUk>JegjxyՎ"t hѝxBFЕXƣTU*UQsկ(ΤN'w)AԨ)66rJO m[+G7ښ ~UғQQj%.-t\#G .::PrBV&UjVINrJsg7(ԧFԛjT'JI*t1z0w*U`4U-5nNGlPծz5z-5+5//woA+Ժ[ DZjW+5K(6CO HWJjUƵ5hTJVU*NjSpQ FP*)(PƔM5/WamKwይ/D,7Mӓ:Λi}Yä\Y &[IdaU[j⭊UXMWQqjV*ƥV֋Wʜ' eU[<+~r7 T .'Zqh80kK#MmxOA͕ % ծamK.8WV OrJ^բVM(J2m&tV_EjArR/,դ䅝cf?_ A?Pxökge㩼 O}xDQ.+Ǜιgg39}VWW9RĨ4㉍DN0"IԭJ4EO!FwTFJ1QP00QN ,(ѧMgtz'ςŸ >V)7oπ)znt_"!K>c.wBcMZ(WJmR#PVqEKJm8TeZg9T\7M9M7m?٣7<sIKW?> N-SEz$[>۫gcw5Ջ:Tሞ&ypzrSR95E)UZXZSxNyS{zrNH78{RGA %5 Io#U{-CL<M,. "y-85Dc\DjT*:5%m(ф1 MWpcU?iв1RJ"򥂭9ԩ^i9ST產4gƿ~|FxcGmxIu nk[dtbPVue+(kiVf(1ir^9)F21WsZ41%ʖ;tNj4*jܡ(ʟ%\2 ."he}Y])ۢ<  FoW~& 7a%th-#]3BKk aN/x]VJuң^=֥ХV2N:i҄Ӎ8T`2xuJ4 MCT2AFܵ*^mQ|1kL4O|=VM'|/WOnscZypmc$墦v1X-L"pXʋ-ZVMrc9FjMGX;USRܧ9C_vROUuOZx6:τ$V<3AQҟ>:_@kOU]Wp^;RUfdSu*JE{|Uf*,v"6cZx4 UV;M1PjիVQTܢtkz0 RqTႥ;Ǝ[| ?eCFӍJ'coen~Q/uXGR]-<:0uu1y%L8*_TUXUSXW5YMԯ\"mVIeF?WU)J2Njt֒jETQ⦔M\|7C}_/=R]_xB K~·ױWJu5a[!'ӥeOeIZ>wy{:iNR*)C,$W.RR'%fqSjׁ{ǣx;zD>tZUׇؼ#Gg ѡO\çG6Zʶ60/xҝwSuBu*Q^kIѩVJwtRӜSTBNJS9Zsg Ii)FKF̧M ׁ| bV|h߮Xg_jvA K%W|V"gԣ[ ;<-\>%c(TtbF*sԦ񡆭:T]WJ(T1tڶ"j֥RBR/q؆g}3PյO |C5߉uu~#QoG6~#ua5;-7khB^Bh Fjx4hޝ*{EF xuVhTOR%+'*jb <$חWVWV4ሡK )էN.顯K⩍NJ>|:%ϯ'Z)a+S.L.VcQEiƩ͆$ypOBZ‹CK^0UmQJi9J5RwU#PDөR+p8C2{>^i^Gci6ey-[]/#Hł-?gQ֬]TU*ҨbkkNjW槈įW{QJ(F}SkFFZm*\ٽw~ _Z7σw\Xx>:-|#"xSX"<8!ܲ/!F(aoxb)bύXe\ue{bWUKThF\ҦFԥ9Ѝ_ܢg?hiJ6u,]Asķ ~^zn~->fCI)aHĨI时b9ƪRWUi:UyUUZ2=&mR1BU0d 3\ԡ78s7xFN#Q$_)|0kT<ӵֵa >Znnu;m;a+qYV FY}éjAлTkB44Nlav69<}IFsĶ"sV2gJ5*T)69{ғ|߂~$]ރ GN ??;-CgL:׋#5[|<[NO39w8mթ_~թhbQ#i\M\E*q)r׊r9MSV\ERIR8Ft=6IaHF vB(iJ,o{@Ե+-gQgG/mVL][]jVږ72Ě#* lڼ(Sz J_FUcNeMmMԅ*Qg8ҧ]B)k5W_J2 "ߴN5Uxӭ?#]*3rD΃X3ZxOmw]tqZ< }OVt]Mot.,4qk}{DGy:l+ԩOS UjβΪj+TZf $xTlR) (E|Ul|U.} - V՟M<;oKמD6xZnƩibc6r`T8Fʯ*uaK+^LF@EH?7KΧ_";?YL5< Z<'Q쳙ߴjigۍoo6<%tx^r֍y?MF?7nKgn󙯰[~>^_ս/-RSH-<5iO:m߂}3zwmL;8" ]B=pῈн6K[}O\?YYrMS1)0^tcUcJ88Qsh WrʆW^Yp.OE:SpZ%MӔPXZKN9ë:~6xHi [|/OZV\G1>ʺ叇fio̖ڡڶ͍b'Bif`F!VȰ|$:*:`R(T̫,jW.2B熩BZUFtR4­TĿe9 Oϼ=C/~$x+ +>;#ּ7u}MÖ[xsxCŸ%Q;74˻/F4R T-֭XmZDe72Ww̾C S٥E:JzV{IƦ'M8F-ՍdtU!9 j*VN5"KU9'jRnR<9g'𷇼Ax6-|7SDM]"o=]7uk6š+ Qj0x ts,.3 G[ :P%C)K4 nSs6{I`ḏ\52+▩AMxƺx[U_%4Z"]6-mȚյrAo}+{kYuakW峅5,.k*4CW0spkf9nOGhgq0OB84:#jXXSO*~Ə!X|zǮ^?7޷-$2h/A} jWiFW ,:%c,5:|1zц))i}n=7U12]:)ҫ^}1k,>RƴnSxLMMa(iJX*"pn|D|m7HsxcO |^?z<]&!(ix/xsYGy6qɾONxL6[ UI 0;)s'A}c(bLA­l,eBJSb'R-:: SG8T*6kߴwO/h 4 ?[-[Pk_ 4 WZ.Ě|7 Ƃ 4 \å}X+ V,Sӌ3Lx>jRG/aJ5Zsڭ1{Y՞yl1ѧY}8J*znU3ZzY>6E7S|$U(ԩJ\9cc]ATeu3b' 5 8:Ӎ<1Z1X8Q)T '0WxĞ5Gk_|wc]3 gO x>+]Ri ߋ7QYRh9乺Ե[Aqmul(-1СWfብ*ӝ.lʌ}R_Tg)JJcg^z4N8 >jW}k7:u=)9RTjF*xi^*D֕|׼7'z'-f5|^;ꎑ5ԶwWڼiq8>J”!6\IC/:URj#kN zqJHҧ jI‚jdSiJs'J.,EJ1TRT(ss:RR? o< -b |=SUM3NBOhǡ0MTe3V6u1(*l\L!:_ZyWN5*УZNt)ӭ#iyce娪tFgzF SaZ> Ѽ]gzL3մx/⮫ />,ӵ߃^jx*>$4K]mu]u ]t$BO>JTUWRYPeÞgZ&2}+pUqK4] 6+*Iͺ|qh?έ/ 3uUV˰8gOj@ijn :"M^]p*b))Ƽ}x:.1 xbpKі)X<]aŪϫc9_gF*tOC:4cRZ'B:4ңJkR =)V yҡ.i*b? 3Oٴj?Esl^4S5UR X]i~TOC,5*|c}^53Rx$zR+ ѡbdl(eQJY85N*hp(ʕxSмÚ4?'5?Zg~x564?hoh6zt^]JW^[^SQ OvSI(qSqV"<4ԕIծ 2T*Fshra),Fν\LO쮤ib9G”)rSJRnJxu`ƧkbSuC^ .}hxz-K"χ|;Meh?]'²IqoGǣ[j%ήGi0P ڸib'5OW?5c%JZu1rX,=Ln K\,Aa)UOJ E4J#^uf=<4*Yl%(ZqQT#?d~-5 ݯ-32Nx◉`_ cZvJe%ӠӼIh>HRzvJU_1U-pfPk SC=x**}B)~ν5(f8l|5 uJ'8))FN?f8GG ,T>񾏪x>,t}ZCֵ zfiRڎ6ww)qF2>N6l6+EW୉B|҅zi*գRyӍE8ѝJj~[*4X/ê%(&k%78^\5=7gR>weow'~$~FiIoH|gwxrZo|y1 K/4^*tW Z>?6f7'L R̿ai;ѯ,f,DORtf\1exU!N Ef֟lBNtJm8)x_Gfxu~اYk_$OK/ [k:cΚ^MkiqO[Yح^ʮ]]K!"z.}jr(ʼ)fRiҤםz~}J(IP҅ ~mTi尚PSC:QOުj4ꪞ+wOz׉ ir÷RSZ߈DzØMJŵZa}amr*4|Tqr˧6GU%Z灜yZOWPZTq<"  |6T_BPyju-XF 3K uVc 6]O/>^z>17> е}_SN/4MK:Vo.8o!X e8!Rc)Kih>]z಼E]i(Z*f4%nUX'u*J=z Z8F9+S_a[SS _TJyf8zr*ѩ RPԫbhNRofօAs:#Mtkoxs"4;CuJJƕmCs6&-1PfKC8TtV5c3e$J.Q"4~5,vKJ+Uc!SꔸcVL1j:jg}Zy*X:ק)s}zQ:rx+ź<Qcy=5~[|">7ֵo㮅xrG-6?'mF 5U1um`0= ՝:>ΦU,U:V֣9jQ{UV]jXb%͇N*y< 7 ϬbO 5 OW J%ST0T%S%tk8՗?0~!I >i3+ JD/]M vy|5kceb|S,7֍5Rl.,qU<&[*?k`ts_ ZtyiTYэ)ֆ5hbiB5 6=aQ,E&m*֩,m|pW5<%!|Dm<#n~;]ft3Wg5;_i^ozFtf2]zC q %RU*ernU΍ obKqNYsV0 xjk<0T;99,M Vaĵt[үB0Ҧ\O&ߕa@P@P@|3HKO|l%RknPm;X׾MOL_ Z_ O X0K./$=޹#PK/F)`iΎ7xhbIʬq,{JTaK TIwVf9qPX ҵcBJ2ӥXi*28ա*T_Z'*^X,E:!7~"t|<_>!i~!~-/yHsY]p)`bb ynZLeb*Ӝ*8hҨZBRQY>kVC*%ӪF8ch13*})b)V->#|Z񷃾,i|4 |!{:~ۯ h?>*m-ݏ52vWk6Ӭ uyu*apT2Zxu8e*uh0*9*N0G%qӤӧVV5'-8Ub9-CO8a_-s\bo-)¼0LWѠⰸN*>N㏏ڎx־</eGWO|_MgK \/P]ᆓXjowDNwwlx3f6]UJaer<Q*Ў'^2өըb<4Ua SX x^(UҡZNW<xԄ*a犧G 8ym|[Oh}3~mu<#|#G>'緸e5 ]-~cn5†# _R5P#BބjՊ^PЫ>fNKƝ:u/34u}|iq^|y75[L+it[|;[4rW^t2 ,]*جUUy ^i5RJEZG+ *ӡ_$fbp괾K8Ў.<]Jxl6])WBK+uJ9Ne%5 x'ϊ4Zƙa:i>,V}~K5uutt.we+է/Wp֣i`0#':߈5 hz7~j:w/~"<o[;|8w5iuzd:.Aֲ+ =Nx:,-zEa񸏩9`YOJ>|&oNkVPqĺxl'W/z*(J.3[(co ؏khO _ QĿ6O>&aq/Y& 5=O~!\j ּ-⯏oiz}_V]~.-..1Jl"j hyM= M@j6f3 UfZPEѾ>9"Xhѭ:)K*#SRS˩Օ,ヅB"Ye*yJIQNѣJ'B˨SbЫR~ ŗ>%`d7?64I]5|w73[= vj KA'aNciNSR_-hF ,)B,m|#Jb)Φ"cFQX(Qx4eRqiWC&B U*FPMui<~^4?~#_xmy%x+,6ӆ5u ~>*|IoxjmV!⻟ =*m#헚:MMzt8w]}\]*4Ҧ.aaY\V7. iNx\.#NW]7ܹQziSRyjɆ-S'MUOT4eK^:.oQ1N;o&-~Z*VXW׆y}x Su0&u67W3UPzƶS<~?!h`㸃Uю"XH(,UYr1P* >aSԩC[2ɩU)J'8  |ө)S)x |OuQ7BTL yaeFUaco<5\;VRO?AT|ME(4jRSg+OZ5>q%tfo{_h/͢׏A__e4 ?*Aa_u>/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&kUSᇎ5]7]Ï[ѭl}c>5]*:ZiO=,HČ*cvU g-8zk-TX|VkBU*J6snru)FFBu#NN'4;+g r6ٓ>_ r[ kbML{K{ũCl֦8(uf;UCܮzR֥<=jqBgNqR,Tr4(tF8YӔN)Ƭ+AVNjUE-G|]/ ;l.mFۋ{oqymgmMZ81&YQXQ<>u#B?{q?uk($'IERI+X?>_:ğ [ų[|J?uOUյ\jdT{oRX7&#iJ1, CJjF:39F11rc*B0U5jp\[*cW1 !VJU'*K eFB ۥC.>᮹>~6_ rڤvzFI{uxA[s ,XUjG b(Su&FsTQ~xxq2rTYRr˒T_Q T燲 SF9B(ҋTNt%$>xĒП| ៴ -|ٙ^mC$eFKN97 B1 ݫQjh{՟X%%('i?fT8B1ukTIS5q< ᷂k x(G.ꖋ9>`R7q"ѫR(TiF5"jRX\3|Ԍj֩RgRIJs'ԩ(,9+9I5,|2èx^[ix^Qz^XkZz(QXG[]Okp.R02xʆgIUSCN^(YC,;h+s^ EA|#|@&~▋/ [Kմ)|9-͇;IA71'HTya02 2c(ӜGFHQ*S(t _VxӫPeS&y=Z5pJt] 9S#t<Ӎ\ AXt)4p—hwuO>^^"bkˆ@g-_[[Z<^"*IF3VPJytkS )y\5< wOBzNVr*i%Y6IɹZ/ ԼQxRQƚ~^Λsckm}yg.>;~4s+RJB|8%5j#!uk)c-,bEiK(9a@ʕ9WeԫSJRQqnnf^<ؚqY]ڭ(8R8AbVĽ1{R|;=G?[BN|'^ZυM#O>:%HY pĪXF۫uʤq5/jNU^UVFIrBF~:R֝:5} O9c;E5Z{T-CEE?h.<=? |A;Sƽꉭ߇n$u{f8漳hf5wiT8te,5XWЯO$jSnBh6p)Q8Ҕ6Z5[C7V){qqu*A3qsrm^o|E[V_ x]KM kZŶ$;i+p-J y&S"85PO K\D0*acY8i΂'NF(a-(Kf0;JUk>JegjxyՎ"t hѝxBFЕXƣTU*UQsկ(ΤN'w)AԨ)66r~O7 })EL:'Emn'|O5|hF_UD׏=I[Mrr+s&5YIR^tneq$I:JNiǸ x^ 7#hLp>!o$ 7'Y5K}/UONO, IZI.Mfs+PJ# *t` )/CɹB)7*uFX7xԭOH'R圓yf-[ ׮%|!}f{TV4Fk8}:;If]?A/&Y.)sR/iougL |> +a8+Z1ЧHǤb?uY{w/|76&.j-.`l[Dz{d\zkH)SNן۟}_sZN{ߛ~k|.0I’Z`ܢ'g&՛g1 |[$rK DRx~֤N7ԴيkfmEǓEl5\5,$𝦝kwZe>mdd1\~ idZOY8JW '*><#T熭Pץʜ1XxJcMe9ujr&,E(׌kі"H}bThYU74jN6{ڟ%)Mgj.g&eEt<]6"΍U| ʜeZT%RteU;՝'+rRPXyO$08 ®S*ӃN&t›pHj-J͑x-uh 4CeY~g->|AmouB(¥%Tu#ibے,B*Ux0.OP˜cqBP 11I*7R(m1*ےIWlnt xfEtk]JlOLҬWuf(5kأ ԫ%:\Tufb%RUdʯJS sƟ(XÕrBܱm)Mr9[JRM(( ( (=IW>|=~ r^բ]-ߊ"WRYUm\xFA*-(*xl\jBUVV5BjWJE5%:TsW WT:2)PNW9BF..4*i6xEh:_ ]iz&entkH'൚[2M='3 5cWlTjhգVUN5(8FZ5NT8\g(,G',B^sSqlbaq:ԣGiœG_7z_m+o}Czl I/%Hnt[ h"YuAº }pfg-8VxC\HԌRv iEԂQi5뢴Rh(eR yyd$$,uV|1n >:[;/Mof?b}6{C$:ue,\*tpTeF:m{8>|I±O9F|M s-f%],Yks5jnԡB*Sj}Rg|Ez*\ujSi¤-UGM*ܣ9ʢug-Qzii[nw9O_3wWҼ?x 6GWuGmmR+%\KYҧO D4pˆ֨\[hš}gAɨ)JĪ%ku6ʞ'ӕ]'*uT*AYݚ: W_-wLƉWhKi jg`h|1awIml̖1$#R1Tѩ(iF!Rj#HƅTlG$,iΥL=IΗ:ҧ<>f{>5C6?mtX{ĚNx_UuWZ&6Z)YC[J4gYF1K2J1pYdӜ*ѥь(T؈Ԍۧ*w{QF)STf E%5NT*ᔭu8aq+F#/ Nohֺ7-[xwB6h^{ /;Eii̚^X[:uxDz^UۭONƵ,<'N*JtiիN&i¤IêQhWxj⧉?6" 6/iRcjw+7_Zf|>{ڴui> }7R{t{˃kp%Go-3@aj`qT\jЍ:kԄc6Poݍ/WX?ڬ}ڟOV9l|xB|!'O |Z\z7Vj[J4&RU*(1P)cQRo#VZ?c_фhJXxӊ )4p(Vi*45>oQ;-<#sˆ| {Ǯx2?^—0oyцsы-`FEWjRª¹obԽ+jdO*1JQzpVWS%8FcR*4jKb ~x6j^>RwZSuq ԲII\0&JY>Ν/k-j{*JԩMp,‘QJya"p)9({5'M{JWPv 6=!烢Ү?ϦB;8o- xr>9ЂUW(VixΔ뺞:R_NJgJS:%R*t%BR'jӝ78JKIJ6rZ6e> |0}oO Xk:- G}r:S gXJ^-" (:F#<IIj+BSK"0p9U&5% 5i 꾘UB]7Oԡձ+P*J){6> 隆|%gKíX:5+}9{c o]D F8J4+SQFPC,=J0Osê#B~Ҕg5.i_5 >IWS^8i%^zz*d EXiN?rqpM _Ln&>)K ?I_u2ft'J~-H|.5L>l4#̓zxwezW&]JJX*]{jU=IUhnqƪ<'Jj'u5FJ]SIݱGL.;IK+wvoh|1z@0,l:Ƶe*ꢭ'YV^E6K_XsR5g2~ |3ė/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&j7tZ_/͡;7ZLy8Gs,$ټY]Ay #\ƝU1Yz\6[]*^#eyB4as-zï xzS|W 4׼ k(->"VmWþ} 7y%.4dR6"<,n7/T:dh!WQkqXjpqQ`꧇K`1^8JiT*gS1\M*Qӆ_*Y]`qx tTh*x|9ψ]|z5AGzjEnhsnR#,Q"t僼eg**.&ԨVҵSN518zmAX1nk# ҮY ͨcU)PJq'z\Y;PJp"|ϋ?V?=;8mš"h|? iK\鷞X]xBQO V֯`nn;aqJ8ؘTYԌ0x9*!JXX9xʔ3 Jify#,?שu0(T'EibZRN0t}΄Eb!_uAp|={&|&>><{7P">']{v7)?[jKNc'eFI!W88eWpP*_Х_U<>%ԝ7K[ԧ:oweN'/Xh{;ޮ.Q'U?XYkO0:-i_O 6Zm3^5-c0שUnŸ5:xW >4|pL7h`+i x$u=ryo}!AZ ?[RJ7ZxYaY,Yav5IO Kp쩼J' N\%:%\a0z5rg:jkFJT-RaTqӅ?g_mW??m|)O^>+k~K3x|!>/r/÷֮w ^502:3 ^L.&9&9´\f *|̳L S9b\j:rk,qZxZˆ2:N411Q[aR_|jw_~/?G<-MBOxUBQk~eᇊRYuo/E^0X SҎpV#T7Ic*WGJJKQN/QpeXzN V\Y15hdFPkG*0GSR1NjF>yoߧ[/Go>/?ĭDi6N x+*~ zK!IikR %|9N/^2R,V#8p:^Kk㛫͎Oѕ8X"[O CI-.+=욚][NcΖep#/4b&iS CjUjUcRBrKwBrRaUC W*4U-,U,T'Rp9\eMƜj/1 prrJ/>G_ ,cNjYfUh*U (UC 5)bR a7QH_𶍪owGվ9x~Ӵ> ^4_?]?K\VΒ+"^2Ec] p9K ϲ*UXyʶ",:)R̰u,.ڴcBխ죗qnpPj_.¹U %LEIW)3'/lgM z5 ƵhԮ ԷY`Ox:Lڵxt=ӭV'7:_,%|}V}cS:uṘkVGgKkS%׭ 0U%R] .Pf*/'U;oc KʫVayK,f\KWI**)S*aU8j^QP@P@P@P@P@P@|3HKO|l%RknPm;X׾MOL_ Z_ O X0K./$=޹#PK/F)`iΎ7xhbIʬq,{JTaK TIwVf9qPX ҵcBJ2ӥXi*28ա*T_Z'*^X,E:!7~"t|<_>!i~!~-/yHsY]p)`bb ynZLeb*Ӝ*8hҨZBRQY>kVC*%ӪF8ch13*})b)V->#|Z񷃾,i|4 |!{:~ۯ h?>*m-ݏ52vWk6Ӭ uyu*apT2Zxu8e*uh0*9*N0G%qӤӧVV5'-8Ub9-CO8a_-s\bo-)¼0LWѠⰸN*>N㏏ڎx־</eGWO|_MgK \/P]ᆓXjowDNwwlx3f6]UJaer<Q*Ў'^2өըb<4Ua SX x^(UҡZNW<xԄ*a犧G 8ym|[Oh}3~mu<#|#G>'緸e5 ]-~cn5†# _R5P#BބjՊ^PЫ>fNKƝ:u/34u}|iq^|y75[L+it[|;[4rW^t2 ,]*جUUy ^i5RJEZG+ *ӡ_$fbp괾K8Ў.<]Jxl6])WBK+uJ9Ne%5 x'ϊ4Zƙa:i>,V}~K5uutt.we+է/Wp֣i`0#':߈5 hz7~j:w/~"<o[;|8w5iuzd:.Aֲ+ =Nx:,-zEa񸏩9`YOJ>|&oNkVPqĺxl'W/z*(J.3[(co ؏khO _ QĿ6O>&aq/Y& 5=O~!\j ּ-⯏oiz}_V]~.-..1Jl"j hyM= M@j6f3 UfZPEѾ>9"Xhѭ:)K*#SRS˩Օ,ヅB"Ye*yJIQNѣJ'B˨SbЫR~ ŗ>%`d7?64I]5|w73[= vj KA'aNciNSR_-hF ,)B,m|#Jb)Φ"cFQX(Qx4eRqiWC&B U*FPMui<~^4?~#_xmy%x+,6ӆ5u ~>*|IoxjmV!⻟ =*m#헚:MMzt8w]}\]*4Ҧ.aaY\V7. iNx\.#NW]7ܹQziSRyjɆ-S'MUOT4eK^:.oQ1N;o&-~Z*VXW׆y}x Su0&u67W3UPzƶS<~?!h`㸃Uю"XH(,UYr1P* >aSԩC[2ɩU)J'8  |ө)S)x |OuQ7BTL yaeFUaco<5\;VRO?AT|ME(4jRSg+OZ5>q%tfo{_h/͢׏A__e4 ?*Aa_u>/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&kUSᇎ5]7]Ï[ѭl}c>5]*:ZiO=,HČ*cvU g-8zk-TX|VkBU*J6snru)FFBu#NN'4;+g r6ٓ>_ r[ kbML{K{ũCl֦8(uf;UCܮzR֥<=jqBgNqR,Tr4(tF8YӔN)Ƭ+AVNjUE-G|]/ ;l.mFۋ{oqymgmMZ81&YQXQ<>u#B?{q?uk($'IERI+X?>_:ğ [ų[|J?uOUյ\jdT{oRX7&#iJ1, CJjF:39F11rc*B0U5jp\[*cW1 !VJU'*K eFB ۥC.>᮹>~6_ rڤvzFI{uxA[s ,XUjG b(Su&FsTQ~xxq2rTYRr˒T_Q T燲 SF9B(ҋTNt%$>xĒП| ៴ -|ٙ^mC$eFKN97 B1 ݫQjh{՟X%%('i?fT8B1ukTIS5q< ᷂k x(G.ꖋ9>`R7q"ѫR(TiF5"jRX\3|Ԍj֩RgRIJs'ԩ(,9+9I5,|2èx^[ix^Qz^XkZz(QXG[]Okp.R02xʆgIUSCN^(YC,;h+s^ EA|#|@&~▋/ [Kմ)|9-͇;IA71'HTya02 2c(ӜGFHQ*S(t _VxӫPeS&y=Z5pJt] 9S#t<Ӎ\͇<7[[=K7д ܻX<վjOEۮvՌ+V(Va^snI:Nz8Sw" ia8fRG>kT 6lԢry$=mS|!^ׁt3Zx‡T~HhY ݤfP%Ƶhb+VqTjRURJJe'z_~N:xa*B3RBtRuiN4pV1)(:M$>~ h^!߉xyb#9SY5z\bj^5_!? ~x;7<=n_FoFG">КUMm uJ QFXiӟ QUPwʪU%I TJn.JN39ƭ*є_,j SVjbqQ{㈭4RޱxKLg4 v ^iCL]ë_higw`W06i_RM0\jZ ilOKql=FX֭kVqcjZR^Nӭ9օy^jU#596*QSPR8xݡGT*^sI6O'o4xk͡}NԚ_ xc_ym!}SϰeͽmM+RT'VIƫʤ:zMѕZ̟Jrü;VtktkB.KgV0bSIWZk]v [ 5i#VJ4.-DZ};[;%$0뚄QKM*NucY:ʴ mW!a㈕dʼpEYuV̨S18GSQJʔa6ÕFm$Z+7:e폄3gy:5ݮ[6ZMiVzd+Ziֳio QUju:u1*r|eWU%{U~M[cOq,aʹ!nXZ6VӜ)o&MYP@P@P@P@P@P@yO6~2i+K/Ðx.nQbm Ģ6 0)PiASbR(ҭUzMZ#RU))JT\=zgBє)J%Jr%*1pqq)SMA;? /X|?D%]bK4K-?MtZFgfp>nBɖi?o[{?|3eyIy*Cuk[Gq˨Հk39iEbFeFRhUSJ.I]+GE{,D$\%5i&!g{X*/ُwo1&xoxE{1j.!o5K)fD_zǴNT*18cQ/oS)5u+R8sr*Q8hҌTiaT*L5 -4ha)S ,5 4ikŝ3ළO~y3/ hd^.o7H}/=g ϣX˝Suu>֥ RTpc?+RRN'j?jiVU;?ijNwMw?h \?~9ú+Ű_?Bx;m o^/D϶YXub}qΕ:xxb'\6D燢ܣEFԣ{8BMEJUh֖%V,T^)^T<ޜ9SR ԑj kg4Mo½cFDR[3H~KP<#C "H4Kkfdo !IGJ4a BU=OF4,Teȣb9 p<`Nu*a콄WNt)9(>y7+=6^[khzLJ$t{j5X&ռ']YJU?j1eZ\JQ{p&V,n>e F2Ff9Sڍ*1J7(J))rW k-y AZ5q~_VWxJvx'DFѼm"ú߅?oxIBI+KHLЮdƚEo!ӭK=URjxtׅO~5a:t)USNZt4N'(rLR#BPcԥ:~w)Pݔg'.SkSͥγ <x P|EtυEΣSWAUTdYY4JQF^G$!K֞28•UxlT!jՔU7(9ތ#BTƜU8`NFOPѧhx҉i>CKV=v:|~a x4]`^In5( W>urTVSxu+%[U'uR|QEJRӅ*Z9)5#Uex4W._~ nWKTWWRzҝt;Fn@OJȡ6WGωt{YkSRVO^ΚmS`P ˅EiIC٩:krTںGuoޑ/<u&}6/hehS×0ͦL!@KBRi`l)@կ?5(NO WX(Ƣ8Xʭ5),Ms$N{ _>-HO&Ew,zg8z[X;V3WYc^ؕj(EUR4Q)NmB4#F(;7ZR|E&t_~-Ÿ׾#uG_7u i+=5YeGXRv1*rXgTZNU^UVFIrDԌjЧL59Œ5(M5MrI>xWkC >=4=?rsuXx?z,{ۛND?2uvJVU_Ys`et.%Ѝ*0M(ӄ!'7A_ݍ>  S]t]x{Gֵ_SմmCu.K Z^,!N65*STBr6UZ"-j*%'-I,%FsE.[*T irB_[?o4 x3~(Bխguw[6Z??4GHip%<6#_o!m]gS2,MG])Օ*X+MƺUU$1:?WT(**FѯȭmJR[s¤8IW_'ǀei¾mA{6yup3ޢc=^ZPFXzqvX'B ׄ+Jm Uj8I9RZ=ZNZΤ鹸NrwrJ2n.si)^5s=+<xi.APC1ǣo/bMS-s<-,Gb3)uST f6 sW:XXҎ\3Uܰ:2ׯpc&cFsjSaQNF+VSt:06Rz%|mᎫߍ6G/U<=z^9PNT:\4jiR2%\ WV2SGU=Co.|A_' iFgc=Þ5jQ}#5zL)R~ tѫ +qkіsJ3Va/S[CC]SԯSW4j4#a*Tc zԣW 5:t1SYP[^9lHFO< 2;԰U:.uEk_T|Cqr<}N{ZymJx`9~i"i}/,UooWF{?VoG [j2&mc-ܐ[aptXpZ,&3lM~K2˸nZʬ<++8E|5\5Zَu8L%S7N 7NHگtVJ.i㇏>'aC[O|D]ψV'$h뗾' *dBڕQf N_ ~aJJxg_[OeMULL8WN t)ש,>LZKԦ1/G9SXwJ0xRh3 8f)Ͷ.|p|axRu/χc/ZNR_7md>ihĺ7e煞GЩC*U(/oG 5YKS,֭)(}0GN B]cf;W+֩+`:MOjuCn#UkW|G~)|*n|sMbRH-ON[G&hP^ҩK0<@թB"J:.Hԫ^JUZQ_`bdjPo <=LEjR)V:3+VrKSZmwھ+koVXy䲸 bd \lr<$Ҟ'rtk;BuhU1ԞxJXyBr(9bOG ̟k{,=-zb1PsREBcS88PVBƟV2xKFԾ V7 mS+o$+kmҜ*^x*[mU,fa*T(V*xh᰾ӥ 4OӍ6VqpsY^ ⧃uWfx> 5_ ' +?[F]1e֖Zpm ysa &xNσ| ,e'Ya2\V)u08ZUUҥYiG*Gzs<'"՝eu(5,5/NtqTi+х\-5<4NbX= x~.'Eмm#“=^oo x[Yϋ5__kmyuWe[Xk>{?`eG0cpT(ժ_Rtg^Rppj2fL=*>KcJlF]5PXó|Oūjbk;K/iU1MF8޴p[+f犫Fi,:<QY'S2jPNΦ*5O:Wu(f/.=*c:exޜ0EUu}qTR4Þ ujka RoMƿ}uH.ouse5քn5[REaS`1%GSezԨa+Ji0x,hRc'ScqT!,x,;GO8?4Vo_ªפFtrFa M\27X޹ mxOGnx.Yu>񆢺O.ֺ^=sL0m^Z\}ۼw5)aѝjUK8)B/ 3, UUj:t0PPҡV0g3URեB\CVSQT :fYFfӚͧ|dž|M׾:&;o[YZ_0Eaf5}Ļ͝NBO >75AӒsB#,"6\}(BSѧ՞#V20iPRT)ŧ&:$jTM)6W?h[)>#ᯇ?֏[៏oY#\6[Z]o ^o[ ћHK}_ܫ 502GVӫ UE bStUuPNN1x'Cw4MG]>:kӮ;ߊ-[KO{XbrQ2 21tm?rѧzηb% {Z NUps +R\s8*qy;*<-# QBTNT9J/;ǎS?x@_T~ I9||wWA~xWW״h>mSP+#^>]Z?P˪8FKޥ|4ҟ cq6.\_WPRa`rïg"rz֕ HʕxƂ:ҥ*<)N-cSjv·VqV:>K5OwcT+RѯJXs{f~r,=cKR*ja<tզcE:4GВtcJ&uhJ,W֡b9W N|u7 u񟈼:jϪxfZ_|/m:u {fĆ>^u_ya`:53% X*X<غ[#V?gSg؊:JpiN4:GԔbOՄ*ʱ`14Q*X'm6Z[Kwcj̸#]^]J\ _aV妝%Ӿ"]{ f-Ǚ͗Ulg\*,ThJ#׌t}fj4ظ *gaC/F1ׅ jcVj^5! y`8:[E{w'@V7?_ú$>3L[]y|ǠkO76y5l>$GBWK_ۍn0p­G첸aԍjuT!ЯUkalgCa'MT>lүVAQB WX6:/04#OR/[ b UВ9]E҄NuӣIc &' 񃧉}s⽄$VXx+NO;߆%ma~.a]*˳qu%^=kK|2𵬊S(α ^xqX|n#u|X> J4RA1r¶#跆BxTo/Ư\K|I{9/fS_W5 x[^W՗_K{ LiR[/`\N)UaugժS4)֡q+J5yաqTغhСТ0*1aFS:8J񡃊`spk~2|]ǧ~7Zux7,$e/Ac$SzmVѽv-wqgS)ͱFZ򼾲N*ٞI syТa %60*4>jHbhajSt,ƅ:- ΅9URl=lubAQo񑩅W?xőxۿV^i+|'um|It>DiO{P:UkFY%Fto4kb(νJRʨ)TTueK-xBYJwRdy}((TSFhҬЬ)Tغt*ԟGe'<7Mg+M_ VmCo8'REvIly~:S(T9Wha|82 q1K_RXgєb<%i7J^ 5TcZ~ɪPJQ(FZ|<_wu^ G!a?wŸO_[Ux>JHepnm^<b8ᩩbs,#׎]B8x%<GWJ4˾Xb`Wˣ)0S SMw.Ta^o\eNUܺ!SĞмOE.t85xC^kMֿ/|KC4м7 7w6 ellN]\ڿ?S?+xG ~<%A:N ~x#ĺ.|U|xu æi'IJ~gԖMPǢyHK0 ~)ƞbS0˧:u*|ZN5e GO7<=8VFC WVqr|EQ ^-{<5XEh;w+h ej.IW tŭi;~xN^Mռ;JN'9Ei "tKShQэLf4iU*t0r<]ǪTt:Vu)0ԫWb SR*.rJs ԫJ:pXE8 |l>)i?lu~)m|1š=}DgOw7B KHR2]\ܼQXz.J":*hN*èaS󻯎tk^_ j;xBE="^VOxnO2xFQ[[+//o[>֓Ōo.# ҅ iG.Hq93Zn\RN1tU\pc2XfPEG/JgIIZԾoi:w_'eSM>nt|y=!.O˧{[k]&kUSᇎ5]7]Ï[ѭl}c>5]*:ZiO=,HČ*cvU g-8zk-TX|VkBU*J6snru)FFBu#NN'4;+g r6ٓ>_ r[ kbML{K{ũCl֦8(uf;UCܮzR֥<=jqBgNqR,Tr4(tF8YӔN)Ƭ+AVNjUE-G|]/ ;l.mFۋ{oqymgmMZ81&YQXQ<>u#B?{q?uk($'IERI+X?>_:ğ [ų[|J?uOUյ\jdT{oRX7&#iJ1, CJjF:39F11rc*B0U5jp\[*cW1 !VJU'*K eFB ۥC.>᮹>~6_ rڤvzFI{uxA[s ,XUjG b(Su&FsTQ~xxq2rTYRr˒T_Q T燲 SF9B(ҋTNt%$>xĒП| ៴ -|ٙ^mC$eFKN97 B1 ݫQjh{՟X%%('i?fT8B1ukTIS5q< ᷂k x(G.ꖋ9>`R7q"ѫR(TiF5"jRX\3|Ԍj֩RgRIJs'ԩ(,9+9I5,|2èx^[ix^Qz^XkZz(QXG[]Okp.R02xʆgIUSCN^(YC,;h+s^ EA|#|@&~▋/ [Kմ)|9-͇;IA71'HTya02 2c(ӜGFHQ*S(t _VxӫPeS&y=Z5pJt] 9S#t<Ӎ\/_ 5 j/Y-cw~fF9WOK60^+gI8JTӓ?[ iYCepksT7-\))TJm;4sϦ~ |@9f[}=XuDOx+R{-z&5ͽ:<,傌 ~h.3+X:x\2OVxQ:ԣՋ'JOZ*a)yB1ʙO?bT~/QI^Ꚗ$/rj8u L p&Oxz14aB*QIaҜm*päEI{5FѯL>&RjS՜)Ճg)AJRM2ើ~_jSj?Y,kq\S؟k YeyK#xHT_QsZ|<)¤-nYU:iE'?JqQ#+)+$k.RkLu ^᥵c5feXhmϗYԧN ZS Z|5JS9U:m8ʎ"iµoT)өJNJ(BXm0Vq} |G|0дz?|)iγ3YYi1K-]pSZ/&oaj>Srzг_ak^6~ Ѧ㚄"T\K^]'vn6 ^5Kkh:Uƛm85v> [Vn=yR[A:;\ĽLe(TՄjcR%hkJ1Nxxn)PSn1tN..or[jjrSM^vU{O/W$cexSqZx ¶2֦7͏!Җ_-7p*sYF8a0p.T%C/b'J\.F]ZKI'x'Uq"d"{o𭵟6ԧ|om67XԮ_ JmFKo+kVӫVXץVtŒ8Ԏn5%FO]ʒ|u/NѭqOZKըJH|3RrT҅RG?eW?(o[6ZΎ^-/ž,zvYi峌O-Axn'M<:t=J.  M PmW{JG|A~5]{S$M?PԵEw,r\4 [T÷B y'wQ(Tan:n0M*Z*fTlL'CVpr^2RTw)Rێι{Ė6-u=b}\44E|1;Ċ/EZv{ >lӭmJAk NwEFpxbNOMQPCNx^g7R..Y%J0RʤʤT*K0JoykQnR^.ue7q\XGi h$K2 lnm&4k! ,`^&998)86Wn;ݸ:/ϖҾգOҫ:TnauNbn֭I;iNH|3yC~ _#𷂼5{/3Nn̺Μ֗3dd:ΥI3)R5ppNj֩JJRtqrZF+){oe4Zj7R5ۜ--M~;]m–1X|-ľbj-?@ bb΅_LksXKi FJrrIBNi40+pm4(aX=J"((ӭR2sկ?_.|Mis^q~Y{G%x] %^MݣL]\xWXʼp^97)RpttRqBl- qib1zPV:RT2S\j~)NjZJ|fʭTP@P@P@P$Sg+֟ B[ݿ9Rl.i\* .X|7}Ao٭7[dz>=}FThoo:O)Z_{I_tKӎ&5ڕ8“X'R(Ӎ9>ZP,"9S!֍(FBPIF:8*PPF6Y> x^{_ |$gXݿ#>EtےC.r 5i 7[_jP^)J\>[ )AY3".W)Rq֦jQQs3߽4y4ޭ{fE'/Ù;^Ҽ[#xd+:#`NOyln%%V.,S"x8jqaTJ.xz-4ZaMJ> QVibUjN5:uOʮ:N ,I/xcD+4oE%4W 30LI4>$@䶶fK  qRxԔqF)5^TcBI*V\6# Wʖ RNuyKrOiSRs3|ҽ!ySouŶvxy=M'I׼/ƫmYu ]Bk-[zEՔY3欣U{`o ^2ihPc*XDjFmӕ;ң3r*|pVל0WewnL7tH4k]-;]_g4/ ߽Ѣt M/Li-V:Լlmu[ E*֧JxTZBX:4էJN4Rqg$M(~4+M5qS˟rחzG;ޕí3P>|=?mZv4xSA𾛩]=Z=ak 8LڠAb08TUc*.RhF[E5B1IE7ʗ+UbcV>OJSKr }JN6rwe?V Z`υ]GJ\T\>-}u=Ut˫O^x%IVEEIMԩ*eTqrB؊xyi(ӌ)UXm7BVYESrӟ4%KڬcoïKv`[hO [h0X#P"}S WX)aUO}a\e7RrX^ϕZwU'͕]TT(ʽ8R+uӒ#ZJ1QFWSI5rWޱ H<uu}5/Z _^ǩ^xn;)CaYl$$Ln|gN=%jT8_ H <\YIJTV=%OM{htw^My ]riW^gb7[F<9sahAk*۫ C~JuO}֝ ԩFuy'FZ)ӝJNrnNxyR :)Npt5iΛ%%9-g2>X|>7 x'^W,5[E>~a}vA,%/|^ ZX_Rl$pRj)ӋK8JRƆRu_LE*ԡR.jPj؊_ZKƥ JbCVm>3] ~%aKkYGڽOՄ pݮ٢GU {a%(ѣztV'ZQ?iJ34$թ4^^ֽ\=Z ^Z\ӆ"U,D4V8{/7(]ė > kL3@^YG?ie>go^Ο6\½<;bk .ץ F%,ExÕVE**j78TcUITB5NJtT¤XI#zZZExCtvI{a%z xZ;DAmt= KW`DcZuQVSJsSM9_#^jE*q\eNi)is?f+Wgxoy3jt߇> oqaKT<=MbDDhHXGrȿ)X>5c1qՖ5^֢UU/QsJuRT#B4arþhN]u(\gAwk)m{?Yux^[𶟢ˣsUKkY${hl gc'+^~,EKi]UUUUUhTj*\+MHƭ xZTQ(sRQ:G$e~hFʤhiIsʕ\+I\m#i/|%cD{,-bSb=0 E`uq51+Rѩ^Ztq1ҝY^r"4ܜkURIZ#ӣxEBOOjJԪU)շ<*JSn~0-~xVψl+xzch[>a-(Kf0;JUk>JegjxyՎ"t hѝxBFЕXƣTU*UQsկ(ΤN'w)AԨ)66r_>A ^G&^$t-_-ķ2^?5:fgY&Y^BK':_>Ck^.h)KмJ.׊ҷ4^15ۭMQZHQJ3jhA5TkS]>m?Z~/KּcfM?LԌ%+$ dIDKkm2QIm'Ѣ_/UIO͟837Ky[Y>67`pKKo]-}OϬZ}$Omj YfnViL&`G<\%PO=SÆ7F;uwGڔjbiq _5 ]J🆯| ]KY|I}e ڷI5?x[swgc}Ck‰ch|%R×5Wa)QT:%:*t1g^akJ&k_Sl8PI{,F>U[mC J'V)JzK7yfsmF4OmSk7'.<ZWz= 躚_D[s6ڦ7[Ε(UCKV`(`upNi5iW({EFk<0X||3 *O?*uq|9&bz0TJ 1rcPףɸYtI~ٶwz+S }Cc/4߅tM{Ph6t{in;rڵΰꂥ7IԅL5 =jW5kӴQjrGk%Co&"1~” T'WʭtiUt}kV Uka)'Mb*SR=^iUNWvWKk4cBs|Ae:?t;÷~]|<G㫽vM6X DKK1Ky'KJ-UBV'9SUҩO F0 [W1ø<]UxzxThe]I{K4%R)U+F&J.iR:Мpt]Yѝ KmCut&j7WX^⇉A 7Kc{G? h:C +"%f0|\D'K RyE]vKHztʾxЌ>*:r<&U4ϗזgQ3GNV,Fk51ԧ +t(5'OSUta!h»&#X˨aՕ|e|Vޏ?nm<>Y kkZ&_4ZV M||a_-ցGm :)`#VIB<=Hd8Zѯ;T(qe:r*:+u(K:wFkBQXx>Y,<8YVkcF옯nQ.>*oVr͠X4ڢԭ}KԜΤye': JR=aC.k1ԇ>8ic%%†1Ƅ^+1U$e<XRmVSO_j8yХVK߰ۮW: *M1X\"ծW`qT9:KSjRʱs0 ~ )F8J50q*HB*KR7Jj{_mENu)(C"3x O8$>guO .|:|w1o7$@")a1Y&^Ʀ &)Mtu%,Z7tJ?TF XyP2J>TeVx&T:xyciUqNYөS0Ⱦ"t]kݥΦizm',8!u& j^' VIu^mx\,+F&JUBWOKuyeMxGa39ahG1)*aZXCFR7R}^R*SQxK8Pj/ak +qxjwiQjKY~°sEKmwBu+sWTuVrxq "X5 N_Su+WGN1* 0pzXN*Ό <.+:q ԧZUkaab5)УGl5Hb剧V<'wgঝg;Yuz֗xs‡ƞ Ҽ_Wj>+%ɵ+O%7s:y9UqNbӫOC4Q^u\>PVF aUJ MԌ)kNQJiM((ӥzΒUkѭVuR N"dTdU:TեRNQթ5rTc:ѫa=lLpsO0r*e)I*2nQ)ƔRpb$F)S C E֕(Dk-u_4x|Eg/[sWmzINN.b-^4b-RCq1xkAoBL<1קJNY)hON5{ƬtM)#%N?oVf{J* ʋ!jkY+5;k󿅼cox_F].> ?ό_6Bo/Ō|=siDŽo_Iuc}s^sX<-2O$x gk+o5?LsuPT, ٳZ9f q.# NFUaSß,Ej4'QaFVr"TP|D(jSTcSU_D>{^$4-3jZuη]C,uu6}~Zׂ=oo"SgX1j=%aJuiV(STץ cq+?Me LhFSFW/RtiՅiZRVyT񘖩fS?v=ž?6凉gy>:Ggb >3fi慦_>̰M UFXzcV5~Qb#NU]%;MXNyQeRÕKROZB ~u())TNQT>XU:r|Ys>2qsڬ aݼ6FW5/xP ׄ<':ē\vm-j\/baػQRqV24Ukش^"068|hO0c^Ir`cyTyWԥUo: 1T:4 |)xčΒuAR%) ϒЛx}_V%eJUW#bb'F*%V^9䫫_Vx{O pvX.J0\}0*QqD]&9G)xMk_ ˥OQ +[^/xsvCil|;UJeJB:ʛp ^p`^eia7_Δiҝ}dRRhT xXTVi„0(^VRl$0I.qfn,OjNGM<\^|PTσPW`Ɲ,wz^6zaaSnTJI,D!NNpSхF]\bib= __1'ֆqR4tԪ)Rʜ\S g+?eq,u;)oʉ*:#jLRseYN䗻[ a%Zs4[ J-7-x³"U~mI=Gϣt?Ug//,?=_ 7CQ//3G,_ ϣt?UI2 O|C>Tr%?=_ 7CQ//3G,_ ϣt?UI2 O|C>Tr%?=_ 7CQ//3G,_ ϣt?UI2 O|C>Tr%ឍYZk~(xO{j.n0xiwJZv<w无HtK{ٯo.o.oApL+#JZ2*>%K *1ӜxxS |)3>PliƑcJS4{?xim7 uS0T\ZgY:Spܺʽiy]]G/*Ч%C5Z%Rtip25J3Rt5)e*XuJWO.bJ"9ve…U8bplKEYT|+eN^kB#,wd)ѧbhT¶WbφM_k?u%\|Q7i~ _ioF48֦Nx`>\:aSse**?]<5*VL-/-6pjRxF8FcC%G'ϵ©AC^3+qPNeյi:RcSTWUB:t(Ǝ#Nt%èb*ҥSh :g|1?L';Nм[}.G~Ӿ>A=IO#T uO[|UacFaN"\.aԔ/8X|+ӥRe:Y|j%ERXʾVX8OZUn?VFXzUj:V,<+*JXG 2gПXxszχ|{zˍy7N/U/4u鷷tbW7ko-#t/F4:V;2,F# סSVjNRqf O l=jQR?\%08(OV.热*tkṿn:U48|?Admu?D5oiuLjuY[K뚮L洂ZuK{x.u-+JM.ǯ0 MQVytʼhST/dʕQĤJ. J2Wusa5\iXxԥR^"B"*_cpxJ(ae90RSoEkZmmCᗌ~C/^! | sQ]H &Ö66\:ٻ)ԧ/ ]pXp%:LE:uYbROz-T,<'*`TePЌ8\>U[㮙S7uMN:Hj:ψ|K0ï ,b-bQ ԅh8פb F4rʪq*ԧ,RujT+j1a(Z/|O /:ԩ敥%*m*ѦaylL>ZeXbZ+S^XF u)''#9ӜkΥ5 5iҭJqX׃]ڮ/SxsY '^.<=χ? {χ χu[GAKAYg6/K|Kۢ WBsL&>*J1:t*ʝ¦/3r7)rb)جU n/K97V3 Q&Wx a^cƝZP1Y~ 务5JSO^>-]Q6>B:<5О/Լcj6x9,&}nƗ0%*0؜#*qF7/mΥL6F0֡ZuJj:sĝVGQ(Ӗ.1tZՏjT%WF59 Xh?*?O6%6'O|mxLi%+oi\TM懭PǪaIYӯFXHӄqW~I N9hFE:\(QX<\'SJ0JqyBjJ6Aa&U4q)œ#JPse\E ^(<&[]5>?Le[:ߊuo OMN@Z ^IJOdY]F;[GP}J1QK0 :nS "i|g^߂|G׼?3 G ~miVׇ>o\/IVp*bXJ%p-ͭsbv;1/gR߱Rӡ͍NYS:XXNgUs0#ȱIQ>"\xiROԥ 3sDZxw_Iռ-LNV?~ cZKVEmFLv-<+ K[uiWrτl<+V,f/)AO WdNZoS ԫRV S嫆> ª`#爫V֭JTNXaITԕ:4N*ʴaOޡ6}L5x[OZ߃mh~խ5sßZ&hQMq{ɠScˢIm /C 5,o:hС<'M.LE$, MVX߬`⣍㇧SAM7J}a1sJSitfV*s]kĿuCB "φ ?7N/dQP>JO] wNuq-%幇0WB*lda +j|JUq8BpUE1 8| ١.\JjUԠ**{t]^zuSu'S:XʌoGxWoK{M&_ubwN8Rb'uw._q$v ^*J %Rgj1TU0"PgEJ9ҚO7G :D-1/?D5ƼgtunU-~-uDtI/'ep[ig7b7VJ3KF{S[Z 4Ln m%:ڍ^j[4?[ a,Cg@{zji_}I|u:|7cPH^)嶖t%{{uyt9nQ!`BQ$qMݝʤkiZKQVf@-'5ئx+}c=@5O o=ċdmm!i88Bm(v^Qz5T0hfռk7"x|56Eiu/RC 64W "O :teQsGZ.wޟӦlhOX&o4ȟ{_< mi;^6w&S%*}ý ,/G_?%(_ $s/}_ QA9|-G0rZ`aj9^DƩaOjZęou(um,5:mJ)m2[}g$C%$N6E//l#<~> l+c2 .SI7<0x/Ő,kiAЭ މp2a{{Kv4 EjUzV{'4i k1DqxDZj#D@W/(kE͊/?/Jkۿq/㏤8ċ[XjS-֗j}ǿQƲ{9V?iOI|so(N2%ySѴ;nhk'1OxBόcv1x=CY}-m[[{];f9dE6ɨP8E\Ѷm{_߽dv^~*m:_ kQmv&gQi2 ޥ[CCoFE卵V˫Z'}wafֲnO|̿^?LOoV??1Y@^BO*YaUQC z 53?AgهkgUG5ϳ/zfk_(M?z >>ׯп_#}}_ƿFx4sx},0^BG*hYaUQC >UQC >UQC >UQC >|̿^?LOoQA}it>ׯп_#ׯп_#ׯkI)p9/ׯп_#ׯп_#ׯkI) _}^{ƿFxTsxK/xz Z^a{UQC/ K>ׯн_#>ׯkgUG=]z 53?_}z 53?_}z 53?_}z 53?_}zƼԙ pk_(U??z {~UQC׷k_(U??z {~UQC׷jiKY([TߙoN o&޲jVUIF<խ]&ZߣG^t_/컯 E<%alt_/._E<%alt_/._E<%alt_/._E<%alt_/._E<%alt_/._E<%alt_/._E<%alt_/._̾ /SѮoĭ}(gLмd~!+3]5ͤkN]sk>&v JtҽOHF/kTD4 t𗄼/=62< 񔚆ȑޯݧ횕ǕgEG 0tFT!(߻m Jm^u/xYN[oھw}Xۻ(IbfhDWM&׺]"Qv5uOqnZŮ ͗]Rh'(g2 ܫ ʟJki[/Oۏ8PPDfI4fYeMy$س#%ى%$Ivo2y#Dxs' >g_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_rF9@ V?bg_r-ZiN#Ma32[K+ki elĬP!*N2 1QV4i>#Y|sCIsWu_t/ƣ\ΝӼ7y+hn/5*XZ%jrd5\6+-\e_ MƍcC Q|5|ezjTV J [JTgO5*TДNeO爔(O֢|ï'g+_/|>nCaxVŰh/~"kIau/t}=߇[Y5p|$jՒ| "jXS䛪vgF  Mj0n)Qrz|N)S:SèFiVU8iT,( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (~h?~ .sx~}_V.Eqw{'Vk ZxMk"jz_N\-YԖ'|,k;!RUYǒuC9bhSON:1Su*QIѭ=jmʥ(aI*g(SªhѫӅzS1}dOKռG?IxL՞~"%"k=Kڝ]>FO6 4=Bިԕp5)Xbp<pwRiE̝UAN55ZQ)GII7Vwl⒳40f6o;Q%'TxtuYQl`̀ ǻBsǓ;:VMj3TAE''5RPNRࠥNRP”Һ+;Rdo9r6TBw껼! ,ͤ +h]ږ6nbS&S7|);;SI֥kr)^).{'nNo_6KM#KՒ9 K*:0qZI*2D`)*S~ʵ:3NR]ҩSh{|,(TTV${qkT՝:74ؘj+|ve4Q ql/ӭDۛ*m$U&"ӕ/aNSiF~ūhƵX^jdi ;Jg{.PE.(ŴڳJWoOռk3[it0s d--kyG%A{O{{Yb+M/V$W23k 7ֆ[Qm(2zI^F<&&aiJn1SgS:[[(d8**#ȓ&jSr4ϴ006kwmV1dNY}*)S(*q׳R2\ps\8ӜTڲiӨujMɷ81om2Ix4H8d V/Osi7A,伴[k.c<~@! byStUx)JT#4$Y]-ߛJj.kr3qS)FRA72m)VGX9mhёE]qa8Nj2Ogg)%\%(I4Rqi٦erڧ|?3 -tP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@k˧_M>VNbhwYLX̡I'oFpV+Q:&TDN.n\$WVZNI8gk_iꚵ|TuZŝ+sw2;XbMS^Sۚ¤c,W+擔T`iS{F^)%hÕi͸hZw:%XȮدb[MoJ]YƺDp%>)ݬ4V)Y'T)ӧEӋpstsjjpoZiI]%,]EO.T6AbSt{o4ȮnRk@jq5$IЌʫݬ*J?( +QnM5ks96*{]2ySN}/y.UҊMK2_^K ey]}.ǗY}w͟7 ya 6h;hڥaKΕ/'-x)7-T^^ܞW_C቏(Z / åB$ ]5)yld!Hue.K887ӓ&MF F<(s[)JIKߔyiFN(NN6NMݶG)m綻Ԭx_D,dѣ[RjXjP[;)X2TOZo:F`&Ԝ.jr8|t(TJHͮy.U5F rR傌XVtBOޔrNP*)_.'P\ .2xvOhN5`k}m.\+VU,`,coiO;#NPVޢVTz_Gmi5_^[_ľu֯Ji]Kqvo`D(4U(ϕF9rrT:k|/,悏c?ϋ}?yh(0< =<>/,悏c?ϋ}?yh(0< =<>/,悏c?ϋ}?yh(0< =<IVRY7sKRCY#Tl.Nd6( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (+XtO>VX-4(ߺ8aZRV:4Voh.R3Z9֫ 0"ri"Նa}^j3{{ nfCѡwEub)N' t$תvhp*EN8=5t[,( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( R=I=OB_xþ0׼+K El"U%ԍqq GY, 8d9<]uPR1rP*Rj2R:O8HU|Ŷ w~dNo:ӥRjK#w䨤2IA151|rkf[%(5iH77U#G̏/Olo( xX;280\i[vk46Ǖob^Oy:yU,Bu(3ʽNyN]aަ߱J%5BEK=cAGexLN#QE ojwZvcğl GoW ^|~.e•V8%qdJNug0N",VT}L<6<NZ:u( (RTע4RBV(:SAqN]'_- _Zvi_M#x{>-[ ]JS1k,WwiC˪J3UN3*XY:S-,^#93\%W R|+R^0qxIMOgs)b)GN4ԍhjaa u+hx]OS 𾔉{ÞЛ\sǀA. }Z?B8uټyuҌeSU f\q0HRxOK *թUbX,e<;JW:xJ TW[ %)B9UqBTJ.LT?>(FT>+Bյ >Լ)_izÑm#Kjp [C2^fYdu#8YW`!Uuq 9JWNtE+:JZ“K)IbjRp4ʍ&^XK_5Na*+?Kǖ _]o-=CVhQΑ_]oGi/ts&㈯*b$#,F2.RNΕzFJt) ̪uRx8ַcnMOWnMU?ifӭ-m( mR8(*Rq8JJaWBkFk:|]픥*ݪStkW$JP)SJRnoW|K<^?c_ͧD+xÚ ~-MiG7s x~rH-Z1XUiRŬ\)RRb:橸qYe*_Vq<5էy##ʟ,Ɯ*ԯ(G7NFZx''N}Kx Iȓpѥ:ͅ,f١XS CHsN)aJJU)SRZRGFRkBuh=*c=RP*jUhRgNe ' J/e(r*K;t9@+7>/]:D—i:[Rӵ xNĖwOi4Z,ogr%WW8K|SNUUJ/ :qxTAugIғrPjT)4TJ#YM1F2VÝ x~/,-m c^4{+h۝' ilm`b3|ȖڡRf=|ҖKڨүUI?nUa*{R<%/UQӆ-Њ˪T1QsXx0ע'MXE|5#vԮyZZYlک^It<5\<.l4hy? ׃-O j>OPl4-"XM},V1=ĩmJXEy:qJr%[7b}Fu18UO Tp|-((P•8E_ޅ ڄkK{ʣGcKS;{;[}˷i5|2Ԧ5i?u e~Ƹ@]J+UZS[O1q|f eؙ[5]>_g䏳V=sFe~egŸ?^%`[X{_M+wo Z5߇|+mm.-cr*&N1Ռ0*PjSjjJ^ʟ-o.~R9g+INZSVRujBU%Ru*9sթ)z5HP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@m ikjB&Nl{QݣIӴ Q&%v)Xgu)Re)QN-U*87fsW1Sr#Nn49%u~X\x{Vm$E{Q=OOH&XȺȧnRqjn2^2 +QjmiT11nE5$]8J2NI`nP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PL$*Oj>1}3GӖ:;Y}'UQcu{0Yۧ3Qҍa:zYJre:wwjhySR_+8M^Uʗ%K+.y5> XiW߆:SG5/YxLFv)_[#q6+Yq ljʓk)Y/k)t٥YF ҵHՍTB1W 1mhM'-_ x~%y^9zK//:}0y1ЫJ\>*JTөVx 8 T=qi F* EbcJ,Oі9W8ȧ N4'VNVYFT}/o:4PW]< ];RÞ,t h~46{'ټWj~1{Cui->\p97RTSJU5V<3*ue*Tp|1FjKFqX\L'BJ9gH|/٭t+k"i'Wֆ\iOˏQ35HL JMЩ T*5Œc TkBxV,hʦZxg9ӕӣZ4xyrڞ"3\-ZghPTiJsUO 474|9k,~Ϛ+隟HuyVZݵŃM0Eo78N0b)p,6T꺞ڮ5^q)Ji}_ ᆧ*S SVnNJ9M W8T:* F4U[a7NsJ9/< )o%|F/ދ{owzKΣ>[eM_KtC<^FYqt/fؚTb.Q,,jFSΩF'<5:j0tK^^5e8\DQŷ3!5ZXxlLUhG-͜4)B8_%t|54wĴɜ z}rȊ(W$D|Xl4:~xLe:YFQ^4c+7{Je՜y+ؼa۴y8)1zlt Dzo O΢<hzf7_m>!*@ӮZO$j[9:j˖"רb2SN3J9UJYRS|Uj%;`e*ЫBt%~? j Ex]ZK-|v&L\)-1*0 ^hn3NVU*Mӡ4VӕG,u?*5heԥNXՇ[iJ viѤש^G SꕧSGjZ xgHh{ zi \j[xn./xDcէЍZ*3X9dgsuЎ&F -BJstQp NC*EK \*NzpyC^P9ޓsƨ|c,mOFZ7)?,~I6c5ޭj_A-> ~ՄV2'7WVxT[üaFx dc(*~Ug_T"T1&?ST0rPPYNb1T$}RøRL&!ڸl~*KYmoŞ *1X1(T~N-˖nsrǢVf@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@r:-hCk^ #/:YiB RJ?c:T/ŴQpNk KTwE<̫bjW)•*WN*vZOg9M*qsVTݴJHt`ڍ3φ4]cT:O5N]oZ4 hVƯo6jv s޳]O$j\ԢNvۣ,3m'9FP\k:Tժ:42nU!VO>E gNʚj1P\G; p/-i~o<5IDҵ].I#J&=HJ%z!]7Wߵ\DrMRZN=9s.NG(ѕI҄n-ƜW;hJkJiOI+ >#Q?K@ X{7siWwټǒtվWgќ*b9 uo%)5%Ri+,~,**^S|הOW4f|)Z/ x{Pά׭rEn-MuE "/Qk?4+v,yҥZ*5ƭ J#$t: ){N/$m':sJs*T[RNi+9{H7 ݾh]6/|)]x4{_|6= (wu4;y9 մLR5" F#])88e?#3u#/mNhԔ)s]M'&OxHrЏJ<䍩Ar܍}e/4ټ[Yo_QzWxE""d]R-&5K<:ۈ3n ү U74 pv)ҩV:q8Z)¥jR6q9Tu\,]WPu\vu(QhҍN um_? m_-!FֶV6ͭ?"HV+PW iӄq89TRXv?{C*qJ#B*~FʹR|:e~)gk\k־𮅡[[z{iziv$:S5jgc 9EpQJT)Ǚڝ ՍyтJUҧBUc94IիQsԭ(Τ嬧898Jrwr\)6&wlt .kXqyx6@n 6n.on.&y$rL^ѧ F:PTӊ0a$ڜ'R{Ow'm[՗)P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PΞѼGywxOu|s;ch~m:;+m76:Vk~-8xcmӄhn$|<'SSЭMU`4iձ3ujm5SƾYJJ9aS SSbAfڴ(P'(΢:zÏxOvz>O_oi k2/:Z:I{Kn\?<9,58ap Wx|<*x7Х8ӓZ\/F|ٞ5xlv_e,khb1r2,i^r!t Oͼa>&D q$o 3_|rk&)A!1r~8թ;ԥytqg6 PS7˩|Ğ9~2cUX ;ǓQF{ie9*+pYU\W4'Zi]x/#ԼU{XXwkW$-5]ung#U(bk3 MBk^y%/%Rl<(uey^ԣK%Gဢb="Bxfj5PT*T K6;ZÞo,ľO;MMo|Gj"icc֫yl,Kh80z8 R׹Gx*T}Y׫ cxמ&n)4Q98hJRp*Q6VJҨN-Q~1RJ~?5lz_^X.>/7Tze_àZ+KIXBKRE5yc^i>x'/g9B8QUJ.bxJ$N>FM8XU]9[^Pok^L27w}SNt~{k^7Ť_]I:X*Ru/YЧ9FU}NQpUgUa8hJ<%'*Tph$xBiPW>"դN*BFIF_G 6^(Oh}%ot\>ZZ]jw0ywKm.,cR?U9ݺ`pIU,_TCSRgxJTV*1oa*=j*ӫNqVz3{>~&(u @[C]6ϵY}_{đϦ Šw)m_XOrJR}[IF*֫YuV cR5&Ԩ֪fbsL*MGLEeR?Vluk>|_zݬߴ ]Ut붗±nn W)AJ 2\L3* JaQ؊xWtTxG JJ{(Ξ:9}^uEδR)GԤܣ'J҇xOQoĺ$^&k? o9bLW0|Q ns5լ4EE-gUy~EBj2R^yћq-H)r^GNpcq40%ŵuHmgh=kf=EZtŠ+RP*Taeew*JiPU֏Pxi=o (WUG B)QaENS=KƟ|+]r[L]xZŮ-u!Z=XGs[˨E4% /oZUk>kgU!Sc 3yb~ڦܓqMO/Xci**Zx*Pha,K18jyTT| 5O45aR;{JTW*#*ѫJRU(֌2/Bč7~kKóx;~! 烼iz֋SHӧo*E4ZƤy˪,KdMa`ؖ)ЎW: Iө(cs59SaBn{.4ŧ5|U.xR0SB^YJj28JgNv?s\嶩^!{ootJvz~6{Z6eKBm'C'5KJ|%Ojڭ}F/H|EjבCb#N[գOUBu+֝J 40ٮ+.'[ݣ%JTjʤ%Sܒ btF/c0p\SuNXX?iJI4jI{:m.-v [{{ZV>9;mS_S/"2I[Rv "%FrV>Ƭ(ʊWxL|%i ]5RqxЌ+HO K' ZU~ZyIRʓUSsrʕU>WJ/awt/]>פ:}]y3m.QG4"H$8݆Px9ќTJnҋ-n=S٢H}5*R\*sI$%ŸMZPzuP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P[Lռ5' ⁤|K'^γ9NԾ'障v6VֳZɒYWVvVMĿVxfF<*B9QХZ=,,%WI¢ڔyg8|nga3|4pyKŬ63V\,%S:Su8ӭ(UJ=3^׵/_ 4'/|7:ֵsEӴ[|#ab8x `2,fjxjt(ѡO^LNITRB)${1IT)R*`*4ҎB^I:c(+Gj?V}OKXiĨGVK7k,xhlšt0>-M[NK(lNr_XR^***s*&XE֥QbbZ5KPG T(0S:P_E:TR= knzQΆn^쓥Ÿ4˖>i2[i { RBqȶ֟4ܥTiU_s[~5ftjG)ƥ5^2\JJtSvʍOv\jХ(ЫB=t{Ojj*]xu[ |S]牼 X$O,~YyzM727J 6 hz!H|G_KwE'_"1Q<~V|*xEΤ^.1gN)p*IVOV ҽWt֔`*qéѫ:stf8>JU}Udޱ֡폅%w}'gE΁gCCy6;NQ_OѼIuAq z cSWCɴ/2ˣZumoGZ})#S V+GaP9=:j$)hrVU(T盫B F)J-bԫJBIӚZ5-k<5H*sFSJppu!% j+mdj彎k+>ew'U?;ok:IvVmcOVSSQTJRiCTqU-e{VtUs)Q,TcJT# T{*_\YIzGF4V|N#ȇ/F,7o }|<ڤ2wW^8} ^֬oaմ&Ь٣襊,\1xZ? օiS"t`#_VxB 9ӮyQ7x`iUNaR>[]ԫFGOŨǸN cswxB\-tߊ l.6LDr;q ^дmkg1㋯ܞ*)TS8UgVJ5c(JxUVH9SU(RIӣ_TR%Y(gJt:kBPdN*reNXUeCË;yQi Kv^wCS]frlu'bԣ- WU֩NҔ8Y_=gzVmGMiPmO Q(tV =+ҧƥ SnS$rmN>|"O5 k= ú>Ņ׉5wf {O [[seַc,v6JIjTѭQ%zӧEORATԜԫ0TšK֧Ut1k7jJhF4>XͧQוyWM#ZO񵞣o ^:ooeM+>>ug׼?eV,crZX]{)<Q?V~nhWnS1?, #/.|7*_ qIaT?`A ʏ8$kª?eaφeGFoBob?Xk?5UXN?r/|u8:)df)ƯWpzUXz|SixS_I4 jZi4AL-匲BҠt,]23Zl5GGFRna*sIfvۡF D\=juݥ:sHnںoVF@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PCtEҼD>>jEjQV4o]bl%-#tvQt"mrO63ONAqnmu%8Fa-m^qRPX,oNsɳ϶GҼe>ǡ"Sk{!P,K! I3BHT)ԭZqFe9rP!)Rj1bI$i"RpJRrQ")IF1rmWoDy>9<;]iv|> xG}_0/ S bA52=۬.!BnE3^/T1qI{ NVeSEI>u)ԦSRmJis*t=hQT^TOGҏe>9sWhumr@Ҥ,<7xYu7Zs4@FQVZV%\cooeGJ*~RqM(FrRQS4#V+_?+\K'ӧd){)o'}?{)o'ֿ>$-Io ZB4/"G$Ӭ9I !㼾C4{M엳j߼k* $(^JM{kK9I4g)J$ddR%A'(ڜ]Su$RTWQ|]_4:3ۙ4[̷2܋^[]M,j4f6[y~FQPt-N *Н4+^X5~Qӣ ..};EJ-=~H'JI*t[7n[n|o5.XllcVLVo勇'K?_cfwX$E㏇8e]׊'j&KsUՄ7X0q P0GV!5UpRZt+aƕfwNCgZI.̿7 ,y^|fO2Av|B#Ub.[[[l㡦k``z%y'P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@-֩Y\ًfi;)'$# +QmJVo+5T ?Wy˪= ?Wy˪= ?Wy˪= ?Wy˪= ?Wy˪= ?Wy˪= ?Wy˪= PE̸Q5|QXE-ca%$kXC٫^K|7(c~;7(5sInc`u}HjZSi;|ЭgV:dnYg )ҥKuB.*I= \*qqPvR沷S jpxt~(Τ+Phœ))Cӧr^ծ@>-V?@WG[BORy>6'Vo.a?<UOĿh/u/wͿ; Uo~%G-~' ~6_w ?x ? h/u/wͿ; 5|X?2>$胣G-~' =mAO!'D9o ?]K3o oxŀ8,_>%4r2ORx{ vO_7skzS[hZU42kzFhqO^"iK$mXG/*4CJU*F3UT9Jj(ے(F1(]I=ZjV^k+F7J'7ud*$۩&ܺ$W P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image036.jpg0000644000175000017500000005104411665471332026764 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"M !1QRTU"4ASas2qtuBb#635crC$%7*!1AQaqB( ?j*i.5w9dS5#IkrpSPYn RZ4~zg|rqu:= )gy^*rn}\(lxz9q<]^/3 NvC;jt{Tk}e-Ҕ;p+3UCƞFMP9iwd3PK~j5qn#1ܤI8 jt{SSݐ߆]+U5Q#;SigyMNvC;ȀB8cίCΧG!5:= +\2AQ, plo+nNcSݐwPGZG jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{SSݐ&Н jt{V Z:&\WWB%GaMmk\8N?vͧD tg̳hfܽ\ɨn&xAÎKG+ic5M@vFw^Ig87ϳ/ٙ gS 0(Ev|0"uܹu];y1O]Go̮N3כvV&2+uW8É*-E #R*vfc#f?tߢ/=xHe kgi'*J٣I&`!660Aw t[&K$/3pCQ3cÈ]Mq8mǟgZc1N%ap)n{}tՖys;j\qhKd;ͮ\ unwc#jRcǎ@+ls$yŠ Ҟ~w.BS~!)-[siW.r։⣩$vgaӏG_ZydҊwϻ# +̑Y&#)_!?%[޾aKAMnh}3c[mUWp^duf2\N!:Yeوִ`2scxe5)uH13ch?{gg̨jagNQQ-qaktq ͿwypV%KPςZc@PU. xܼ=("g4+ڗ2lgZ4auw2lgZ4auw2lg[m4auwNyc~MrE쩈-Fe9"aTŀA$ p<hޣm0*b&-Fe9"aTM$[z>rEe98,-Fe9"aTM$[z>rEd$ w Occ6m0)ޣ"m"aS-FeLX@ w"rE$[z>ʘCoQNH}$dFb\3/iCoQNH}1hޣm0*b&-Fe9"aTM$[z>rE쩈D>H}oQS6|m0)ޣ"m"aS-FeLD!E$[z>ʘCoQNH}1hޣm0*b&-Fe9"aTM$[z>rE쩈G$[z>rE쩈CoQNH}1hޣm0*b&_Qi6g6Dn WmGrW+Gr~2:Ly&<6TK\ hbdApBTw;| dydqюp=CqUH)r2w8{a#W8@d{xN#+2h՚jX餡i"\ `F׿Cf˰VC7;U]*R6TeōԚ*gP.:Vcq$bwmrREJ1a' W9_p Y-bQ,oq~ Svu* cbN%De`@G:::Bdt$ww7=aiDAo8n {iJ(+i)Č6&ӗ=2#xT߮c+m!uS-a ٱiQz[$ sєpԑmlLS3#%ֵ@t{ZlNccY9ώ քH:ډ5LWkYwyN>^%Mi^c%񻜙8s``yp*靬upsHVol|$89f$' \2$ cF.s fF_e{ca\ lRW>Jyݑ՝wv#Dm.*!R4b1q_>l)6exFXfz)Ṳf OHkcjsY6Lwι)MQI,m/qh##7E}e˜@* tqsĐwA`."y#O=9t UPLS8H&|X,˸>I,p:W\pxOw2s#-t!͋p\AU&{Ne<3I,Ly$Ov`w_P&sF.[D!2,x놢}mkWT'ps[qf3VADkG ;kQ_K-DpE(0̻h8X㑌Q>zysKAyNXU0SGp1S'kj`O>?Ǝ^><3dž),퍍\*P]`1cuw>U{uig/m&!]q#a;J.RY'TVډ.lf\/vcx?rTI2.U`E3/c3KAʡ@EuEDR/TЃ%;d9`\5Ux"yl7/x"yl7-J~;p+EcؿK^*"" ܈\,8dV[- XlzfɳWo$Wor$Wor$Wor$Wor=K M4lH=߆T+n74IE=߆T+n74IE=߆T+n74IE=߆T+n74IE=߆T+n74{4:f蒊7!^{q >Woh7!^{q >Woh7!^{q >Woh7!^{q >Woh7!^{q >Woh7!^{q >E=) ]nR#F;W/-:;W/-ӂWWcؿKJIɩ+&k[А1pݎ~ӂc~8SWj ڲHIxilp3fI#T |_T\5,TC . .n bLJ$/,|nkɣ҈FH[α';BӥTGrm{j RJZK 8?asTcd˫_&QMK1CH߽fF)Ref9TTyZ;l]S Ћiاtl97.QJWRߩM+<4zqFO%MNbG)nͭ we$Y|Z$Қ:7+.ƓmnT=$|q5LZnaÀT蝮&P ,q-<ȤS6G$ FH^O`M"+fy `lƟ+OȺg˯\f\0-c/Ѫ i$n`d1bN(n.v$A=E[,PO,bb~(Ƹ8ilU:HsZ4ÜnA]eZJ`u2ZN%ÈOGmTcֱqY_*֔,@e}C&7K#w8 |DPt3L!u+5vq]*DTbVo89v=M98 ITSVZHZW(`u]\PAD;uN;~#)T-ID㨺Y-<+h1n1JZAaůtlUM>\j kֶG6Ƈn@޷3Knr:jTUt(d$7x*]R*&M9{}Gh-a٪01kl4Sͥܥ-H$sFH;AWʛ'I W#Xz9};qY WKI1wش`} m'꺬SH 3 OE;zA3ސMyސLސMyސLސMyސLސMyސLސMyސLސMyސLސMyސLFtoߝ Րbv4^'?wȯ_[?!u^'?wȯ_[?!˯~TV?]]=$URbHfX܊%CvcAP& 88e- ev8e8`,q8G2p;AU+X)7aT:{3ji^d쥸j,v8~ z rpZ Ґp!?yo8Sg:i\5nRΌ׵W;OgDlq魛?F*׸{{^Muyo8{^O{o4Iޚټo{oEmM; PavL=1ſrC3sE{eipM5yo8{^O{o4Iޚټo{o>ʷD'[7zkfQʷD*׸{Dlq魛?F*׸{{^Muyo8{^O{o4Iޚټo{o>ʷD'[7zkfQʷD*׸{Dlq魛?F*׸{{^Muyo8{^O{o4Iޚټo{o>ʷD'[7zkfQʷD*׸{Dlq魛?F*׸{{^Muwcip<+Pm3 lJC2HqsWe#& WQAvFE^&CC\1Î쬿 ^*w_;֜_V|3܃n_;֙{ȦIFv/uSTIk~'e Us|ܾUs|ܺpJ~;p)ZI[)ָ7& ́yT[\ MZ9 +ve}DLkf'6'HssF8*EUPjF`G, p11ʾ  %$p3C;] gm(f<;v%N(櫤5)@iK6-1v~8 g8aBZ 'EVieD׸c9Z #jqRǔi˿p]x|mtŸAVV kɓ#bx$a{fmdϫQ9o,$y2!:v91y{\x3⯲V,P#7(y[|VoVxH_ Oj E\vZ6HDy qcC+^> WYo l<-4Q1֎G,Ws׹ꪢj֓#sbxpZsHjEgܙ5!MppkS7]pq^u1Cm\3>9dž8rK?)JUwֲ{͊9iYkͼsyPGw7W%-&CU 6UU6CNZ1k%wR) !G_vON  ݽE=Iƥ2IZ4xy}+寒13oCӂu110kY S [d ୩MƒOP&۫䎈ꫨC@k$h$FW[-j "F']B FAvHďltx{8HW{sE] .u53; \ɂ]//nLu+#ԶƎ]0Ty!}$+rR܇)ME&J F> Djzx#,6oqK'!}>)GQCHwG#d}!P*(d}!Sl; qM>($"G6C>Hw#B(d}!Sl; qM>($"G6C]ſSRLN'JSUz!!%1c0ymqEIStyD)q Y7ܭoTTRC+(&Rē.-ߏ;VkxӐWF86qG*L5M LrCKx8Qj;jsc1ӸJ^g3{,꜇Ѹj[l[ZLrxIg1S/M 'ÛTBhVȤs@T}XUx"yl7/x"yl7.\ QXv/VWJ[V6;ò$>N+7h/.tp\zF6If41s9;)RevV.cY誨2RVfvkwcwWVm\ /bF8 ȋ$U& 59q7~dd5͡&Խ{10('"HlP˄F(?8 l[j9MC ɗ`2 ̷k3gO EM⺓J*$㉎nQO~l1~6u]qIu]qKU.UodP: +DDN<,.UAr% A.*N.>9N.>h-gܫ-A "cA#V1.<4@'ڤj}}3M`FsT\N.>9N.>yӑrpk86,~ u 8Q/EQCh[Vdk$2@1ȯ>~R&Wb\}rWb\}ҭN"SM, ϝ5YƵwC(c:a\Zp xqL[N.>9N.>^.smBjgm!tkMcswFzX:ĸ:ĸ[Ih"tLe9nT˽Ҷ("rdžPp,N8A;-YeDSKNSKR,Z] 2:bǹ&f10ު%KB RI0!~\5?fMqAɺu@ׁg UHkAUF[t nnNNկ5uEEuíc0*NaXf3]7|lvW<ʯhu]qIu]qJdHڤe9N.>jpc#jͪ>,sv.-)k!:Z^'uCZ؃N 7)u]qIu]qK[?+F߲b.c˟q2qYhII!Oѻ^\1;ayL#K.flFL1+U^y2 Ym!ck31v|UؗtUؗt&TQ)VSE 3}@ Ǜ> o4QG3XYķXÀqVm֮9N.>9R.>l]#eTGM9fFr|{4lC. 80;yR.>9R.>Fh5308B=.{ r%N.I;nNhc% p"v^R.>D:Q Ip#"4kiַL)swǎ p8eK" `} %J~VK}ښx@VtzH;Xq@]2).HͺT=T-CeCaav}AVhdp v7KMn$+MEq48)iNX8*{qlr>hZJσ'(L l<]ʦ:VTw^üy[\/6_`GFoWQM` 4vlTO T6[78sk&7KNXϨnw8=%uMϫ"Pa%|n7KMn37hU aͩ"RAܠP'tukG\ۼk&7KSitb<)Gq484'nvICWI,H+$8<qA^_mstj:`[\y57x-Sh&]}%²s#eq-9Fn\/;MViC#L8㽸N{hVWQYS;Z>Lŭ1kF?ĭ\/6_ gF_COE!ӽfh%K51VUkٚ3EEܦmst QaeU|/|k9usN!0~ 7zϒG< ~7KMn{Ei ڪd7Hib)|{ъAKHs/.xnOrқl '6.mM}e[pӃAujM~;/kAJ<`s\^ A ;j3CLI;8ĜN?UEmEm:6[)N;FhVzKMǴL0Ƽ'?NT_<~B?NT_<~B?N ]]b.{q8~*~ݥmϢkGw﷏K6<,s!bOKB*K3ed{[mcyؓ,ݴԍYdu.G1 ey0's,..KO%Dqe"1y#|Mpbb662rep S 88.>K=J[h԰g1OһM(gO 5n~GB;zW9rPm6C[tMdcͿwaoP]xDr4"&X #M1ؠH+"h"6WYe\˧{{PFf`xb6]E$Q26Jq)\j9j׶עF<ɑ]i6OEW4O !cُјvಸɺI֭Ót[(imdnqy4p: %ViަPS#3%s缳<"SV\j997Hջr Hk*ͺڸD$/Ւ4x oߛ̩鴾4ՔT.}U҈c% wȤWCɺI֭Ót[)T:J*;1\[k^gm#MCn.{(f8$srnuw$Va . gZ Lӈ-D2C8$eu:[q2 kq?3esF;7I:ջrrnuwM%RTSKBN;uuu[5mT uHx%1v˸?&'Z{NM>n[CkY "jʙ$';#!䨡5M, %c@0 i7%_^rnuw$VaU-m 餦V:a!IK,9MNnj9th97I:ջrrnuwѢst['&'Z{] 97I:ջrrnuwѢst['&'Z{] 97I:ջrrnuwѢst['&'Z{] 97I:ջrrnuwѢst['&'Z{] H䜓0o칻es-UL.!v!qu[.zէ[T'p?Y%]K脶z[8+7w~P9!,gRuX}PtcAꂵY6*N RuX}[lTVvAb'U݅hة:>&IaaoD6*N RuX}[lTVvAb'U݅hة:>&IaaoD6*N RuX}[lTVvAb'U݅hة:>&IaaoD6*N RuX}[lTVvAb'U݅hة:>&IaaoD6*N RuX}[lTVvAbjaSB7y_TH ъx ~9"8#odV60x Ol͊Fe`[]&RyTJ;W/-:;W/-߃5v/W~YTDEջ䶭U>+7w-PzUV=PV ?*" """ """ """ """ """ """ """ """ (.kwIy~jr?W43m^fnH|I-/T+NT_<~B?NT_<~B?^ ]]b.z~;p+՛DDPjY[KjSz|Hя Uhjj*" """ """ (m1Coܫ EOݗ+{x^'?wȯ_[?!u^'?wȯ_[?!˧~VMoUS7&9I.~~KpOI I;ڠ6SmH/̱ͥKJ\X;~lHqYWk 05bPucxbeG*0]4!BDLN$ }{8,0Iό4ocx1AX^n:ث%/`{tv?tߪ4s7o^)WJYIqFOYRj 1i`u:WYMnCᓗ0Yt悖Ӿ6Zw58pP{+ZQV'DEEm}P`|uUX 6t)9&\֓;9# C5U]7&UVZXA ۝-aK)toq{ۏH)вPװ=\?+x)H A>Z" Ǯ"fЩȫ_,H++t5.tuum,]PaOdHVbnw ֺث%E-+3rZHÏR*;  4zsJ|,ۉF9Èk](Nq\ʊ{u(=qVTJ7?Ӏs =}:JQEaDCe</Dv2[Mi(&|A$nR;VhrVj 3U?p+b o23[L%*x"yl7/x"yl7.\ QXv/W7ʈ""" """ """ j"-" """ """ """ ت1Dh_ryzf>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"P !1"AQT#2Ra3UVdeqs$45BbucfrD(!1AaQq"( ? SOi$V-k32e@rX]H]{PS dpƑ_!}C!ҸnNRvm.[]ۋ]Ut)bNbwڮŪ5Ujv6oQ.#9A<1]`OUI.;Ru+x\ܩ{AB uVf7޿.{mm丸!5,HU@I=Z^jA 젳8H{,Lc .u#?)3_?__״w}Mk9~!3$ @ӑϥ~j%)q'eD769 f58%)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)AOT|l+e\F"w_uF-6J3裠u$$3YVh_P$@UNwAOkR_>Q]9omB]̻3/Er讫dx~_?74 kSSTl;5o!RݙrAs P+g(Kgöٻbsa9ro];J$ԯljcɠ}S߄~ z׳IHFH#Gv8cI88T_j4:[8cj1W+lB0="O_~~>LC%Þ>MWԵ;I+7i$U'G$z kUIWjl1G4qȥe Ɇ7#:e喏nXk$YiG=YVeڛ-m3,Ҫ'>@ɫXyar8厴~տ}{|ZնմHVHuDS9)vO-$7ƉjӪ.HOE=<>_}[߂uO~u!]Vɻ\!u|އ7h4Df,+E 1!ϝϗ*'Sﯾ\}_WmY N"%mE$! nR23aAGałܠ۟ u]fEK#3SU麣\CY+ߎ8q頓?5uՋ OO"itkѶʲoQ ukDp3ZIBbbvO,M+?}}׻kIG{RcDiGε\֩g&YY9#V}_/|^u]{M`_]tw9#9)Qu+mPH۬bo;g_ʟx^?S-_LèIv'S ^4o忶Kr[$e.rG# )}y~/P-ͮ,~P.n 8Uyuykow{nhӯ9:ǠXw^ﯽKFZ]pvE pӑah[67qnFebVqOR'[O}sӾq&iY#ީ EaIF,9xEx]kI{mTi Bu-"`30149N+{W5+IdHM*ː2y]|Sƣ5vEC Ddq8޾؛]1VNúwϞqkh4kQ7v1p1˟< }̿ٯ2fX6QjV]*0,\pNsyTK- d]gOkHc 1zg.qI'kR^IۂNykjzZ5!7%w-,ZRWzhķOi2B*q#0]͜z\ ?NvZ[Ib7ŮHfRdcjZiB{K#$P2d8 =9\n \k wq-Ŷ۝a2"8+`*1yW{;ڙ뢍\[@qj #ϐ&KȮ`k>oqp GpL ,crW^Vz.o۫%J7^ Mw])yjrj7"lO3H* m Apzk:N\NKY^IpV8X0Gi eY/,*܂F꾳 66Xܼ$PJѹ.:Vw+ٮ"ܴC{*R,?'J.o=2 (fVRBH(s, t[وGo;8YN@c@f}n/|4&+Twӭ##!ŷUG4; ]A)%Ԣ"ǩnٓԝy5RZ1h$ Xs$'VEus WP NA(CF8";lg[pPۘ>[!Ҧ:L$,^y uUpUAǚ9r)ZK%nMM;*  gܠwZ_ZCm;\ܱsu`Ǒ9鯑ht+`R]nѱEOe{%eQ#džT7%vls0vcG8Gsѧ#9 -kϢ`rSMiӬкqR4fgCT}5[P428bX#r(P bKm,.&%"2h%F@9O:fcodHk7ضuQ:6݋O\RW3 ,w(8e]iaI3+Gs$d:]69n\9CG o+}@\LE;듃F]3`2fuY78E(@u,@ܹ>bL,heaw#B(w Xor [8QfFf;#/< 88ݜdn?`zyȫ١A@vgJ 3? .euC?O8WZ]i㍢@oaH.QH! hw;_fv)2-]XԢ<MKֶ)AA4=5mDsO'e8ť Ҷ)AFF`F񣼬`͒Ė$99?M^((((((((((3uԴhfc`*3G>;50(|W7p[҃,,"0B2k[TxcȆ.0Wh“'%j2vOTI,B8 ?_:)KNSG3f+*+7)k_{|H Ԛfͦ:c<2Oc E(bUV lw WeJ4,ZInL[+cFGMֵj){e+2%Ű:wjBȳI*5g$asGQC_RQ+iôo;:2?`OαmSO7cه ͛_W>'i :(t+3}4JRxC!,ǚr9g?c乍d#]0<"U <sַ&D.$ f?)E2 +VT0[ol?۳ʥNMx_cty_nSċNg_Ň3PEٛD3%zyJj|snG$Ӷmdʶ|X!RxXQھlM ( menU@>IHO_!G6~zF%8"͙L:HaAf7[5֩4˹Z i!%L3Ṝ7}j^bPXI>re}k쵪lwvo!YD- essH=nQkX&YxRHs,ڧ%FAǒ}NRMf~4rdd_3|-n_Auqec}uomjDEuT3qXA#c6o拒F[nB2 G"3:-{KuY*nRp+S0GIݣ6ͻ5nF#|<Ҽdvk춗KCrSȀEgndve;Q]3B%RIFa$7VѸ셭ȲjݞWK`ɲ6X9_3w=pIZ:kEW{qU ף犝/j0ؿ `tSQ\fO \`QSrd%o.+XHN^r2p7 H;)m%_^^Ipcq1A&9TT Y;Y7g,sx\4l&:,cdAU"VQ-:MEJX$ |NF\yw'wե#x%iY:bzO2#>w;0(x{1vrAĎ2KlQA,XG:|_V}o:}&3!\H Ü0q:;Kx @!s<]1iZe,$N_X6 ܄U@;Jtx.;|q@B?.c}58φ,d'XU7#8EFNF yfKvַrI<`4 9T``*OZel㛌.n$YH]ޣy`m8vfɞ2Ϙ$yL5"/ԞY.-V7ƥcV _DV!hޓƧ{GH5s=kԂ9m(I|wps>CD5}!ڸLn'8V{GH5\+CGkgƗtTa,iIE$7<.oZۏHouAW4]:M4wE<в~YNP91R]m`v2˘#,8hXdeu9 BW0i'ҸQjmf,P81Rnr9b햟w]Xd+4͸DmT^ά>i\WO-౹I;DXsr0;ğ+䏗475 f4H4d2 Y~39X?䫿?Mr/gK46S t66!$gzdD`pϪ/%IQ#`框#: al+vOq\n,^{3@HE$cy1V}ͦf5R}2@pxરž;~F.ͦ[7iUTNwRj~p[_]pp9-l$b 6GAV^ڋ)n't1l^6~WDn#mvz{8Ȍ=ُ(EqV\^!3#^xIYhTObg)Ԛfnx S%;%n Nw[0OkM"Mʻ-5 9,,zs^VWo׮bFԭ7o5 6EXpOɍ_'s몶^UkP[/p+l7C("/4Ejwp; 5ݰ&ݹ~ޙz/)=3ClubH&9 @H*  j橩EC V2-g=nvO5Poׄ73wcmJ8 zantWY- TbCSp.8{KOq:+sęu6_n{UgŰ<7~1692wrk;/R*TAA=K4m6_n@Ns :}5cd8r k[\O5Ԑ)P)^$bBH'A^;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5*͛u;6oRqټSf_A5Rմhoʲ÷z4nn|A6oqټPd|< ?SFYµR% a~_0}j)vT,a[;yQxϺSn҃/,qs7 Uv:[7a_\MM8Ov0>F! FֻkcX3\#ˤEuo6hi%IPC2=yni%~ϴ7ĺDH{0L:@ ϗ^X9Tip.1# 9:J7&9e`+z3gwg-GH// EYVM"7)@!ytn]+bV]sd2d<^ y&sfȳĶDj$WRaHR1מmYv>KD-:8"Ń.VEb&l'I}݆[iFWi A$GA_4JSw!c4N )Akӻ#NozZ=lrW{e9y=c-ޯ~-}B=Ʉʕ Bw |5۸qvz{sjPG[qwZK1-0@0W< r&ucK4dz|P[*o%J QYe۞&"qw}-xIFuFw!=G>&Mwl;4D#fFCK^ˤevu!$86$jFJp V#?ݑkM͞3-_Cyf#+sG æW'y0vA]nIiH֗NR9!a4H<9}OEҦҞRT `+u&UגW$Mƀr.㵸X u:k\%͜1NZػ7I J2+?ҿ<^ڣGQmȎna[da!Cd`'::ݞc(l\K ye7.F9ҽ=WeT5 wGeX-ZGn.2\}Z}r7qs0d4..x~n1VEC[87tLN%A̓UX1{' }WN%7;Q\1ۻT]sd2dI{' P66U ]29&t}f-KO[5;a +au"4b4ެQJKo\n]\<8ɞFjZX;GyԆ6opwV %`UWoSͅiͤ&w:xWSf9&r">@1ԩ]}xIcc\\)Sp}G\jD;kmƝ߰r?cKѓW+I5W-AZ ,/efKy[CؖĀv`j)Jn¿bn¿biv:- z H$EX%BcPb6bI?I95 R R R R R R R R R R R R R R R R R R RMU5C{F7Td36x{(idaԎQcOCG:}6@xKOLWH!ĠːK\mϩj'm9~<1WHQ"6!FH8S_;Dr]v0`F71-ϯ,|~1[m,[Bq,q<++MjL:Ms]%@)A WT$R 2*>kbjT=١;C P;_fv(&C} S4>sh|1NkbjT=١;C P;_fv(&C} S4>sh|1NkbjT=١;C P;_fv(&C} S4>sh|1NkbjT=١;C P;_fv(&C} S4>sh|1NkbjT=١;C P;_fv(&C} S4>sh|1Nkb{F7Tsh|1SP`'e入yf,v;;ZqRkϺSn҃ FYŸo>5OJ H{6Z]zsR⎙;"R|oMmҔ R R R R R R R R R R R R R R R R R R R R R R Ruimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image056.jpg0000644000175000017500000013351211665471332026767 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8"Y !1AQ"5STaq24RUs#3BV6rtu$ce%&bdC(!A1Qaq"B( ?1Le!y 'Ip_@ԟVMx7 Jxc1 4bV?QwOTοGl^MN@DZGFxdOrgdhmܝ즌RA8«.5^j`PlF2RF㫻>0z8?*VkF'3̜2[/u0.c\ˁvW$CU-,5щ'`n음4Ϊ69<=ɞd&y[2C!$l2Ok7x9^aܹ2Ѓ^NCGޱzN 4}^S9 z4}CGޱz9 z: ^NCGޱzN 4}^S9 z4}CGޱz9 z: ^NCGޱzN 4}^S9 z4}CGޱz9 z: ^NCGޱzN 4}Q^S hio,sr8^e Ӻnt25Cd) .vh$8{ i],{B7T972!e6>J6] I*嘆G}V.;y՛B*DfTa&5q9S UYuC3S)2 xhSO #{ccEꣴ:6-qtZPSS=qUHiyMLQE̶7H[FdxWL >'rNȃ00F8= VxE a.9ⴟ c{k:q〽r7櫑jlq5A>m:JN=b ݻxn<NFVVUײ7O8`d/Y(rXbvulXu@[<9ڨǂKN&gcN@D-pۼVudPK7s|AjGwF/[ =-fw8PۄBWYVvOlR3P2|+5*xdp/-/vKz#wjr7gR Z;5$k&>7 IC;fɬ֖gd`= g9sPc(類9٨g#E*ȡtmd2P o m%t\9m; tx"H=S}E?~KS侙A-wk>R*I ep-;A8fohk3`Kd3Ƚl'FP8_& \5rxZi璕Oݨ^jq Yf6gŒBnlsN:cnlש26:8]mvHk䦖+h7ӵ.wuٟUN)-4SBӬ#4쮒HdB %sqU\ uԏt-,*kvG,dnө<i|8P۪AJCγyܑ1{~㆞j}ªƪH.kF%2hhsӽu|/*5\GGs\ I#x;֦qPų5bCCNk*w Ʃ҇Tv44jd>ҷs8AnlVS r&;7jI'78GLv"6Xg7ή;$wO9M3YZqˆ8d]LC3tb. s;ٟTISin!%G-୎4VܮE[qRcddL(cnqdF#oCC~7s]XҚV(;7jdsjPEF>@F ;@d2] ]vuwC޶zi䷶1SH;:<< %NrZ$z V)5$aܥ}MU5Vc/dЗc[]pY j=ebA tWneCnh`<|^>+DQ3_#9:սBu⧖Z\@l!)]U{5&}m)n٭7Bk7H7k#|-Q3͓y߅fbpX6z?&&18 $pޮu\%Xl] A$˨',3Y$,$_T$v;mԷR7UuW "(䁮EAθ;SW] -s hòkQ⺙"F*,Yى0Nn+3uT6(ҰxήUrZ-[,&ֽ/t%AwbVcdϊFzW] I,0Ďn# R80aQ;"si1iU_]k\:G<1"IQ߯CGpSOP@98oOmi@S}izTԶ7U6a4v<< i ,koNzcQ҇u_Zъn5sTMc\18[ڦlVF5v=zU &* hY&3*"DNMqh}wNMqh}wP95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ\{]\{]95ǽ95ǽ+_>KUQм _$A{FZ<Ū64d}Ob 84 /Ju \ K߂8cX 24DN֟/4oZ6Nj1υekGصEn4\)^ۋ]ՍxoݡUX,ܺ-SLg2OG*tTQha 1h0fl9n5Ѹ]r ǂ d]=E6K[]Ee>4T5"wFVKCq5s#u!oNG2HMUcY sDݻEL@o5&*H޺DD;?S~/XR6[Ku3Һ"d 88x^d,93zgj":6ʍC B6wߏ+Y"?ȩyzA™dl cCZ85%D[>G b ֺ'1ia ڪ-n+NQ:7Fdk+Ȋ $i4E`4oZ#FZ<Ů""" """ """ """ """ """ """ """ """ ""^c8'"kz{DDD@DDD@DDD@DDD@DDDA>_b&v}y=]dhkGص4v W]*Z." HcTAYM%5LM8n!gXnݣH&8SI!ˈ\uV 4ԛWI `ߎe<ZۛfMUI2ӺJmG09iuM#}>ݜIeNNG5xgƼTiE:ipG,k\z|YVk0Qӛkbe iڻ F־pAt>9ApCF #{gvYspd7d2H'\v&eֺGRc2;r9D""x&~Mj}Fv'?= jIUkdy᡹8<0Aϔx 6t{_y2ML|j 2mw k]R68  f K~RݪDh{ / H =>Q ɍR]DZ{ ھ4rS4M.ťt\Zہ&ڲ-zhaeP$k2sbһ u1D:s+[鷹9-ղA,2w=.pzxs5JJdu\$:ưá#)5541=!՚6;{ u57VܨlH"Z:sM:Lf9\zsM+#ji)74DTj؞ǨqW_o~o}ٙ9U $'z[M@&7;xឬrMV|"`nTC^F wn=Up+=J*Xeŭ`h-2Ff/z?D[%ŖAqbG AËU.M=}i|=kc$//ىvgd_CgSCx=3ekf7 IN_vZe6A:.z'sl͒,mssK<#/TZ_HJF׾GTƺgE "8n`>GūzWJȄĹ-~ݞųzQVx:v-fηv=.# 7u4._u/֋rZ:r\_b+}ObY7-u*6eG&Hp8:"o8n[0oP6G䧅y5;BΦhe=$m 4$bCA|l Ͷ򖓼qlܭZɌڑi`pgŅQuzXm{45I3wdu[Xq89p(}@˚ӐgⷜSo#DUN g>6CNa_y:!pe3a䕑2:vAʖק]/Nl2=Q] @w+stZIf*hpZq7=y$tqWW6vl0wZ7>VŝNAW6Ns]GRR'079%u5s]ԵQG<,b$a-csѽfU]mcmKugcsÚ@F㞕٢JIEHkDqB[&F~.7cO(`Z)YzbgcWgWZiNG,k wTON0j3$I#RaqxppOà.[Dp}Dpl u"pݼA!_-RD#Cr_lXk46液KmUaɲ΃c9݌4:9t ;Тo9fX.uK u['. <fRh!l+SatoduQT3gûz[eZYd| 275Nwֳe*(6,،C5g,3)/KTeiQr'-9 %`Т\/:l4Sg22K`i9rZZKtq֢jb]s>5iEܭE[,5zN X蛼4{~ >ݮ.[9{k e/(hqladsLYPѬDž7Ӥ頧k̖nox Eli4jwۮm@ E@A_6Ӑ GY$SEW8hG8$I!k<`mÆJHKrZX$l6TTdsop 5x,Ǎm(ɹY ʮi>9hLCGd :] 2-TWC_s}E9Fkob|DBoi)2HcFGV4~[]T50r9Ѱ jAǢ5VQ:X18L48"+`" x%Oɤ(MC)-o8#FIyHi3/ *}ζZ֚)3  d%C9H!RҚ 94& eA\Fǎi%c: ]T>&~w$jk} 4uݕ%3٫IdM.ӿfh0Ӷ*HjıuZ1ADp֑GI쵔7:<0j?ryS6{[YSR3bt-\ yVmP\vFv#U_Kh| 펰vA9;Nڡ:xlaS #).߂q*h¥G5uQO՜=ظ`jt %k i-EUi֑'ToHzK|S5Mv;H:zwZH%jȚu촸ppG+5L)i6Տi$alm;'`'2x:@R1jd@;J] 6 hdPLFIÌqq>dEES雫k)hxO>02u*L""#I;Z|M$iX h{Ѿ֏'k3nHE7*Z٩d vӐAGB4~UA$5HjqVj5 nC[ji>z0鯹r{PͱeIps,I$eComcݗC@/{VOSjߟQU[GGPV."j - gzC*8+tqWjߟQSjߟQTh66,ͫ~}GM~}GA3jߟQSjߟQPiڷzڷzh66,ͫ~}GM~}GA3jߟQSjߟQPiȞEO$ӒƗe;VjiD$A(TD)=B|[VZMfտ>֦տ>֠EoϨoϨ4fm[=jM39tl.q(tYgI,-{$oR̳ Pj"ڷzCmmω,ͫ~}G_cC_7dIGq?H |Aݣ G A9D?H |Aݣ G A{kᖸ8uOSn0LhacA JIUjgQQ h*w2#*XfP8KY_P7>]n`,1qTWll}Do ˝vnM5tbX_3C wc^m"5Lt WZ74磊DI;:J};3/nL;+%dMU q;%L= q[GT/-mj@&ӨӜT(wjiEpZvG&;cWx;%4UjW1LNW5-"PCe-.esT$$eeh}D }pF2NN֖q㏍abMkaYN ڴ~Q5H@<䖺=әF"Ax`ZgRV9JaHѲa{1߹*)+"KV3-.i8ZLL֫z]e5,, 7OUh ZfB&BsCR"S6)Q!e=9o#ztFXj Y@h!lS8c dk]c8=[R}TNWP@qw/Cd|K35` sq 2so *>6MGKf1\p!UT%3\ i;`3CQʫ_)ie3Aτdi'kO؉>_b+;FZ<Ů4oZ)|}Kqh&~ESKSKDdcsƸi]9i)&tnyh# /i-8MGQfRߴtlaf;v $2sm,^EGe]돹6ZEm޸TvZEm޸e]돹,^EGe]돹6ZEm޸TvZEm޸e]돹,^EGe]돹6ZEm޸TvZEm޸e]돹,XVbshRkAEG%6tVӉO|MGOK4DNrqI=mKm5=\2O#"j_.WO,U͠vS=΍Io [u)s͔N1Vsb-5$Զᦔ,9ΰ#4jHY,EkKqgI:en}LwC '7[GBK5jXeYdBgj+ߡEMl6 5KAww>iqzKkj꾩HrzM Eo wǹwhK2{<0BKVO_N|m-6 y(1:9ܣwg?e=ggSŻwaXFy^ڞRɿ- ihq[=]ﷵh/5(`0 ;PPmc8ݹGMjg[lvGW>`qiY}pCe]돹MD˳k56-m p||KѽKʊ5 IJ$9~I+w>%KS83%LF$dQazɢ vQsC^vq=F;"PO!@i0k Qmr:MH'eos&TYf{[;<|lgwZ4Z]&[ #;I)@o֭UGSOc cL0eFJg00~I89U\nqMZ] `};7vw-Lf`56=0 lD)Z{#S~۷횹YA-גڄj5Y6VˑFCa=K+YuF4{#o5XШ"Wb+SXƌ!,}cQλArkٚsWtZ#KW&)U?&ġu3+-2Rtn#?&Ĕ&g MP>e+`D1.>pV), NGAO,4HbIf) ZZ bFγqFq6m4M{C0`p[*vU1$xOsmγƾ9`M|5(up٪OkfD@ ;g52:>(XJi={R.d+hY D/#Gĭ-UTY(f=ylWF\Red2ETx4ܧGsFCE|w:ϴj?|w:ϴj?PQr_mγƟmγƔ:\BJrL` 2@.$$*I"i'kO؊hkGصFy=]A]ݰ &{4.tJF Axgv?w*BF0ʐes9qA^ Z}WY3dh 7g>L[C1޶ m{m6Ty#p\#4}g8 T*X6a54^fY^T;\`/Lk3Ӗ ޭoui͛w>cҋ9T7pUtZ+M Ap tm]C[L*%vccs1;W8V~Y;fX51> \cٮ q$Ƹ;0pث鷊iK.j\NcA6TYC'6L8 t*Hs" "lϊ>Vp$ulB]<ϕsÃ'~7V*S->jR PZtjJicRa-ύg.T7HmOf2iɮq;:+0h8U;ZurюqZtZP_ΉU k8oߥQ#JLm-iƩῆ|VI*+$|-m#*(u\&1GXfKO1ć OFP೪-'\$dc/in 5Yp(g7ZM%cbΎZb9ŭqyv7oPaN+i52=FG3W+EjIjpc5]ӓ2S5-w6у#S#$xB=(Ҽ,q]#Ž-hi.TRch> = "fM`ӌ07?:bU]LϪ5ꗱ;tE˴6i2$"P#K]ќSݞ4!G%檊XDp@vc3Jcnkg4i#8uGCrs̛i\H}Vvw+U9=T4h$lNN #ؕcK%k5>s^u>Ĩ4׻ڏhis핓jeKHH:2τi- h_;d)H^1ڧxx(.TOR$4$3_b+}ObY7-uwv?w+ a;DAUv8 K[kX#2M IVƳ0qwk u|4Q,qI Mx-05F)}W-%G=c.)J (;[45õ/#Fh.f[ֺq $E s؜ yܴ\M ,1$8f=-2vK}Tu گʸ(%_XMC"k1DZ91yѓ/:IISI5Ka؝,u"vX9e TOdMh,㠜,;Z& <1^j*5"y==q2 ^K :I`_ңe4>=G0qGAIsy$m|23׽}rھNև=y޽3#@6$.$c;>+.-qfӜ(<8ٹŸ{GbWlZэ)y|}s!՞zR~5<=#Ơ\j*qx#KW$mTOR$4$3{9g\07 >L=8TH&ALa&\`1ӌ ڗL(YhtQasB C '{%*#ps؋\8b(}(}(}(}(}(} _Qdi'kO؉>_b+}ObY7-uwv?w+ a;D@Twym”N33֌VH28Πۃi椚I[dkyvc #.;ͮX&;+8홥xwEgAzo|RC&K퓱9<,;ԺTVe&BN IoVpFj%]3ke2nF]Uwі"(" """ """ /"8cs@I7&դS5dtJU;ye\`pl4p߻~Qh!cRy[SQh[ u (lZ'}rs>}r <ͤO}?1_e bi$Q= ֱŅ>smzM=}D,wQ zw ٩4$3)K^LNOsjYrۅ; ϟ(>©&sfrCrjj]H 8nKDcx=kn֖m[["-篊 XK 8q+ک֝]^t`b9T{ϝ}7{Y$O?z C4G/Z ]Yq׭ 9 aFQkCqI?&ģi-#qΤ4%cAYd@k:]GBj k#PA>L*c<<8.XȘTc99g۩&ǗTOo7$s9,ni&$/뜿6{ESG$썲F KZBQ xKguH ll{ur<9Vb9Q>68ˌ >+0EfdBPNi.q_?WG2/,do?Z]s_'-PZVPƜ9zoLoFv}I"7-u}ObPWwl#{BSX@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@PTS*YOȠr mCZ3H<uĹ]{ƈYs89D~Y-9D~Y-i>f1xc ~%aӖ-qZ?B,?B,tm.ό5/N {X9kqJ|?B,?B,yF@"cQq=K*.-pJ|?B,lpf\ H"I2;7q*kUPmTOvV楩4%cqP,oxu(etqZX[< U``^5xr_$ ψ:-ۓc>ѵ#Tɨu3"N}u48j=`@8;mDϋ̓ptu5ϧ9i1Z:cH-z@861wO"UK̯c䧳=c%Kw/m @DRP s D贕s'8 _n.eZ!i^`2q}+UWol$J#I;Z|M$iX h{Ѿ֏'k+SXUЬ """ """ """ """ """ """ """ """ (*YOȩ?PL|Ko썟?H =IounKH.%r )iJ=6#''9!|}<I0Xġ_/妶}-Qn8 $G-,Ɲ1c߯\ Qki/g[Iw?р^#17WZ}Ata4bxp[[Iw?KEPh.____I}-_њ }@GsVMPcB=g>exC5-Oɤ(knh',/k_gG{@DDD@DDD@DDD@DDDA]*®IMaFv}I"7-u}ObPWwl#{BSX@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@PTS*YOȠ4MN],_5Q vmkg:d|Ko썟? ZGO`i%?كV S?16ZGO`3AS s9a{J l{7Mhg8R -#0~bl% -$'IO`{F+kX枞js$qgR~b5\+r[R*3GdsuZI݆Y١K3?19B>gR~b MX١K3?19B>gR~bXK7U\j+;4#f}'.Gkc\?YCN\u99-OvV楩4%c~x,/h?vOo {a'7UI"i'kO؊hkGصFy=]A]ݰ ®GNaASENe?"g|S\^[\}#Vu; '~H]!.OE6ljܣ֭ԝ.l:WUlJji #^g<}_G_9ua[(~4᱌~F,΅@:xĂNnE4~_G^h|d:|/p%wN?//p\cU 8D~Ir5PIQ?Ե?&Ģջ',/k_gG{@DDD@DDD@DDD@DDDA]*®IMaFv}I"?;FZ<Ů4oZ+SXUЬ """ """ """ """ """ """ """ """ (*YOȩ?PL#k{}zS@ߩG܎w$Թk~i u=0ICO <#9G}M-3iM-3j#9G}M-3iM-3h*$J;7жߴ;7жߴ堬/=]mjSQ_Q3# s>vomiWi2QJYH&k1Ť`dnP^4%cKSi_b&v}y=]dhkGص'8+c|kpˎ|*W0vk[AĺiTXiឩQ8YJ 2@1ħ8QQg^%[5` n85,tR uo(?:s|PS=aD%w(?:s|PS=aD+Bnp}CLBmS=& >ΜG1;aD&u3 Bnp}CLBmS=& >ΜG1;aD&u3 Bnp}CLBZC#YCGKRp}SeH%4@t56u3 Bnp}CLBmS=& >ΜG1;aD&u3 Bnp}CLBmS=& >ΜG1;aD&u3 Bnp}CLBmS=& >ΜG1;aD&u3 Ba_H+icvc] s@r%QUO<6) 2CNqpT%}Otunqv?wlL{ 8pPw>%JuĹ=3 I3+;,l sݫ{FU&.!O*ZbcԆWKI.˲;/|=0?ml3SI)H 7㻡H2-V+am^ H7ރYIe {w48AOɤ%/əJIJ_3ăilI9Q]lBSNKp@N:TSkmhhYRݡqw=O.5vSk$#L2 qҲQ}I5,'E{9ڀ=[N*-+i 6IɠoNEG:gۿ%Y_IEkk ڰ=7u+z5uM3"sv |R^\C8_эl2Y߬Iv:-۫y]+/Վyy<{ m_j*%&N'Ke%VQ|4KnԚG*m;|sO$vq ut֋snv\w38yjqKS4;P3<7qR1kpv 7WS[ԬQ$#uX :ğ V SjکDgQv~ܔk[=I^50$]G4մՐQGx\Fg@ஹ?o~h \TZSNcYdl?.T҆QGJ*6coɡz=%06ڇTG͑gơvA&Si :]drwnH7W-t-p""" "" $i4E`4oZ#FZ<Ůx**(f8[n#^F[6H?Hm7D0%98Q32?.Ѫ Ǹa_IY7}E)pu1bf1.u =8W侻Nt}>g`frF?yi t%SmWhtmtt s[%Uz:jaKps\5٬ntGI. i]y鎎6=DΨvu+tm`ɛ6po o YJw9K_-ޡTQK4!w0kٝZ4Ԭt`F.ᕌS^bcǙxns )+<31qi7itp"QO%0IⲬuUmLmdTZȜƇa#'U`NjLOܾ%g1SR"5ݤЫh=YmX..=䃼Vnٚ־V߅֎7wY̳PE&./ ]oRrE%./ -}_Rr tY >_TrN EN/>OTgwϓ9}Ao?'r $YAe}'(4QgΓՕsYA}x sP^EK>s/P\ES~s7wPZE[)z%UlnJ!wPNUYWSY \>_v>d"oY/zEX/AOɤ%/əJIQfSd26;q:W64iՈgJk}^YꩡDy 8*z˕^f\[~. nV8gOg|X`;x)S]ÂiEWVM +DDM; g)nzO}k2\iau sHwnຨUɯ!:hqhkx`crvY$x{qq#ZS=-5H qtG,gƱ-m@=66LUQ\Ȟ'=K5X@q;d=XNNiIyFik j^y[wdu6ֺ@"pܽ|9i"z E^EL]iO?+иwPZE\W@xz%zQ(&E3|{O zDDI"i'kO؊hkGصFy=]Av E.ms 1k|oF|bZN:Fꎡ_W>eM*<297p cm˰'>iyN {GFAGP(X^VϮd byMsgxˋ6da =; ÷ EҊM߬+!sZܖ+7;SujZ-TX:ۘcc"w?J12{&>QБNPL9U:Jji1՝g٧m e#[<c4rz (zv@o߻M-k1*&iKvq*Oh#,3$Վx~No_BƶgAjhvWtdIm^WdOft55'M%v$䦛d;%{$hsr0p| R[EEi.i,Wn{rN|YcL12 A\bAp1OMd-6|FQ8t=ȫu[\Xbΰ3es)mkhHkfv{w/tkkk ESYE | -N<3<˞s^d̅I-)$D#L`Yi.4vjQ>ѾJ.oA3b&79Xj9]}e(~=e51vVǩčS4 zL%[3&>I^Kzscu-JIu@Cx|E#ƕٿ>#|lXq_c)]u5i2D0Hn3 \y&ItGK3c5poa8#;<1t`sإǁ~wt댳K]n,6iG;Oױ4y`fڂI_&sx+HU?&ļG,pPmvqǨ {4$3{S_oF6ɬ#C\NeOo{4P iڍ/xKe8u%^id!ŻUA[nO;5ծ=8s5pRʔ;R>k y7P>Zѱj)-%?M[$Oc5ch,Kժ*R2iphs;-9)_=̩I tzǿdRٮp6ǾFAVb7wx##[w-r۬vh3:)R>>Nak3uC>/8\5u{EPD<󀕹8; #usr֩TSlϡ{ j ݸ6ʙ)kGg ;ysy›4em[3s֛&҃Q62ed.bj puԩ.lܩż#o)'WV:gTHHgnqp{Y2M>{C\^쭦"d88#i:?*ku54HHr& guϷZjiud|L]3JU~\*Em;+͈dgfE*MK 0&li7y :EMmEmtHKF>/tfE<66{uY**)*+&:s۩&9I,Zm\nYX͑ͣ}Ce/GeSћ ۥnҞGIZ؜ּ3[⟊AK{ZlѺ,_0knsѩQRXݎiFOFJە5-E5%6ԵϦ-Lj[ZMCs)fA3b۷pIͩ-'ic 5hw~"[t@5 ҆gθ4fJ) G%C%9گcbjN ,21wەkWp}EejSk|ѝ/7$[i*j%++u;:Dݳ8Tأ$v+qe,Y$>WKOQ T VK-{ \<)Nq:ZnJ`CՑ̧IHN֟/I;Z|HSFZ<Ů4oZ ThVwv?w+~BӏU9ZǶ 'N?WoFfw`QETc%<6sT=lYE?$TDl=]n':Z#KWIHxq=o3#qJx&ҽkfѸf̵4TU QMp{Fw8_E޺ס]'mmeKFE;cyZnHVX9:ԏ9ˆ;Rعy5lb2G$:\AaE ldMcS`S5|*..s lp֜;GA^2[`L_$p }* V:umϧ=sG)? h]/Mh) Z TeB@n>=Z 3ԬT*|AR5fkw 監-аCU%ɲL6&4@*GMi?Mqk*$1ц'-'-5wSEjmT,%tNZʍx4SLB.ͮtekgGwiՙJf ѭ(q o~OP8-dV9c&dux:=6PLYAsZָZ[߽hڬuhG:8_#T. -)" "" $i4E`4oZ#FZ<ŮGNaWwl#{B+7ꏴ(/vzULShlGnTOI79|32ŒFp枰z@lFNNRTƾs&~}ƫ\[Ïbq>z <ɤ_4e72i 'Mjpλ@&l4oAk44M")V}}Ee/*O K5 MW嚢J%وsݬpܜ Xb'ϴޮ{6ڸ*!d]yxPlOR$4$3pҮ/8iWzY?R_K]jh-/'3h":V]km}<VIXWšJT]d*_I &r07g&BGZzARYsc=CQ8iWzY?Ӝ4,KjNRgGf84g;d^H01! *K'RZsw-Kʚ iUx7R78=B{ֶ.CQEP!vB;,kkl.Fm_KPdi'kO؉>_b+}ObY7-uwv?w+ a;D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA\T}d*cQ$7BnLIAb_ֻƨO6ɰK6ɚ0nԗCq{q~^-#8[?q*%N;` 9τt)%P`03֣7k1ֹݪ0j}FΖ!951gϔvx!ԾqpiΩX^m#Wkp9o{^- `]g?+x#KWF/^\~C%{}XddTZ8mGSi V?ZCn 8tӏ޽7X4$?8ޛOU7?HǷ@lVYTEeM\smPc  IA>_b&v}y=]dhkGصЬ*ThVsQWGAl)b]fk ^+~BӏU9AG4SIŗ' lij?̩?jiͫOOVw5UŭCu z,.7Etym74&zK4cG$ԷCO!=G\9/1[5c'Vѐo[{UTR%@Ã|<3V~PheleD{<۴SG[$.%[-[yk<_Xem  S$@@;LUWJmp\ N@#5yÕ_<~.W3-CgݦR5笐mZѼ8֭xQLM$7r;ٖM&N_ĠâTl"1FҐXN3lqXT*+_2JAS$A2bûCc̖&q8 rE#\p~.T.~o;:M NE,j23I) o>> 6=bpvH,74i;:M N K!-[s0]R llaF 8C&'~ZgIIߖ W\j* 0=Iߖh;oEsTD=d2Nx%Oɤ/?gCuXN:Ml8gU{Ih ,8u']'*Xu)GWIʦp蜪ncWX9? |+`r~Geŭ7dnS򩻜>%o^+O=>OºNU7sDSw8}oK½VW'O=>OºNU7sDSw8}oKNSIG^ڊc8ߗ~r>'* hr>'* hr>(*Ɗ6>X:66ɒI84T53AG_蜪n-ORe|ocZZrdoVdi'kO؉>_b+}ObY7-uwv?w+ a;D@DDW=ohVsQaU?&Ģջj~M'D;XwA~}"`#pX_g;cI#b6$N{vvWSOBddwGZɪmix"qk䅰{wx8"Uz=- -tvv;-Y]weU$l8 qIuHRS8wj55l k\`jm%s䭹G1h oXQޭOsIl0؜wTuUUE|:z Լ8; y7,ƪҹu4#-;xh8@9F+nomem9B9v@T脮dvFdlnn||d߿;) ff#G~`4sh:l5ښB#YHvJX:z'hkI ƒ#I;Z|M$iX h{Ѿ֏'k+SXUЬ """ """ """ W=ohVsQaU?&Ģջj~M'D;XwA<@lY|Q^:Y^| A&P_QA}D0:`u| A&P_QA}D0:`uWol$J}S}XA>_b&v}y=]dhkGصЬ*ThVW=ohY_UQEW:Y ŧ-QثrNkyqo_9OoZ5Q̎~cs#?[_BgHM{pfp22; ̎~c$ {r\3ׂF~" cq8 Pm\U5SU:K;yc^@grq5kUIU?&Ģջj~M'D;XwPOY^׈Rb{a'7U]* $i4E`4oZ#FZ<ŮGNaWwl#{BW=ohY:r@Л'S;$cQQEKlqLdnuzr:PfI_BE}!=-OY?FS}'8tcIicEtn(ާN=㧶<ǭSClbhrG2@~ONqƓƙ [FT0.[ [Ǐ0c q#TEb]'XŌR)H~{>{o ?O?[mimi m﫯s%jRY-^!2Hq%$J"4% (4sCZxkZƆ` r` |V݄'rA[M'rA[M'rA[M'rA[M'rA[M'rA[M'r{a7}ܛ OE: a7}ܛ OE: ( r:GJxȈ24DN֟/VZZ4SI.@9i%_g}2xdQUM!{$u0h||y ?zsI|,|cZQdKOV8 h<Ѥ7EM$|ϗZ6?8OIjVFc ]\͊ϑfQ:1V\doiS棨罒j=I1Ds@OWCJ3ޜu㤵SSJ9㠎[kCJ%nkGDg:hsh)jtw8GlP& sr~.7ӹEP 3v/Ғn:zW9CS z|'cZ5>6s:.8=\o9?z.ʸoD3-{Li='ȭ饾meڒ_ 53+Cg} &/2x%ecvZ]+CKx[2j))j"t~ ԥo9?zi5O: q5Ϛb4:UZXh([YYk}2ҹH S JM8y15Nw8ސ殔8U{3zL;?&\]_4tPO{AqUNE7fTG LSi֗1۵uwzzm) gCqm,sac7dFπZ=UL讓K0eRA4p*;u;uUӣ-rz5kXr9*]ߴe)v'ڰڧ9s8)]mxj=>'Or09hcZ0>hR4mU3 vU65F2d{ZA9zz mIY5eLlfYXƝQP3*QFSsI-Kvh #nk1S%,m"&5ŧ;T$i+י1Y'rzzvq-ʪXaXN7 8vmtWPgssIf,,woNwoAEQu#b6$z;4 E)k[3qmn£]m]mce9792:B].9>՞rkSJFp V;u;u҂QMEQu#cnͼ78IEQ"ne̓Vffg  uKӝƣe##wOȜ> ۣדT]W[QI iueWdc4p ʓӝ5)-1YPE#2k#ַYo8hy6\-Ϥk%`i-UA z,j^m&(sbv+puG@2z++s u8 *U߿ޜU߿ޑ>KlԚ@Im~•7!}ҩ`KHְtd zz\ϯ^v@.`y 8v5bj*5K׍CH=%Tzz1X&xc%vl-lj230FM7'ME6wgT;[>5]m]mcb*5VK[-UΪ65͐HYRH=G9ޫtUBۅKa|sOS koZI&[dTz&6FC`'igw^WwoNwoAe(*z5M,-g-0\t/ISP.S\\ӓOӝZ a(javq#)a梁UCN1lj#Xgyޫ9ޫ,jZMX*gkXecuGu@όW3+m|n5#h]`~\;u/M&6'#FinOp%s1 Ѫ#R;qIM~gVW=˝ i˝ iilΣ-$3QGFy*/ءtTW)47d9x9+zz~tC4Cr25pV=p8woNwoPi۴zٚ%q27nvYTޫ9ޫJjTʼnr25p+I cx4<E`sW[~zsI Lrd^bOSO5 u4Y֜GOgsW[~zsW[~z~8a/]m]m:\;u;uۻ|#E%΢Xჹuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/delegate-chooser.jpg0000644000175000017500000027745711665471332030705 0ustar drazzibdrazzibJFIF``LEAD Technologies Inc. V1.01  }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzw!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzO ?W֘j7#C 遦t+p]kZdf27 l" R..։lM!ɺ7sIh z/ {9!u0GK]~?<%B^]>/_C(sCa З9G"_xK=?}_%.Q?ȇ/Et?rg?D?h z/ {9!u0GK]~?<%B^]>/_C(sCa З9G"_xK=?}_%.Q?ȇ/Et?rg?D?h z/ {9!u0GK]~?<%B^]>/_C(sCa З9G"_xK=?}_%.Q?ȇ/Et?rg?D?h z/ {9!u0GK]~?<%B^]>/_C(sCa З9G"_xK=?}_%.Q?ȇ/Et?rg?D?h z/ {9!u0GK]~?<%B^]>/_C(sCe+czn|O&4f+9K<챣mͅRF5mE3iGg,7 r|^w(/u:϶2JМPt6UWU{Z;lgo4{x_~4=gGMNY5-XLvNjhK=+$ۂCGB97NVrZ-'kݦ8hׅY8)E5ߥ5zz-o%i{쮜M22 @Xِ(j{8Gʦۊ湡N)^NmXmu4;:\I7 sMݫBE5y]YYY`5?FDXj6Y-٤Qv$^`+Nt*PchsEr7{6W\ɨ-Ic/I2Q-t-os)m& PHfyXeBrEn V6)?HÛ{EYs7ye{Y%ʹZqQVɥ6mi-HUR54E|ڥٽ‚\|*P1`8⛨yr~E̓n>=Z'InU~F[IiѢa{TjWX;oO'o<'>oɍ{T+ZSpחDKmzkɵ Xn3Zͩ[Eosj0D ! PgE+)Y'{5{>i*mlkD֭=ii֫[X]l-6s$9Fc$p(E (Iɫ쭪NWtNIeZk652QlMj_o-gtMj-絶H}R4p팆;aH'nTvRj ^Y>k^+wiu$UV[hرdzM,.,R%n\wOTfֺ-.X5vi4_k7SKm.U.Te-I˥ *"/̅'S!bITJ\u)ޓQӖM'&IZjsIkRj[6MM%'%w=]hvWz} Dl{RdKPHELG%Z\//y9-Ut9VB_I5|̯ͥ껡`մϰhgmukk{Cg 0F̊J'V^+o\#.UqV3~M.Ma.jJ,­VJ6Qm/n.7>o+njDyE]r]$\I$om8ǙX^ɽմWZy,2$'Ӯۋ"K1gyX)"΂rf#@& :1 )ʽHA/q4RQۗB蓺WjΔNٵnr)9Y/qCy6ܢ%){2l46IraH;9B/PQw\Vu7RK2J%-I5"K6$K`^!iXŪFP*bpqB2-}p.־wkw_4HAMo$Mo$Mo$Mo$Mo$Mo$Mo$Mo$Mo$Mo$Mo$Mo$Oּ7 —ӼD>b qxühy9v]f϶CjuZZ-RyveX#;2m3o4^(ib)SxvR 17o9OweRyeR2 Κҗ#V+2c |{҂jrm.k]#nM6wѩ]UOz?WRoںzsqQZ&$l@c[c)dž#9[n8g+!Wgf:f85`д8_vD季މ6ˑNGISui]K=17F*MM--xJ맑hΣys>ukq'Ho;Ś|"2% a6OĹ4hS[ RԱ.6Z%EtIrt2ӭRUTRd'9K[kc8<k=ztm?Cawz]wWVV b[-ag% fJ. B\Ruo9ǖ3qTIG6 NmZͤ~WúAhiuƗoYi-kY[i$2DEtF oR}j+(V ]JҊ5g E7R}"iZTJR[rU#882gd-xOkgs'%gm:cPH渹Od w^mwoZ(9CQ-ok{>XBj&BrΪ_ܓq0[:^D*JNm|+џᧈR/e\M=5oêݟ:|! 7mUslWtF઴fجUD(To%I>ifP:Лs\ܯjʯ4 SCwPҮkI>La[b*u-vn'NMՏSSnڍ6I5{b"5iepRN$S+mkʛZc$]TxAx`E/4~,WG}oc|g$^pgy~AT[: X)AK s()S$z䌢ڪeYGܲZ*沵EkTo}ikSӒuoAïGmb975$wqn0TTT\ܮֽ$ 882v!UI$ϋRΝ,%JxNNU)IsŴy5KIJ,~s&uytuN{Y8Et0p$C55F]v5h':ueiOQ)?t֣RVpj*8ꕡ-T9Ќ#8%d ŮZTn6zK줛LhQKw{ay!eԮYS,I7 sfԡN ^<𡅩EKY>W̡u)/y%ea[/ӭUZ>W QimTRM9GxD'}y\BΤ-n}#Rw\jQy 0eW=.k=HT:3H4'.[>^VI6s5C F.RjͦRm+H''5fF_٧#clE^-" rFy7 JT)B~Zޯ6ך^^(B|WY.ϵH%KT]>F ɴM?1v/TEeQ3jiĺRK޶+YƬrUV]<5Jj\UMJ8(I(r'毥[ֲ H>xv?wYt歜&M hSGcEZixNO\M7OBiM^P撊eJo)'$*E#t񰂖y˗E%&QU 8^M_UΉ3w=ń&N{y7G5c [&j,U5](Ζm*RmRP\WR_ d%:\14{){Jn^8K݋JƇ~xPT8EEKVGibΧ{yCx~{VkH-%TKrY!E8t\jY+ݯu)FRSJFMsU,)MsIY$ݢڊ\Wo j^%Rt -Ʃoki kA C;Qk5Ք-Wx!4c7Ka F&irN<ъ9TE9{u$c*Mm:58YZ%փrJMN08: KgэkChCƒEԭ^8l3yq5YVi]4JU(*SMUK Oͮ~ZRYS\Q$t3SR|܉s9KSQTl8 SI^+W?Ok-k#F}N59{Қl{.t̬LNP_I8M w| MI%= F)9Z3J3JI%S ONQZ狍ڤZ/\(%fuW5_ը6ƃ-q*[[V/o[-Y-get4)UӍ_NV 9MԧnHF|R?yޡ2m1êz^.e ]:UJ+TK&>}{g_ִkc'KPf8,'/ܝ1e '%G+/uRUoXCR]8>Y4;%ӷJp.KޝL:im5\M'Ou8gTzD:QA^vcyFվϴFYt^ l.:`ռa[ϯj =͊ON#w1yzMFp{zxzq]%fޒM[s=Zn#4֖f 8aӚV"RWI]=%%WM׆<=CŒzKbXEƣ).K ΋ti`6@QpO !ѭV ƴ8O_Է,ۖG0FZG̹e(2ջ';sٵ 5அ82c݀/{WnEm_ed~g+f ~Lt/&:T]žM#C5UKPe~l#}3Tm'rG\- oN䪏e vA _G_?*e 'q U?{N=$dVvvuy^n.fDx٤.$Dvc%5YFqRQIi%Z;qpi8|mmx'ѫ2'q U?{N=$d@+aT{(H=?;WQ{ݐw%Q? /_JG/AvA _G_}K[ޱ,'ZͩZhwȂKvoUoTь&²EiIKmZtmkg$O_uy%/u$T{@+aT{(H=?;WQ{ݐw%Q? /_JG/AvA _G_?*e 'q U?{N=$d@+aT{(H=?;WQ{ݐw%Q? /_JG/AvA _G_?*e 'q U?{N=$d@+aT{(H=?;WQ{ݐw%Q? /_JG/AvA _G_?*e 'q U?{8oY[k:&m.4w]Xyx3,PWԡRfxzs,;O^ukbꮮs+JI-2MIj)F^i C[|GOV?PVk=3_U壗W/~!/ T9<5c.TulZ~>^$ɧ٢eЃi%.M)Tn\ђNfgxR*]14k}-lH &V$.:Amf݂ t`ԊRRRRI(mHr۔rm۽oVwmݷ ?+[H$T=~CK ( ( ( ( ( ( ( ( ( ( 7 GO?-mK=j0"[ <ıBѵ$!=4a'tSQ/mV}X*KKP,%iNl>ؙ:TU^$JqOa'N5j(R7J<&aU|kՕ b0ni9N!J^jXzujrBT0,~$\xgwV\kt={.6S>'/ a}6-.jha* ԊR)`­Xэ(Vu*Q!ˈ%jxgMF6!AS:s:J*NJ3:ΔBUaNS%<oZjYξC>|ohuKխ|Am~LM;T) (A׎Wil~-'/;<4+T]LD#K KWSuXʗ*jE*N>JBJ(^eJ Ε7{JJ\'@_蚾_w~ѢKua kkۻ&lnDԫS3_©ucO-Ry^¼' |R Q䜡M*sRR&ajbrY֣Ԥ9T[RgN:/^cMivZ./l2X4xuSucэVW7RĖZ^zԥN'Qxͪ\I9WsTp5cabaJt#VSjaURU+Ν7XԤ{OkO~g+S+#J><дMbU-_ǂ, Դ=bo1tۍ6@QQ*Zka9FUqpEbS瀩:>!ҙԍ<=LTT18%N,mT8bt'Q;⿁_IGTX[F m)0.˝? [/N-IRh۵(URtҧMV׳9 *u9jVùUlE(΋UO7-+'t_w+r5oKU\9UjYS)Ծ0=<`֯hh<7izd2fCdMiZCj.1ZseX9=CW #G ѣ jB0VP凎uRĺ>]^،Z8Jlc*)TNr~{]Wex< i${m* jm_J]WF]җOVfX-CqkLgRV5Oi4 _xGѴ=jTѭno#嶕 RUN\MRBxI``**㋧9TF!8TMq'%XեJQUzp߶NV:`7JkÒ6xQfD #RVI4۵TZ<5.YN0U)J>4_NT%_M0ѨNRJX|6#Zh%U4RI*ܘJsSQStSFZn‹VH&kTƧK-cƫ[v}_JEէ-닯$DҌ(T&S,'ZYiBpYG u#U*i:U)hk)!N>VJhOJiʵp*SJrcB-'ƬJ׿aʔVtiEƤv?|#x^,I|@߉57^wusKnt_ G{w{q>qky sjnZ_ ˱t.kaM) ,'F bogNғRҪ%,f'R~֍|,өѳjϒrtFBrO[&&.l.'CV Λ7Ӵ)9z =OUjoN8֫wt)ת$C NLGܒԨBgVok8:(Q:U)F* 5)rNVprFUԩ(BjUy}?;iMڇ_Sխ xQ@)Ӯ|yejo<:zeέ [][̰ɯ*n {Oݩ΄*ʧ,qNNju~{9FVxlBF<=Y)(b!Jm u΅)׊5+Aу*IpԼ4>|]oJψ]j:'67tkǭE Z$eЮ|-HTXW*j0K7JN2Y{Zqz51da]'C9'R++ɸԧR Ռ%QR6U 8:Tb+c&ߦ_ FjM[Zյ(;u3_EIӕJ|o- # 5)B푡~QiҬk,JO%F,EIFJtaRV:eZgJԌ8ԣ UTJ\U\=5]3ZN:(ʅe 5$,7$&} ³_Y&RxZtegkSNjVsjXhbwNup9emrjbgN(TSJU9ҩlT0nPiR2HF{'2F5TZUU*TF>rZEy?tԾWӮ=:-oW 'ljl.#HlndzTVT^Q 9F4i˒wVMR*mÓ 9(418yT)BT*^RZI/i^iեjQJt8ӜQx@}#Gzukmvjz.{Q5ͼq^6͵yiıȉ1 xUzPמZ<\bv(ل׳ RR&t+J)TRiJE~ey$* (|Q`O[R%ZL"_A%f~zGƺWu].>%uHSx7е=-쯭.t>\,,K,ReR 9ѝ:Uh֋XՄ'MuB Rv+ӕVT+RڜHʥ:)SaR2MJWW3:3U9GʕO8Օ-jOFմ? Y+~&ᶙ5(êkit'[ccsb% !UhNxiԫJy*¦.t({<Xg+O(ʤgKԯN*غuqrV9п~:]SeۃR+Oc|&tK _|cX]JךYXLv@|Rx*Y-cRc\Υ\StzxZ5a VJ3~ҲUúPHΒM4cBx[/c:7:U(JTԥW(yxMz |icӴ vˠx ^)ícψwm֖0L05aJ} 0xETgQ06 :pjb!J?i qάUqӛQP1S|a4rVJeZJ_w9~Zx>$T'k;ɨ]|aluW5%k32'<"|aa*{JP " C(B#CVKQ:ʧT~:3^\!G(:P)W*]T5KGX5YvG? Dg_.B]~4֐>^uKZ8/bE),,*9{fI%A|] XTecxUjZl=a>TZlTz8Rqej0U8Ƈ-Z#,L ~y~HsAM[';m;<1_Z!r{>\ {>kic==콟y%nWυա(_}}r+gH`=ݭ[x,4w%{+;[pMi4em^Փ37$]ZT*]F.*^ν|B$8BT^yRN5 tR T%b!RI}9ZJ/|^8Ҿ$xzG|a{7^Ѯ|9 xF4ki|D׵+L^ i7_Ya}"o Isa5̦ k,iᣅ[ )S " C(BmZ,UKU=}vkR:"WӬ uANeBOFVjӫZY=xEJxlᾭN|Tԭ^ujBJؤ(ӧFTpZ% ^mCW75M< ▀ƁcB_U񝝲ZZjjNgkD>U3\BQK1y&JI|=a`(r1ʪWģ*n*T](NT8tR))N RPQzYsFjQj?de&ҋٗY]7]4v?CIPS~2AFywq?|ScaLS]Xu燩O SJ̲_Pa9UƜaV.X,U`gUJ25p&,\aN)aXYriP'9{g%Gg߳OSPx⦱y-nWZt}]Ao>K%7\6,rՄSh| BR :Ezxj)SNU2L$ZPum 8*TiX8SjhIp6~ΑTK*&{kiF*8Lw1%/w,P0%FYF~q?:%VJ/nIP\eNTrU+AS7.JAϕF xK_]dw[|1-Zփ7xk-:kɡkZmZvC3NY'9NT#J,2rX٪jaxU9)S΍iUR X;:Z+񐛼uayBsVRR UMۥ/v]4-{RǟxHM/M 6unzf֗jO.uK F&aVU DaJgcu ժҧ TUhΖ؊'zhQ8Vn:5QZqtNT/_a~,L4!C Vu_|(xjFtgxΝZi*PxRJx_ו㛗4˞5:3FqRR]aK R_;QNJo"*ӭB\M)RB*Oҡ$RXLe9TR"zq=(ӨNRtE`o[5ÝcTz֭o|WEcSvhF]zX\j:w"HΥOƔ"FzSsS4TFjQMca(B:N|* s9ag 1RaB*jaVZTog*sF/u{H,{íSּ_'cxJq:c-ލk^o4E k Z4Wy¦:SJK8­OiN&5SS Q p5G5^~iO {KiC֩^t2RUp|MYⰵj(שSUUx. "&i\!_\Xמǖ^ڜhҒ RiQtmЯUFY;>UVJ5uVF+ƶ!TaE-jN1V*84~gh?y:'m Gė N򿶾/s7]=J|}\wesm)<ܪǗӕ{K.Htt9|5L753|-kZKEFu<::%,W4f&Yx~⸖Kwk.OmņrciguMZVj~ʷ3*rut+JJҟ’-jU*JKNNT猩ΜT 5_u'kWl~!x)%'Ձ׬4n,;grO1)K%VggkҭJ[Fuzm/<kͬiZޏKjյT4h";֭^O8U}H L=XƜbN9)SqhqoQzSNxw[<=Znu$ 7IZ%8<+|W>to'ѣ_A?n5xuF;Itb1oMwJ1ޥ\hΝz$aז"^l5NTJuեRn<2Y}sxV8(Э+*ճ*T㈌a]ʍZpQVIaூڏUx-|Y;oOx^Ú%Mߊ5k7kCm>Iu=\`\qLG9ԝ:Xqu>XR:HѤ>:qeS-=Yc0U?eJ*pYWάbgN*)ѧOS^t_%}h:&ixwZį oi]NLտ/mIV=qUkb1XB*1 #+0RR*K*ztXtG.ԭr\>2*Pbp֧V%UUz,_-*^h 'ݼ O67 3ƷÙ4n_rAL7P_jR+ ᅫ==jSTz5ͧ,,U*tj.Rѧ2Pu)y(TuiʝX>iN2NXNJuxӭ Ȳhw$F[=7L4oZAmjz5mFi~>i k~b]l^L=cSaѣSas,F.uTJ!J'V%r^/:n1X9R<-:xhaաo٫Ěcyƞ,ô9:fj7_|nYu^ȱ;+Gqp|,WTԜib^Tبi΅<7$*ĺ3Qc^UU;TúNhWùڭJuNpFxiJiЬPK]L׬5ϫxu7Smn5et].}ndi5WԵ!utH~ʠk"vNNuRYg e:0p^] mRZJMaIRhQKE{֛+F5!*PTUIQ[sԌ( 7 GO?-mK=j0"[ )^^Mm6iijڵX>MjKvĖzeӂJt{OhHҍ(JR浹#975Њ}ܪJ#"_k~0O:eGh8PG@u,?/?gOlT6o ~0O:= ?@{z[M,im<gYf(,Ӡ6|8E.;:ycm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=Oax}OI?gGAG(oSX^cm:aDğ3'6t{*?G???' ͝ʏq=OaxkR,ڧUTdO΂)/?@{z[>(:eI,2) :{9Qє#)*? n'. WD("_L~nya_Or3h%@$GOOXӯn[ Դ;jךNu^#Y\@nEetg̥JQ#8̢-NjSQpQq$$\{6 GO?-U/Po.?-Vo^`GedkK8Hc_?/G}\'@P@>|C/z.&EgoG Vov#MTpPArmRy?)泯 N8c\TGriڽZRW<5io LFeikkѳk?k}&DV] 3H54Ѿ**]hMNK.ҮZ#zFd 1 Ө+#/:VWZ4.\*USTқ"Z]*sƻ9bX{%Br}WV t|5}z׃u)|M{ؼmÖ-W]/+7ŅӖ{M%7a[NQb%OUR[zc傅IAI:omPp^|6 ,<SNT'QUyV)⣅ˣEʣQCGNg5;/x:濯펝}#%>'4tY!mQ#A%JpVn3\a֥Uƿ*sQ(TUqsB$Я<7,/o*qU)ӌxTۭJ\\iR)rm?0еYC[^/e@{6?|U|3mLtzwm|j:b!t])^5/eG 8گ5:4Xl='*XyN/fмVO VJƬcVUNnxQѫB";}ά|46ݾo=8{+',̞9Ke,ij0ɡ v`S,'Acg2(ESEJNXjЄg^J_TUXB2IazХk)V)98Лsr~$~1Xx;ųh^G|KִO OÛy[XEKYF_xXݮw勖yJ3p <UTn31?g)TTs5ӜWTӧ^ZFNZR^8jhMjU$)VN5aK*:vf~x> եY!k㖿-u߇Z]+VgxG׏鬭<=Kc^r4C}IeNK%*T)SB>ҕЯ(OXnzؼ4e~+ :*Nc*Tqx{{R #5(U\Jqk O-jô* " E|#o]=d>$Fޓ-[wh:փygYGՉ1ZRp)PtƤ ;u!i(N Dk/d§8N Z2TRJuhWTISJu= ( ( ( ( {w?z_G>|'!]>_ i .Ae HmnwDWڣT,-o)EumI%t&=ܩ_4ߎ> wĞ!^麟 {O hv֚"ڴ.$^Z4T*s\67N9<^%R^J=*:֩*2Ҍ,=:𘏬PU^fsZ(P*HT_|',?x"ŔsTҾFkKǴѢV-(R&Ya_/N:![Ec ӖojQt 7HU:K2񫃬l?Z[ݗ~npz~zGxsxvuogi~Ӽ6 5/ڥͿ|;i~WXI4G71CV8VN <֖&;:Puj),v2?8֫pC O :41VJTp؊W<5TTԩ/eRw:´b^RUR _"|#ԾEM XxwPWL_#umF ;QV=ΟX[n5[:}cj{wV]ԥ5Ng=Vx\i*Jt|&b1J8J8G zaA{8a0'`a҄k(Bx |yj<Qŏ N+:iYmM6ȷqX;#$P["Q4jnD?K_jS_ںݭΒ>[W+~bؼ4pi8uS}4M5mY~%E񟈴|Z<9<m?XPkݯÛ ~Ė~hWcoq߼6lx:O)W\*|Py}zjQlN_Ώץ,E'{wQަ.4b+9ʕ9M*N֜)Iƣ-фpxz1Hk>+I̺xzgYq}:?7z嵫m: |:paMJJƌ0'*jx|L1)Eb)R>aR):t= PKFK3S:ԡ VXVWUEOaX4[V/_Ş#ִi=FT~xOZ w[i5ͶO[fן SƤiA9RIENr(sڍJ_5EIV^XVuΕ ShaB4cN4:έXQ,5 5>Y( ( ( ( (+^ǝ{O5> m:YCu񯅼xROPӭŠiVޓ4wS-յjDщmթC5 !Iދ9 n֗OD&?"𽎷/IJjͤ]>#mKFZO$W7Jėss,$l(7iEo{ 5)+c8 aל?# )GU'o?ji_&\?+[H$?_?>ɩ :֗q?@ƿ0_\ N (gO[k4$Pפ]j-W2s.|b;mT;Ln+g%qRwVrݮK=#f~Kw_]΂ C%Oqn*,ku hXna:0 ]}?-|gZOx?ƶ _._ρi_⏆? z}eTӫ]zI?!m&^VEaU xT2ξ8ÚtR7*΂a! 硉b%[O:(u)ԚRpԮxxnfE]LumGL>:2#˨41υ>.j~aMgFCnrc=L~ ub8,-<5_Ѽ[Io&Ls?oNQ_GFU)Fq7PFRRk^҅&(=)ҩVc*5kZ'V0[R{JѣUMqV:XQ|?>3Ѿk |OWO|>E|!o7uk>*I|A|]š4NE}FգMYbCC㏪g-glDغ /QzDži]u<Ljk8Ga#R*7 ?4C֯io.?-Vo^`GedkK8Hc_?/G}\'@P@PN'g3yn[^wy:j_y~W_ek1Z? oO+%|MI]?s^&su G5;]Ǻ%-O?;R>a}wo<){*+kOk4^rbhЫmJԱ4WM 9e.T䖶g~mƥ},> }M?-|qs}jxO[}K쏉ou6eƅthOG Ct6/*1)R(al":W`aUJԧl-Jꟷ%iҍ(ƬWB5$QWF4ZuխnwD,9mAeŦ uf mO|*u kIV cӵh >-qqiuw6 _SͱScS8YE5K -_y^%#/T[+c8 tb~:0—~ER{Z'(z`m-E]cbJSl 3i^c k_Ϡ ( toJ[cOHu zI֩m"|C(g2(ѵC=&~brYgE'y%g-/>}t6i;>众u 2[MHi.];OLj#.,| k>Rt>iwf0؏/cAޫ^/🅸Yt CZiɨivSFU0·UX'RmJ3Lt)YZCƶ"ZzNet'ZyT$XOPN9(µJ01?hab#C0j(P\G Voʽ ¨f8 S Ob*T, jU>Nt]U:kÛƄ}n9G*`Q~jxbSBt ҧ:a$NrJUOI?h ;.>x _|:ۏ}KJּ'=xhz1ҵX,ݖYmt*G(JZ_ӓ1MUEb"Ɲbiנp^<>scjPU(޶\Gy%*qkҥV!SK|7_Oɮs\o5?B{N|| Sԭ6X_]O;zJ^ʽ S{ 9u\4*[R,M.UB{{}y}˺*U,%&*kz_ψ2y?z߇|c'-%$k>2 vlaO ZRXx8>W^֜:8WV𸕄GӦNn冩B'KFRGJ4FX4"`뺕u0Y4+կx:oZbֳxGƳbWW\^(|?Is?.lnT[X!K:atת=zlvkNЗ Xz8Nj"S:xa|e(Q,*a:uS)E*hAab0q0}? W"A6k0xmM%jz>wYikr<7f[2&e:TjSQS89NX|ag>NrB U+jR=TUqa#FMV =iVÓqRzu] F塆=O?lE?i^M;CCsjzvivFZ햝c 6u*Dviz9*b8Ofr|JG͋[-xV\x1??zFOKb?"=|Q`OSK=j06"_A%f~zYMOPOִ1Ԋ5zUtP@7|Y4;WBw k+ua[RӓI$l[u$E5+nRgC~ o J4:siᓠjź?|Q>ד:;mΎX(NJPչI5k{$.WJψu?xSKasV#ίxSm*Zk OuiJo$6xy9c+2B9f*cN>έ,'SIrѡP擛:UkΚX*(J# ik ]8B1:T`ZBÂjSԬmt|A3H| oV,ɩ :֗q?@ƿ0_\ N (g.dxjTiJVJ+ԭZnXS<ʬW+Vڥz.jޭ~i0bT҅*|5:8l5:4hӄ}WӼˢiS^k.4Kp/<[][:J P.cLeYGVj0:oRҔ:J.J1srqbVֶ&ViSV*&gQR@P@P@P@P@P@P=GAu}W'9k??ϥtKb#}x^׭zK<+JNzxj4Z֭.^U 40>ֵYP!B+ԩF(N6%שV)a;^sRhҥFsZiF<ҧZ?-k#|a2^0|Q'B<3cᏉ׆|Su> ]?BQ.agf1X+VffCUU\_a('%J0&*bܪUэU.ztht9q5%gyZ)`F>2\R*jNJiBc^x.])}_^Z^Q+:o*)MY4?]e> iѭ-u{&6 Wu 6 Y~Y a?oL<*JSVrKUԥAJ:K[ XGsӌoiJJPOEVs=i{JRê7>-x'#ɡxkQ-Γ{-7Z^g%Z][j6Wp}Lu $Mgusm,SIۉO :pRUhaRqXzxtSZJէN9^HBqWOΖWbpW\&" J)JHPI¤{\@P@P@P@P@P@P@V;E=L z?ktx_4 3Wh5]Wo 'N/MWMQԯooyWfg=\>hӥ݊Z-DwVy2tSzǙZm5K4(Zhφ W]iz_~ Kӥŷ^,.I_on?xD?xZ5Ex=Sn4,j6z&XOmiwX;--Nkҫ*STКJ5pQ~ﵣC*8Qװ8Nd΅zuե$ӅD9I|T*֣$ViWt?_džtln}/V?|^#u[5<#z*8~ğxQ^75[;F ;O x:Sv6GX-̸R-3ƚ&68 e'Rr6qtT5*P('N8\6q\U 𶙩kZżuyu?]'mRklllZac,N0N4i`L(Eͨaah*?eJ)ϚmݳSp"N\UjNm]ժҌcE44+SS!ֳ4 ( ( ( ( ( ( ׿w^觩/G n/lx~4 J_/̅^ǏG jޔOz\H[]u<Ljk OOOKb?"=|Q`OSK=j06"_A%f~zYMOPOִ1Ԋ5zUtP@7|Y4;WBw k+ua[RӓI$l[u$E5+nRgC~ o J4:siᓠjź?|Q>ד:;mΎX(NJPչI5k{$.WJ߉ZwCux) x%4Ko\m[J>Giswsm#K5|#7:iJISZ\ha}jB5'FW3S^PImKWR(RêwsV(ѥJ:'4ҌyaJ5qOFZ$Y~ܞY^LnxSִS7#V'k*x(ӔQM5IVƭiM]R~#P7ų>V|LtOOÛwKY< Kcvezo-=6gS{%*U\Tn31b#g)UFt*U:u8~z4ו&ac(VBuhNXJ)Ria:V*|OӧFy4|K xwž0k/ k|ex^kcZAx;kgEԥuR]̕*l Ln_m*<],Ft+P֡URTR$aq8|#6-([ZZT1u)*N}]w~ᯈREh+>?x']xlG{oYjz6-\näZZ[ ΜD wW W3*<2P76'bJUvPOjd7xVRNl>#ԣ_ OFTcO.;S NqtxW6 ( ( ( ( ( (y״)gKC[4{;M{;OTҴvW-W4*O@sj0VجN#c]>y7iD䙛i%vZOd~pB^eZG5iL_jhLJ%w k h׽ OF%5}i'i]u<Ljk OOOKb?"=|Q`OSK=j06"_A%f~zYMOPOִ1Ԋ5zUtP@<9q+M%tmž"m׋5Kk5gv%؋u*nw|^^k嵓#OWr[۲Gy?#'Vv?xg}wCƛhM]4 {~xӭʔ*&\=og*jFphP zN5y>5+N_?y>js^zuiI4Q:~R_ 8U~]֞?>.x/W6#ύma?C,o]a[Eދcݛ}U-ͽB4i N;GJ|[J<= 8=8T3Fg&SvBXNUwIU(Ζn0FzU9=3U]cIִ|g=*6k?\|H|e:uiO|Iak7 9ԩ X?^_^it'/ugGT"c=* bʬӔ%Iw''bN8Uь=+A ־-^6t_O-VςECo2EᘼHix%-CM'Eq¼*Z9)b~NgBZ𭊥QCRƔ5 V)7ba0ѫd\k*5qԩfin |1o5]:Xx1ƍ%l)t>}O2i7m-Y -hR"2NC(p&\Յ?i 8RTOB5VxU\eםLF?2T7ֱ5EYL27G.R+c~"'/^$( ( ( ( ( ( ׿w^觩/G n?b~?M1uV[R:#>b \J1X;o8O^R*ޞR<WP]Efž7tԚ{ ws `NrҊZPhLn{_OK;+c8 cל?' )GU'o?ji_&\?+[H$?_?>ɩ :֗q?@ƿ0_\ N ("g}q^ux:^z+jZr};÷Q$vpnhE{WӪ[{yg>7'ڌ▙w7jPMwxVEiJխೝ,"[ʐin T3rkWEmrV/]^+lz7~%iӴ{m>9'k*x(ӔQM5IVƭiM]Rkڋ::m/=Ok%ӣM?zFxX;ҴOIh>->/_ΖVbK *s'M`h%TRJЖ&HJXZT0:Ϭ(URgFXLl0q,OVN M|Kma(V8RBMRba[hJ&zwx/?$;Me7 S*Se]taόNuzef5UZu0M:u15˞?k_ FS|KFE<5Rף TmoEu] M6P}]Z^9Mխm."Rg0SEJ:*Ƽ"ڐSPzN*)ՊNH8BIaNRo:R8p&T%Ju)N7pJJU#RIӔdk2€ ( ( ( ( (y״)gKC[Ƽ9"D-+i9_ e:Om]oJkPB#Һ:xSy="0—~ER{Z'(z`m-E]cbJSl 3i^c k_Ϡ (9_xrVx?MSB.MԴin^u{;vY :Ft橽c̭fץBn~_4q>V.]l:Z ;-?&pGxbi.Q?eUIZ;C%pq% 7{/|i=4o+]ƻ3cMԴ[Ş4MFDuk M".Guſ4T֍zUeJjZIAƮJ5#8Op(rU\=' W{Yu\UUsrq[ XR,c&ԧ9RjRkX([X,,18 8TrgVxFʍl ,# )FiNVI`kIE;SZMψHf9\RVSO/gF*4F:q#9P@P@P@P@P@V;E=L z?ktxׇ?B/v9N_%<X~֫ yJ\HZ~?]u<Ljk OOOKb?"=|Q`OSK=j06"_A%f~zYMOPOִ1Ԋ5zUtP@dys7յyhǓ1y^g+gy^_[/V ?7鵣_﹭T# MkLq[G.F5@.;UXUM+\l4$HѮD:6}|▗׽i4~V|_Kmq&i[[Cgez% ŞTԭ_!n#/ɘb/bJZ:NyZn7彚vj]3l5%W;jӃkFt{>o]SŸt<Ⅵ~|B<&OYƑoΧw?>\.UG8cSuPri[ QFTC-wFRY?WKejU_k+eUpWU'7YO''gW*9,*T^GÚxGAѼQ7<[öh|=.ҭxS/?_eERa ˇi hyq5-qƨαRRʳ 2Oڪtbj Vq^Ha=҂Ѩ 8ethΣX|41-*Sѩ7EΕi`xOc/t^%м ?Mω/<"WC ܺUumon6'DڛFT|FVJe㌖jeZpƛ=jtթFJThӭj>*GR&s˚pS)cԧUS PQԣ*օ%?b]|EVxc2귷~*\x/LoNKk\h^#WzEϏ e x <5 ޚECs7&AiQPԝZlFe(קF+UQS0b)ҩb+`QQΔ*t:r NUqNԯ.ԭ*tMFՆR&4q ~ K U5Jxm\/>q ƜIF3BH!^Jy 5Lm^hq(*C:5dRJEf/n,f~xC^𕏋~xi|MkG{efE$쭭M ͭPN\I 5%<)̱r'J',G8kPxJBXrO)ԅ*0TqSUqrJ4FҨNS5*k3>iKk|A[? ./Qs]Z{:ս6~G_ Rj38V:hC 2%)b(Iarcc50GN.Vª⧆iUjNӧNrKJj)ƢG~xNλmGZD^:u-|K6-żuZ_]I46_]WJ…煦(Rn*uhT6S|$|YwvnkJ[|#4ޛ+ݮR #Vn 5ml]2L6wuܲ[DƬ]mփ,TtM&촵ه+_!t?58y=#<'_TA(V婥JKqXدo T=~C,pc&'Z_טE=s*: (2tY<9v{cu3Ro/-+Yގ_SzyY/w֪4u:/7n'Z4~|/?;ԥ8=/.'~M~K\Gu*o,/ DL9Ie+ fxU(J5 'ԒMٸ RT*ҫ3{^ I]&^!0'l [NMk>5uqe 7.b?jt;3 3oKu3 )Ҽi{\.ex9iNRNMԧO(B s骘X Z4V漣.jí>ڬ^54?:y xKLz68bYDvWMg,VVxFePig,t\Z'GU֌qqCVujVZ8H%N8E9aF1ub*cԒ.)QIA`aS>x,V^G.w^ GOW^4ڏutyi|V_NHЭRj t%PPXj^֩K:y֫*NVU9FUU!F>22l$ O'˚ Q9WGV,-^OaNЧJ_OJ]Ic>|KZ|%|GqDZ {{?hƨ!Eb# PT9pSahIʕ<^c[48sITbAԩnjtppgB5Z c7ThVjqJ5k?ɫY//GMj^ztV ou/wjla[-" +~wPi cV2ڙ6-&j؜^QTyҭe^28&_Vp'}S,<gVi 35t%Q):ΦBX](RUc5^|C/Nk|]GFxOHc>Xt[F&񟉵.~!i~m%9]I! L^_Oy X\q8%R~:8| xikUU9#'F84֣[iw bkbSUF/T#Z_i!.xូ.vO|9N_:%D?m-汸vEqq4pڭx~l=jӳWwBURӇ&"B4b XPiԍJ*X:D'Ztq1KV4wz5bJiƽOjGo?gms?4xO?g>&k:,!xwOuL-r[= F?5>qK/ŵ 5)C9Sq˲ҍ:ٞ֍ZFrtia1y~:NbQMf:WV.'%M>u{ |(牞]|SKu hYxOx,;9u6h^x\4:;as{YRxbO t)ʕNR]* b$NУ x|2txJxUZeZKJ~ּsY4]/&״{{Lś]V5ow]j:zRj6+%55pfF"zu#SPGR80:>3V0֥<6tE<=\%JT燯_ FկJ-*O*ONOo[ w=x2K4_,^TXceQݼ.g9Ir)4saㆬڊRP4RQm6CM6=m^2j2r/ɩ :֗q?@ƿ0_\ N ( O2f|ݺ?uF/+Կl>?+cc'=6~ޞVK]5|w77ே>񿌼+qXxWP6>w6[7ŭ6z忎4FڝZGmaƜg&~4}=eo}|Oc_X1io{6&]X S¬rIx7t[g*0Э2n-u˦#(kOk+/e'5M7IBu~1յ;Ozol< +ZAxucKZ4m]a,f+ JuZtƌ9\;Fm8ؚRnj\e\6qEbpxa1T\hbq*?|U4O{þ$G o+x֚}h|7v7Zmlj(^X.H[ e.)6Ƨ+t\*8L\,?Ju!JxwN>x %O a*a:1)*|< R*\)J)'*JV Z)d\-a.|%/xT[oBY&i!y.t4ZK.EG*yaRNnzuKR¥ה\0QP[L%ZWQa%('O+ѥM귣Wo Ki(I5 {k9כUE˗5*T)0rRt酡^Qp嚌QNaKI'44)P@P@P@P=GAu}W'9k??ϥtKb#}x^׭zK<+JN PψzmúψCp Ӥ yx-ʹo[¤p qῴ )VeE99NU%G4FBWiOڿo9VFUcQ}YөgF5/N-Ft']_// &Ӽc6i~4S_u> l +ˈf&Kl$*O2f)CU8}y:b*VTVkT<>\0獨BiAN# [я:ң5FJQZTF4TtmSC1Z7z,6ڶ4W56ǁ+vn.m#R7FXFN֧<3ǥB QK1PүЫBj^QPJySzҕ:H::5)Jjc F!(/ ax=kn[fK-N8]"TH iewVkϾgPJpqAӋRrG))MJrRT׳8B-r0eQN1j 4ҊMCRio5E}#Ǧ:X#WGX#VVRVA\wYzP@P@P@S}^w_!~b{3WD"?l]Džz藨ĽQoc´?5щל?0 _I?h~Z_ġWIu +7/?O#2G2jxεoyP1L~>( ('E̳7nGF"+OsD2,\s`0 uJ|E\ JHRJ8BOSMqtmcO"s7'ky Dajؔ<)(8TzRZ|czѮ4#"s|W¶jlT_^tH:$qxmIeqC+?s ԥ8VQaSFj8b1p!,4c8'^ K[9_ꊯ*|X5̰*ϫ`CIq| Ok1jsKuX^ͯ8n4K>xOH67zyOWm|[NԿuBxzٵVYB*ʳ)*ccMR1㣃_g 8úK.2,BU:UhQxe:-5(TWR'W8N !GZwl|+ ݽ/-;CZѵ.S֭#^氳S[ 6w7ٞi%쪵ѕE*~=5 MN)A֥bcIoBhQp!MJHCޅ&"ӧ*Մ?e88UrUFQ ( ( ( ( zD=T>8Ofr|JG͋[-xV\x1??zFOKb?"=|Q`OSK=j06"_A%f~zYMOPOִ1Ԋ5zUtP@dys7յyhǓ1y^g+gy^_[/V ?7鵣_﹭T# _A Zx5 x7qqyx;P< .nnxU&.w(:ћ(֒4?>!m߇!⨼wV5?[x>9tڕé5>$^|>dq,mq)ViaBSF,Wk,TT,E*1z]iՎ#NRRu'Jתybb*µJ)JXU#)Q =w8<=jO &|lxGxG—V׍|w_ R(ϊYœd֝zՕ:L BvՄFgNJ)Ƽg PN"rԊJ.xzr_O:>:wF.եIn)ҩ QNq~^n't/4?jNJoEIk5O> ߅0Z>j?qif:SaTü5l4e/gVVۭ/:xJ5jԣWVk죈xg . =W3*[ Gt !k-N[kx"頶F.X !FULn/5T'&QM蜛RTQrzl۶sP@P@P@P=GAu}W'9k??ϥtKb#}x^׭zK<+JNs2ƽa]@\\~SAlۛ8ga Sjv>qiyWq/,qO[_kdeߩUxDѵO>TuƜ:^\C)7eYK^;* sשK NHžNSvQ5yIQkpERiE%v$xJiW߉ Ƒsx&F?Nt|hѿtR[;OnQ[{ind6RT!)gJ _"^ڛRUFX¦>,6jpX՜ЍI:tR*TV*:Ys<+[x zǁ?o.񗆬<_v Ë rzo 9UKmuE ;XZM}ްu}uu69K(ԍ>lJt\7:y+ B9ҕX XN9VQFSs\iU9=G/mB*b%S FEU~kz6ַa3z/ <_zkˋHfF,"Z^ν<^aJ0'KU_aI9F uuNcW u)c+N^ c0􌤟:啣eg>U?ZmOÃ}0O܏h:gMsg|?TֵG[oWI"iE- e Id7Zp:ҫRlMh/v?Xc%FYEZ)TъR0PyB>(NI:jQnu;Jm֌P-,EE8OlO i_I4G~ Fw?غ~iS]g]\⬑lxQn^ a]y­:PRg~ҜjNeupueRUL7ucJttV^. 3q5U:FQVc@ ( ( ( ( U>ٜҺ%bIoBFI lAwбf5k]_'J֚yۡ>ihZWiM14֖qXnqG1.򱢒[ rք1JRFiE6%*n2qqi٦M5M]35E|eaefX_ [gٴw@M;“l?rx+hh.";tj]jt~SQxNӌ*PjrTqQ1tX8OPPb O4uhG>δfaJ50o 2φdo[_6x/=x:մO2m]6}Múzω.W,K\}JUaeXaPAQK,ƚE*U(aKJLFWZupcSaI播XXRJR4HTeCFZe ulAuÞO(hha4[XImj +4S +QЩeXXTQXn[R+bbS ZЅHɩ :֗q?@ƿ0_\ N ( O2f|ݺ?uF/+Կl>?+cc'=6~ޞVK]5|w77ே>񿌼+qXxWP6>w6[7ŭ6z忎4FڝZGmaƜg&~4}=eo};i!4mSϲ4;n},_qq%Ηj@m`t41|ʂ0R*ӫR0SݔaM^R}c\#)rQI]I%oD.?hfӬ5[ujZWm"d|Y7zo>'A?t5_ow㘼 bE{qYʍaTՊl>JqWúUիbba#m W*t,CXS,rt#G Er*؊9p%K,W!TvǏt>}῅:E=XѴyu ~җ?4mau i~#]\Gj4t{{{ފ1J>ZQtՌ uW2~cV9%;N8Eᒠ F"<>:xxJ%Rm*JTV^ ҫ,U)JX]l߆T3DYahz% ்ζ 8j8'?hoi<+._ttMku/3<5x-CHdim{[jXa}YCєkQQOyRK|pjՆ"WiTVF8zU*}f%~zTJ)JUpkJ)C<$&ԧV1NWZR'%ztEYC*|:^gx@MxOռYI-SkBOZ\"p-9cMah)SLQ&q,1,P_5޵ *V><:0хHÞ[UL,)S,>"X񊗽~!COo :φ|AqS }V;L!In!-{E*)^6^1E40O :8p2qxlf'VJ4gM¤$$sb1Yӝ:ob2\|=,E:%(8䖪P ׈h>$ִ{|Gþ~5[z|enm_ӾxS&S[ah47%Ҵ԰-jVsjj=lE<\OJUե jСGJX,q,F'0Ls˩aa)csGqN5$񱬡K :rw_ *Byήx5?nτ>"mNI x#Jn ukƖo3xM? x8l5隔mj:tZ*Ge^Xcb*(b1N}q*,Vm`%J%K ;GWF8|*UZRSKV"Z]W(U)rU't#?׼kh qjǚ6OҼO$i4;2|OT(zyS `t2챕^; JP\HehaRXLDjc**yµ|-\_N:#ʖ*Q1qT N^|!k,z߃>${]|Fh:|Q??JU♧6xula&!9T…U*>a͈Ppԡ)*aХXyWq' 둄l>JLUZQ 5j*!G[Bu6b`SN \D)PNT\*QV2|.(AJTkX\)ե%JNLM9'' )IFQMs>yI+Zok~T,Eo^鶚Ěw%ZXT7*Qĺ=upcyU=5,!:3%ӄ#V9V1 Kin/5H![DGYZ(N)L?xq,Ra&9΋c9p%8n:(xGgpξX|]xQRB*89֌WWJz9!;IJ".tө 8Qs_a'>*kCDk~<]e6C^+ULZMtd+6n~qԝ:0INb*5W& C Y{IҩB|dG:ZJZSxj/rCG EJߊkM.~ xK~WÚn 3uxSSutcwjZͳ9aj`Sj41V=MW>JV5*ni¤](ŦzUU֊\՝愹g85(8ԃR~u^++( ( ׿w^觩/G n_ ֓KV>x*xl(tþ TO ])!>r WZR2,h˧ٲ h ->[_j5Z]wj*%[y'~44ݾxKg3oIvJNk9<GO_7[>k8rb?hJ"WGlɋD?*A_{E3&/'|~Ϛ>GO_7[>k8rb?h!ğmVbf\=\HK.+ #0Dh%_hE[O *A_{E3&/7is]X"-+#Hw N/"&iV{.>!ȖҴM2*a~2ILbpGTp~չ6#Z/?$ya.PʤʽRPQ䦬cһMNkUηkX /x8a::C1%mi)<VX5x{_XՊi^Sy.P ԍL;:4%NS8xTTiTFU+֌l'W]TZ9l?#¶;R˦xՠ-tL_H9un~mI,-c>m,U,EW8VZҩWZZ+V VdP8hҭB+X79WQ:r%VN 7BFu)xzxFi KO㨭4 UW+}'M7\k5(bRuI')Gʖ*xbS*t!,4*†ҡO:ҍ\EyTXh0uhV^Ч \ըOƜb*rG^[b`Ooo<;uDӛF;5ZŗKwoF;%0\MVY,żPL-Zt¦В*Tp5$bkeUʂSB8~*yBUV*a}:P7V:NsVHʅjs*Ӝ$ldN>#tz֫hz|U~WFx>#IdeI<υMQW*$R.TahAS-8; RQpU[ GJissK77)Eu/uEzG5+֓ 'A^ՈKUdf(8tiץ 5GO_7[>k8rb?hJ"WGlɋD?*A_{E3&/'|~Ϛ>GO_7[>k8rb?h'"l,SǕot'@Ah.~-I 嬀xTfDtvR{l?Oi/@X/SKo.!ZkkW7ޱL<0-F%mXXV\#ӂM;Siڍݢօ7F$.iɵUySv5y +DӥJ-E]cbJSlYx'F^%imk{2[Xiz>Zj:wr ]\H0+)MBTiJirS!:&eR|SqJJGJ"U'jM0B<ӜpyNn1Nu% T5Z)ѦV!/7oji K;x<-'Tힹ&s8, ii6i>ލ'VњӺެjƼ'V0XZYS ѩt:u.^Z܅jdRj^SJtU^G:SJ = E>n|=h xCg/^*$RKi{]]Mciږ[hmsiw[[]Z\os SBե:.*|)Մ8TՄjRN9J)Ԅ8Nel/ze ѓ8J$JP O~(( ( ( ( ( ( ( ( ( y +DԿC֯%ȸWIYy_#~)^8|O|?>. }?U;=WӬC ^VI`-Kuo [UyW,<7V IBJ)ԄS*JhVCa4Uө%FPRFb%N:]:3t,qԩ(R־|RD-)|?Dڟso_OkV.ɪk-'קRKe4E㇌EbU yHCSS>S')J]|e_a*pa)TZpzUSXIns*U+{JΔԔ] 5*4VǛQW~ h!ǃ'Nt]k[QӾ :sjtؠF]wT//t{{3ych.t[KΊhֆ O JiP ԖӠoь)KXK24sނϰ}}?̟Medk'GK24sނϰ}}?̟Me!=s2 ><生ҟCeR {Jg/oSx,?<生ҟAg<(?z >&_'GYpy2)? =?ނϳcmMs8_zk24lѺ:1GFYNVRVA銠@P@P@P@P@P@Qo?kj_ġWI\?+[H$?_MyKnm!>?Sy-nd|iW&BֵbA]lbqr$0XԛOGR%gܣ匜UZJ2qm>Jغj$֫"=i~񇆿e XKozO/Oi1-rs4g0K9q+bOVIt&ڔڔyU"O,U| G imS J4I'R^pjiԓEx|]Qkª_9? KG3D#|*''^ hx|]QU`d+-Vk:?,윟xO%b_iIac |_6-U/VjotORZͳʮԳLlB%5TU:2XN1njj;b1-B:UqTRj)BJq,+NS(*nozXjKX.iTWJ)ԊI'Lŵ>lKM:?||96K5<^.%D?ps,lR{&* گx5jwgMʜ9sC.*re[t)JcO2dSS$R1h?g_!xuwC\oW冟9? KG3D#|*''^ hٓJ)?4'ǀlSOlbGETi5guR璜)G4JN~H,Mw){:s>X\ԫ;'NI9|N~;g<&|9{G+C^n5]MO͈HX૚s `pn#WF*ժT:ujFӄ(ߖN׋Z0.a8ZkRJ))BSSbֱWWWOsӵPTԀ- :% `P@P@P@P@P@FA(V孩_&KqXدo T=~G+E 𲻲&eYÚVS?7'LxW p w#X>!ڸV_Vng$gkPӌ/a8Ls^> N $玅fZZjpt,yVߋT冣e:%8zc{XT([FKfAӿ(*4όl<gxTsk^>&Sğ.喧'oji$/Sl=uьaN:#c#r0'|x"l>=֯jL*iЯN RxZnei0tqgRqٵyyL1uy9ѥt:wmbY}]:~ м0'/j:ߌ*/Y_t0,?]2iBp<Ζn50ɢKG0~R),5:Rj`FęYҔqW0JzxН4KkRQTTj,6"XC |i.}muUd gMNiY__umb;K5u#]oki\5U XRWتTьq8T'F5*Μ+Щҍ[:8VQi 1&p0Ԗ*EԧS?eN&:֕eM>#ecƾ'׊'hiZP'Ե/zU >յq\RAsV3;9:|5BYb+fu\Zj<`hx:T2ejyBXKGNUʦ[J9Aaf ȬU(ӫW]n|pWձ2>1E|;5|[exu˪~Ҿ Ovu?] |Ex]'C2kYִK,.[=6OgDVR,eyWɱxio헇PJ+C JR<^"+5R8F/ t} mVNT:x/No*3VۭCtĻ~!|b3um+Kl)K6K UV `)JqiJzlsC xΣRQ+C-uBʽLSnMmS쟼GzGdi?4h/wBsba7}jl$}iK\r_q/gZiZք/:zr&칢;+͟&gT1^u9yKNjrcصo j_҉+L ( ( ( ( ((7 ?/Po.?-Vo^`GY|U*Xе[MK~&59cgp[1?E9OC$C0Umj89µ)4Щi(¬n̕0aúP:5`ڼyV^ I4\+kݵ<_Ԑ?U$+,c$s{㌟]br+q /6n __.O쿎5cC?:|[[|B{9G<7,xet/;QA8# ? k/>N79mow_Oñ :|[[|B{9G<7,xet/;QA8# ? k/>N79mow_Oñ :|[[Aό|ژԚ,QN79mow5o`~xG\~мWj׵#7VexF[MЯhve-V9dRb8 :8=LUjjTQ NR81yNM86G3ЭC Npի8qq7.VoR);7{YKDۢXwG$X2Z%{;|tP@P@P@P@P@PZ'J-E]cbJSl,( ( ( ( ( ( ( ( ( ((7 ?/Po.?-Vo^`GuIa@P@P@P@P@P@P@P@P@P@FA(V孩_&KqXدo T=~CK ( ( ( ( ( ( ( ( ( ( 7 GO?-mK=j0"[ 9_ ivXWZ];@4*[毪MDglmm3pѣ6j19sQ T;_WvKyINQM*Ӌ=Z:p9;+NskUɽ.ƏɣX[еvQ7~ņ[-G]#MƵ 2 fٕ®SFF剦ҝװˣ:t4\gO2L}luCᠧWj:75޵W SWvr ?oI[u?^-4%1i7 9WʹstԌg^ rSNc)8TU%ӄJ0~+c 4+T)SJ)xvڏ/zOjO .>&=u?Fgc5[۝7L/-[wz΢I(& JtN:#^URIS|Z~B4JuA.z{jk'*PXogFxhTiԍ**4cNiJΜ*0s{φ|AF/.|-Apm5 -ൺVi$V)aPJtVR2FI)HT$iӔ+Qg&VjqnR*U"ԯ' PItN.r^Υsܕm~2gMo~.t6ޙ>֐ir[H(歹&I}qAU14TG NnlMZT#z%RV >zVU$wJ䴥Q Y_>u+Q'}Ahj=ƥ .+|6:Y} |^il&-[5z)W+1W [C֔TJueRwڧ-c,n)TӡZӣ^4iԌa^iNjqo3>>͞i/[0K@/-dAC^*UV&qR rV*΄hSqΥsD97fT*BZJ8z1 4 6:*p%7.VxG$)M HMSDu?^jTȭU1%K,o TT,L^G-ks8ӯO6X`*PsQh)ƜگAFsaFn:RNNs*ks[̱ppg*Br:JrStқi/2&z^7 PICMLë]&qodZ GU*Q:M8V콕6:UgiOƅiROQuNvx*u%G uGBRiƭ'.fUH7e8o~0|$|=oGë |o_\vs֍oOڬ2Y,1 lBQ5JJoiQif7'5>h{΢*JX NWGMQQJ,NG"+$lGGRC#)H U2 EQm8M;44iꙔ' JrS4EEQj馚i(( ( ( ( ( ( ( 7 GO?-mK=j0"[ 8蚞g-j"4k}Z\ZEwjZdF{Stߴ ID$~-ZtVd"T&('TӛWϋR)ʋJjٸE=9Ns^<M Ӽm?Ľ w~,Z >,~ jz5Y΅"M+U.=Kt yF8bjUn*,7* Sr~-26s_=X8QrХRZo:u*InX)N\~xf帜Vuu֞"zrc&5nfKwtfWP|Eh9"=GKI8Ќf̦"q:;ペ,,$x62NV7]iVEW \o:^'R"*^ֶcRPC^Is(ӂ;/'ݮ"&Z/w^F\? g -47:6&Q4Ԛspxl-ԋOw8e'&J6 C* ӌVl~|E"pJW-u#T'F &6n԰ zTA;S?&xN{ڷ[z] 3i ė:1>vZ~nSe*ԩU[LG<*1Ȱܑu*X<0:x'JKSTCGOOO bHƍ ʅL YakWׇ x[Z/+=~6|K6煯m[CD"YD\:+/y>V"LFIuG >g(VJeaF/MbZ?g?GT3,&. Jb iGإJuhrNnUXMNx[G,l(iѴ׾ Y {ڏb˨뮷>j|'i]}Xqt4Y3||L*C1F8*33)&Ga熧NUyqʞpv0 ,f.Jث⿴e8>.2`kѕGBS}rRᄗֻNjuO.-W xUMӭ4Si{۞Im;HD;m.7Ո.3,ClvJNTX晌*9R'!VJ*(C8Z]Z*8JY.*RKXl$2q׷t|ς~?o>$4}?ViqIk^ԟĚߊiVq]+~ZetFmRMu|X#j:ЭץEU}]T5+Ps Y.^i*Tae E >&jk Щju'N)avƅ ᇫ:U<M|c&-\xQe񏄾*~Ү {}C?Zlڱ5*{ 0SGJ~brqNt>}bfQBQ-)N RVP7A:UTJhp! fYU ψ5YBiҧFi헲CFLEZ}ӏ)F՜(P_{>%h%L۟^鐾a/ &-ZO KO2Ohܘh0Q:Q0tS2YZ~jNJqkVtӤ*sphNq4NmsFة(aib9OlLOJ2NygBi(7khѬ]jwZ Zt>AԌ)p?@| gE*k\,nhN\TB&ҋJpz8Ŵֆ88OU8ԧ;_pwW]c%xM+7 I&|jV lt|=Oh5ѡ=p!Fu0BF< F&4;nW F&ib”q {|^8Ҿ$xzG|a{7^Ѯ|9 xF4ki|D׵+L^jO 58(URJ!jlJq*4 r]ژ߇<{}kEIK/c$G4UVTFxOG a37J"Tk:RXZb4-^:UՕ+œ!K <]5Q+Rr, ӭNRj5IƟSB9֥S/O? 躧>|Fwg{m[R冣xVyxDCrOj..,{qwV:XϬ:SlV+*Rt+;T=Jp4JukbhX|qSB)—)}ZO YN|՝<]<]5IS-B ]S|{_jNN#(gJIΆMG)}9/>^o9(*U^Ν\U,L#w/gJQ+yhm=5P@P@P@P@P@P@PZ'J-E]cbJSl,( ( ( ( ( ( ( ( ( ((7 ?/Po.?-Vo^`GuIa@P@P@P@P@P@P@P@P@P@FA(V孩_&KqXدo T=~CK ( ( ( ( ( ( ( ( ( ( 7 GO?-mK=j0"[ 8xYkM/,~Úm)OysXwZ@n :*z0hԎ&zK IUN5fZUnj/Fl^" PSUҊGJ*jrr:jM$Zm}(k|',kό^' ,,-VI> 776f4 fUrZi:U8F) B+rPnsNr"F1UANx\'t:8GyNQSH𿋛T|Km]Mc>Mx_~ٴ v~\RWa&sQBέU*4ѧY:q*Z^;2 4JZ 7*ԥ^t-MBS/Ȥt֚[k:}yeeX\E{cyZn,rή3)F8SUhSunu(rǗ־wRiƴkr.gh>V{yC>Ũ?n,|8>m>mR3q B?tRަg*C^_[Ys&Q֝.NX9JQ3կz4"9Y6Z&V%ֽrXޫhy7Oj.kYZQ$R-Bni׍v63~+-м;coW4 jwo5_wOqMwzvwwa|S4SeԧA9/J5'TjJ*u)ԍH^HI7ź9<9Rd߰ ַ Ӕ'(N )+U"w~K=sZƟOk<)mwN,NF(6HNJ\Ҝ34\y-c8+KfQ$8ӗ,i\K,+;;I=4P )SZ 2Ym-羱Y F+e@9W7|דOeo{*U9o+[ToNg{KToF\@ D9%$iNE, 8PN&ZZeJ%Rr|\۲M&DPN9F+EvJjxE|CG4_Jn-էj6\}(̷77]uV*kU֏%j'(7+Ÿ5kfe Ƥy{5[4уxguW|Sw-h^75;lֱ7t}FLlKb;}>ͯV#s*u9c);5Ne8҄VvB3ZpSxҨӥj)Ɠi9Iԝ*գNz*J)RjotOkɥGgkxg:4- ojya+]KYY\kZt7sZn5'ז+܇40RϖG ]Ќod?gj{pU ʤc(Ϳe,<*H)OxuR$=\贀( ( ( ( ((7 ?/Po.?-Vo^`G<[_{v-ual`|Fp2=~5PF0)T7)JW<[3׼)ZRoZ ^z ~]k:͢W}tn5XV&yWXu%STʆ9v*I}S/.3~l–)U,:^҄2sN5<G2sa'R2׭W8N\TJ~5ia/H|C xGUgCPX:7E|eC;Ծxş%Ԣm6+HrZQ >Iq^cjIJ=:8zyrmW [URSB3W8eTh!An<= c\UW Ɩ' +bCu \\)Uw_= ?$4? >*/`% ƣ;OE#kmw>.ÖNP6,$xI<{|cX~&-ׇF Pc] ᧏eO64`$d We:3Z0]oycZxb#M(*sHXhS˧N!{zͿ>\j?|A;LΤ4|~&Ѿ%۩s-hxStӞmH%3a|5* .\LZb𒧆w*t:O NQrX57 qs& >J*JUgj|N*SQӧMT҂Q2+KGNoXlS,T|1MmCԴcG~"w?Q=GFȎkK*ir`(ZXSa3cUKb 5|%gEVsOi^㥅rOڣyM*s5}ZtKi'/Yc,K {k/'k/x4kO.s]i"O:P.wF񍅵!ƝtC,QB018iՎ.ytm,U cV+%k{|6#*,EIԍdWu4ҥ:8|fN9e_xGD<. : s$u:I7߂ 5HE֧~ ?O jʊ=O.-#{Z/]?1ZG*(?_cWTQj7tƯio"A_?QG߂ (zi}cm5ߓriextR ʄ$Yt!|G4 }nsxO~ V̉r&u-2$a*Ă zG>6f??bqy0(-[ w| 'G?x}KC_ ?Ajp__9:?0&Xb^_#OXoAK_`7KgVM<xb^_! qhO>/VM<xb^_$7?K~RXktz;ݪ!584τؙ]HN8ҞO*獜TۚLR|%/uN90p~YEf#>7KIY xKHٞ;WKYݙ"7f0YO53v$+7-Wd77 77Nk`x1Pjı[]@[ ?60c5:1p+:ލ[U{(G|P#ᾭxW*|q?<[xZo0Bu<35F4[Ηyvhk2-JY)E)<jc)MF2NGC~|ޝj -HkY5`V0zeoQt1UJ>ӛx)Sq*ZsSO(,?4zM׈!mhW$!_L>#jG3!ԯa#VYW2RVj.;VVN1EUqXխC~.xk,Pc)aVEj88* :Քbҍ Cy~8<$h7OöKr:>Md'?u-Y%K/%ޝS}E⾕ $qZxX<5,F/%Tg9J[[$חQYln"iЖ Vycq[B"0) Y-E(*jЭ6(G1PBSqIJXѤxI-x/mxvZiZv+n<~S`x{׬O $~qxV(Ζ/ ֫5k)F֧VL<"*j]*kTjXgN*2G1֍m|=5%']18ʦ*4iRK҄0<1%'B>ƚ5?jMC[Ԏ\|Vڎu >yox&VvV RjUҪӋ?7p '(q[^. M‡/D'5}OY%3qq.$+ j]Sb(U-:.Y05+{JzԠ)B7}ס_|^{ۻ|^{lWŽXY<+Zi1g+7e ׯKjt`ڌRMp,q.OCJb%~UN+w̩ a?N;_ 4}c?ߏc?%m"oOh3'.DZ&m7Ug=*4d(e s)UtYesrep$B.Iϒr&G688تi`s(FIa1{rX|BV Y\o34xsNyУt)丸i`G#O!e%:,.)c|qB,Xe%c*xu9*R夥%MF[sTԮ_.z9qK95e ʤY}^jNs| - &hVmb֚7K&JX^agWpT۩MTrpMթ:ew~J*U-Rs0`(ƖN1a(i"I#[IpwQ/Æ ϜgY-ſ0_Cs~ |_-,vQռ oebfd\澱WX}/ Qڌe&;&iP_ dq蹧B0#kK xCXXW|Y '=OD֗3$VҨe$4augR]YurL>9$ӌefWOSo?k_ġWI-E]cbJSl,( ( ( ( ( ( ( ( ( ((7 ?/Poh6r\[Ϥ%&<ĐFׂ6 _kܓ+AonI?5i!=;?/>פզ]?~!'7:Gs?5i!=;~_}IMQ(3CzO Zou*cN@9kjCT{w? ^CVwӹPgUs?/>פզ]?~!'7:Gs?5i!=;~_}IMQ(3CzO Zou*cN@9kjCT{w? ^CVwӹPgUs?/>פզ]?~!'7:Gs?5i!=;~_}IMQ(3CzO Zou*cN@9kjCT{w? ^CVwӹPgUs?/>פզ]?~!'7:Gs?5i!=;~_}IMQ(3CzO Zou*cN@9kjCT{w? ^CVwӹPgUs?/>פզ]?~!'7:Gs?5i!=;~_}IMQ(3CzO Zou*cN@9kjCT{w? ^CVwӹPgotn8{]:-Nivl̇%-U N3%-_k_uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image066.jpg0000644000175000017500000010531011665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@"H!1"AQa2Tq34Rr#BSbs$5CcdtD)!A1Q#"aR2( ?$ >RJJ9ͺ\ 0%B܆J43pHuHn4E9R 0 q d9N}38Lvu.sLGR {cFJG}^Gp/wg%)R9+85}IACsT{€ʰ:n_Gp?(z~R)NeE Ց> _8r N|5GGg p07G.)) a-19)@6*#_:!!!`iqizBD>yiNTڸZaړm7ks&bO"?\F$(s&jO[qґD279̵Ɛo+ yS\+*n,NqGmF;R)*r@;r57gi' }LgZ#Z[NiN@Pm A ($vQpRe2 uA) :N5 *9 #%#;H%ugGV{~ɹt3 i 8粃ϸT.o(eUed9~Q΋M < {w ,`iV9P8VtTIӑ洂vRTH=əh%/8uMZR;JV{~Iϸnqu\JW:6:r{#ʭϹsmd<EJQ'$l܎G(6Z6a9ЖR ꔬ}5n_G}A%M|9}щӶL%XK BBpysA,Q.a*N[՞bX_aׁoZ_Y9.r;yUF|yŶ40D,lJN<A4GV{~g\on*jD})p9(V6ؒ? )Ah}֟}֎i)AE)R>OŸ]sѮwju?Fgi(;LMIW\34k&~&]sѮwju?Fgi(;LMIW\34k&~&]sѮwju?Fgi(;LMIW\34k&~&]sѮwju?Fgi(;LMIW\34k&~&]sѮwju?Fgi(;LMIW\34k&~&]sѮwju?Tvbb;J$ZPW*D>;#d^~,E"'Pm9)nWuHOʼL0“K1@*Jx'A,`Z!Ȍ@RAtS.Mu˭H|Oty&-ԵJ\mҟW#[W%ëqRm˚ShTF^FTWʒv>#?FFQmN(r9:.EB*e:KI9qբ,>ۭZ +Qh%9{UҞMe~)nK*h6imzKqL$[CB8zWZsa#SsZART?*G?*mIQV<ɬ92$hS$tEXmZ%,)NFprq|9DWИ.RZA|d`x:D 2GPKaI\a* ;ҳ6tz-/Gd|S4ʇUDyڤmI\q!cN6U8i\q NIG'Keʡ'Ѝr<}(tgN"1U4r. I#;u[]wRu֐8>luWa:=ĸUi1WBYBSJ}-"+˘* hs?ZK1˼pph֜݊eT=Ŕz+IگcQxEYyU}_[ӧ@$ds>4%~Tu/S 0,OeZcQTKD{K#_MQV+GOʎ=~T.J/S򣨏i⟕5E* D{K#_MQJQ?*:)STR+GOʎ=~T.J/S򣨏i⟕5E* D{K#_MQJQ?*:)STR+GOʎ=~T.J/S򣨏i⟕5E* D{K#_MQJQ?*:)STR+GOʎ=~T.J/S򣨏i⟕5E* D{K#_MQJ垸kT2-J!'HxZiP Ay껪]^0eGXC(:+hԘr$8u *YrNMdž-%Y N$xyUSR!:K/vV1LU\?fT[~j@U}˶A?jԁmMJXa )I;K16:$)RYZVBvNK˴uǑ6;jdu:L ܨcT[S%GIorFc[IKnC JZ}㘪DYORT:J1=ee[*AZW(P#O``ݽSjKl +̺RǬ oZӅy%\u. )RĆ'`M.mn"e\d^x{*ēщw3\B C`'aZsG!^/%M XHP<jt_-v4Ӣ6--nwUr!KIHAu!YW1gGb=@FLgzm`gs;W L|L `4p狤ov1fpqz̜>ΘܖJ-4RB{JV;UiM]"d6!*@ˆ?D> trDCm$)ܨeh7KRbFlnPGXӨgƗh}pU,(6I<k.ކBtFFrs^LD[VЗ6*P*. #zOFAm*ulldJu3ค0V6 zu6LNA՘'8md7n;QrTv(o %'zwRT!rPbOIQYNg`bl\$!)@dlv  㯰xe5{ޓbskIP絾ƪ6ib3DPe FC*sW:\1yzieFj' >^4Ƅ}~WFIhdJ 9 ;VY"CaC Ʈ9e.3S2 &Dr0}^uyiD3PX! Qed֥%lwg$}[iE)^(v5g輯E*KR) rc &\`:C'4[U!##ܬ{,qݏmK8qg给'}CnJBTAP5d6&< uƟe[WyZՕ9VLI=i+_ƢhK*I9ynYݶݍuK ;vpp=Q.qxBY 劚ʼ4%qMq@J<MuH[ N,TcEyMZrS`Vx80T`e!'=+<\,\CMR0 ti?x*2PѨ`t[OF3zjevڌsfJ9>>MYKDɆV5 ^&dDt`#Ǖ$Yxuy,MAm(yIl6[=Cl4ՒW'[.J%I*G4՚jζn@ %rl†eD|[jK PP v<_F blp+2+ر.,̒DR_%-(@o]Y5s~}LPO( y8pۊ/:-,"AƷ9KBJrIտ:Y#2)ؤiA+9jj!/:rdR;&;ai֒ԟJȽ@5BԷ8zTe'Y!;<؂ Si[KPsʲ9Z][Ԝ`ckWSU\9N!n0.#|'쏅fз98I4hN*>\Re\K:G #Rb:G #R#?d|(П>*)c6|fdiPH? #'+Zr?Hɤ"~b:SܒR=?j~CZj*-Pkڵ }*e~j@U}cQUmU_j ^?Cmryp*>C>x`_M36P RO'_ic'4wp6!ݿ<`xTѸfE3'Pm S$–"ETq җښA)qu0͍$S.Y@[d ';c9$aCVUpRJsߓS^K.]L\^ 3đ4(N5wz# Zq $C5E^nq|BZR!JyZ"Ɓu_N4uO/ƙGOr,t%/녆˺P8pTp2Ƙy% !(i[tf#)ɖTIPu\nFudժ>::s#X8iKb xiΆөG+*WHLf-:nvF: rF)ntS6'$$'I2#F`]._*eu'#N3qޗAehA=EH 'INC񭈲[-gC NF5:3((Lz#YJDdBJ҄}6V;*Wy2]qm8Ɨ=!i=JQ vyrɩR].Ң0vT䶫bI ^ G@1$S2L` Z ʴd5mF@nlEepGƳG.BeZ2!4VE.$ެJ 'c{Cے%%)ҷ %;AW&фIem}*Ӕ}pn(XiO.hBYoW`u'|ǺEFP1޴Z 0TJ4lyWQ,zDBP;1c‡, -'3Ձq=ye'$񛩑V\7c8CkaVꂁR6zظLDZ4)$ go_G˹[ @iz;aBʐn3)NldA_2UzB1 P>L9{qtR$FZ:y`yTˢJDIϥBY)t G܎jx+pj#Y.}'YڌP\kKi#!#;Ȫu y BZ` N?C O):pFû_GXuk[NrT𣚟ʤt6%/m9*",CV@q'v5TK1TR'ciK%֒xc8*w_=I- B޷҅, +ݽ[ķ., ; NJ{ xi+fwfzi'W$'o\Cr<&g С9i>0 6Ȣ2թLr` BmqR% 2c#WVn5[Ԧm<_ w$(dmjbp8Bh}AèmlfwGթD5IʘI2FV# RFY9s.,+d$!ҠAN1](6KM - :)/)Zxdi9Ʃݮ-\6kmJt;qՒ!Pp: cΧ:ncf´ʦs}i(.RaqÈiHH X؁"ilHBR@dWijcz[1:͝haydH'l9⮉Y3rS%:BAҰsޠ02+V%N%3 mPm6fLk6Q)Hu g$H!1EH%[$jo@g—~s16#,>ߓK¶wEKmmFmBp6'Δ.d7,|]#,/xq\%)'pSEIW ʹ!M4u6PZ-'*s)8ű``oΫ=|ڢ]εSgN7MK7!oܥ[6KdI*zRga sMWKi5r\q(Z^p IJ)X N["1O 1&,]ź3l=!xNXqߓrZJnG ⠎I)>Ű6քo)%ՕSc9ڛzh~;Q޶DqsmL灍D2Gl&?=Vo݈Hy0eyQ Pp;SHuvюP9omMɜꔒx5rޭ46qc *)m! Vr¶uQ\QEQ@QEQ@QE-Q@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QE ?3o5d8씥N GaV?ri J]I qVGW/;OVU\?Eߨ5GZ>_vPkڵ }*1UEU O7ŭDeYs.ߏ:Mq*d6m-9'NV2 kR#Ź]/Sp[!H8Gxp=\2ʑ.Y NQ~ugwT} RuE  {JrW ɸm"bm"[HV`xsޭ}F;1KӍYO (uzj-Ǒ+aHHR:zħ3lneb0J1!ϾrpEKBHCM8!sԎayq\G[R$[- :LxN\6SNO4y~ғpU ǒ c*P*=+[in(%#'TV=~ rs/3qm UHn8-DlrH9fv`MK*@8dj1>bDBVx'9j(.2=-nD#\nk89;rrz].-%2Ӌnc*(q-$ D8ȅh9o{S=J'^JA# swF"DXԞ2 #l3]cojc\A S@>seWPx%oj|cwnW8UmRR7lVry[i-l.%*8#jꊪ+Ez/Jyl$'Nv$&mTNqc'ʻ HS! =֧kSc )/-q 8PA s;WkыXq.:xAS; ࡍr[yɬ!}EǾJ%AI# jGSO>%T_fKxB C koʷ(B(((bdYEb<-,!`>xAusӎ)׮y5.3%mm Jf\.Ѩjt|xT%J!)H'0KTuKIyTK3EVIi.m\dƬ-Q@QEE K Byr(%EPUlA#L81dAKQEQEQ@QEQ@QE#&2G]M%'kF?ֿ~CZjRҫ] }VWݠf?VQU*MqrZqdv H; 3Nd*2cy9@Т@{tL{|g աʼEO:U6ëK!sVzz9s3YZ 6LӎjV]߅VZe!Yzw j׸B@Bٮ;%qp4V^N Nv4/%èuhPRT<#x""W9R-S-11)Ht+ /bL+zZ' )ҕu2ޜ$Vy07r,S/jy$=ώ*]~\]m8^".[J8><2uL=Jl1!+)'VG0q,[. Ou>8K BS:JڰpEo3#:0N3< moH\8$Jjkʼq)X҇f/ ®#XG.)z;\-DdA{;`֜^@TMTR1Ifˍ8v"ZƳ%<03vk3׉c,gĹkKsaO60HЭJX[m!j{Nq;gݵD#̍W c7zuuE-Ƿ;6r]iqv\HRG-'Pn&!m8.7s?0cbs:^lui\xcƠae3(62៥&4%Vb8at(@ j7޶qu(mQzoӣN8*.?RXN8!Cy ㇲ~tO:)^QzЕƒ`ޠ 8ݞǒْIRO Jm~_d'Oi+US7d[> p, {w*i7=PYZ|>>ziCZN3LFB B?}njPj5E/tYn:%n0.#|LRbQEQ@QEmjuiBK gRv$HaKN;%)[)!Cz#[ ,9(j'rtm_t~թUk.Rҫ3_jU[PQU!-2X{,4C ԝic*Q.a\YԗNJ;qKe1SB 4Tw`3['o"7NBq\rrql7tncĂ[ZHaYA>קѡ{$2rN9ǻ;ra9L&"hun%gQcƺ|q^Rif^ZM%ה%yRTF;^n[ý_aAs;(1˚VaMRA7=c]&Liuv S#>;*=I(5ep[[-0C}9Ϗ}jBnCQRnەѡ#ʳJa;kE+6% 6~\zWm7Sx̭dvu2`wgqDzI uF@Ub(O/TFxGYǗ.U(iݷm.uu/d8 󫛾r^R8EղCz<n9- emGyy:ʉQnĘ[рPZ#aZ0zA.T(=j6r63vzIّVKKD|է#`qUԍQ2xh1Lg´!;`$g;s'/:#*Rq7ߞBH6vBJXx2IFF{$/<ݽY|<SdR5h*gYqK qy 9<1dp"~\ޒ[]<\2) FGhy:mLUDÊxN$H٧1eCZD܌ClAbF|z-2y JN5J8ݎBdrIjS(By'HoP:F}SuDqB#<78Sћ㌦m.IuhF!Rl(-\JsDbҟ2RJvJ vߵ-7k|#Iq pl!*UGFr!' f74-=0GߞqeS0- ѽW,ЬON\u R NNRFpF =#DD/mQ9*F 풛dG >XhiQ9ȩ=le6jo*%;dUE]0".>Wڵ|!CL!-[P‰qZtSJ;6ɷxiiZ3pOu'C9pNrmɭ*hL;eMR J zRs<Ÿܠ^Z8'|㺴h.kΤNˉsN/t'GVO]X)hJR' ()DcV#'oILRxT!$9CgloI~iIֹ Ru mpƄT1CE' Wl qSMAIL$x2ˑx%: Cjק9g+Ui UQS Qlסz`i)G@}JLi2kAxm(-nhUp˔xkImХ)i*b*tO>'p {^;b/5{7&AieZ픃*ymN&_R\GJ8FߵcCq-%ζq\FV@9|uX,نfmV4cTk.&îA)Gg|qwe{N H<;p(4E2h[HuDt2)+9QZQIQEA-Q@QE SG*J=4r3U'rtJy_PwڀA?jԁm_t~թUhEUTU* ЇPR`C ԪrH>ZuΆG(66Q[׭! 9$rS9MIH<# kБ) Yn3Idc#;rHoTk46r%(IϬ1zg24x414+ARӒ@QRNq}0嗋tE3R F45JLuvC2莡9I;`wZ͞Cx2 cJcHϕ>leFenȑ IJx`+9Ɠї%9RVJJU'$c9w56zE%[# ^2{IB9'OOiҭmKbm/-A IJA=ߍjz:0ߎ&K_qKN,ctmPGuq2ZhłrA*s`1KοM P5x|ģU9X}![|-c+Sc';3vR1L |zSyġ)yz ȠI!/! ZpT,U/(vYϿxH8C*II8֑@`O`Sј^.Ǜ5$4P5 v{׭m4e)g()$@;UͲ\q倰9 G,5@Ir+#m9.mOwʧ"ƬK6ݜN2#"2uV63qpPVo9IsK"pbvh2 JF7G=6:A{gJfvJsjSj\%ْ֔*A),;3QaK\SѩY$ fĎ- u) Urr5iIiͭ%mV YR0:LgU|.K>-,pp`A[`*Gz:Ly7Ҝ/|cʁBw˔X\E (98H=Y]gYmEi.ԅ iΠ|ԞM xqn3c9V;rl'Z1[SR );,R:M6:#͡r%8.!)IF1+v#Ì)R 31rxR[}S][VR*y?:r/;ֆ[L^W 7*A'Z*IGVd}ږë$$(|RzyZ訮}} hiġŨpQv?ҥ} R!BŽdXe\L~D62(D*?_rǻՈ>ñ[&JVïC\Eb = yR/@<0]e:€*w1;: +f&<'=-2Zm5s%9:zud&’W^qs:V7YjoSp%#dI;^. 8SoiVNr5uBxZ̉qZm [mIt4Rbloe'Iw6߅5Bq-+ Wٍm[y҆mjVS=^nh"ۥ (SO9-gVȔTe:[ X:x$}WgSovTs?19xj2QFQ@QEQ@QEQ@QEQ@QEQ@QEQ@J=4r?SG*9ߥ_w/;ON;N~? }VWݬoHJT3_jU[PQEZm!9&A x#>&ٺ踼eƬc8h]E4dp?y(.8|R9LHIKA\W(S@O]_arƇKcRq*ŝvI7e(8Qq$, 9s)TvZB:'IӜo+X9 ƻsB uAN9&eRJVPZwǤD1z%9ҭ@s8G;U/$g֧vN1>'ja3^[ZM0j,|q^3cPS6͐lyrvN>GGQ=Ӟ3jubNӥ@ Ʒo68#\o\60652*GlIHA! p;Նk3z2A ƬG5u[tIp di s }wrۇ9݊Vsf8+\7\z"JK̶4wqog}p:V0m5NKb,pO3I3b7=? c8UeσۓQթM Evkc605Kc sz^xSEsKw. S:X%=`zn9`ZwluRTT4-IzNFk(?Er'`G/9!\\!C ܂;؟T 0ߐ1!*⃐wӤW?OSzbz;*)a1Hb' lB37u"2x(WO~r1o,UF\f8 !i F~45wN u(d6u"vdV9ȉ+u*RTV{"\؏jqn!pԃEx{]f#+#PpkŠ(( (( ((GU{hTg;N~~~Iܾ?m_t~թUk.Rҫ3_jU[PQTm碸wKBtgޫfK/Zq*m*)*+,y-D=fO'n!<'Ƨt) CI20yjJ*N{Fh/5!<ˉuhVB"%\L! ԦBưPE/nKs“,,*[VzwDZfȓL{-.J\Z2 x5+-EFjOVʔ,qp|yuLgL`JP. dxLW#27H M4T++ `$G;m0rm%J傄P3F5glg$˥ZA)H$UǒĶg}z6qޠ$*,JRQ@FVN0*ć鈸zuNH$e@ON#OQSFk pdW(YW;r4}0jHǎެ1.1"Yǣ˓)Qޫ'YnnBpy\ʓ +O;QhP"L8ɖieBӥN#°'Csj_Im ! ^8##6|&,l%S+VI~#cóF6K1]r„p>ﭺ1Т+ ( ()P )'ḁKmR0YE QEUIeo]smϻh_#ґLQE"=4yP PΚ(%yl;x?J,Gc$1Ќ>E5EJҷEUQEPQES+P7h( (( (( ((GU{hTg;N~~~Iܾ?m_t~թUk.Rҫ3_jU[PPJj+>xmQ3>U]v7.anH Fy灟u&šG%qmԕ,lRxدhu3ZD:H]+b/B- }:.'ur³#Rw+RC$;d$ΰKJCR +aW&pc|3-V9Vs5=?iu2%ˎ6 +΢y]њ{B8^EBe;]yRZJ6$B6y$Zg-aRe-6 @HQV{۾a۠E<&02C%3UE\2Ե䐁wG&ÿzA,: $8VQH#l*JO[dH!jA%* 9Ӈh̾CnzէT0Z"txGԣPɬz/9!RC:+V+UzQuO(y-ԥac*O7:#r[P(iN!m\vqZ0ޓX:/qWLS (9:@P6HA]մp/9g8q&w.scԝzy}P{j!iE䐟yeBy͠)!RSu%Gb}nl)dKST8Y [e`V78&t$G#ʖo"INqs)I;,X/=WR T>U Uo1 *C*% u'cϾyM鼛Ln20gs1Da'Ik`3d4g;%+0u)jߓ RHյ%MD>H #u'c;)2QJ.'F+t*"|S'Ix<j+%EPnQ_rDТ@Nљ3Zu..*pnÈNRJ8;iÙ7kKE.9,?؊!P$wW[T .:s*d%kb LZVTԆuD)%J$y܍T&2[aezsY߼cjaӞGMסLKc< ׏΢I\d͎_oh:IV:&Y ?\wy?MD͈pmmIWV~8Yph&V FKcF~A)OBlҧWpNs#ZڧCuyTE ,%%G|wzGż.ƅ+@ g:ٻZDplG. :Nun0Xt1-Ԃ3b{ љWU3%Er@d Kdg;iP>6i^ 5mTv m)N$*p&CpF!X< >>UIo8O#>F[^qQ@CZ i^*)s qiulNv1.cI$O3>jI FQ\QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@J=4r?SG*9ߥ_w/;ON;N~ oHJYvߨ5GZ>_vU[UGWڃ=!rNu62iv:Qm&\:FU sijzju(^'|!Cs8Gpcn5[_JE ±s^9}[܆e ׎tiPي*ᔨ`ys΢z2ףD\确!pI )iub2ouH*Kdy={zɑ #J8g)*<+r/pwۺv1r*O (rgP|g"0_2q@:AVss~ /9 k)'il)R)h11GFﴩVД $}H7B?H-h2!-m -y7{$v-_„0-ciK[/൭y'd9b+Ju!G%=|s#AoIy)q+qg#Qnw%,BlHoV5cW-lI;ڵ+&efT:d;Z3uäPmiVDN4ۘ&Ҋ,$cxPsRR KKʁ9ѸnHԩ@kRZԝ^HωڟiA6:2gI g8~U~Em3PAZ<Gv1":K[/ )mN,Z#8X^1֣ygCn(8`R)9K͝|_UGFRvi%"5{( (( (( (( (( (( (( (( (( (( ((GU{hTg;N~~~Iܾ?m_t~թUk.Rҫ3_jU[PL$W$)\ 4J>WQAv\ ZIR#9<sP90~K B╲=e7O09֓{kXqP;J|A֋N[c)t0VykeH煶֦e֛q \yi5\MN͆̅rҜ@%“=)j2e- l" nC ;+ק:z/-4Kۨ#µZ]D9op8(qCF.53/C`(4'd#G[ŷ }s`\pB֘Ҙq Λ2l9F,_8 .XU&$kj]eW-.Tƒ':q#to[Hܷ$) }/#i\.=+7trRjIqjbva/)ҕO>3t]o vY1-*Sr)M?`FF”O["T ԕS@ 9H%GHIdy8˨)›h8j::O2-ܤ;%ƑH֔c t`Ÿ1nC* NA#qS"lK%aHQHI ViKα- @rId W4Œ%@omvl1jlM5MJvu c)=B/]m^qT/>)8>xگZS+ ´c|rX[}]%\u BP0NI&GGͧJ-8eq4 ) dBP0h'~[a94ܣć6HZvRiN9cnGFr-QS8hiQGI]alc +K\1(>\Ԅk>U1) Pvd绾RI@*NF9g;an[c-Q(lhszL qqjVs)=ٯctrdim2u%ZΐO'tI\#թu ^gm B-P R 򟸷=(CH J$(H߼Uޤ8d6yE =8ޟi&cq1X'ڭD3$ A dîWQ)؜Zi]Wfi$eI ۸yv`6΢+%+>Ym#&:cIPqA'W8F-,CLǪJ;Y .L'6f”NBw=Mll8mquVpN[CmqV؞g 9E0m͈-:_Dۏ-`NޟhuYvȯu.BƢ}] cncHWaKMB OGm6έ6 HWyRU urBBHT<D3ӜΙ]\)<(UG#?]IJ֖T0|jprFz{5v-0Juc# Zݓj%K8N9oVFuQR,V "uhi:F}FJ.sӚ1He.PPY#)NޓEߨe%}$vp@7$wӶOLDbAB]RAPI3KwecHKJጠ@{y$ems{Ub9*܄!ָr5 'O,[:ÝVՆd 0YIK >4 ZbZ4F36v-h$$=V I)~ TtRtXr8Hou\F쏵vm6yyuS CĢrw8{ nI wR4/ՖKrRp2WF~|9eG M?dyyU٭D`H ⁨c􅒬]nK%.ڒ񖤩֥푥rywrlw%!6q^6I.˜e@䨐Xas ɩjRⷩ:LMߥ_w/;OLR\FtcR/;OPߨ5GZ>_vPkڞaŠudcUqN8QJ:=jeQn2/;uLDW:-zB-l%cjp*޲'ƒ\"]jAy(!07Ĝ1 {A1$ǒJvlrϬ𣬿Ԉun$>r]`8 PuDh;\IOJMG7!A%P^AUag𣬿)o=&1{ilZdFŠ1USE`WD.4\SH*%?]7YٓTMi<{OH% tʑ7z"3:)$7X*ۅ-uVJzB*um Bb%#q½/2*kG KN XIJ> Q}q]:WLn >ܐr<6β'Ž'‘z]rGvKq*mĜHC5aڋykkД-hewPsb9m]YٓGYٓXnn y`7,1ZFڵ `9To7C0b2ㅥ-pF=z̟ :̟ eZndDŒްR̐15(~eԕ/TCx+RG.{/2(/2* ]W+&k2‘lr$$wo߽;u "RU/jz\#2Z1ԄƕX1]@ Fu?G~ 7)//'QmX%gF~)wkhBꣶC.G,so?u?c?߄c&!. /-% ҡ03.(^ۋtK[Ba\A)@+/2*9a6. +B(x,y`3rLL1]/7$7<lѕ>/*qA%F@vGmRla)Vu?gulÑƊ{,imTȼf䥹rK(iԸ_=(j|]YٓGYR38͉2bn Mxy=]YRv6W𣬿e65|n VCFqVu}B*>4u} -%kpV9 --HLtNyfR䆝R)ՖS) ԜdxV wnDf0(s^ⶦ-r#Oƻ 8?Utxۗε-?ƪ}AߺjpNNOT\?@[~5Y:vJi @W!|*RDCZq}i,r42YB_t%({Nt'|R].5pLGRezjsZA./QI3ڠA|x µG ~LLӰL( UoL-ˑ6F\V\ƣAS)~l_p6ΘX?|sQ)?ElʏElʛ:r\[q=IN dxWqq22CQ+zۖ:Ҵ)#^Qq8d)*@){Q)?E$~qc$aιG\a陼c^u?Elʛ:pVq˒B3ȓK[Td$6TrP (낓Z}G*==O*\:࣮RAeXB2!ʧ0R9(땍$Ƌ)1" Qe`)O5Jr8 .(땞6d'[S-8##¬X?|urߡƒ%ՃyRkqiw.j K@S xE6rI,{d>Tz,{d>Tu/+SyVG%|%ƕ-QڑpFYI‚U4Йҝz{mT9(딟ǶIJQ!)RY7(W_\VL&ٚP8܄()ElʷuOc$ac$aιG\=O*-9}WX1(TjI[,54RW#OU•ukаU*oRR⫘\"(낒R\{0R9pR~''.E @XIj[;d' TmwQZeT+]T O%ZyQmsB r>s/HHLx9?JdameYUq!299%A$ҧwڜP]Jܾ?YwڜRZa:T4T˲6 CRo_T8nsK,#V j*dww J%#cS̿ΗFWCk:mMiehXdti޲bZr;I%:$k8y׾⟁~),%L 8G+0t̓ε[[%6ҵ@4 -~)xZH<K's{;i'2mi`,aʹ)Op\IH##PǕmf_~Ge: ~}4.,)J[ֲQ' =ۊV1&C h,CD #SU~)~tzf_O3atR:aI-HRKnuc?gC($vx̐0UR~>&̿μURR%$`,h\- nQސXiIKA%Ete~tzf_~K GTGe I;cuP:!=0)iAЭ.J Nq0=3/?2S?:XND> s5ͱi-,7!*$=$/+V΢1_2S?: Ǻ%1䨦Z+GB4*(# g~uki{t!JI#b9{2S?:=3/?ɑ.d#CT'H ryp̈:;gf_~^&)9Ӥdyia{E_}Ţ)[ NI#u/a2t ,8WYO`d9ޜ̿ΏLO);1,pp8+*;C*;M%qT])Te) 12S?:=3/?󥌴>zmd6*!@j #9v“62TAPi@8Ms⟁WvV?,> a9JRuꑆwQ 1cp90Jʴ9rH=WΏH=WΧ?謈maDZ@L!J' )eY;l6);M2OEథ)9'mdAZu踼8xGltGw2S?:=3/?󥎊}3/?2S?:X訮w2S?:=3/?󥎊}3/?2S?:X訮w2S?:=3/?󥎊}3/?2S?:X[LOdҐ%*;uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image038.jpg0000644000175000017500000010731411665471332026770 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"]  !1A"QUat234Rq#STBVbs$56r%Cduc'DFf-!1AQa"#Bqၡ( ? wܔَIJGIOZY<{Clt2Dv⑬'QJzdg] JF5sk6?MO1^KOM7&"@XҘܽ$sG5b 1L<$c9I18Ӫf8O1^hyo 9zVN\m"7#!<ԸVO1^hyt;G-ϚhMRRHcFԦd.[ZrA>F>-07yEld"lmH~zo$fZ";.;r\C*pOJ`ld曆'/}@vbDyDjRt$ qJrd"cc"2 u! \ ,ccd ڑtMRT\HA;7Ǔzv~$FZHR   gߚv'/}4Y<{Ld STגϠAEl,cc|%05yElrO1^hyAS|ע6?MO1^>JrY<{6?[9NAS^'/}4Y<{g )>J`kd曆'/}l%9L z,ccdﭜ )kd曆'/}m%9L Z,ccdﭼ )El,cc|%05hyElO1^hyAS|բ6?MO1^>JrY<{6?[yNASV'/}4Y<{o )>J`jd﯋6&Х)H';~>JwlnR\ljjo~-6u$)<4E{B-dˠzLebBGSX_td}|f dΐgbR;FSH)[Ot^˛<7Um-2SJ8F|UyE>?D5Ce!οEq鉗'G`q +SiTRv8q>`jyyaG1RRG@#CS|3?]wk.Tf ƕp]cbzt()#.OJ3?ub?7>yaJKRYO] C%#kzKEzʋ)VNJ :Z2]ՃC㚴W|mڮffS·76!<):ZΡY0֬`p_=,6D2,a'#3?5<3?5&&<#^yj)6(z+KJCNHH$*p6c\4/,!:^33fffe"*)NV@Ec91$΅u}N!Y=#6)JJSοog_7˰%;V>ucO O:F])3jxj522N|XSSοo`>Jv|5?ucLS%cg_73jde+ O:槆XS#.|Xj5<5?v`>JSοog_7˰%;V>ucO O:F])3jxj522N|XSSοo`>Jv|5?ucLUGD,c୿VucQ\U4€u? Rbf)Ѯ5zKʃ JĉLJNg߃w)>%).)K$薞> ;ǓN6&>K5Z^~+V1϶wē":C1ڋc7%BnNy;k҉뎧RuGw~=^5uTWC Iݼ*y rZI x8`lrH4sA%CSe+} 8JN=KI,ڵ%<ZP,tQc8Q?!bjD ږ\wKd$o5%8y B[A5D'bqPNT/, &JR)$^ *KW/O0qJB+ CR4I>CTNW|1p>BNYBTFBT4Dtr<{lrm$O)cgTUMq= 6R 5Jw#qMm;(H,O 4x8 stsu,DUY6Ё).@yy$ׂ'm?KM"[|ļ#Ҏ 5g(K9՟U滟kU滟k 135ۋ8( %Á 5osh-*un $pWLlՇU滟kU滟ky]3\P}g+. 'Wa9BI$wQ<:s^WWMEg o=.JRPtF)V?8bFI6S)9-G-(Z@Rˊ$0*oU滟kU滟kb o.{m۔:j;H+#$G8=UK]SsG5!KV;Ii'=/ª]5ª]5H"R!k$I w,ꅭh$enJPKJ1VT w?O w?EU8z_a")MJH65wZ8~NS%S39 +|!\Ra% J\BYByi o>UbIzc'S…'V6r9YTͮG\٦p,[$u78kT}nWeN84YNgMTvа&" ^WWW'ҠxU^kƺxU^kƺXJUyUyb}*U滟kU滟kWW'ҠxU^kƺxU^kƺXJUyUyb}*U滟kU滟kWW'ҠxU^kƺxU^kƺXJUyUyb}*U滟k+,sJXT}o欢>%D6t@ǒ-喯^G -^eUBK?PuV_c~w_o=ZBvb2PmK!!JV*8IV%N|9Q} aX:8{8O2hԄUГܡ :yP-)HAH{Ձ_a,ݭem Yp>Pst8;ga:i\1ӯ0NJ/\ARr}]_q- p@[cJgnvWŲ88fmp0d軰悕nJR= ۤ\44J~FaMT2B[FV޺JcǍ ;n |x*c'H;qKzjQ$!:[`VRpN$_i!n2مA[n+8JN j:NOp Ri8zR q>.$ 6]4o9dᰇZ) oAWL-@9;7ǛmW۔K|dyN4p;AD^iu)ZV8 g#:9T%qB[ZңP'+z.q '2$4Z[-NT,F1\Y>Ͳ,&eJz4 5,+j 'bsU \#mi656$A؞];2ہsq_51[ eAztjΡE;YAF oϑ9Z͐±R8)4(((((1sq<^CzC#7YH~ϧJū5ǖ-[tx(o#ѓ5b,Xg?ovtd 'Ulyepu820@#X>g.;hJV*Ujmbc dfi*HN6? hZ $䶨e,+BHNHU˄#n&=9)H.(?5YP:9=zO4\+t[[2\jZN{S zIIOLi'=ɷ7pr\ڢ]J´!K@)8;\}zpNT#-Qf>Tea*t'BNbAyEQ\Qkq,qވD{-8°5`eXBkbڳ, Sܹiq4QQ5jԝDa) 78-&q3$JhB" -ֹzKӡTu|iCz(ˈ ri䀴pA d.Ou\~ka9z'^AQxyI# @` -AA+P)qO};A%:RJUgppAŶke \)XԸҥ)).iBawuMj"#!!^*c !$c/P!9Ρ^c)^2U9DEi\|1r\S2 SRbJV*XR1#[2,juA:^^`'Q:vi3(q-Ĵ_֮קۍwlGb}S SАcJH\Q)NVIDb4keզㆉi; +Qư!ƐߍxaEV<>0LƀHxjl[ܚeIit:Qy>SW,. ZwJyI>PVH?LR~Yj{*/PU^_]4$~w_o=Q,?PuV_cRç)Y%,jkHYZ @Ԡ:dyj'AD %,n;y,t%a J)P=2[[zҝXu ;xRR _'spqzq.KT@ #|qHnXGB:^>QX}U /{φݲ}u/%9- RSxoRu-jO7:uΘZ}zn9Ee!м YRtc3(2ףob')ivbӅ)?SDw+5}R9jqpU  3k[hӔ&8ѧh&p) iҗ-t6I;lF;;cw+|%c(ml8]dd/ lD> !_!ԡ w?c)a eG.-( =_?,XKc Xp2I 2H$@ުb͢L&[m RZ*cI98n~=pJ Ź-nIRRX6'\;_NK˃IRhHI;r!9܄D063cRJ(k;d$N2FiAheŤ9W1фݛQ un޶['+qo@)3M3pw4^+7lH-"KQӍs(7⎠TVS"t.--SZO9]Z?zVi;[i\ɬ&CJa2]Ry:Z IʕNAvw[n />\Z^iRvOPޤf/dnЅåm E\["["r5~%$2n5&:aO)i~CBĐJ֞aN@4}u -nWmnsQ%S9'^ ur\GV#!9qTqڭv4%p!/Bq*5|Tu>#3mrE$\e-x$h_ϋuw9N"jq LG(J8r{_eIfWeH^ZAZՂpW{w|;Ay3G^7Te\gd2@ĥO-Zr@#V3:vvv\ MgON#)#W %4ONh V.)n% ssґE}E3kZOl BamŭMd l1t7|:y^;Fjk4aw] nx8#6zy眽nЅå:^2y-]:I-?$䑸o ftg{\^@hx'W AVr>!JW ͪ.ntv޼uƢ3Uo Ė*t Cmඐ%Ap2 gc}yv:B}%RXRQ*o PN:;N&R篍35Wh3E^4ϊ#ħ[1C%#/~zϬ!=W#Uy}z喯^G頗~=^5.Ƕ*%R {bXt+!JR\ˊ`&Fb}G$>!$ 9.1]UoQ~**,[ʛ9Bԕ~ϊJ-%d:V-*0'\U;J#ٯrc4;CiBH A` h̩t)aj*R Q=2||1:^ yyl [q'VTuRK'J  )JIqneG|EG^$R.|ZUqP]dU\uZalxg XTWs5&i?ܟfPSrp0ÃB~P]~M'՞G=z-xᷯ%=`%i҄(lAҪf}UѦIZ_4 dISsU"~2b/lY* &,),X Ӡ T2Kx[{R ZqHpH6eV̀`źrRnzT ]'=˝s54nt A#FiӍVuN g -8T6zb:UiWv7(Z=9zޤ2Ji¢IBSdN2z%+u]{;Tt4[ilwRJNY둂F34[ܻ4tD Lr"%- [iREK9*Ke *i#z+#_\-2c%0Ƃ09K)uu2nC6DKhT![SeX3ԕ'm:P AQ$qYמzse3'M[JJ.JPHN:8F apd839NҝJA#tcf*^J $I*eצik* J4ogu_̊mvW!:BJI9+4v{J~(Dk`kM9INNs "{;quCYNz CFKn- JBDFe|=sbZO14cZFqYnmLuW.ƊR 5wzy2k2cKmIQ*_~iR%A c9Ʀ\hy9lNzNIo.*{\2p8|Fގ ˝7&KacOZ IQ ֺ3ԝ?u6D.}1ܜM]+ķۉeȂRV@uH&8{Q!`(uN6voI9"F9~.Ҳeԩ :zﶪbjR&ݍ+_\[W#:Clňu#)RT 9JNղ|MZmZ}/;p% !YRVrAuweJ^7,CP4)nj9@$xI ӮֻWfb\49֛=:BR5(Tr2-r=JD e.le )C ε q㺢K5 ,N6!*KA—(Rzʕ#"KȀۘ=RV,hNg @yԛ$Hi.79Ξ(ۻb;:Wq\ \}sj8B^54oߊZ64>XBJe\Ƒ`q;_*$)lls'>C& AtoO9iIR؝:W.tѬ;:CO2ɷJekJ :+!Qֆݖ`Խ+ZARsRpFVuXY~.s4sӏF1Qw12ͩ*KJYX†P'OL!]q9V6 x$ mIò~6w颬* /c)WYCUYNU'q_`Ϭ!Od -^eUZyʫz ?PuV_c~w_o=ZC)Y R .\S23"9!uA% -ypxFqD zTQfJގT|Ut6ȂTyi,!֒iV I?מE*Wq^{ JA>6WFeL3K QRHNJ?3bocλȘed✞ҨDpVx>=õ8lY=uxZ#%e!JrFNH#b]2|Y~W1-}W1#dUꬷ6:f+VEnTv ;g=<5QץIr/ Pq€ 1S.w4[ZhgEe#oG~e؛M%01ӭ e$(zpk]N:"~4 tvw+nJBa eҜ0޳fMӌv*bF-UJpq֦3Ȉ qu^j_ ոQ{s};!mGO,6qKB}Òb8,& ‚e(`!6 ̻}5dE Z ӅBz8GÑ\,Jm$ˋΥՓ[56Xm" l:yY% wN@PYҔRRRϋWj/슴s"R~*Gu4OQTWs5&i?ܟf9բpܫ=b)쮳9V /C'`;~T$nJ%i#FvĿsc3*;ekiЬGAcUp pZ8mHPmD@؃Y·GHPؘ⠰tG)iNZg 0sQ "9t%JOvK@wtV5ipӬn1R]mŤ)+sWlq׸~cR/Lr 0RҖRp9qFSZmSH24XJ|q U!5B|QB^vn%J% d}+z\ o Ej -4 SN6%0꛷d$5 I l 'NnFաv+;XߌUM$ UKQ= B9&Rk) Rœtr z k-YzB%INBѕj:)sj|/ G5l:!Ʌ2%1 J SSkZ;_m49JҶSL"xN \M"ҹTJڀoCC3!SI矻UЩ U}%1ѩ IH8!Q#.!*1G,P q:zcbqU"Tw-5*<@Sl]WqsqqBBR:R4r]{'tbB`[DH %3jGچ&:b!:''y<]2+Kr΃TReŭgtI  wɹF޻Ck@aa-)* VVId|`!-XD8h-[q2p:o[3dv@C(5ͷijԳ}J䔆ӉBVpr2HF̀e7c2'Ky[n/JA'j=d40cD'V3БD+â:2ޕ(dF0HjWJ?iGe%R%en:TT tZ𬓰f]r+(E,A;zv~d:@1B[J?vH()թa,c >W:ɚN[Hw)N$ %:r3 N1xMkB\Z K8˥!xn7rJut9[!;Lԯ|jjb8Ͳlm $$!{886p!Xg` CmmJ(R[@QjE(X猑I:UV3gM`A}:R[95WYCV{$ \~Yj{*/PU^_]4[ǫ!~DzBj][}lW=Kd)JP*_AD楔5%)dl{ڄېΗQHSDU{ 8Y&C%iRҬ#J;l1=ST*8&3MC6$|,mFʘgB( '^hquCYNz CFKn- JBDFaW]n.-pI[ԀZFLYnmLuW.ƊR 5wzy2k2cKmIQ*_~iR%A c9Ʀ\hy9lNzNIo.*{\2p8|Fގ ˝7&KacOZ IQ ֺ3ԝ?u6D.it"Vܕ8aե9cY$agoHͣ|] L-CQ\S<\x('^ k q}gIr-( Կ- pڰ°KuH(i ITa,  , zN}D([mB39}ZZYO.Y(;$qnFI⦖[C:-:zЬ8D`*<ƥ^ݖyJXƄg=£-^HjC1)+ HQ:VG7>N3Ͳ4YԀDvC(5(%vF3Ght)@%Ku2v{vΈ;줝-## {ֳojͩV)+JSgxErR2:AUQ䲖c `H+cY!C+cEoh+c}Dά! -GRI/U',"]X*ߊ_XiY觖AA;{ɤr}_+5Uu4OAI;'ߡ{L\Ss\Г=}o }y䴦G2!@^˛œoZ !CtzR8]MfȍZ_jxRPH8+wkv۸NS@vKIl[d{2F38nx*2Fmm%RA'Vrw`;얟pH[[A*A RA&rU Qm&;uYl)iIJg|`&:fuNIyL2 z;K!Ht=@ʲ21<uEޭ3/%iRU!aJ *T{'''sSd[b|>K+a+CBP~{a @t%+B@V]@I;f#/.37;^|p͂<@ڑHB49t816;s0Q2)JT-C-V-,0&ԝⷬ%o'FsfO7,Ɔ@I-:ғ% @ C\\6W6ծHnJmM6!`[*#[ /)QF)~6w颪ql>նc (i $[ah8 '~OJftwG^d:W*ijǨ/~zϬ!2zϬ!=W#Uy}z喯^G頗~=^5.Ƕ*%R {bXt+!JRZ8qegOgmjtFqg>wJR"IeSN u?KCsZRt#?I\!v Fa!J@ZTyI xnT}>Px#qLc4) @wRG]p}5kR#!CZT ݎ%솛ZRBӨ(E\pl)v|]}#Rk#wRj::![WJ U]~M'ժ)_Aɤr}za7rܙgi 聓WxX}Ӯv‰j[ ajA3j%W ٙmEK+VP;kmݵpZЕIRPTFQ.'m!LT6#!GQRќgIեU H+#( 氵|dvRލ NӨT[Q=sXb9u#{[i IoF?qzgiZ{ZbZ6ޔW, i ɖԨaH-8r@)$ m2CO!TS1qWN%%)'#U]GTN;<$w9ۿmZ.YELTj#t;֕'!kxB0N@^(W˧5Tך{SԀp2N3ЎǸ/%ep!JRb~z?B^.-MTiP)BJJKe<ɯ:p`KBD[l(V5l:VqMoS ehk-Xi$Gۛ"S/% h(F 4p96Aq󚂓»hq9>FZeI(ro0岍`C(doD)'Q QFq ;5'dB!":䴗 jVtx@ZFcvIJyTK.kHWMS/}$(iEH) @NVnKy[-\:) ( '8'yEG-1Q[tr'RH]3 q/N )H-i3[R5,'yiԦ ʑ5l&:oU8ژ2 *SM86gP5: `A)mt NȨRD)n, ( jmE#}N iH`m iI|!C AU()r--Ԑ³_d)V[ WbnsLŸ29Il-'iZU@P(c'KfHr[n6)N6`c{J<ik2-% )Фyi;6"6%N)% ׌ѹ'ZqV\y) 's+pFCZ[Qҗ uZJՑ]qeב쪼BW#Uy}tВ[ǫ!~DzBj][}lW=Kd)JP+S23>)mN82ߌ3iJPG!C@ZS`zO渾6xÅmSFJ-)ZZBӸ?ors??IG ~ndWiCx`zzh+.w8ϊHJJ6ȫ/pr^mi_QԵgu*'=\;ێ9?1 ѭ%9qx8j%€[B5caМrn;9o[H I saH 9LwIbTiMci$ੵ~Tۮ l7 $hǓ#qQ6 r+u,l+Bz{ө?ʨwfdBF$сNn@ȈdKAr䠬Q`%ЌM6\Ap#Sg#JwzB11xaRuay(ԓS\%o>svkV62%#I| "D6%ò=H YG6btOd[ƌύqZiI9J0!@>*c&qxjVy#6 ! 2rNԎrW uSD! SZE]u6"jإF.ԕh񂐵$c%ˮۍ!ISy#lm8۸g=^b9N8!T:Ѿ]83r|9B[c}988\%OI)S Bt)aÐ3|.ӯÁP9!N|џVxeGbOJ -)iHFURZ]M]"kqdGi<$B &mhXR[IQ܀03+}&~)!ߊ_ m_+5Uu4OV}&h9hݒ_EwiCH~a:$qA6'Z`.92ƈJӐji=n r1@n^@bb[ȟ^Q.)M KwXhB )j(;;Տcݲ=v,RsRJԌ N=WMG&M7 C\g#)HNT07lO)Y-gہJFnMkIDH%$`PQRԔ9;lq/"Dž ){w⳧SuW`\ "ٮ#"WlqN0ud'5+M/|ԭZ2#NrTF|qɡKUsCff[Ei/2žJ\Z!Nؘc;zξ_1rqq4Tl\[r.Й[iִ! )NېNqV [{z xB/lqb'9#nQޟ:CiM5p- 9蝎6e)w OiFBHH EDW4B/\oN9shjޚ'}_T9=ʂW#Uy}z喯^G%?PuV_c~w_o=ZC)Y R Ì+=ϊ}#?kS23>)Rk/#VX'8y79/^0[DkvzҋJV2b|:4soo.OOkH7߾~,gjP!)29 j˝Ŏ3;#+*>K-\Zyu-D!@JI"v㻽}=3s<0´kINqgj%Im0">ۺƐ.2"14+y\4y(+(| F:#9MqB#8av\'ҢkF{wjX^J5$Gt> Z\|Tc6m JZp'!e'7ٹK c8Tӭ[sGsQ;F*k8Lm'-”]%9AώFCr:VMT^2CqHʔ gp>%;:Y=WBdt q5gc+ZPH_7H:S )؎iwnC[ażYmJӂ<]]Ǧ F KKC/+Da,+ьUgc}r"[4$%#>9;HdRKttu|ZP"TC :s>/ }&j\GˎJT/uNj䨗_I4VY\nQNPn{kmqZ]HRR Ž5"~6nnܩXʧ i ꃑWqXӭVwŠj# }i@TR3* k#}lXAƹj+IO/P)r0r1ZR{BVI)!@ ?܌~tpeJK2&ŖK5i 8kYT8X0apz{Mby.YtyO0 x68?)rUl!uh? OkZה(Y+~-ϩĶO-iN8 QN;z r?7INr+oa@`GQH < ́=6Hv䩙2"<i@),KJ3]%9 <9r'g\*S%cGUcV;ܸ=%\[C$lBZmγ·wE 8MC$B ^Hc8D)Zgu TP9_gDnVxR~H8t,/[O - I9\&B #"SXI#02DT^TvZ!ZY#d:SQȆT,6 8T@% I#cc_ٟ5Ԗqeb{%) N ;Q ͼR-9zB T֩ٷF#8y_N)uUT(A$aN)CY+ZWir]6ע<ޠ`) 5^} 6:2H (rzn`cNq~:VhW1iRspwQUZyʫ.?,z=W] /EzBj][}lTKǫ!\KIJQ9(\,:TTRBԂw&A[} TTN6t4!Ԓ2TAPq_{r?#Z8qegOg_nGd}BՊ%JA U]*7nGd}BLWy rjҞ~p=F5~+hz4]QiJAO% ! )HW$'ݲ:Oi3'־jF;X>+S":)*J 8H"S>YzM}GRB$r"^_k}표c_Vi);834j6= KI帔@%+ӑ<5˭d徝n{C[x9"N$%͆ '=1=&Q6]!Es搖V@AO5ZWU#ْJeEK== MNt*@S(u=>!r\FezvUqwh܂ط%oiޔH.$;4(YZK(e;aq03$aE8^;)FppI(/,c|cg6\L="JJunF Q13&Q^ȌLcp4ŔK3mZZ\bB`Aӆ9*cȒԇZR]mzT{tvAp%kB^\]M2HY+FBN6Vnm:i_ө =R$v'SDzV"";o̔.hOAҌp1:;iĥKt,t#Nב|'>J"Lu M,1!ݖ'H>6 S9;dYPSpD6e!NZ@I'J#J (6+F@N:R9wd箨C"Cn)>3(p{O..&j!%HZ44a8N4w_I5g =Db,c9a $Ԏu p[2D/4;+RF羺wYح@ffKh$KKߞv^o0@jiq,,.-A)LHJQ-kwH(JH9T6tEr`l!"I nmdN7+fNK*5xAǔ#TA:bP^cťB*qCm,C.yxԕwCbz×;^O7) @88uݹ S#2>^D}4p [rjT <*ְ\WxJa7DBa2ַh%M>/WyۑPu;r?#LF0̖]f;Fl[!aiSyYJSa>(IUjxnל-a2IJRJ9tu$LW T͎>jRn Ҥ.%D<`!CpŖ9W8J.[/!JpZ$A;w;r?#nGd}Bo6v!s]2f َU9 n^aIHI Vd;"MUɆ %U9|!A`6~&G+N܏{y 6^zݽ#%75!)K.3bq쇥c:eSZ`jR'܏{-J@KI'3ɮXr\O,qҭ%Ō)%$zpLø*KɐlK.!aZ? FH#W}UUW7gJ.|;hn mֆ]}  9V 5Km\w&.Ruq,6iQTUUUlU[;r; WJT/ce37g:Zj5IK#:y)RIB zNПNПHfݾFݱJeE}-oDʲg}pn8wt.RRqO թ&@[h}i=TA71qR_uk=g#0%R[#R[ ҕNs`1-vte-l vՎ/Qu 4)B\y`6NJGxV33>e-7V[[o'.8~:`$3ퟃ7s/j"G9R"#^5)tJ"W#Uy}z喯^G%WC 8V߬#4zBjE FoZ'Ȑ:jQ8ψ[Ȯ8Zv䯂 tQzȘWjœS TB TI.MԛcimZ;~w_MJ#8KJi# @))AS ;~ȭݧF,b嶔jJ诜?4?5]ȟ ߬}9!{iѧiѪD^d{ȟ ߬}0,{O|T\m;碖j?YcNP :Fs=F7^SAޣ=t4/j/hbaA-$V\ǴhUӑ?YcXvOGǴhӴhw"/~=OG1EJxu8YZT₴#JwZ)jǗN]e))b$a]\ޥBqsXic(ql'v>ejR\BzgJTR,S:m)AGq"Jn\:eqe*A'o@;T4vGSIʔS?穽ŚM u>n~,֫d!)*R $ tQ""QňdI O]$O᫋˒.ĺrtc; lE%$d|毐%mK+)@@`wU-vf{mL?5\ȵs[Jccc",{O;OWr'B#ND^d{cij?Yr'B#L Ze(Yծ 9p罴TAUGBJ6"MlaNU܉ӑ?Y=Qcij?Yr'B#L _-D^d{}Zy-'쥜&]9uk?_jǗN]e))c]9uk?_襌yuI&AW $H( @s!z\Kv9Vk2+H##b|/6hs$a@8֐pG`3Ӽ ?Oc$] 6*4'يJA*BI6V_SY:!* -^eUZyʫ뮄~=^5uTWC I?! 3:H 4)DAWF+ʬi\pE5BST|Bp󐁱}a;$9.j-@ l NpP,iJP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP@U^_^qeב쪼hI?P <"~=^5$ƮUQcdG[xSJ]5#o{jom*fҔnj+HYA^()21Mbϗڤ6R))PA$ (%CsfU].աhY$%@$GHYi\* Hw itFtw[uzy-(Kuh*Idݚ`"8Gmm(*ƬN:k_-tvt%@A 9NjҢz5QĎޤ*vV5T۠lҐp(lwxOYm\m4{QFʰ#dόs6^B02\Sh`+p (H*HuzuiӫFtNzy(OudmyԤh:-H PQZ;8*,[BH(õ2jPHZT7Bjk=mqĸ}U)֔(j89'jkY5) *S+Jr3ReZLw,P>Tv=z6"*S-vV™Koį%D( !+;utk*\XqD,;%AĥkƗ[dA9{|i Kq#Z:^ִp]}hwNKZӤ:VTTƒ0h*O?3e9K+lER@!d6 M~1%[[`KDxXo04=NF#r٭ %b[Q(է'8wJd>w;K~FP͟oŦ ncOe`gQӑT|Va7,theNIFdAUuc4սTpe 5oAR)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)AW#Uy}z喯^G%WC OmrK)9Э%9 A: ǫ!U__.lK2{,/ʴdUĿ)˿̫JPUĿ)˿̫JPUĿ)˿̫JPUĿ)˿̫JPUĿ)˿̫JPUĿ)˿̫JPUĿ)˿̫JPi0؇#FIҔVRRRRRRRRRRRR)@)@)@)@)@)@)@)AW#Uy}z喯^G%WC ]U-WUJT/ [Ogs|Ҧ R R R R R R R R R R R R R R R R R R R R R R R R R R R.?,z=Wר\~Yj{*/_?Px"WgYOњaz?`oW$)Y_}Dhy}a5jw 6[}VBRq+o=cY{Mhy2^mJVV&0ˑsŁ 2b`T\6Ζꚗr7(С.:EvJiJP)JPR)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)AW#Uy}z喯^G%WC ]U-WU_uNGO;WRVi\a)Y;[i@)@LEf1tI*Q?m((((((((((((((((?R)@)@)@)@)@)@)@)AW#Uy}z喯^G%WC ]U-WUJR!L[k:TqAcJr%&?ԉEKTH?R'4-"KTH?R'4-"KTH?R'4-"KTH?R''̜3%9'OS--Ԡ(#ڀ:wQҷZm#514s@cAs@cAs@cA̵xZe hHDAW#Uy}z喯^G%?P[ǫ!sR((((((((((((((((Qşu5UTqgz Tr>P7bʹn&Z+GB75G-Pu>P2EL-AccZlOʙHCNCo n6THJR0oO;mj7RU/ϵSgڍR.Tw>oO;mj7HRyߛlQu<<Ͷ}ߺ"K~mF6~TU/ϵSgڍR.Tw>oO;mj7HRyߛlQu<<Ͷ}ߺ"K~mF6~TU/ϵSgڍu"K~mF6~TU/ϵSgڍR.Tw>oO;mj7HRyߛlQu<<Ͷ}ߺ"K~mF6~TU/ϵSgڍR.Tw>oO;mj7He C8i*I؂QUw>oO;mj7HOֿ؛SOֿ؛Vw>oO;mj7z~}z~gڍ~mF#?>ZboO>ZboXxyߛlQu<<Ͷ}ߺdg__M__M;mj7ϵSlkkuNnldx)Zi-aa*gڍ~mF"w-n)S7EϵSgڍ[<S-n)T;mj7ϵSiiy/ԧO[<S>w>oO;mj7Ӽlt_Oy/ԧP|<Ͷ}ߺw>oMx"Runb$hؒT[Yt^}]4uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image046.jpg0000644000175000017500000003407011665471332026765 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"K  !1AQU"2RTa45qstBu#SVb$6r3cC'!A1Qaqс( ?o7[}e뫙4ἣ"-`gA-rƕhy8`®h ZvԼ&s'sA::̥J@0Qbp&U5Ž|ںH44Jm[DEAƨ˚ޒIg:k{.$*KkdSs4 ']]/SEPjFiX!.ǿ++c\I{.%kd91앱 `ֺG 7-dttsiCr0lޤ2lvˉRY'ITdsgW'vUMThu]6':!#;k"'sMMq*~AAeUu\#k utU_m 3O6icuHӬʳ1 ;Mq*Z7Smm:8e[v :əPb!d>QWar{.$~[#tM7M-n=mYvXi-3%8}*Mq/w쭸|8_W#Wyel܍4 9!ɱO.֝{.$Z-xe36}L?w-i]w*;5(9Nm쨓cTKƈ\tuT)KӪ52RxԌo$0^ok]dB d#VZz[<,68*ߚwxqĤELE +QW[  嫚cmgԍt8(7] \<#Yl-68=Ƨ@o_[5WHkc-58>i o\(sЈ*[_L٩:5DUhG9ui oLRl:I4nms9|c $ZoG؛V%1]Ldm90xRjbbw;LO@-rSᎶ$,rңɠ9 (SNzfh7pi]'4} sM`5=1hhr?Z٢ԳUGm--Nz8Sw+oNi 9RUhe SMw*:mϖ2jeeTR͏VMxFr0Ztm<)6a˜n Cd7Q19hU\W P0e n90xSm&6aЪ䡻]"fhk\ç lm %cm5,OAvwsM`4} cNy-:'iћY>\L'+giMi"JvPxΪ90xSmIAGMVmB]A:hLI-F*s$M6aœm<*o9U6aœm<)k>mzoNi mzo>U6aœm<) -SGOUe BN)4M`4} έuwz:?Ҋb[ ;Fu1N]FCvGWU=i(F p}7.=1]]]_-Nv@汥pk@$ld }cNpOYIWAQrRpV]AIfe;,p07`>v?ōLW%2jxQ 98 0Hu#(mqqLک8MAv%YV{Tnm}#d֨4-#҃EUi=WD,}[ -aw[w^ _(UZupÞ֓9`֌.8^1r z[5O r GϹbKU3n3SOK(i{r `)?"El!G';+T쒢Zi DNaHNw=IvzY==Ců82pF$ _L#gaMQޞ^ ImXFc#!;j ۔*h)(㡍IǬ%9c<kX2w!{C q Atx y\칬.!l\VSOpe&O:Fdr4\Aye -U#$;X78cj!YO&vT#EK5αKl>(l^̲2us ]o]$r%典!ݹЬfRv_jQ<1PKc yw9tZQGGC44ԇ4|hh9IE.;p֖ቮ&WG}̆(Q<1S۬Nw 8#.&!MJn 8i-N$gqK}7vSM%[,lT-!l.lmWqp:ݐT޹̛[⋀_j7%Hlc5`5ApUp]W-3yMޗȸ_ͦd yg5GfWx^K ׊V˳G1c ZsFI=@Ҕ:\u$u:6da~q溮C%,eT|FvGSv7JӇser,A=Ү:s5 `ɘ4}ݳH/Ux%y 5muwpR2mn][uz\򮪏HuM, :F@' nWEW6vN@`p5gR*ʚlM}-'(ۜ^ p蜕rQVOYTٵ\jnоEɥKhl=N`f^)k]l1NϪ؃z'k8=K-s^89 b-LvCPɫ*nEAk8 XZ&ILFNKn^aAԭPUTzf,8x@Sܨ*j.rTu5,瑏PGưvwZ/{-VHE#$чH.]Z+~m3'I/n/.!W>zY`jvӲ9vw;a"o:mE)cvp0<`1MOf|Ѷ~?~7W/ލܺIuV?Gu,Q╁-NvY]L^$ pnF\Xz[-e 1aڍQcX#{LvvM'g)' vGYfSJK|ӍW?3D3RSJMg.4wI݌;:j:8iָv ;W.RY) LIf^L4b2s3O5ⶲX*P kd4R\_Up1^ .[F@8$DII>j_SH@le@9UE.M+ ܤZlU sS4Tb\5:k,Uά{}.&xtd*/RFIetRRN^YrPpfR*cy 8 Lp#rYh\fjj$nKzW R{hD͙ltIi s.I;#f{2Z\#:Ĥb[XKfilSw ZM40* Apv=o-/l-K-0 \s+# ) oiݿrv-)G1Xrüފxc"cs6Vɗ;wU ͒Z;m{b'HvWq;Gpm:WTg{b^Q9ˈᐕ}K[ych&3'mҶ1OIMn5ZwmtriSIRf.Thp݅Y;4)採 3N2[l4C~wtfT:6c$z[’EUK=lPK9 <ӸEM=¶kL<4Q1G)q cRVhutM/p2!{4n b854s⦯YMO59YJ>jZ%oukH&r}!Ws!Cz>>X-TmS<54Vm}T4$,1QI4T&@rwaF'VOCW^Dռ s&a|\1.l 7s?Y⽵‚TP8P>T9W! (&О;WwFsC1]X lԐ>bΨk6IY[Q yWH6@̻X{ MS[]$AL i8sҭ)G-ANgܛIl.S:GuCOVZ0Y8=*τ)'! ,CU05c7Q ͹85jeAzFHީ\"3mS89vsw{EDW+{-#beQF=b\T٦3p0r?z_˝dut\]GOAh䶫m<܋u#oޡ[)(Jjh|K5Rk4rf&C犓Smla3CdnuPD[5v:(`7Q<{ k\ha5On1ܦ"qG-8P7ԢYmtSGo\bMFc5b'M3Y& #V-;m%DtѾG8em8N: Sj{~,L#C$ #B\I$ Sj{~,X5*j{~9 Rł$p$~ j{~9 Rłd_5=WZSb4_jsMOoUS5=WZ,WMOo4_jXE_5=WZSb4_jsMOoUS5=WZ,WMOo4_jXSY-"y~m>;bϽUJ[\MѶ~?JK?ݐ)︫?(V?G6g5,&6\EwXz tj !x%|qeu[]H#mh&F aѕr[5) :0s}V$Mf\yW7u#Z%`~ZFrVn]&A#!`sONO)R@c\ڲ/?#,Mdn+0c*dOzLZ=.1eREJ97`ㆈx-z?WK\{UTd^@lEj F'l0r\ۗ;loщ3 o‘0lV_EU6ܔpEC3Py* E[n W05=倓8o\I;ݣrT2\=;yUS26?D c*[8qH_6\ǮKDG~pwup^Y:ڤ78H~q ɴU soZ]hsꢩvLd47j2l:Ho[?]yү? TԎuv6 HH[*qHgٟ{L߿=jn~m|QlX㉺'8[9K=<9MHp kCw;qU۪mƉ9,m3ʴ9jy1;+Ꜹ v[~bg)( t{dix÷gYݟҫ)즕>kⓕk^]dM]QT;[K!yF촎.*tymSgd,g4zct$m8*\-ȞVuS>G%'i †CA%t^~FW?59ypu˵:7HY5e4V`m5skDlɪƻ~gz ֕쭂Ϋ)b0ƹi|#}4f9ydX9ݍǩfJRy39y%c$d;مzev$a$`uⰠ9+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXw+>]ϪXj(U߰gw+>ؙ7߽g#wE{f e֐5NpFn[%XUT+#~򊚖ϫal1S\7T98vx75eֵ򻃵NZIfHS/nG-<3@׽S^8%^ `۠yhk [?eԕBhOc*ZT=KdYsXr'=|ST2W#^\,i % 4վv{9;9NLy[ = { d"Y+[LF:W͗G6zɱ˘̥"nd+adJ5x![7w:V+\6ٯv\ɵ \3r 8a`c@kFUdl9γ;X-a#p5u4w!ڃ5q'{jd\`6V o|t{c Qsgq=}mkv1XÜcqj .5  k9ש7WWW޾MI&dOc7wݳ_Skf0xXY`FӪz;hpp#w0Z56FY1Բo֠ZÏWS]ܳv}Mڸ_cI$;ǯAc;j Zzz7X`Nz ^]]\k;5z]oXc%[%r\7䓻'ܥݷ_Skf0xWpU]hfT،?FӿvH#SNl7/SNl7.4Ucd SoqV~QPld m**jXXV)V)j#WLqjXu2}naVÆ?$[.njXam;ֻρ1W-87Cm+hcUtţk٥Yܩ\7n$[PC[LIf7M䑐<Uޖx6 q143^D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD*" ""wSE|?AwSE|?A˧M%XUT+#~򊚖:AzENq0ܜ5ǀ<OJYNfi4aP[sS-4bsG42Ip+}x GI)s $OI'p-M3-ŮZ8һEE63T 1!f5Kw x<V\"""" """ "",3ޙڹp(#SNl7/SNl7.4Ucd SoqV~QPld m**jX{Yj!ъ))`'SrqjfWY-f։$ 1 m,vVOloh= 5Z;huuE P7?$k7ⱧJ[ٙ@_F&z@5O3+D+] |C xI Ʋn vQ!kαF9mLi`b./#X.XDzdǽag'=AXO{r}cޙ>XDzdǽag'=AXO{r}cޙ>XDzdǽag'=\e̍Җ48ʆ+t&sgT>LXHq)in/6,[dǽ2}cުv"f٤_ݸmz4?fv3gRŶO{'=l/_lmEۋ͟K>LXHq* Inv:AWp1o8᫿X2}cޙ>^j뒏qA'=qNJ?Dž,kzdǽlxSqKvO{'=g%œۏ 5ǽ2}c޶rQn<)Gy>LXۏ SU=m5 q0XRN>q_9kݻRg%$ZhJru.:'#${?.GHH#ĭ+t~7vPF&uk4Jc$XmSt c}V=>Mpi!{O ?GmG,ʘ݆an h4J*eRWdmxt(fy??_[S&Zc9Հq$(r.0]e>J3s5H>oBڭhmSTD#׍`kw;c8RZdw9:"n֝NP,)$c|OUWYq[]gm_,*~7W/ލܾSY-"y~mBK?ݐ+Ecd W:" """ """ """ j"-" """ ""I?q tώ0\F입F>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8"M !1AQRU"at234#STVqB$rb56Cs%u+!1AaqQ"( ?sU[TL\KZƗ9͸iݾ^`G_p3)]4 g"6slv7&u# Ӧ=8ժjծ''QS& p~/ֳzamE@fl[*c|WGEw>jqme'K33Xd:0Nxb&! Xty*x"ٔ7@Z*JzEygٹL:tɂu2`GUTuX0I`/E0vBRS**' xeFm& p~/ɂuqSM]Kph48k {).1ΰkE<.72`GL'QT +0D"¸ &IJdf3&l'QS& p~/_Y **N$PZ/}M:80LH,m)v{L^)8?ƨ"|37q̦kTBQqTE+s7& p~/ɂuA+ji:L>dYmhm]ecRL@.ckXǐn)p$:0Nx5u}`/g 3Y{.v1bT﫫S6 aXn]}۶־K3& p~/ɂurJ+i+VbK%=l"jI⨈>:0NxVpm;X Z$#1ٶ*FɴoisQ˴4\av ɂu2`GPj*fbp2>ywHln$c~Eed8?d:UVIm +**x>NC#e.6 rYQWcdF0x;#qt0NxL^*f*6*w6Y+TmٷjUEIW;\1{h@K& p~/ɂuGI&%K61-mǵ}Qz.@nBEnCL^)8?kѶ(܄fVOK!:LbP 7a}L^)8?C F_R4JYy3_-WE,sIe;NH͕Gmt8?d:⸶u3j[_J`s6Q3rs{_a]1UBh.K|ɂu2`G^*祠KYS4d@O5=e3j+ispJ֒ ;O*a]r`GL'QT_?/ Z*zNa!Is7k~eN3Sbut3>s9lWMWL]fM aьVILmή#чQQb6 { U;yk<7)%vcSbQ \UH;Lc7+N4m['50S i'cVk<5NdŢk6n3c,%~캕G5_l>LeDŽ-;yzj(+xBfy|ng)L#/?>_ВǤ1L.m1cia|FF>{N1.)M 8'27@#fcu_;yk<˼ݧJf*XAv\pqG`[$Ta&r]NB#qw{Vk<5Ne*j[~]STS?<-C8)d{#ro V՚5__/6Hfu#4pl'e!b 91 }[Ymk1jp3̺9c)tkeH򹣅tn%p l۹΍Sk+*Xjsj,ޫ@рvr_p}k<5Ne"SaIz6UQZN# Hp CD1z|FWAV)ki#hs{4mOkDEGmcm]꿩GR."9-e`=  0H1ϱ^Qi1Wa슝5{kR&൜GFz\Įq]{3$~er:* 'SӶ1$8A Y5$ᰶT3vbh[:w~e*j88--=fR1X ka!62.l\+kGql#.c տW;UN?2iL+I{fSJ '?ۖeqHPdѼZ!rNifaiy ll ^:w~dt1z1\ٱF[M$RDف!,Zw +Hi}\aZtm(q;C_qٹm8꿩GN:wԷEy_Z g&,jiKNIJZ8G3m6 ^ոy8꿩GVn|?fY$b;*9Xo`yLtlt7Ub-v[loy:w8SNȪ|ã.Z , ;N f56R6\8Yh6;EqS̜u_#)\:1c0W`e2FK9G)qζ~t>Ff$dU38LnRwwܕGqjb&#:9n 0@ۿzS̜u_#$\s9>M*h'҈6!,vÙ; DZT[]KJ6zS̩>9pC67'5Zi_WOwU770xMz\Ƙnpb)SU4~y /v?{*R?^pIn(@KD< M$w>er@YN Ui-T2&I3"i$ 9N[eci}?f툖 $#!"bEC[tPTUSQ'O$dF嵃?ͻoc^E-9͘87NbsڮeRG5O&Rih9mvNv}tPhBgCM$pn`_ cxݵ.Qi5^ ƓO kk\[NIPYҊ(hLqUɒx|N7;1ċoHU,UQiM2T\6܂Sh$Ծ̈́I6 /}_ccqmVt|v 6;؍&"~DO DԲǚ s4fmuMJ's0B)%2ݠxs.6m)xtGGT8QMNr8Ymw &-"&|1YLdF@Z@9[v3o YCi0籵\;Cy\洵 &9.+S3xsi-hm]J!d8Y%8kwl`7'bG54LBNp2Kk2l[{N.EP(MKs!-IAkX)QWBQU /|bji[{!Apv)K23Pe.ٌ[y `&Þ3d1.o׹t2zrVHٰ?5WVG;3^j$2.gM"..::/Ȅ1JyK]6vrM {(';ZX)%k6i eSi>;w !cId2:6kK.-{^QnK 2Lʨ\$5IHc.ϣp&^qp*M$MK,yї3Favx^[iĭw=s"S-778i9—;-S?tvs!}@h'er^0(cU)@gC##;fw [r/q`Vb*IIPlO8H s *Aƨ73;VsC7f]7-e{9׼O3@]7.[k 6;AҺhgS$2 8+l۔l: V2g$/ 8 cb6*htʚJ6H*#,T&9ZnE&q;7iQW  uDPw<˗,Z ei A7qg wEUe9o{v۲3ԍS#K 29Mk>$;6l/&gIPO 01iȩ1-%L|s4/k\\3nnEڣ n%DI4-sECɰȵE]IaՒcF_ #u ؆j6RGEJ畲+HAO-8I\"2z:Y3!c;.m4R6RC3)s sIhyKbct츏J>ˈQmd\`?^pXWY4 m L4]h slAˤs!o*Fk5sN` Mr7+/,"u]aSTAWAW=D-tw+X9h~u[Q1bL4I =$f3&thGh)PsH{\zojtv~ HїC6܃py? 覿Lkt-VH] jG( vk$cbrUh\وӱW!wَI[#KN.6`A幤5R ӷe/q]sئ"VBjSKnhI5cH^i{)U#8e$` ^0Aݴ*G[UɃp l6*i9&tyteۍ.qz>6 I;s#nHkpܯ'7da\a-Ȍ2Å7 9woyZ&(]l{vCv'^};][8t搘 5m\]lżb=XBELY$ ~Y@-!jQ6*.  q˻)qJ 5%s}cd LsD7vkml"1IQR. ;p$k[vI}vXXcXEV.Skt͢E-/ALva۬Hu+tVeUuRW6PWL7/ʽZ$6bJ8^6Fَo$4H9R9dT#LLw$#>{{ymFfi@iKqe;nߣ~Ms:ځ?^&dC{CL|%88nkE, pll9@۴oخkjOT8FiIP5Sw)p.7ЬH2>|7}f`1Q\Ge}(Ӳ.0wQB. ?UwQD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD5@1Q\Ge}(Ӳ.0wQBbTtMQ71skyT<UX}L4SµBei,~EEH¾`CF$$i@B&˰ -<jK\AMs˶ʲCZf;+hDм4l0-c@rnD.siLxZ捥%zFxhl>{4ffvyKKmL.dF)&s  lMՅ./C[U%5,gydn,^nCG*! Ja'з&]+q6I! npFWcp "ǘX~sC[{W?EF9t=Y$pۮOomHOdlu?h^XǐkPMŮvx~[,KI+ єl#X-#gɓ˓TVUCis- I&~i^Krm?dOe:ONǹ/A#I۹4\@"Dx t+8qtv96mݸY[qp2Tp_3eM#z8/aP6y#h4eŶnctS8t xH f\Ŧ݋UCUI#)6@@nô r:3O[[I=K4N4΍DdZ6mAÅ&1ZH4z-'zҼ:zjED&x#ie<<9=Vq6$vvMy]iL#%4m{Bvw&X m=p0r77ٰ+0nRLBٳٿe+4:IS \VB86 Zq\bHhly8=CKZӴX ٴ$;U2qc+!nƹ.9lHU۪1V3Ra+,жi{@Glv7:.q Z K-G /yM˛X\sUESE+pEڨqzLf] o "OppX4w, X!dTD"k659l;R6Q]!S/54`]m<6 "y$X)evmp"BU\[6y_!} \mE5T1TUNF] &&314snm(:G@+ bR{:A[i׻(!VU$dƶ6q'pV?^pK~~p԰q7?zӢq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢXq7?zӢX̳s 3ܝOsK\Zwejw*o`b츏J>ˈQod\`?^pOJ! e啑Hr5?@~G YjX[gDzS8=QqB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RC8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RB8=1RBvU}| n}?@iGq -싌ɩ{if3|DouvohQwQB+lN(ဍ# ufw7qIkpu;:{){XEv;KQ{/1N9#sln6uڬd2H!>Hj$[#\oܛa+l[-L0nX.nݫ1l]pRORI|Z\Ɩ{=o[`7Q)4Tk$3G F d7EoGPм>;5Tia-RUF(LpqcZS6Wky|" ;:./̽Ycx8˴{ X  |H#hnY_/1Զgۼrgg >hfitJZ;yh'iS4B!#ᡢÓc@̑ܞt3+ bgkV%Iv rYi2L&!n$;n:s$aݵ;3S9h+/9ED.8s}t^viJCIJ>]xi/q6{;yr.{0WBI_, 8AŴZɥ*Y9pd l HO|*I $録8\ٺ5-T0&{WYٷ `6U=àx#F4c\,p; ,]"YQcdFƒ]rCI߼XoGiUnQ;0(LW9pgْ/I+ZPY^$1p F{4:p#:jZyafI` I.Nm岌1,[GbOl Vv,ymkr_XGVB({h3n&;QM(Gxvl8}ǝ܃uM54a!MJftq.cr\mD;`;/`m k)s-;HL/q.;uE0\&H|z% r>&H|z% r>&H|z% r>&H|z% r>&H|z% r>&H|EUuCO¼G fw}P#kVc$sK/ksm{J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*J}!Mr>*Jw\>~ G?^ОH6o! % n}?@iGq -싌Qy095=s2wवl޽?^p],jF l8]m>K4i1 c\d-e6{H18"1~4t/F!K@sIX9vȸZA ;$9qq;v *xc-3#G y\ݮQSE|lߞCrs:_byF" DDitQ ,6H$%e`KEͽRʬKtXό#5ACcq7f$H9c'qzL8r{lyv j4Vӈ"ĩd"VJX^.7ѷj")z {cjg'ÈUѸNesKHkk ;i5;q!nlyia1 s.Xoc݇N;“!nGsUv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)=o\b}Uv)2q\IK]+laA]eLqVB&??H(.#~Dҏ>^;"{*H!\![{UF ?U d~HŎe.i )̉MxOhx(]\tQ2I|eph+Uz'<^= 66 }Vo6/iBVz'<^= *% ZMxOhx(%kǢ{C5=ࢢP׏DBVz'<^= *% ZMxOhx(%kǢ{C5=ࢢP׏DC_^= +^= xOhx&z'<TJ=QQ(J׏DkǢ{CED+^= xOhx&z'<TJ=QQ(J׏DkǢ{CED+^= xOhx&z'<TJ=QQ(J׏DkǢ{CED+^= xOhx&z'<TJ=QQ(J׏DkǢ{CED+^= xOhx&z'<TJ=QQ(J5g{k\|Dҏ>M(.#~Eq{#,u E5Ն 0;)> ?U sK#X lj*|Tdh˩b nxH&msotldlmcqJpܗX5봟Ci? ڟCG`*ׂ@] $sX9ڠzmd |5q6Q̳\nNi? x4efVz\5OkC! v{'Pt\5OkCpi? xwE]*/{Q`$숈5@1Q\Ge}(Ӳ.0wQBclR1k"k.8׻(!R12R!IPPMUt곂h㱭Ii+·hc1767fw&+*yf8Y+dxch ֱUQh kxp tmq&l/bvõuFa H1ym{ci$9i @ؼFrH)asc(\Mo`.v&#)ZTCOAWKC~`Ӝe6vӿػ Xi⤬lSԾx|9ݮn`HAؔ:n #>hh6ŷ ]ѫѡNɵ,7 y.ofqr9G8Py+?&1D:XSh3H-uw9S@Ȥ _ ,v[1%]{,OGE\3a\ :GIhw6`oTj:KY]M?B'G1JL&#0Gyi6/KU1K"٬ q;aźXaQɕc@kZpIQPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDDA5@e}(Q\Gm;"{*Zx* |; Fzr~G YjaM(.#~EӲ.0wQB. ?UwQD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@U5!ĪhauD4툹ckGkH[*}U2MQˌv)?N&e;+$JMQˌv)?N&e;*JZJX.uC䆹"CX@mvl}8TQꦑ"\T,|Fʸj\cIq5G.1ؤaSi&'SM=TӲ:*S,<:Vq rש[+vG3 ~F4[2w?N'n&e;'T2O6e-[d@6RU&=.G* ="2.1HFzϐ8=و;?؂o h h"ilNWi6 rwtmo^Y18=kI-^6A&R+`nf0\\aҾ|2i]B8$W߰TagJ>ˈQ4츏vE ?Uҥ~G YN""5@itZ V\w`W*%~kLpm{t4:?融/az'__GU-l:AN@{phжSNL-#72ؑu7=^ ?OF1]SK"G[mW*:4,./{_pDk{ (=^ ?ǰXclqU0e,#kz5~ 融/adP-A[SU2Gn9G6R푑G+{XͥxTމQ+9`eD1n#C'+{yZ4[s5%yuϊ0ή[Quu/rsXdgѫ!50dihngWR-N(:oz2nX2>LR<0YhE0ή[Quu/rYE#rzg44o}j+(l.-co?gWR-N(:obj/w3{)LcccXƆkE1Q\Ge}(Ӳ%jA+daW274 3HpϽ#N>}"TK>8^~P}/G ?z8gޑ"%@q3HzGpϽ#N>}"TK>8^~P}/G ?z8gޑ"%@q3HzGpϽ#N>}"TK>8^~P}/G ?z8gޑ"%@q3HzG3HzGCzG}/G ?D>}q3H8^~ pϽ#DJz8gޑ'K>*zG}/G ?D>}q3H8^~ pϽ#DJz8gޑ'K>*zG}/G ?D>}q3H8^~ pϽ#DJz8gޑ'K>*zG}/G ?D>}q3H8^~ pϽ#DJz8gޑ'K>*zG}/G ?D>}q3HP Rp>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3"2 !1A#"QT%24s!1Q( ?*D`{/YX|u֖ۍ[& i~#޲4k_ūv=!P_ q)$eNE^o'Ye9!Lg]jvᑞz鍟fL}U`MQ (Ay/Z~&7dT>U(Vi@99Oeh1W5cvP* A3q˔ej9ٻTڬ"{d.H>'/huZj*tbP-b%$BHI\ˇ#Rd rʋwD@$tE7VݬQ%:ϙrqҞj&ci% :8.HGy?EWQ@uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image068.jpg0000644000175000017500000005043511665471332026774 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;y"P !1"AQRTUat234cq#5Sr$B6Dbus*!1AQaq2( ?/BpbTd .!i<`6&ԟ ^]c$$EW&}5\E/~yڳ2 Zv%;s迃=9㺛{ =ūEKz;a^:4[fј%{`8GZ-f'tRoiZIf 7u)'+qy|OS)mω$HH>+U@ڼxMDqp[R?; |Ԩt>i)|OVտ[]${`?>f`oa wz(ir:4{➤OR‹#M?QW)N@'pt>i)|OU wz;=I(ir:4{➤ORw .GC~4E^x9SԝQr:4t>i*;=I➤#M?QW)N@'t\4E9iORrx;t>i)|OU wz;=I#M?QNGC~ySԜ)N(ir:4{➤ORwAE|OS@' wzT\4E9iORrx;#M?QNGC~ySԜ)NE|OS@' wzQr:4t>i*;=I➤\4E9iORrx;#M?QNGC~ySԜ)N x8Ì9S)ɑݠہY؍k"Z!ċ乹$ҶK /-cոq=;#lAV #<9. ^^M7~ iy,c&Kmn+Ӣy;5M  /sCs KO%~xbgi!tZEp ڢmMCG cM<ʶ6W*EwMݦydSLeSpSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pSwilY>T<_|pg+O;6W*Ew7vuN3͕'ʮQ77vuN3͕'ʮQ77vuN3͕'ʮQ77vuN3͕'ʮQ77vuN3͕'ʮQ78)]EHHڋz][WQE,?^ . Ek fjwF iqax_sUױτn{ρ됮MG ]Q/(*-01z:!}8i!L -8ܓ}ס^_p0^G<6~SəkszYX}Ic~\Գւ3nMrƇ|mN?XTCrZӼ]ǔ jLJ?;&BߔNV lSM4.,b}+؁aB7eGA81bPBp6,6X,s 9uGT?һa1lI,+#d}^spX j45d5TRT"/ź,°:Yid9t0C kU6_l,_hb)(UMR}{ZloӔXXUD:ߕ?},Z,iX ghi% )Xtu)'pک&"B \H_<Sm'e'|sLўB[3Z.,IY8MjFfZQGD\Eqt #Wk5E(pw D#\m y'^^mCC.%8֗s8D5Ԟ؞#bf 4Oi{ya.iiXkKcpP.T"44cׄ>Xj?%z闙/(/LDEDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@PVJaFa-hH@D ՙXJ_&ԵēD:KH,T!5@㑄 tAs3Q7鼒39=7S{v)R #wF,yy=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" y%7gbrzo$ R"=7S{v''Jo`" <);y%7gb|);y%7gbG鼒39=7S{v)|);y%7gbG鼒39=7S{v)|);y%7gbG鼒39=7S{v)u|P 1 g3VF֟\u GW3r ]zU#H6Fx\YW`?^P ģVbQC5!Fè˞K.Yx]5LR6'3afF\ e^<*W߈a^76i,B#ͱq/$?6ϕZC`tj(1kZ44 oVŁؤLe[w|˴I#w4^0`O Zy*[Z1ӫ`gDOu5bos^,#ˣS,#ˣSi};DUj|񛙩--\/z[ڋ$Ua]a]Œ*.N.M$Ua]a]H{.^`pwQlm !k?^P /BKyd L{8 ;t=]?(F=3NR4-\8&'3tlThZAo촶gj:ZZZ*x)/4s3cn` ڹ!(! J km}..n8cZZX$l@@ @9K:|T> IЕ[x+Mı- su4CIX:ȣ9dsd28pCr67dXM8U;3h34 AiL{E~Yx 4ttS?`[%<;pQi#cAk!tX.5WpL:9J\"kAV Oo}mۘ›C.ÔǛ#,$%ڜ)MT;;9(sF ir@IC4soT#SacCKZn,W96 ^똰b$pֶ=:ťI*^ d 64Uipp浯FZ6,@ue:\hme0^@;>3lnNğI?uzlzc+ӆ8\eꗐڼgsI8_N:2m-nP\l4 z:MʫbIe{satywXCޅvrzm˴lqV6I/v:^SSWԃA.Bdl9N]ZђG1X&\Coh0FbVH6"ť5fx h1aUEEs8ahB뷜ᔱ#%Xbxn#>#O]SSI O¢2g}lHCnLny6/g[%y~%T2ˣē]V${Zڗ909n6MAr*Ȫ9F}بrZD[SX\x鷮/{#+UC91\R:ֵtω,^ ch Y_awM [M+xseVdJëSӶ1 !ނW^źQϲUfX)1h5p*IKyw9e2k#"sS!{KD q7hu>q*WMᮧv>WMQdlnPy.$-ׁ`)UW$Ng {T 17-ĀOêj%tkz149YtÏ$&g-){ Ipki]Nkv6/,-fP/g0334 !iTZ:UVȁ.h{y՗pI&WhɰaQ` 䄸4C<9ǜ/ *M1OJֽf/k P Љ7ms6W8Z266UlSH([%0`|';\kpףvg##_QUItƱ BI-` أ27CO=:x[YO`s! p?Ŕe;]Fi_J )dW=u,U4"hpg:Wa󙤑ы\X9'[ch̫tJ t4Ixye,HOF & 36v*9ĩ4M&jG?#ˋD qh$'Ml(v ԕuewA|LɜrZt$͗ €WR =I4l<470oq RbZGDo {`lZ4 8&يg݌R6PIHV-p z `O9sɘ2P,V066!V X?t(41a^υ˗ |.\t+x׻(6gwQlm !o"==q/yh: j7MSL&V8f-me2=-e9c$"w9l[--l h!_翘ۿ.m{b¶HeCD;3Z_K#X; ${.2Ő.NR CVoéÚ־9k\qyM͹:\s}&+uYNqתUSB9]zi&`&жp66{-nP\@h:MʡcꪩʬR3D֊C$RGxkffqw,6UM͂ ձg#`+6+Ct"v~I?"Rpe hZi@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD~cY,_ DZ0^gP~مz>.^`pwQlm !k?^P /BKyd L{8[ ]5lnA+y̳lrbc͒ v; H6-6 GKKKEO4|sm61a[W$2!ICmz,uKKUҽbh')}Ol!h7k_mX`jt@arv|f&ܝ|.9>b:,W pk*GUQa{y=4HKn`[8nH` (. 4]&PϱUTeV) dkEU!)#<538;I73Zl-[g/=ٻIYKȠ߿4/i iЋ[)#{jNI K@ {kxGjA3䑰S㕎~vsj~W}t;L`Q$M~vdtksh2t-qh(?19˝)qx634GA౹U#`2bӕ^A "'§e;yc.cN :4@ͰZv (+"s'FILqks3薓PyښVQZʆOQOE13Q im JMlu\W f,һtKg19Un2j%5r nOi&;DA,rg]us&&GHj%j&KQ6oᰜ0؛cK-qz\s%g:x\ֻ)#+H)6:͝k\f9Z(i%ɔyvPq%^,쨈~%~cARCCf\z0^gL. ?AY-|[E?XcO<8askaX|M4h%c9mRXC,sS9AR.siſiihংϕ{׺,+jX4I(s<\5:OEii`JW,Y-/M8f\:9k㑱;K`lmNYh .Wό<ۓ1'lO]^[mz߶UuSj-40w<_!ޛ[ƾYᔦngykra[nVL^>Ӿ&Os7[/n6=׈8x9R#9EPHg Z6zY`6u@{E_z"+Dy6w[tNsGEU=6VCQML1hV8|]"ƓjCY258%tLs5L f/N*qjZ 2y4Λ蹀#-􏇂f9(f{TS͟uoZ;6[8ψaCptŧL2eV>;SD#ȧJءVFX9!%u=44(tCcK呂s u `i*gf)dte[@ʗ/8:iNSUO;=u)05ˀk4SڊIgs#tmG*1'8s>Љ mL%q-.&bUSlY+!pR4kbIw 6YRe1]I\FZ0?$-9{ē!F{tv;5-4KZfIsKlln-kva   )e;Rd]xZ()$!ZdΕ ^E=+J`w՘sj Zd{13\avdczl:Zb3>Y#ˇ0?!ip6^+f85-"uUf!{ky%?u ZE6I(h{Z&s$DDD@DDD@DDD@DDD@DDD@DD~cY,_ DZ0^gP~مz>.^`pwQlm !k?^P /BKyd L{8[ ]5lnA+y̳lrbc͒ v; H6-6 GKKKEO4|sm61a[W$2!ICmz,uKKUҽbh')}Ol!h7k_mX`jt@arv|f&ܝ|.9>b:,W pk/.6f &&vT/R]#$kyᔦngykra[nUN%uhqhN)IVs9gt mM}o=פ>7TvK)o5^A :8uv2JyO#b{f7BIi!TWpH~=д\BZlB(lO{ @!+E΋S^{9A6 h$Kn`FrFG8kp :V Plm6F&eI8w g)/} [w/`Az쨈~%~cARCCf\z0^gL. ?AY-|[E?XcO<8asaO$K,Ѻ%cr@zxC,sS9AR.siſ )KSesTXsm0ztmV AhPfxk[kqswtgb$t{bXZ_q~q*4u8sZ#c-k| :2ڝ.46\ y'_ bO؟xN=K1.2J=un-Ĺ%mnoǎ]cᔦngykra[nUy*MAV0Uʍ?';}g\%=+ۍwG ͤm5D13rK$hq*&xm@"-s\Xs[@Mj,mnW4(8lZ@BvNYwu-oy̸G kg_>ָm`0zܻË|S?#pVDŽA-->>c Rm-1 ^ yZ""" """ """ """ """ """ """ ,_bT"~مz>.^#+יrx׻(6gwQlm !o"=ReZ`ֶ ~Ji4X?Լۋ.?@裒IOI_Py`TwB @ ~PѩpD=g¼EVEX9c+b:oiG4]pCtvzA;LJ'KXclexґ:VIYׂ֗>tٶ<GCI4.MsۻY1Mɹ[؆EײlR(OQNMuhᦺ.ۏ/\%Ղ:B\$tms-xnV\E[T0fM^ʊ)#X[,:J.[:Ȋ̬㮑WQ#YTjc CArY&id29-{ \OY'OCR'`W=i kI7 qf#4@]|1/3#^7۸Eͅd)=V #dSO5[d5F Fr[(uci:8>$ cq`J᱙ p{$_0wϸlbL&*#!Av捃#RZ.SX=|І8 hwë+95I)3]v98 mT zfӗJckc?B3ڬ2Ixy%iqn0p.t:_E,[MMP[RZ^ Fv_;wN+ρc8 3tl%THɦ2׎k1.$ƛq75dx}EK Dqׇ Sk;D v+ 6>QObgtjՎNK2$K`;|VٷԀ\\zMX o=[sMW͇ TK$.2!l=7[`mF[3/wR70h1ݿԁ/ڼ1FĶWIk6AֱMMࣦƘQD\ę~/rx؍]İ7cLWǻ|Η7uNf\1x]4/ ;j](qn%AV,sln }k0 Y`=47[ KيON*g. sY)qCNz,NifjB'W̭1 cFrXF9?fDjL6hťіf H Xca3q|+ xy8לOO-.ՌFF'>配cA+'š[ud3oFO^7>z"iԊ0 X֚hdH_+H ].௥eM;ˣZZE AB+U,5bGI={a0Ȩ 'qNc$nk$RȈ""" """ """ ,_bT"~مz>.^#+יr{B+chVg _zV 2XJ*a!kYKZx,?a*eZ`ֶ ~`JhRn,nUBKc%MG=ekKM>'^|ԲXrJkfZE &^ 1>RIb+?彯]=Ry6LbV&ecփ$mpoBhU1C_;৒B8jF8 1i.K洌-`UFXDQh[%yj2 dn 쨈~%~cARCCf\z0^gL. ?AY-|[E?XcO<8askaX|M4h%c9mRXC,sS9AR.siſz,%0g}]>o AhPfxk[kqswtgb$t{bXZ_q~q*4u8sZ#c-k| :2ڝ.46\ y'_ bO؟xN=K1.2KQ^zٍ^l3SAsDy/JxnJa6vw(.6h&UŃMOIPEO$VoH͡oBKu9y6L68+]UQ$ݗM;okXqӈQ?kFKR-@X ZAvRamUs/0zI(iK=6!DjX\9\x8kn+icO(N!8f=+^}-ڜ"Y5/{CZhsZ_($`H&x(YR6<&=4b֓}}G*;eqUw9#Y$8 pv{5KI_) ,s$6w#ctHqxmy4.^`pwQ]*\WKʈ""" """ """ """ """ """ """ 騈41a^υ˗ |.\t+?^P Tx#y:B7>\o~XʤE*}NOؠ{߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b Gw7qSv {߸y;{>'b LGW3rW5n7s7s5|Nh.!s{B*R?^P XTDEK&<< x 7p'»Hy?3Ox?bo#p'lY"x?{?dM$UR v7Ɨ0/MĪqD&Yc~奭$:J TR$ZM=#|,c6#E%dx-'Ay^S^y^SJ=;BLT<[IP@VmDhKXKhr;moGTv ZyksH,qA܎O5TQbX|/s DF]H-F[B7eKZ~V=g2R8=%gfjA~h1-4xxyrnᶎ !* 9 rJ6>XZIT9Ź-p/avFsP)jpfϜIwJeLm-k.k P 008𜶓ʡ'~S1IUDʲS1cp<\"Ew/nWĀiZX$tfB3I99uq-_)@6Бu", la"-[[\T>F_n1΂mNY$,Z ro;kxZ[8c;6:ZGоG QYnOAtqԍ Wd45\OJ*1/]dpĽu ThRT}'Yh,WQm'ݣ58/z.^x׻(j sjPBEx 5>dĽ~e9F-m5>dĽ~e4Zѩ&%'tj|ɉ{6ɡVGY6=<={gd>etj|ɉ{62b^Ϳ2ha=O;?'I,SLKٷNmC|=Og2b^Ϳ2wF̘o̚wFOxN|>m5>dĽ~dý32{ğ2e0Z 5=)XpA-m5>dĽ~dЬg|£Nwɪ*>ug2b^Ϳ2wF̘o̝=j ;&p՟tj|ɉ{62b^Ϳ2vwɪ*>tg|£V}ѩ&%'tj|ɉ{6+;&pӼ=j YF̘o̝ѩ&%'hg|£V~I͠cflz\KNkܓ{SLKٷNmC|=Og2b^Ϳ2wF̘o̚wFOxN|>m5>dĽ~dý32{ğ2wFOxYF̘o̝ѩ&%&ѓ$32{ğ2Ϻ5>dĽ~dO1/fߙ40 '̶(ctt,k6'ѩ&%'tj|ɉ{6ɡ9/|r7$HI?/ѓ$}ѩ&%'tj|ɉ{6ɡ{gd>d '̳O1/fߙ;SLKٷM ;?'I'{gd>etj|ɉ{62b^Ϳ2ha=O;?'I,SLKٷNmC|b/4ѹK=νn$J5>dĽ~dO1/fߙ40^gK{k0[Sd{'4]pADDD@DDD@DDD@DDD@DDD@DDD@DDD@DD׭DEdDDD@DDD@DDD@DDuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image048.jpg0000644000175000017500000002401311665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"K !S1QU"ARTa4qs2tu#356BCb$Ecr'!1AQaqѡ( ?}'駼URIK2ZCrOO>< F@3Y AaRSKN=  }>ΝZRO#hܟ6Wͤ9 s_V;uҐCNs򳿣NZxDvˍ9\&]$4utZ.%hI)siCPS[kЀ<?q3v\jUs}]:fTFOv~*CڵSENzSǟw~q3v\kK(hs=A|.Q>8s)뤆NoB|w3v\i흗?,-0Ȫ {Y-D0\zI}K՜h?7+K tgz|{s;geƜq T[*OWOU`{^gt cU6/|Kvˍ9P坎zZ٥038~NhzZS;geƜqhzE?3v\i흗懩9KS;geƜqhzq3v\j懩.?3v\i흗懩9KO흗s;geƮ9NhzS;geƜqhzq3v\j懩.?3v\i흗懩9KO흗s;geƮ9NhzS;geƜqhzO흗s;geƮ9Nhz?3v\i흗懩9Kq3v\j懩,S;geƜqhzO흗s;geƮ9Nhz?3v\i흗懩9Kq3v\j懩,S:Ɨ:h$Ia=PSAI}H-Ա[W03)MQ'-8dzq׹15ZgojH[Ft:aobY2ˋ$n;+oЈS&^IpnNjs5wv7߉WoTnE}FumfDPx`I#rdf(WK,9, ɏ8VX*mDBF9zվɷz;z6~_ DXy._h'GLnuhO{w365ԣ77#]`Pr;_y+It_b_81Q?.ՓU]9G &2#:28j65ԣc[}J?r ''g$IhG4o+`~S~iim>4Ƒ)Qi1],|&WI'&PSXַ^v{dّlkoGƶ~F\w&.AWhC)d:vG\i?ͷKm MPڗ2Fz2:SQj'7noԊ)æ'gVKɋG6R`Nג{Qjc|}419SkCJq~~B c]zRMm(5zRuzkhxm(4RS Mm>QQio511Kke|w.wbrnj9wIܫ9zS?E9q#q~\MƟ9.zb8rջX TV?evsC+:{x$vsu6@Oz.2:= 9-mRZ?Ho=*D:J))3O12cxl1]#n,/OZȥ7>CюH~+}-;p9{CC4N=dkY.n {F)kі`::Dǭx~[)hਙn3)9't{QR t3W6ֹŖd"JI3\pѸ篡z+QhLe}DS7xt:Qn.* h!:d z`peeL#;b !$dn2;#=8헫ºI)sX! pKCAs5wf s-4JN4Iz K9X:K\#QǷ{,PL-ZbiamX!$#hFula6m,JG=-+˚F 9?=pkc\ip΁/,axhpT=[etCsH#;[y=8#LTRGҒGwt 1Бp8? rzkm*'PQCO.tvO^OEen;k;3KP1н*wjQ=M-9Ȅx@Pt+}ƶ_KT[kLl{KFdpܒ? x)q(bOcޓA`6pZDQSe4z.8 61y2c;Zm\U⦚&CRiL.:]j.7;}U֪i5َ2Nq(UWMe;X̟$D)n [7;-ɷpZpt\wcchˀ2_:_LږӴU'?}4=QW| /}w_-GrބWc_WZi79ƣ@3SY}V9PIICs鱲F5ַqk O&SɄ!kh­E5:JC_K}dgHQZSݜz |sFZ?ГFV3lMc{K{ ۄwK-T4Q3BXt/+kmv:FペAL5:OQh m=M|W(ixkAcf@@SV.;,f[/',v1WGphHC݌yLMEN\áNp#w~i喆-pokm x]ӡ߹jnTwjQMK-c)ȡR:0z108f3^}'J6i!k莬2= \&>یѹRߪ}<5I4NM23yy\:1v٩q>V~ $d_LY@sP1&^9w;,b-;Zʗ7X]+\747ASo;.-5hGVQo *:6^+D1TL%17y#)s;;M6'1$ӿw-uNӲC,zyٜsWVв{ٸUSZ]O&:3:A Y>Pk$UMOՎ2SX-TRFFDt߫+jKuO4jcƜs`uq\E 9OVmnu ̡.Z˵ަs'pYˇږ:˕D IJ45ѿI2W%iG>S.:z\7+BpAG~(Ds^qwW9`i$.<WɦU:;4rZp`  mW&,kg4d{r dd[ m9-:X"cek$kc6% Y\j|*b2;uIb-T 4hH[!pTԜk/VMp1B4 ::T }7z9kD.5oG]-((ᅳ3G54c8= T،< ]"N 7fr:]i([GmR3XeyJ;vp\ cBc5u63 nOm-:['@hkK)W#y1hO lbfFs){s{TUj`1%ё:b2:I1OBM莡v(*q,Xi)<0KvsvqI՚JhiB5pY>VK=7 3i2'5-i੪.U-J[tW6dzü?C[tO%EƶYjɼvR3?ԮmVkxu{c95yی}[}GԜJSmt-45= TOh]X3DAWSɫ5[bl - k\Teʙpk"i8DBY9)lb-sNNLmڷ F^d  ۺA[OM+^hF2w ep2PH8=q `ԧ 9=k>-9p9rmjtEidtJh$̧" nNۭIQme=S$ytc Eyt q9'e5VRrvC\+i4'v7=8i8^YV)ZZڀ\q Ǜ̧"#t3K518 N(e$Jy;hdi 8 g8 8~9[3;)dl`Cݹ8ЬQ\|^J|´D@DDU_s+g\U9)yz]]+^+bW[eD>64R lqѰKAcAs: h$(tE4S ;D7ZקUzw5ktZִuQ5?65?,H,cc\@-ƒ cI?c_^Sc_^Rė1{ 8à2m~zM~zK5qj٤zNzkHkH c_^Sc_^R®O\aׇ cZ :p A($jճGG1ƓteGקTקTf4:2?UQKPZӂX^{ꭏ}L A=b0vtcӤrkklkkX0: 4έ:a21uεקTקT$9p= rXÌG|Q5?65?,I߸oҘ($KKA]Z#=遌`cm~zM~zKp@  /,aw3ޣkklkkX1/*JHhiOHcrwOI'Wƿv?ƿv?HkklkkX.ƿv?ƿv?HkklkkX.ƿv?ƿv?HkklkkX.ƿv?ƿv?HkklkkX.ƿv?ƿv?HkklkkX.ƿv?ƿv?HkkOCYKeC44# cJNE._C_<[?BK/p)%gؿ/ VւIaymu~C? Jo!fsa` 􃀤i,iHw2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi2mzi?*,iHw,iHw,iHw,iHw,iHw,iHwʍ[#MQ1|PVU}w_-GrW| .]]+^AB/p+ՙ[;5E^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#_/DA^#,sEjG P>Qpr#{TEEê!H=gO*.WOT\:YM#{TEEê!H=gO*.WOT\:YM#{T: )-G_iޱzIAU9)yu_s+g\hI(96;41BORZ@߹Lە>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;R"I!1TAQR"Ubq2a#Br$34Ss5%Dc+!1AaQq"Bၡ( ?gU-ǕkWe.!HPHV+,NLe 'P7ۗ)mI7qZќyVtMMIN8R dXZuI㸲K `^C $\Z۩yIl{k*זʵƏύA0&aqZќyVZa,KJX}K_ AOUz:]lA0h-<)@8yh<^Z0lN=oZYBбe Y`dL9P0GێuZ=8ԚSiamth5J(zc;!0t0P{VOKH}Xq $ V_V(]*[NM}AJ>M# Yw"SKuRnSќPGMf Ȱ̷ğ|öeu$qmHpHmQ*PUiz1RZΈ aӈ=5!m$5Ӡq\Ԝs:[uJvi61q~u82NJT,,z8/qc2ė/(+#y;Z')xN)'$3$ϟ?%2wtrdI~B~ګ1Ő"M~TIң$ŖgA㺵N%oC[WZZ7^4GG^>'7]^T#~s^"hr;&2%;oS0P{W:q0o_; 1 ?J_Of+OA1-v6eBG 4*Q[ċk*a &ڧ>|e:;;+[Qg<]yx+ᒡ+8o'CM L[7%ϟ?,o1舗e(aJ'#BѾ*a7t0P{S=;=xѳG!a &ڙ>#ƍa7ay4lHz|o=a {v{ggC}AGCM3}G;=x0j:|o=흞a7t0P{S=;=xѳG!a &ڙ>#ƍa7ay4lHz|o=a {v{ggC}AGCM3}G;=x0j:|o=흞4&ڎ0jggg6v{= >a7t0P{S=;=ѳO!a &ڙ>'ƍ|iCM >a7ay>4R0j) 5M[Z}Tj~R#0amHq%~dv崔e e_^K,t8"X!:eoVZgFD1QX DJԥ5wn J0lM0 ܎O.wZIqI8IPkum׿ NÜRrb$t8uN&Ak%ܙ6 [Y B7k|i _OR B#Ea[ yҖ9(n8C`vDM iGUIJ묆.%(u~[ՙCl\4q*;o"xqD9WTʔs\u?{ \ kUNk;_z<y/³roNg M?gJƎ Zl 2C{ҕQ =;䠔Nmzdb')~#¯&;̗Z qbvyh@Njdg{#ud~~~}$1'ωRPҔ]I77mJF+#q\FQQA&z(=OUyJ(wf:B1n%~(v d1!ԧkr?xב%J%MFyl%$(1Nrx{ %^^?WzgET+:?-PWUzcLai^&5/ `7)b.7 Bc!koJJ%饝_JE{ױB:ސ5جr‘QTI[ӨJ@J\xUq9M=OQ*Bd^GmNQQו- j JxNl>QFz(џRZ kRV7ޥ,6-r_g򊎊$_g򊎸 K(_M]$_g򊎊L>QFz(蠓=OQ*:($_g򊎊 3E|L>QFz(蠓=OQ*:($_g򊎊 3E|L>QFz(蠓=OQ*:($_g򊎊 3E|L>QFz(蠓=OQ*:($_g򊎊 3EG̗mqkinRfnke\+uGO.k i 18X{X|}KAWx<{o´Q]tS?*COBnV 5MmX-P/Tq[&:TMmjaeJш*Q%ExJ^&:Qnkd+W}OLyH֒Q&pÇuoKѧ|m5|m5z~F02J+ji25-/^-2ΰYoT%J*HLȒWOAhLĦ>DrA>^шt9y&C eED\}O/b^ ]uFK#] OPfӏJJF *t7EL'-k)򛑾[-IMmIncn)9$f-mF+Cofqp3NP$jm*8u=ot~ cSII AI#W?Iexf#+ q*S1#!@toͻoͻ[oBŌ%ƒ-+'H~!TJ굊ܫs|m5|m5>4l=M)KC"zY o6o6F&YbC)RKDxqЋ=|DўRWiЋ=|DўRWj̬ucHsU^Bn$ ؋X.:V:)64;篔3JM=g3JM4ħ@zkRкxՄY!C^zI^=|D)zI^=|Dӷin*H$ڡ淈fkIRPB Y%z&OhY%z&N^}C]a I~%4"_)+4g{P-5cW167M 3JM%z&MJM%z&MJM%z&M$ 1 ($)m.jzG\(k'RQJC mʢ[(xTY=Ѭ|kMD^Sjw)OU..#2PyxE.kA|hOy>4gkѳZix>4OSUvojpߕBLv欽B*CrcRǚğñY)N=Ѽ:M{12uPc8}@:kxSGC&('Ra3 i!jKbG85n7\u\>qIO"kZ3|c5އS`ۮv^9%+}q<8 Iu׈d%!`X\Z{w^5E-"ۓ?#DHJ.7 ԿSƹWz(|CpJ/GC6+W{~s_Ž9 X=GDs_q)d]v_Ҏ/œ`)R0!BJ:ƱsHb: ugZ#GXL3'tJQQTQcSrj}ґmp-dcbQȈbheJ%Gy p'e^2jkiZRQO_FPnP~ԝ:||pasy C%#y<@'VD {¬_Oc, Y֢:e_[ ?xhcTX[bNIo%sb_R(A7)I=Wub5F;<.kCZ>=QaM$VIPYƑNT,3fCA$6{T5`/`U޺1v^iJ)-ffԚ# *+q\%!U@~6kTaXc1bȓ# Z~oMGMtRŴQě+r` )WH6=,k2in.Kǒ=(>~ɫm3;91cEկ\oRTR.:\NmCXH-N-* 9`# U\eHqMIJp 3uTm*I #V$REAW SRVʩhk- ?Fbn7Vga% ÖofRS T>-@Å}cSR Fʭ&խS(p).*p^ 5-mjO0iL6N,? :&*QN}>`jzgϞ0XqA"d8Ī).$$-Xi})!tokUKAJT,R"]믖b.:pK}G 9Nmŵ\[rqjiR݋Śa,/,u [85)I n]ƖLlaNlmn?*B `eDR <-[Ee<,v[Pѱ" ؒRIZF|l6Ի$bO~?!]]?q%k2jtZwj~M[oz# b%/Iy9uuuoa[[T_N[eY E1]SESlmդa9lXlK`*N%k)66]I~: eFãY}MHJԔ*ƽ5zڒٕ Q[֢~|fyzZuX?ҙI/Ц([PPnFSƵpxu 5b_HJ< ;4rVJc- $,X\}qV ì'G쎈\,;iֱzlg8"$(:@!D V꬝<dBĔ yoZ:+:+m )InAtRVe8 (v lohj??jV|M+LA} kq]u#UI$)Z_N*D8c/%E< :F׫tgcIF²-"5fyK٩*(((((((((($UG\EU $#VI?*}W;i?dJsYR#FZ5+ k+֪ Z4eZ(2k+і j寸FZ5+ k+֪ Z4eZ(2k+і j寸FZ5,k &+?֪ j& ñd%J7Kw :uR_GNK :uR_GNKNKyI~3gNLyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNLyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3gNKyI~3%q1$ Ƕ%jA%C}5tuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image064.jpg0000644000175000017500000005625511665471332026776 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"K !1"AQRU23Tat#Bqr$CS46bcu5d'!1AaQqс( ?V*J5)G&[.D% 'O9tF M 7Ne1j!)S .ԁ}͖/Z@H@H.\_>riצ3Hv>)ZJuD#2)-OFɖ Z@QJ?%futɉ&eZBE0,㏚z!jMlr=S/aLaWT &T-"f&6ښR ȷ8C?=C$bVqwf ěf׼=_Uc~ Ge fO+ †/+BȯHiRhJQRÏ8( QIw ot7Ԧ90z_Ǘ' SAf+q䋎6BN9,CƨFyJD]ܛk;]:31kc~ Ge WtWܔD>yבAS2x[g`|VnSIҗQ"*: r( Mr=S/aLam*LKs;rouo)Fj2\ֽc9<x|QNSq TۃP+˕$ٝ&8%Dˀ)Q es7? NK*A۫ /mZD p9GieH"xox+MU\MKAY.KbP|* ~lKhl] EܒMO$tWI&,8C莋tJN-s K|FWO9oҚWE2{k} ;X+D#QsEAfc fCJ})^w"/#+?Ϭ)T@Z(Ay(R,R8VZaMWڎUXy:Ӎ,lsFGѪD'H%IuWJ >wHC.UtyJ!5JKjkTZpyKa2 F5͆,aJ̳1-H0ֵ%(]$$ .-c#z.pѪ! RըJŔR$f0 h2˼&|9/*dKn蜾52YMjl4Hom[! ȉ=ۧS'Kk i]Vt6ةK;-KAm (D!9XEER )4) ( R<)>j":?iZϐҴVՅ'$\ŴZ! hZ.uQNT)Ĕd0Xǩ:.[K*iKK(q^e[#h,.ռ LR'Q7'K%m Xyii$ܥ!W/"~" Tժ?!Vni jC}Q{8mk. aY6d)ܗK,%^rJ 1d1T+Iex56m<@PGek ֿ-/wc4eсWYdX!ΩXf=I 8ņ6|H<bnz!*Q $8+%pKӯ ϧ_td01_'>}N}:$!9%Bs! | ϧ_t8A/N`cN}: PuFHC%BsKӯ2BA/Np_'>}ђ PuE%kZjy!Ts^zI3:OމNKbSD랚S@$ w"b;MJͱ}[ҩRokAIk舎y5'v\(>^'ݫNO0uN i%J @o1A ?fVfn@"M-)<өK(J*ĀHbj15ZC Mcf,f¢BHZwF`f9r1iMug)srdKXsn"eWZaTm)&!RU : ѽMIgZB+72T(L5VsQr[+=i+ʚn"*u3((ױ7b%.LU=(er3 NauM3Fګ;6RBU>ڸu7A2dcΏURRIݹqO8qk6Iœ;Er!N@\T. >UX"uJ&i /-@&9F7v锵,Y)h`M:ӍKVl'C!8rBoK UCjN8J0T^_3leRĬpNJl(㿚!ѩeP̛dVTe91IB¤˲Ym:p34\'{w/V쯔SkӍ7 팲 *qRSLՁeB}X^8qVڋ\ry V%)abM1abEmTf.M$'x)+-y}nJuNQn6ihK*JɰIȒ0T?.\oX" B,% 7 haMJL[}a*n7ņ_+^ΖGČ)Z>!@!@!@!@!@!@!@!@!@!@!@#=':TsZ砤5$Np MD-ӫ$S2 b3L}[ͅqjbGS̛4Uј}JyKb ? )*>{cj_JjszD,!+V8%&ju$[`Ukk5ИT4fuF]Ķܣm҃ te67⃻<'H+ڹEz[aV0j*{ Jmsk+"vpt?0-D1ٶs70iEI( Z|6lwuVjb|F )["AX1nTp#4ls&-QKnl˲ g|N#2鰊j:kHI2P ե(iBPrYcV~isTjTס 2Ҝ ׸U9bdEai1DyQ-]J7θV?Y䂉FMd Iġ˽+P#;S3B3+ՊBZqrS2S!J  okhcJ3&$X HRJMҥc{rDr beGeWhdac3:]Vr3"Q B eKZZ3+J@Yҭ>ʜ3ҕ*RG2 Ჲ-.0֑evu&MR3 kJb؆|U ASdJ|w[R/ų:O*iVZciTI)u"g1{n%h3 fauj .,.y`%!@!@!@!@!@!@#=':TsZ砤5$Np INN5"]t(N!/:?F}:O1_UF%Em( WG rjXc\iae%)$) %Sf+F]ԧiI92Щ*k4˲#8.HMƊ.jAsG q*X( U ҳ$yrq2,NS:]y :l3B^%+){ k*[J \_vCIhÛRY66;0Q06rq|JCS^Sr!.[<ҕ&A/4{s3IuSCa .s{qSx{MԄ$meeAM$XKےqZ32x̄_-VGx$ozgZ)CSElj7!*12Jd\^QD%M* x0,r|NB&&i>wU/0%KIc{*8ܝ*Nei2LP Ve"Č+X^+8Q;+4+•Xb;zge+rST jJ@g JH!`1l%mfӀYrdHV%#+I/.oM6ZOM*'Z-JCYDHl[5o '+[0r.J6Kl0<xv'-#<ܝ"Ur&] Q-chitM6c0p4e8O2UksƍMTe%䞝Jeaiim$jH+[^ڙ2[kk[-F %I!`oI G >.LHK0mK$܁sj!FJ-F*2ˠu*)+#;{%oJDҚ=(}HCa-u*Øh.SS+Bp2eҒRl ,16=#98 FVuhYFI(PB GA*tKmcI@Bn.-c<@Ih+M͙+lTaߊ-ɔi#FgQ~}V1RBP)jJ̅*Xrbtd$`Fl6P8s Kf=(4‹( Y$)9琽L:aus,)JYWƇeTsߊ y9dQqhmAm"AI[$\K\$ܘwZ̹n9kH &=3Oun&N8)kCIIQU@̛ EJgDK}Lis+fnE:ѽr"nRZ^NQËRYP]*X/tU;ifkt`eJqd\ C=MSgeٹ)yM)֒429 _JD5uu CȖF%XKQ9#X'KcZ<58-Nw#j Ut~F/iY]Ra =Lqml$ H@?=*MTӳJʙqq;k}rNeKincdncP!j a!-Y 81Tg܋akL%ʐݗQ.u\o0!kT˒RƔhGhtw&p[BT|W$ R].*XX.(j _khJRJRiZm¦R@lЛ :[t:asƜfr#ff[rZtam\>jjZ稾VmL1NuS{aݺ#'4~uM^duBҠ|y]p` J֚lfݛLy8x4n'Joz\*l!a(sbsG.촆ާ( LkKj8YNMe+d4ҶT0eVMnP0<^0!Z$h&eY_JZ&T<:FQeTTi)Kj71Mщ$co&Y.^YEJt:En|~WFiD>u70qĶetT 6pVyP)RҀlOD2q.BdљL _A46(H$ab὏91$ta皩;1OmɂҌYJּSVRM߾œ.1DJ,'$#w}S\řtKKRjm:ӬYZM@~^bٖr^7 lEl(~鱧7RnNmb-dMHj|ϸ L)*ܱTVRN%E Ecû!UFe&}4C 8@'1?fg5U1K̵4q@R{II)uur/M))@sSW`JB|t*AS*}* Ve @X'HqĴڜPQ !)*? VjM˲T\PVPBye^fYL90q:p-#;[c43FS,ћ⸖n)n%HVMً%Z^SMB) a#$)9{EK557TR[TšIQp${#ѩPS3,m!PVެ(..B  fFe1+)52ZSu$qV(Wx+3-Pj( )@V@cgeə\q`u㜭aEe4ٺz[3JqGI!$'u"9֘j4uԳVTFJ@TҩɚĔ,Cx !C %GAݺ1?rau . GQDg*"yRf]A:[,~V H"'C;I,ʥZ.:1 )i#%M<ݜbwKwi)S.4(ʮG#/)0Za/ jxK-*RD"548L'DB+q* 1\dY!cLe$Yqs3RKAl%As+YZ#WFb)5A5p]a(RC0(b*xP'\*km,JU˪@e wLHmOݚ_/^9(,+1y-l$tIddfV?al0ߎi9+(Ni)tKtqt4ZIB*mf97$( IM94٩ǍNJ.qRm6˞0E,h0#n*WS{ B::vrR1,ܫLJTWw k0,2t|J}=|̳0R'9);N{65P3}8AM'׍'4k|fW6Ԥ*3I8w^|Nk}*Z/+4천m6i+ )ެF2}b~+M}l̶) g~-VY HK!}Ao+s#90^=Q*3-?0KMH6,Xkۚ,N;1)+(qBAHш-vw٠VܨKJ53-2ʥ@K'HICxNtfU-,ҕ%Eac&hܕ1(E6 2Fi8s9o=$O4]2iaBdvWVԤ*vu nM¤Ė.%`{Hߑ4l Sa MNg%q72ӌޱ-!/) Jp⽒@ fwGVOosi*2<[BMTEe Ӫ<6”8JijRJ,i*/30mHQ%'M%$Txލ/Ω&]AN $\bVy+4&h*0JcGnQx6ޓʼJM._X5!%;o#$r no`VXJpaJN#4gn$Բ%oŰߜXIkHިiY$ܕq-Ќ/H Rl,NJx1L2$j.y+x.! jTnaM vAn8uWdwe[+'}Jk..b*&10IH%((J:9@ DҚ) LBl@ZەI2MV А'Z[24YQRUd\Z\\n) !N)TM& |! CEi)%Áksf;c:I qi@* F$LBBAIkֹ)>q +ӫ$'?!>^'fP!O(BAZ%W7#'u.F5EaT102ɑGQ.4)_d1d` ZL.rU%ʭ0%kKa)Y 07$7QyS} &=ZG7Fg Vrej-8%TC4 ,r%)7!sxUqbwJ5d?)b%:6%8jZx_8&%e<הf4R&` E'NMSUKɞ[D0ڟkB' o$H=Byx;QTƵrkB iFL,.E܄۞)ɦe$sr<4ʕrӊR pR$bYRĬpNJl(㿚=r![CXT$bĦX(Ut'.YyIyVKJ+U (|)7r @)Ԯ5X{bXרɒL"Uk5e\WQJUB`l`)vS͙&<"!g?TBr-RS KhV5!07Bf5-PrFsI$e3 C)RҒчՐ#^,nVM>ĺ[-^ .eC Ax+~e<ӎ m%MP~kD? ڔbT09},%j!Km/u~Y=[uUr*C,# F%:b.lEJԇBRZ)Jg=8UNƤ=, X E9!=Q;*40S,*a*BJJR*- aXLv~ne&qHe dZCIN\]biRx1*]B )[mːթDJ y8m|{%GV柙I7V a6e>y(Ն9)K7JYH9V-|EJgІYAbQsDIKKK\iy-L$ꂖuZhۘSeL%Yh,-ǒ;YywYʹ+]^HTPVQ. TqjRA)%fjz^z82:/iAlj̨]$b_˔*Ij^s$fj$Ӳ08 1[ͩW2F(:HoVVey`u ^h7PݛVI:FddoK8v)_BR!iN{q$=I*zY3/'l{9STNr_G*[P A%iNxxI2"-ULLOeve *q!@2J(iSMO0 M`O1˔*Ij^s$;ay8虨VAm.>"  hR5Jۏ&ZI@!*vخ l7&53OJahm,/p3x5SKKNԢ׽a0A74JI0IR)6$EfhzTi?ZXCZ4IDŒ@J"֊-L)E@LK%7ϋ揨\fQYy|ahqT\Xb>Ў:bPIrfRm3ږD[Elbp yĹ8f쓫Eey>5ve%BP8!T$T[eOM<ԾxRQVA!;7Ή̛nԖړ0YHA!GwB%bCj//YK]RQV ,p() ԛ:e:F:P1!*G7{GSTS]Dhm)aXu+J$Z 1a*77JNZJ+tm>R073YD<"zxpbJ*G7$"zxpbJ*G7$"zxpbJ*G7$=':,SraxQ!+mΫ 4$Թ}:O1ZN3i\!*8;ۖ5(>^'ީ9;.m8"VoW? tL/*Zu3.k 3~X̪!!'wG6&<Ł:;SnjmrOe[ZՀc*F#yxLl*#Zl0HơudoxVHLSJf%'>66n)hCRVclAb*sZ#8XSo&`8ۉ3ϰ]Zݵ/47ds[zT!) T,37ߔ;C$!!Dӧa\‰<,$E!'.hY&]v&Z}帤n&]@_x.P"!!!!!!!!!!!!!!!!! uAIk=?a)>qƒP}:O15Np MDT!!@!@!@#Ժ*%j+Qw,Mʋm-ŢuhI-6Rm`@LI;côlsvJ/9.J/9. côlsvJ/9.J/9.3s a{(Ի(Ի϶9;O|69iRR>0=0pR}K(pR}K( côlsvJ/9.J/9.3s a{(Ի(Ի϶9;O|69iRR>0=0pR}K(pR}K(côlsvJ/9.J/9.3s a{(Ի(Ի϶9;O|69iRR>0=0pR}K(pR}K( côlsvJ/9.J/9.3s a{(Ի(Ի϶9;O|69iRR>0=0pR}K(pR}K( côlsvVӖ̻as1o6\ ^S5=':Z%e䥒ijxKȨ'3ҹ)>qƒP}:O15Np MDT!!@!@!@#ƌ?_4gͩD7B BBBBBBBBBBBBBBBBњ U칍d1_'^'<B BBBF|ڟD{3"ț!!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@j?30?35#Ngp5r砤5R?_)>q +ӫ$SS32’#jqD)"6BTj :ne,8HJA'!"jۑKT[RԾ!´:ҚZO*C1l: SԬ]Y|:Ra$6mHX9k=T|$ ^e*NܨXK]/ k)*efۭM-+MȺMȋE= ̼mUέm TZZxJجZ ̞fo R֐s%{@G6 E/qa qX%`]#c,RbzVY%SKhrgh] (*KeE%>gxړ )ں)/oӄ]8Hr 7'^D}!N.NYS:ʴ^{C{$HE3#xџ6D!BBBBBBBBBBBBB찄   5?W?W39msR}?LƯ[\pOքƒu{bj$!M: X/`O=BB4gͩG>mO"$B#:c#:cR4wWG-z O'\u)k ВP}:O15Np MDT!!@!@!@#ƌ?_4gͩD7B BBB찄             5?Ww s^RMknwWG-z O'\ubH?xAIk4ƒu{bj$!BBB4gͩG'C(.Jٖ@D#Gn=mǢ~!oB4v?z'ЍO;t#Gn=mǢ~!ۏDCq蟈w@oB4v?z'ЍO;t#Gn=mǢ~!ۏDCq蟈w@oB4v?z'ЍO;t#Gn=mǢ~!ۏDCq蟈w@oB4v?z'ЍO;t#Gn=mǢ~!ۏDCq蟈w@&CC#{{318VnFe</tGb?z5#g+9sR}?8ZRMc=';x_ѹ}:O1.㭲\Ki* ɰWI3iIa՞d)GLny ɚ\伺ZJTuԤ @& H ~+WO2^L4}+HQܛeFe9Tͨȴ?U`}D)$7\r7-CK/6Z!JUV;[>OҕTm*)Xa-+Mq#vBBbO8JyTڛJq! 9>mO"$S? 82xbn'S? 82xbnO\Tj<0zQቸ@Bpe=qSÃ)늟G& O *5'S? 82xbnO\Tj<0zQቸ@Bpe=qSÃ)늟G& O *5'S? 82xbnO\Tj<0zQቸ@Bpe=qSÃ)늟G& O *5'S? 82xbnO\Tj<0zQቸ@Bpe=qSÃ)늟G& O *5'S? 82xbn;dXC!^!DV%랂 R{zy9]sR}?㧍%pu{bj!h>^'<B BBBGKIgQSn}GK.>܎Z‰@yIClo> iB\b.3&vC D6Ť] gs HϚglo>tClZEЦ|<0شLx`&vC D6Ť] gs HϚglo>tClZEЦ|<0شLx`&vC D6Ť] gs HϚglo>tClZEЦ|<0شLx`&vC D6Ť] gs HϚglo>tClZEЦ|<0شLx`?c}!H}b.3Ť] gs37~mߺ!-"S>klZEЦ|<0;c}!H}b.3Ť] gs37~mߺ!-"S>klZEЦ|<0;c}!H}b.3Ť] gs37~mߺ!-"S>klZEЦ|<0;c}!H}b.3Ť] gs37~mߺ!-"S>klZEЦ|<0;c}!H}b.3Ť] gs!4\RAG.z O'\tٙi텭q&ᛔ9AIkW WI6+κ9 ikBpJ  y_׿5>^'ji1b/o!ĞV!~`N4M\ K>[Q*}aA*Ĝ$ rgXu  4"fQ;mO"=GvYj@zqn7q' EA"b? 1~zy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9aszy9asioO?G+z O'\uINy{r砤5OJA ?B}:O1T\o $>g'%,$;Xn"Ҫ<Ж:8It曔$q9^ZO'0j\Rf@[kZS%@b"(5$%jS( gr .@n3 i5%-H}6]ēc sPQ\@ XDJ& ׊̉7 vēAeNe%5,[ jU5I (_b֔JLN-) ㍸JPS2P#q6QfVR1)ua1.<j.rSjP3.qgKYS%E*K)2 9c6?_4Uu]OxDX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y *FyU]WS5ŞX򪺮kUu?\Y 8eB/# rG8z O'\uIuAIkW WI7R>PK:^[ro*ѡA ?M\ K!5fԨog5d4jq)Sl*Hm R)IQq dYb!,H-I6TZJRR+ q"R9> qTHD^8D69!R%!{CHEsChs|""R9> qTHD^8D69!R%!{CHEsChs|""R9> qTHD^8D69!R%!{CHEsChs|""R9> qT찈qmsBJB"9!9> )8D*D"/hs|"C#=':bSF[g\pO%pu{bj!h>^'<B BBBBBBBBBBBBBBBBBBBBBBG5z O'\tAIkI\(>^'ZWI&3ʐ"!!!!!!!!鰄#ABBT5*4EUjc&rY~LqX1*׋?BK& luIsD6:]?"$ \ t.ȉ({)ymYj6BT22w_g?Cc3K#lO>ʃhzy%' gwLluIsDIB!*>^ߛ5R1 S2 ]ZNJRԣo,7 RW1HJ'P;Gt.Et\л;GtEuiԸ㭵M cJl [LT"Zniq+;.8M" ;v:.v5sLJFYβaH)`6ܯ4%Kw@@ݖ8#+;v:.vW*u ޑ~D~+C-8mwA$r,Fhd;Gtiԧ(%Tmq@)V'6"6 k\pOQk 4$Np MD-ӫ$QHB"4rjYs %B-pG&%⸍ѶД"Re)HR'ψ'6OZgm =i8pG}Zkǎom~`zJeW5$ ~MPÀz;_&Ļ3R뗘m.4p Do)X(R<ǔm{W#3c'xg.}C( dҭKTzZuI7o{@*mS*+R%5r,T'$r99x)AI:Zi8%_q $ D*p$b7\\(9?}gxtsn!IJHPRn͈7H5z O'\tAIk_ַLԡmӦzFT%Lt=sRTZ|QyFg*_->(yFg*_->(PRTZ|PRTZ|Q fz⇔fz_l-<3ԕ/<3ԕ/rCan|| u(%K(%K[yFg*_->(yFg*_->(C3=IRiC3=IRiG/6QJOQJO9|!PRTZ|PRTZ|Q fz⇔fz_l-<3ԕ/<3ԕ/rCan|| u(%K(%K[yFg*_->(yFg*_->(C3=IRiC3=IRiG/6QJOQJO9|!PRTZ|PRTZ|Q fz⇔fz_l-<3ԕ/<3ԕ/rCan|| u(%K(%K[yFg*_->(yFg*_->(C3=IRiE#HvXS}6$R q!4?uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image042.jpg0000644000175000017500000010664611665471332026772 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"Y  !1AQS"RTaq#235UVsBcru$b4C%t&6DEde+!1AQa"qB2( ?aȀĉu Z֐I$Rk"Nh?5rQd\3Z[:vkkktwN KVݍ\mn,%GH3'UXb  Sq(i# Y8Z<7cWӾxAiF 40sǧ-Mlثwx TN*:mHqC9]Uԡ+QdV+VcՊ;n=XAZ +߭衙[ClII P;ثwx T#*S.ӉS t禸ߓ܃ثwx Tna<ړ܂# n젾VxFh&v*,zGbǫ]XQn0:Y+7q RK[l!:X:ѼTv*,zGbǫ\f:ԵOvs(bë-k-)e:#8;Un=XVcՊi\y,i '4">Ykގr|X_bǫv*,zQsjDEʔIV4[H) %Gf[hRRp QnvTWTd=Dk(#eÊB kZt͂7'j WKlκFRRH@Qyµ v9I_*9T1a+^VOT1a+^VO@!zCZ?E 9 ?k r~ נ(0@SP1a+^VO@!zCZ?E 9 ?k r~ נ(0@SP1a+^VO@!zCZ?E 9 ?k r~ נ(0@SP1a+^VO@!zCZ?E 9 ?k r~ נ(0@SP1a+^VO@!zBLݱ{5j3>K(#8!*Cl9lq AyPp2wӒĎ݊ޢ1V;?8վ;/ +uKx4WnSY13v>wԧRf t+N5?SG;_clc}HM٩pCIv@6'ƜUKq6mTⵕxA[lָ&1րAp[~*s%0:Ӄ(ZNBj: `ʷƒ&v%-2Rn Du|Xy@Mw͎.klk%*_,BsU LISzeFSS/Ӑ x㦜DvѲƷ]8jZB$!:* dSwZ4:uAJ?Sb``|\8.u/6RTddy@MEBJIqkek'cf ]'WG(II34GTCea6k !T`kw$|tScFh5!=h!)KϧT%{yp[J1|R8rޚ9@MTVʔrNx* K%K[Y# *XiAej,Ui|w"cSSƠo09BYoQIy@Mw.Sm|BH$HrnJVRr *wzjT)7Uf#Ȧq!TPQ+\h>c}qroG%Ɓ)K?'(,~O4rX\h>c}qroG%Ɓ)K?'(,~O4rX\h>c}qroG%Ɓ)K?'(,~O4rX\h>c}qroG%Ɓ)K?'(,~O4rX\h>c}qroG%Ɓ)K?'+JV$)'# 9,~O4rX\h+>sT%Ry,~O5 d$8ch K<-iNu!Tgp".O,m-P&Bq2Ң@kg4CqV k8ͺD"g(.mS2srʥC T,_g=XvSqRf)9>.LSOBk:BΰQ yVn* -wěs+5뒖1H@N9r1Npw]d[[#Y +E#CVqh6*&1Zq.45RIO[%ei ,PQjsc;=p~/)UEuI92xcڛ&ƺ%?=io$)JI C[kTl)RWd[Zۖ9 WIw$ai%iIX߁#uX"uۃV>ҟ CeJ QH@R,ζAEޒP5F0?զCJ ܄rN& ; !)W#Hyt%i8蒡gw?=l\"O7sﮦ) LHIJA!.1> ݐtM^o!)\Ur$qbrKW+Pr$qbrKW+A+Q.=\oXu+Q.=\oXuQ+Q.=\oXu(KW+G$qb.=\oXuPr$qbrKW+A+Q.=\oXu(KW+G$qb.=\oXuPr$qbrKW+A+Q.=\oXu(KW+G$qb.=\oXuPr$qbrKW+A+Q.=\oXu(KW+G$qb.=\oXuPr$qbrKW+A+Q.=\oXu(KW+G$qb.=\oXuPr?*O$qbԶmEO!xy*5QA|Tf7٧_r5SqY\ѷ)q pdyjTy,Ka/uY T:2Iԛ,ˍ,3 q <¬M3yEҋw8rIiմ;4h;5&S0YHFAJφ]/PldqHQAVOT7k-7Y }ij䊣u(C˔A ٤E}DI<['H1`rLC=vѺv҃h)2N6TRPFzʒ_e 0a*FyG<[!륢G|9KOPuOA,DAsbN2;Jvi!u_$S$RmLD1!饔j4qV i0ݣlơm`t79ʊ4Ecϼv:N.:B s5&zjFR9:S`y&K$p  \9-HJN mY +.nfvZqՄ(do䝾Edڼ]"a?)2Yv!y$P3yj6)WqF+ v5iŸik8הּ]"/JCLYPkT|l~-}i}h&ES7wƯiuډ+pjuIj>s?ӢL.ZxU(Sih[Re2 SIBN؁ϻwNXEFmL.)'rA#$3_bqmQ@QEQ@QEQ@QEQ@QEQ@QE .4uQGdץULe.e ᐝbJQ0.E֐(Q・6GWDchӍ\iahW$!N+e8*FwKj<`j թI_HOd\OCW)U8EL79hFUɬ垞j o=4 %9My+Pͨf7٧B\B%CqP44U:#?nP6h)4ZRBANR?wPcgMW)T7Dy,7&e HNE $V&x'<͝ya\-\FB)8rs*3,pmk:k[EHcFUD3kQDݓAhY!Fkc5h4*&6;-N;暷h܋Tk9[kelC#Y1BcD8KBuJV-A4nDl){ʭKG;t˩c1)Y;%wOqƤ$%1u[8*֊ ,C tajSz-зXbZ]#R#m,`3^>5C#Gz~N2q݌5ѭtѷH}PI.6qcw9<F9g?~NvrQmI84DxH&qVPFAǶPQBلՂJ OB,2ݲ"rKW 5m ݸ''hsvR4}W ;iB<#]*։:n;p9shD5756gt0b9~9M1!yYNK ޣ}2F+CE&lTݏW!}]^>*jzZ5zȫ*lQ[e,Np$ʙ-%a:0 Vt݀.;';l((ghۏ!\L Iϻo]+ȪNEu_ P!Q['Tgnh{uhDuhVm'Wy_N:A^J<ڊ(7oc}*Pl44U:+;D^S99+*ˁ[twɠK/@m@$`U̷!k*JA c㩘 lҵ(Wc[џteoPTj 飻yzIr)N '[[>#9Z:R`DkgN3*Qt1m0ʔq'9Zc)u}MD2\)  d$WXdx?i' "F*Rq;yjOq"6|43ِJaFwUWٵՍse!.OBpHԺ1ḅ;85?SQQ- `2<4F=(m$FT33Y4 V=Dǵ47сx/ RqL8($JnLT7g| iލ 2[fV-( o44FYa矸)IZ]p!%9 TO8{I%6m۷%':RfSER, hayVʊ8T;|/_E;j%>d6ی-RNOHh̛Ȼl9IRy+3?Hu:+_ PR-w7#zE-SWKo73EO E讷"L2!ZSahS`GA4GR"Sъ[Sčd樂Ӧn|4!Iʔ ܟ٭JbFȊ[Җqn%^ϢtսخKqS٪;Zy3TUDovMńĵ.+a$@g5CcB4ɷ-ңX2T d݌VN_%]A@㪹bg|ViM-[_Rwnǎ`~ɢ"̡!akKi9=97vo2: Ri$+ͮ &S2%긍P<Ucidn- 7-naI:W $Um8NR[-p'JWk7sq1qfO!eĐ3I~ͥK,8ZQ'ǜ'QuU[f-1m]u(j)  dx\V3D4:`*LSA<TR+Ặt٘ETQEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEP܏W|`yQTo44U:پiiuIwKhڮJA«Y# 5/JْlreEJVVK $k$x)Kl`5[*A9F*,-iwHo8t d ^p%m)QG(gqVWM j1=Zd))iV(dzY?ҿL~ R%KyÎ!L$R =/Kh>biR$SExsvqI(iW?+ү,~SPl.+c4Cc]kY;uߌzwٴͲECilY;?X 7J>1ASDEPVӠlJ{ӝBޚ;r%R-!5;ʂq?ñO?~SHӛ[n3o2Pv!*ٍm]98 W8:hg£?ʎKe+VuVR S7 ,!+eiGPsT!Z0knf'\I:Im# ?M ̗",g+5lbj8NԦZ Iw]XkkguSkYrk 9=B[j%Xh(('21cr\^8vH 8PZr{# 'j=Pk{S:dD# ]:cMV$\-S"C(J5(Vݜ / G'b=]1pob#K똭VZi:X ÞeղvV/ Mm+:q&Ow#cfK-( l+#4U40Ħr%٪Jv.%)QP9:9/3|)> OTp1/H[m6< QH8Rt~*6#H\B[ $)'7h-6S<%>we/SU ӻkoJeZr0$-J€8Q#yqR{ke-ND-(DB] pc#6k +9=z}^ua It<SQ3̈BHR+q;g#wRG\=H B}qmHx$a%)Jo)4!s"4]JI;#9R3U8]j?FG$%[:K7AQLFk o=%.V$!K$j3 p|TŦ`QXlaV4`;H ܑ0ȞBa~5o9xB-)NJofy2j\ր ƷdKst0SBTX#{ʱ}2cqƄe j%AA}qa ˍM6V[N_m&^\Y~an,mZJJ)7-z=}fN0nE-L6$%*) -qmJҚynCJA=E2Ɩi We_(c- ŽpU8%̷v;E/`d7gxQzzVCi|^S%!e8ʁV1t8.6ȵQHa FBV{+ǎTڅ%GM2+6L4Hq}ԉ,0e* 8)!Ds@_QB0tMv/j2YG)9]׋Rt-EZ'q2Іe2Z=ïGK'Q) 9<Թ:#!l)#;7O QVHѤZu.6R)8VOmh˨S-J"! KVwq56-GLٮNfjJ{%ƒjN9 #Gcn~zvr[6a8R7'꺢N)P&Ǒ=N5KpR25E XE }s$dVfԩz‡%H;=Q8{*".F+/!ㅤ%jTwnkUEA{Cn !/0YJʵ@pFz/5qA*>Y_&eS_Aq͘oNu[QAg@ԅ9u im%ro>Zh5*4-9 B]QK4|kekuPJ 謧P]y[QJCa g NzkIEQ$]Lnݠ,%tQN[Pn7E91PK)HR[[%HI #8P{<5kEAiXSe%' p37TiJ\k"ezJ0vgYѫLyRqZ 4I^2P=%{gX-˕2RB8P椳4va[uJRӓA]@-uWz1[[8I7BfйmJ1NA!)ګPRQUA;kezJذ%/$i25@f3/0eh }pkkgخezJі+P3iK}eOR%KZ8A%#q@DliR_VQHpOqs+FZ},#WnC!iZ$DxَJݐԣ'uC?~Iه !G%=i˘Y*8/%l3G-SueNJuhV;AnRiݨZ6{,ў5^&TJR\y`)D)# JZa\&

cZ* yOFO=*~{F) z*~{F) z*~{F) z*~{F) z*~{F) z*~{F) z*>ePyÄ6ܔ)J= nG+NSr>A^J<ڊ(7oc}*Pl44U:r 1Pۣru y V28 wboJ3S&QPk%%Jy)|>,hEwaŸ}> *]cG"0OƊW)ȮL1S? }r+ ~ 2i KBR qa\rrurÆ;ӦܒMnm7bSqYu (5w¢Z͝'GCh VÑ]cG"}1WjFIwgZEi+!Jޑh^=ͥyjcx^o+ ~Wo)սE]ȮL1S]cPXU܊>9? }4Uw"0OEwaŸ}4 c6?96o]RBɈG=>wtE8.5 [DzKK(khCa0SǍCrz]M|R%Nl1;^7e$?MƵ\bFn;fIHyQ(\A*1ݲKag_jM-frb7K Gܰ3+) gn2C[~ @<<+LwtE8.4EwaŸ}EГn6Te+\i.8eDdtT?x kd/*JBP''9? }HU{^LsnJumn8qk6j&;Zn; n25Opǣu^+ ~늁uZT]㐡xy3d2."-m̘*TĖWWW9q)}ID%Ƌㅔljxpk#Q# mrRpNr+}fs'tn2!_\M5gJu125m螼TRVc8;N+ }mG[N](ZJT91xV=[?dZN9q ZMPjuXqiZ!IP=Q?]"ݮQ 4zmQ lKtq@Ry*kylcЅT#YGy)3|qelҠA3jǩ-b?0% B2A9#7SF<Ol!}bTl(]`'Vwωj]Z̠|7#ͨf7٧LoOSHJQɸZ`r9i] %p6: %!ncX,P@.5=m/\Bèu 7, TRIEMJJDVδwQq'#yիZ&<y-l(N:G\_Un%DS A dU`Q;O MmN>W!'s9´SZum-E RHqT-U%aH*X;^Ɖ%4S!!*sgG> :E/bV5zyQKػիFޭ^jQKػիFޭ^jQK-8KjFޭ^jQKػիFޭ^jQKػիFޭ^jQKػիFޭ^jQKػիFޭ^jQKػիFޭ^jQKغKjPtEZl]EZ]%EZl]EZl]EZl]%yE,2 Fޭ^jQKػիFޭ^jQKػիFޭ^jQKػիFޭ^jQKػիFޭ^j ϊUPԲ\H/Msv4HVi qPh >Q4:3d=• mA[IV/?W{)7sigyb9nw/Z?vRoՋvRoՋ-_r,,^T7IV/?RQq4Z!SܷK;QtzE}bb9tzEK;P0/Kr|J9 7SK;QtzE}bb9tzEK;PBEj;  U[*9{2arǓ-1w]:dZ|7#ͨf7٧LoOSHJH,"{eG)\1N>÷, T]nα!z.8y+Go&FrdVv)aW@͢l9cc-wJZ5O~5,y KhReO.xhm)hH=UcM: q1VN5nޛZl;Ka3*0*E$TN7&LqD:A=ʁZNrM%#+Mno~r !@(dnI^Aj-ϵ%(.Qw7!jqf0r1ǟ4@ʕ&3&2URxoኽQ8Hhޙ[V6aP!ԂPO#ZH{Q_ԓmڒFFy=ra]Xy|xe" m%9Qڱ(耶"q*n֔@oNu9@MݦmOS[7QdxR ڄd8oTݻ}'5f )}'4m>(Dѷo&)}'4m>ronIMvOh۷}Fݾ/+ho(Vàa=E7o&}'4R)m> K<ƁQIyQ5ݻ}'4QM>nIMEy 'nIMqo6PA[$e6H9+nIMS{vOh۷}@ݾ6D9E7o&}'4QM>nIMRWUzI.դ#*I>sEJKFC;d @pF Dsm#=1jλ%ص1F\y< qAʾNv TDC~n$]a|u>N}.pdSM(%ݑpA^J<ڊ(7oc}*Pl44U:dT҉_vwron~(۵ߊ(w⍻]ron~(۵ߊ(w⍻]ron~(۵ߊ_>=*YKiRTORyҀX'W֖/+eKiԼ< mj~7VΆ^)Ssdc#flV^NY*hKnRNĭj?߾,l е4*Nwj"Ɗon~(۵ߊ)]n~(۵ߊ6w)]n~(!GBhC\p6H+S{vFݮP9HwWkl2RhOJ6FݮP9E7kmEy 'n~+y qm?Rh.Ud\AZF\Toڲ?Gj|R?EV0Ė#bT= s9P lÄN5IߟZ]+-Hv#VjB4J5A^Pr2A27mPX!oh{jV,MY_YoG裵e}e~)` 쏾ڮJ{VW[(Y_YoG]h0=Wv@_ա5:$ʥFzE,Fy/!$]< #5-hi+;FSpI[|7#ͨf7٧LoOSHJHRS=+{jX=@);Vڷ'@ƽ\ޜeېR88sևjX=f&;fRmӺʈ13YvLr/T(7EOgHz<SJ~++JH#=!1!-&AiKIʷ SkmO^ko-ĩ$PT;MX؝%|\=:?ddo>=ek>ˈ}U% p,g[ GEiv JoO}b| W)Ae`-$㦗oOtRvѵoOTRvѵoOTRvѵoOTRvѵoOTRvѵoO_W'E%n7<= m=xz([jX=vqZ~)q?y+ިD[U}b|m[U%^CFվ>zJoQ]xz7IQJq{}b| oO}b| oO}b| oO}b| oO}b||=Q?]H'.I#$ylǟe8R N d=*[W7tGlod%ߣĀWRW5]viN+ZyN(2)uOJ"T8VRڊN0rSkYJ IU{6a*XS-$8t$O6 Hy3.HD)C``7i u2Ccwƺxϊ[Y܉;x7zR!KP8Ro#煭.l|S'z Mu2ZS(6T\b 78@aղԄ씩E%9.6N7T~Ȍ#$B- ”W5+nGɥ<*;ji/b7(#vCE'qӿ}Lz!mؒ yTw;Ȫg~%N01_lF“󏺵4ݭ-?-1ݞ7U=V&&JK4L$J]a#;C #8 kzZn5Sޏ5GtF{Q]ym)٧5 Ruԝ{s+U=QyO|,Vd3j\`\Ϲ8ZzTvzUM|IsK*v%,:X!3*$8Dq/-dKΠVxa1VY1Y1ݤ`>'YDNŌ7&;ofHROH<*Y1Y1MI~3Rd"8wJ!*+GY;ŵZʀ|7#ͨf7٧LoOSHOl(JjU ٷ'F;>jU ٷ'F;>jU +! *=[vs:])r@ԧE~J{smk iR.+mi0P٘V@G=Nnu亦q, RHo>4^\$9igI(9 |fNѩ ( ۈ))H}IZIAduv1Ci@yi^S#vmUÑi"KSl I8We }|lQQIٷ'F;>jU ٷ'F;>jU j+OCmf<5)^CC$;>j6mRN;>jC4yC"4ky;C@, &C+eHx8d:1ԛ&1O(a>YTOA+契2 ʃ VgzI`nƬUWtѤm % A O:덢\EuJ\I($s ?>Rۍ VrFW۬ֆkL=oTVI;dtR!Kj nmնޢ<Ջoܧ=RDTˎ/UyV7n魲M\۩XB[m4 9[6oQIٷ'F;>jU ٣O}|Ԫ(oO}|Ԫ(oO}|Ԫ("ArHoW9ZBI_kE߻&oÑmtऑ̣@*/a4oitvHVĪ{G͑-,KT岶A, r*_a4oitvHAH΋mZgpU6$οqm[qK: Vᬬ V=/qM"Z],DۮsKGI i5q :sQ{Zu+ 5 nZHGa4oittMԨ1l9Jr5U|^Cn_`[51R{ _XKO룰E7XEE&}c-?i8b-ڿjefWi2b.u%6MKejOwV) %9My*j(پiiuA|T#8{a@W(-ui>_6-uibV]صզ]ZitP#bV6-ui@]ZhصզE6-uibV] a){)lZFŮ4(kMFŮ4lZKѱkM.lZFŮ4([-+(C-JK_W#E6-uibV]صզ-BBM=HwWeQ݋]ZiI]obV5m x9E6-ui%^C@2m$p]Zk?RkMFŮ4lZK-]ZhصզE6-uibV5.@ Sa^DD1;QFt'dⱬ7 yJ_*I>sEJHWKGxGs8GjKO?KnA'e*<3Vq ? g*ANOEQbÆz8!]wWg.פnJ}kA[;@I7E=$e%:%2&q栄ݞ#w5;+zGe]V>6.hO&ܖ}KBUISѺ,HS[8CvX]Itv$rV{u"K[on) Nv ?wӯHqQ!%]JTO@#*N-'YBA,}%{c+GiyqV\*V5AR)Jq2i(8XB”F2{`""-T O[ZNAI[Z^6kkfsV) %9My*j(پiiuA|T#8{aC?Si>_{i`{4 }}ӔP7o6 NQ@h7M9E{i`{4 8Rs<*J_*==i/)K;i;9l߼ Bse4q/G۟,Ezj*݂dq*bPWYo}]H_飳֏? 5oZO$ ݨ / Z?\7RZSg5Z>/G۟%/]WRҩM{h:AbQɽ)}]H_飳֏? 5tRRo#4#VPrʚǛ4vzv!Z>/ 5K1伫b̄Drp m4ƑYS2;F6"u-4նsk7#) %XmEU71?N6oc}*RDg=I%p8=+6JHا~bFzW6)_i(ا~bFzW6)_i(ا~bFHiG*^=+{4lSҿHӔP7OJ#F=+9E{4lSҿHӔP7OJ#F=+9E{4lSҿHӔP4RKi9_Ɩ!GSҿHѱOJ#NQ@=+%ƒYʾ)OR)JYN޾SҿHG@=+4 SҿHB|;NW4CI-|=+)GU{4lSҿHӔP7OJ#F=+9E{4lSҿHӔP7OJ#F=+9EH# ?U'z=VRWUzI.?h4QZOI'E.:(٥HoX̜QUH;:+ifN-0)sۍu?-֢YziV‚(৉Gy;h4QT=&EJm[/Nm_5V nG+NSr>A^J<ڊ(?{71?N6oc}*VDg=G+weG=*m_8#P7#/9SP7#/9SP7#/9SP7#/9SP7#/9SP0xiG]gw9쿈C"%9@zTlNQ@zTlNQ@zTlNQ@zTlNQ@zTlNQ@Bi;EEy ?P'eG=*6_sҧ(oeG=*Kᥝ)秩q-w#æi]oeG=*6_sҧ(oeG=*NW4CYm'h#)GU{/9Q#9E{/9Q#9E{/9Q#9E{/9Q#9EH# 8/?T"'so VVJ)S|tTjoad͒ %ZnA_X裓_XrKֹ^ uPO~cSO~cS/Z?fltthWV??(WV??)1wu:|҈qL-KnJ:P9UX/^-Ν z[OOf;;%dzFA[ |7#ͨf7٧LoOSHJ~ [ǔS5uSjdT(٫_(٫_(٫_(٫_(٫_ҎGw Խ(W(٫_)(٫_)(٫_)(٫_)(٫_)([jW«6~Cp襯+ho;5uQWZe9E{5uR\mArz)C"4Kj *6jW쥧%v(٫_+mZUpSEy ڶiU âWZe)GU{5uQWZe9E{5uQWZe9E{5uQWZe9E{5uQWZe9EH;$g? W9ZBI_kU'z=@l\Y*aR|yWIPJ+ Uع+M9loRO&Z a,VUZ?W!qT@hsǧ|xNع+Wbu"^^j6.wTߋjWHMY$f֪) %9My*j(پiiuA|TVJUO?EI[%O%ԬG:%{Jm@o5S<>9+}j9hQηE3^@o5S<>9+}j9hQηE3^@o5S<>9+}%%Ӄ9hy+}rW hsFogG%{G:j9hy+}rW hsFogG%{G:j9hy+}rW h?G:j9hy+}rW h-A?n$8gG%{G:j9hy+}rW hsAm$pF>(y+}rW hp mQ[xA^{QηEu)Jm>P[p %{JmEu)Jm>Q[xA^{QηEu)Jm>Q[xA^{QηEu)Jm>Xcb\:Ekbi#F4. 4Jm> cH}/jӒG%{}/hF>蚴xA^F>;Gя"&9+}rW h*Gя"&cHNJm> cH}/jӒG%{}/hF>蚴xA^CvdzmTw􊹨>9+} % MUK9DWj<ڊ(7oc}*Pl44U:eD8oJp[Rgu& (mˈuFREՇ%Z&Ge::ЀN2H UvW'Sם!n!XP/J --PTN'ҭApw eXxF]qt=L{ad)Ϳdeʹ%HQw(ݪq]5z)Z=E5xYLQw]wӝ@媸1-DS8Tp ^tޯ:/mD[@c)[n4UIrG .Z=%K:rZ)VU;79֞Zċ6K l8RV2wx ƶqޅݥ_3lzl{v MC #ƚٿi|h;ֆsLҡR@ǎsYj5NDӹɇj],Ƿ]6KiJ)MjQw;0nrA V5s ;YtfM[[Tk} ΧNI6*DnvB[B kGL1vqƣb.%8En8 )2PB9-$xJͭ#n: mc\uMahtOʒuSn'Zߞ:Oj~CLerG< >P*=MlV T2c1BTs<lBM2{$a8yMJM6U5ISъ`ˡ(uAߊǦ;xm=rӎ[BHR@'~i߬ўS2.Yu' CP7 jZdG}ǐ#w碹@n 4ڣSHBJNzjlVZGYxEeĦB| PA#<*P(u 򗭗+_τ&椱 Zwe֘˅gÕ|a ʭk͹.((((((((( S܏W6*fʧT71?N"xq$$2)>mM 5ki6*4gZJ(3|L~!UY_E[Azc] v^QAza]ת'K@@At#nr-6_ASPZM,Jҿm\J\4#o((N} 'P@#j A#IZUyK^:*E}y}S~wZ_VߥO@ƴJ'Gizre>zW<(t u+Ps}v( nG+NSr>A^J<ڊ(6DECySI#U\!R;3RuWjÒXρ x dLC^(R%6hY8_J>}JvfK^ݳiKZ)(QP1ƣ'K*mK̔H4WwԫY㤰L%;t8Y ʂҰ ԑ68[ASlT2W17J>wԫ\7@T'ثFZAlj$5LZXFwJ}WwԫYEh ˯*l039di-<SR^iU)Cp;Ǟ٘}.{>}J՛sKmm8C:K:hCk*#XHo< A"Ɠ0]*Q٘}.{iOЉjR-QiK%!| j2xb$<BKNGPQIPόTvfK^fkj;gpU;pn {B]6*b~q_اcJ=WwԫXgzWRv9qW'[OWiE6%%dlV8CQ٘}.{AHʔ%{8Z[Q T5F, K3YZ{5a@AsJ=WwԫY'o0@9!m%@nkKr'2ǍܲA>}JvfK^(N[$4ZF@#mZaiKIpTJrTk`2 (i{3RuWJm2}J՘kHXoaSgIO)%8 L4++JW% Ns*U5DSH[e)ZsӬ%q :YYZ\ :~JWwԫX3%Lv{qf d'E;T:Sm-غymtǎ1ws QRvfK^;3RugҋTwmO8Rhm\ K͓ *u)vF_`uyFWWwԫYu0J8DJOqXt b~@FjK4R6 RNz@ gfaU0]*V}'G}^/kJTZ:p ?iƱ1BNA 2nԴYTOjT.-.4rځB1W{LK}6k(0T3}&$^TvǘumBil2w|c}v&[ 4C__fRPI *;wx ++;M#%[}o!jBuG?E*奩UJe),.!Iwdj(c*>ȄJHY^̒A>jrtf;NQ-6Q1''" @Ve"{z)/4P TFLu#T­ wԫGfaUOmmBPJqNr5gqT4ic )&Iz9AqZlY٘}.{>}J՝oJN#YN< 4S@H9қbi.2BZt~wԫ\J*|K5ȑZ2u^ZܣWYlx~7tUqو}.{>}JpU-R B/7(cZ7ku̸ MjIhagWAk٘}.{i!M6\ "?*PEF:R\d(e*`$ES"8 rʂdTRg KcH1dJh +#8}hOnO!Jbs%|uT8Z"ijUˍH`$U?T}aQ*|>М2nNu6ܗ+ϐWB:ـڝqo$( }XʟO>;eO'u#+&뉖Q,<[[:{_*|>HRҳoARsvv~F"p"E>X}wRѫkLb8d(w+ VFKkB4չ6]B)NJµq~S GlbDFfB֨O ϋ#?>X}؛;b0NSjB0ݖRtnƮ1ڴ&BT ǔ9םϲeO'uo?Ķi1ˎ3ɜ9|-:r-Fu:ӜlT}aSW#B 6!n@’:;8Ft=Xr"DVLdw9ܡ¬eO'uZ-"3"1ڸ^H)ŌT\SAY'I8٤vʟO>JPz O6'̄d͇ 8"lUA^m֗ A-SX.d] sfx}aQ*|>QhiWgTij.44KkHNgJDv+rA}h x _mO>X}vʟO>귛=$&l\-%vd~AIF+bw#)b>U =9'vʟO>;eO'u CHfBoim:‰JAsӏ\8*-JC핡cA*|>>X}Ԝ0Q$ pe.3ݜD)ᾟFLqld/2aL!:bʟO>;eO'uQ4qqXٔrK@cW*QϏ{*f %]uH)ƱJ]eO'uٱ6[ HvS+KaV)9*5_*|>(&N-$hxmmuN6)JBGFsPYHRAKrd>XZʁ<|7UlT}aPj!%QlQCTc('p39QMGu ·.S Gl`V-ReiVBHF -97D˙)Nad8M’D8ԔZIX}u~wT}aQ*|>'j I+aIHa(%¾[Y꺰tX Gag(<Ú^ nmIPJ}{+cJ*i!p)ROTـ c3Euimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image006.jpg0000644000175000017500000011057211665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3"U !1RST"AQ24aq#5U3B$Vbcs%Cr&dtu)!1AQaq"( ?$d$:ֻiPa;P%28Ֆ ?;'/ a/O)Qɛ}.!" e)&n>6 RDx4RsLi)RSsl_oWgG5%g3OaEd"W 8QDĖ!ƦJ.q*!H`,[2n9L}_\S8Zxvz~NWOPi3. c%GCk)b؃җMw?MQ "ó#pH"io~Ŕ2T򝱲_. miK=%M:ؘӈΰ9Mͦ98Yvz~NW00:(l#>>;M,oXeJ%Ĥ KGSgG]oŘە%O>Ffв ʞH6ick׼V3U)ZF2ef2ʂg"y)*M) &tƿZ;K}#h#(7Ԃl>5\)r\tJu9aOƺN,dDfʊm-,/C1  ޏM4od:5:KKKj)ТT-VI,RP^m2]o;u^9w rFPSzVRH?xٜ̰F9RBIXjI@+)7. t8ӭ()-&akޥ \~Pm%koNdEu33qXX(Y)%2 @M_By+lĨ*a;̲|,0*iH(I#.'OUד0O931PNnD9sEaN m9Վ31S0OYlhҷ31S0OKm+{0O931UJ?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?NL n>J?Q qQAFɰ XեI [L'o_#l 6L=<\ܑz0O,Q1~> P\6wR~<\x#󒀷dsaIGh`J]ڕ ˇb8@31Gm)!C)[R[Qb (yl:tM$\맶c$ =PqOԐ?MZig6%1R_AVcm!#JvD,#_HA i<-+C;dm] Mjb;:X\J+Ȍ2ُ 9qͥic9"Vp*jXzRVI+ j}o.6"F *$֕%jK.D.7W?ږׇ\)u>t)Z 4筽O5S>Yh WN#bbe$>sjo}Ibk&dZ޼Oӧ>bBag|n2t[W9LmpeƚqYem,}4%y"\-PC]i 6JCktYfa p Sul u}.m܊Fte_8?]PHHXix }weK`&]n٪2ZbȓmYT5s^cIf3D#bЉn5uFPJr `wo'W{2?&r+̥(ҽ=P#*JRƫ|w]ޝVRJZ.Ϩi+¢!fBb)UJ)P) {JTWα~> U hrwR~S6_P] mGR[VQQQw $} r|JLyl:lC)]!Yl]BJIܥT%N#n'Z/ PPj2M s-6iXsqyxF*njܵ 0sNokgWaqUmpb:oJ[6]='JῴVpF6IV')2VUԄp9<4{ߴ %!b0 2CYM,jUwh8Df[2MWBy.6RB8UPgm,rbaS.TI.@"\ghOHaXS#K,6J$"9YwR_.0cr3蚲 R!"Q'. B3 R''LTu8R_dX#RujTFxUJvTG&FSqM#6VSc], jc߈Iq^e!(p WTJ\ntPdR:6.+Ćaedr.+>7,\uO:!n$G.|\ROӫ޼JJ}&^5R…8i^ K [(\.+W! gї}!FVrcʠ}Y}Tv.'2>ޓ9,4.,u)Iծ3qe)JRRRRRRRR-)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JbMs)}5ϻ.;)?h]ZlEuj\F%nJJV-7MmbI}-%-bGd'Pu%zsK2d[2h >BlsA݊b9T7ZIh 4o$nOJŸ)H+jZnoG{}_UOf{j6-<Ԩ^!G JT:Cѝn+JM,//d_[lBeÝ>,IzBd Ek]$s}]yߑ9UJE;bbnIzl=+pTٳX V {T>eGeRIou[>Ds^皦|{e-pWbLHPXm7]j78|tAgό!ؐ6V R HEs^皝 ߻Ra1۟=H)LZ-nLkQE ͜82SyNkE'9$5?W#pyW5?'TWfO}rd pAauf6j;>;b r,~sj~?9~jo̥o4.|5S'TMl4lXLǝ9>9ZuV:(kj9~j5~4W1bFM7I 2xuـg09t#[ٶlT,)3yǫzߗ1\3;vT&R\lhT^9ZikПD.VkBrapӊ_"B+m"l-56*Ue?L~jkߒ'bմu\/b׿%^񨮵+_5~4ZU+g7(Ef2̃FA) CwP̨_#+BllBu}W/?1~5'~bh:tg'~bkߓWext\ߓ_ex׼_WF3~bkA;7ƃJٿ^5!ὛAJL;ZkE?ƃzgx׼xnҴ"Qjy&QjܥiT.^\.+S!?|kLQ-+Wbu_|kNQ٥kr|^{F꿨lR_Qc4RX|M{3 iQpt>&M ~5徏ƃ:V{>5> XO=Ҽh(>u}5ϻ!>RlEuk“ը*`ZZ!}հ Po0H6H7o6F 9NHYi-,ʔFmA z T8lC-̡r *"Ͳ`TXbqDi0SYwi!^YR *s6>_jbg @vZҧKf8tneZJlTn|]尜I(BDvjuA6nDު'f6} !XjYmʕ3m_Mn̕dK` ɶSoh-TWgiq:D0Gmm2HVWe9ϕ:oUKm&&۲X#n[BTTiM:Mn@&ɲi5*C%%*9m繶txaX6YeylFT*\ hlNq,m>+9b6b!謹m-V]Kj$,,xU{_a92ga޲C`$,N(lI 2V7q * @e`%>m tc`\)̉ď%^in\P:[W¥Cygess{swݝo^[mWh9E/k徹j2\B*̨͌[;O6X\lJ2dgV:hGVIM TFbdͯ"JTBBT}-6|B#10}d4HԔ)i̢UbBKYm\Vۉ Ja=p1e { }s6qeÅ=KrdK3bj-!^q);I"& e7f+W s\=}D`Sx&h攖:[U]mKt6J \SRvD'pLAMTk4I]rIÚNa 8W>Y;|g~Tr3%;+yx[f[sUy }o]sa6_h X;RZ( /{z\>*"ŒX#L V H|;"Y*[SƒݚΔuZয়R9;Q"2c6؎ @J\XM+RG5wy j¡+ԌXth3|V JHe)HRm \XX)VO;?XlR#*e#NR#Ko. Z 6̓`ڽ絲𷧉00౸}W@)@)@)@)@)@)@)@)@)@)@)A-)J)J)J)J)J)J)JbMs)}5ϻ.;)?h]ZlEujcAEx~Y} JZJ\J FK]:m$ 1ϡm? Ƕ &)7 ǶS6la8,g @.5_sr])/r}u*6A8YJT R R R-Elħ ԢM씁@;CۛF 3 \ <^߿ Rnn2}JAm;7 *&;"#N#̠,A&]~˵B=sY2- 9€$(׸)XL)(wݶ#Py<ު͌B4s Sz-Nqٳ)Gå/,dn> ݬhr@<Ǖ(H8$gZTd{^i'~PSo-{ѽ`\sB^h"ؐ Ђ+8XDVMrha${ rlvgbtoYy .|,y^UWOLbYA_^׸Zn/&`2&MqoT!; ꬣ^{=o/t⸌o&H޲2$)!Ai6 Ui;w#%@^1lhN\Z ר0JJL^2|e1V$對HFT% h_P++ hXJrS INGY@&8OQ:R3Ug1Go9CkkT u $(ٲM}e~іpF')҈%VJt KԸnxPv3t6eiXuЅ"ڮ4 SqPabS8Zxx9oJrd́8y&<蔪;u %%.Af\X|)Yߤ)*m/*xDĔ()J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JbMs)}5ϻ? O?WV[;)?h]Z 7.+bF%SlqCK P` Ghb369r0A> D( k}Vݛv#2ӇaKkTd$+5sqAϙbgL{eL(Iމڵ6"JSZ*S1J(s( D3bI)m:]pYj޻s}UF܆F#e,ӞA^ThWspo#¢o V5jVk%,IlW}ؘ#8rƪӨV<)w2\F8vZhXR1&),T/; X"6B#`[@3b^+j}qK $wl3u6_H*)#Q<#T/S7c J噹8ix+ ̓Yăg6?yèKNuzDʮk0ҝwhJZ@ mc3CZԋE$j=\iCۘ5+a"9' ]ODx:e!<S$oks{&\7^>4\;^>47|^>~JupmK[I#M˕0O{ʘo'ơv&ì48\67!%VSr^#w)rۣw)7zrfcw)W mhBJ9P iF{trO{P;l~>5&1WG@=?zrO9:b'°r.Hr50b3-, >[Z li'lwIq[ p#1݊ ڙywbaV{@v{N6'jgbvV{N 'eg6/ig` 8 JII6>bYq{3?P8Ƚ) ~1N/fk p;_P8ݡ+*?^ {GbK{S78f:q,u!^ u!^pu-^u-@7B;=J?ឩP7uB5֣ pT+]R?o7rV)oOo}{GM>tA>v} :i::CM: S":#@Ξ׹"z#^OD{R){,=q^זα~> U hrwR~*[.hc[_IXIQSvuV؞Wf8ΙNJn4LŸK/Np܉(mE7"Q\~e.5#䜹,H8B?e.*/EW)6,Z5Lqnh,VRy_I%mLCJe0+`pA+ >Z-ğ #oBR(>AEDQ5үҝ?Ѹ@3Y[xPL;te΢CͽoojoTӈ+w"\v}M|׫=)..Ў%bxtDR,%a')l(}U8%8,Lަm] P@VUA=؛()f+84>줨wFzj?7C{z$zi**"&u1o rg-S=ͯ_@ΐ )d☻Rn"ڏ9ZG/Rt3ٌJwbq*2fL8MDeޕKRB _0 lT rn@g:+PH7:R &bKy%;~:.H:J1vSKV6mhe Xq5MΦ/6GHoLHmsJqqаTs{CdM;#}m[q咣n7m@͔} ~:S~;QKx^'07o?mbfb?Ĥo^)jnrܣNJzNqaeNl:~D蛋[JLD)ؒJ5;7m`7#6Pt6KՆ&.(hv'U{)*q).3S= +cxť=C{Dٗ" AeU*`QQ|Wߙ_[L̿za5%qv tTJ3j9: ^3s̀{aiR B@E˦ jy+V013qowny_K_WiuNX Rԁ{~yأpqXN= LAZ[+pV\K[Pba8-!PjJdESVԢ2Up7^A".?75.]JSeH-]7%,5W~@RRRRRRRRRRRRR!>R\AJ᳿“ծV O?WV~=??QFuq]!۬a Tȕd7U&ā]C 2%û^t-Ыt(hH+“5NඔɒPlvpe9 Bf&/~䲕9ΌJ.nTNVlx\99][BqvиUEn :Wm{/%jSZ nX)Q͕$ɿ=JciŻ-r(MAom$2CIe!䅰*[aW-JH,t O_Ű271P*R7l.$(b&Y Je >m3^Kj,/.cϚ׾ VemmTTtji9^,;hr|LHJ0i$ RF)~ջc 0.Ɠ+tpJl6JH8NAsm9DVc3!ЧWuf6֩E::d4V"SwY\󓗟^z1iE\ۏ5IJ0J.(+*^tOHS[I{R0RZ* Loro7m/]=2y. S]gx{(gE_je`1y>k;ÛJ;?+|^dq8o0hY@2QUIcv@.K2'}%ײ'Am=5N-)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JbMs)}5ϻ.;)?h]ZlEuj =(f^A&(c*s@N3D}";M92ʕ2SpHfNSg^Σ%Є,,$ANFaH،o6iXPEd>ڷ-*7NSsq+J}[նrk$3eڸ0a,-컡וSNlۻ"jiWo6T I TӉq7)MqU s'E&l\S&;n)m avcq9 6J@GXU(ҙu@Z{TRFX5!!)*<\ΤF!9.nSeL@ޗ*$2%I#ײm2V0#M0Q{ɘ?&X,/;O - Iƒ%3%KK`؛D%#Ojlə>Yj8aS-ә*RI͜3{-2s[An:;hH hsU:}G$1u(DP[]~yQ&U*j;ځl2'Brr R5+;`^T Z.0ʊXr$9gCR ˉt&ѠdqߐmWu-,7Y9oE",[yq.&7I6# ~' i.{tfU̒=' C'9)/r~𕨣v\X5GV~$&bYH!EZp.E#Hcqff)莆JU-[/z2cl%%- lXvՔ֗:4e]ay^j Q!kpc2 CfSmAͧ"jZP*vtl ښ՞x23o2TAVmI sZeإ)Q_-)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JbMs)}5ϻ.;)?h]ZlEuj|_KkN@qA7&P:\>-Vq2ښ0n]؈|enF/fl-ڇ$FKؙ(9JM(>J1XxZT64X)`}^d+yN6E %+˕J7JI:44N 6Tm!ŀ, H'Q8I\Im*fH*[Wڬ9~dd곸3] }% rRڌ!CoHPΜQHY?jIEᒌiOa 8m*$($%7I PtX^6lB[m%(HHUsl%m$0c9+ s.U(X 245- œKۂnn:hG>KBmM(\}DWJP`d0NnBr+1]-\ \a7փ_@z:$bkŴ: …saq>Rڷ$cMi LV%7HBPAl,ECrUea<gQu\~$a(/D\N~jGܨeEM \hu}=Ĕ(((((((?-)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JbMs)}5ϻ.;)?h]ZlEuj 6=ip*6Wp CmWJm{w[1/ 9?}/.U_7Ks锠ԗ ^\t)6u@`cnm1Hq+ZJH߅s]GՒOX`1nL7IJhG,e}A5Տ1e#[6ym?ZbD9I,,:Uc[;$[KnFRd]SX` T `y3N4GL|s殒m--Օa&& ?}gPVadxX[DY _q\%o%G?>=bs]R0NUGcG8D?m){ɗC~ <& Fr9 Q#] ^6WGv/e5p97THIBD!C2U{iq}j#+6Y%ŨvX+JK[޳{՝y:kIZM *3s"lɎI( v" -*JJNRM>ʇ} eR-rNC,R9'@+bM@\YLJiRoei66?UOa=)J)J+\*CҔ($fA',&CW\t|Ճyңe-m=҃fY]s=WeuGA5*{Y]s=PMJ,W\t|R+g>je35Ԩr yN*9q)H obFo]lҡ+g>je35ԨreuGA-*{Y]s=PMJ,W\t|R+g>je35ԨreuGA5*{Y]s=PMJ,W\t|R+g>je35ԨreuGA5*{Y]s=PMJ,W\t|R+g>je35ԨreuGA5*{Y]s=PMJ,W\t|Rv3N*FX(>u}5ϻ!>RlEuk“ը+n38Ri+{0"Cz&̎!m!AN7Zc.$\ E*BЈϻ8-uM)_QBp\[[*}ƱLN{~)Twa)*z34 BԳ{kMʔҚ16N6id:6 nD4P]cP:Sᙒʐ7`"}yJRmFF<9Mʑ%+C)*R}tR4cqSa3mJǣ !H,rXfzRO ɝ=fؗ"2 aeҍP@ Վ806Dĕ%^*BT҂b@v]R8yE^;C8yU S.G&;4H* v E׫bAi%c*`]*!H7l}>~jҤ(K0dwxgj#.y8+)ǥH:i-Dnm3`͊V(^H:[6Lݐc(w1FdkSq9$) KXUb8pX*See)A!$QbU$])|l8ʗcx:Qk^ӥ)je350f-8c9K":)-.gA %\j=Դ.o'rTobez)L{Y]s=SeQr4L*"u!juQ[KAHT6Gm,b1b ~+r#96JcIQ7+*)(PϨ,W\t|ԎUUݡv y#3%T`H(W6>k 'mĭԑ.+!%IHPeSc}Wܲ{Y]s=TFA54bby+C-:JT36fu:V9sHޖV"Kr7nnք GQ= aʗemچRRS56Y]s=U!D)Gd2ꓘ;eHz$sv1v:$@ZCzڲJF5M weuGIȢ8q Rme!m$\]&}['&80-8Be!*N bҬYeuGL{9;|`pDD[8B{!7q9oRBbljx{C*2vܐ> A m#@.@ VDq,<+ `2Y%7T`@.n56b:CM$ԣJI:u$euGI>T>f-)ȫ' rK*qNBZ-Һm=r"8x7eIM↉[׭ZeuGS|}.&b%SLW($4 +6̳tY7TBKD86nR `~W\t|+g>jֲnR%bˆ2e B9({t0lKfD򛘄21(, `V/oQ֭YeuGL{qvRjT9euGL{権P352jT9euGL{栚Y]s=S,&CW\t|+g>j P352jW c>> ӭ(m%HP6 >`_[A`WX`faPX)Uفo>X`f_AcJe {HMα~> U hrwR~-)J)J)J Ӈ<z%M~V: Ro%jHJ'+ {oU]yLLm*QSL eį>P7"dNZ뭁|;/oSQ| CTt(He;eA$YuG)~Ng8x:y4ޞ۾w_5ڗVcKQ'B*vwrF%hu}5ϻ!>RlEt]i/$%D v O?WVZ/)_W?X;Tri(IHWDBq'~;njBT`Nj Kp-tRBk0IK>$ʠMҫ(i_`!/[)bcH|kxI~Uֿh p)*2] hn2#1HߴL:fY:x]EBn8(lMŞI~Ny? r#Y8l\i Pq#C~bA뻴E; UZ#PHʤU_Үwf?QDOp-tZ/*i.6H8`xȋE6jl1df@ QU>m~zG#s),t- &}O{w~I~NI/ zL 6jVJQ,y6+”=eݔ-+RJ[ET@{3W׿ ]%R0F60.+[ⲥ)-)~jJEW=51,"tDRJz*B*IVq?L ]%UQemTh0åaIVBO/VԥF, -Єl2 %fĮ<_Skx,)FfRHJ AO[??1Rj]ql&~ 0#11WG[7->Z}3skxI~Uh0#7KZphNА\۩.`XC4nYI9YUkxI~\h8DÏ:ZFnKja!Kukt7*$X[m#!Cf˵ڟJ׶p- ]%8Kbl b/#_m VRz8./'9s=_ic=B&VJ]IP6Bl}FV ]%WQA eRC,)Uכ/`..jH[yNSKzonw*,hmja.*pp-tZ/+f_SkxPkp-tZ/+f ]%8K٥I~NiA_SkxPkp-tZ/+f ]%8K٥I~NiA_SkxPkp-tZ/+f ]%8K٥I~NiA_SkxPkp-tZ/+f ]%8K٥I~NiA_SkxPkp-tZ/+f ]%8K٥ mjzRX\AJbMs* O?WV[;)?h]ZGbS*bK-ҭ$)'[RW< ٰ9lޭ7hV[4ZX J!16 KbpJTLrqXq)nN^TT~#ia: (`R[]/X|ٯ忞皽 =58',lXT,mMX`jap+6sz,) AI?}]yߑ9S~ÞٶlT,)3yǫz'c`N,po2[.bbȝ]yߑ[;Q+*R^'/Ij[$כwpMHP[*"BbsŒr-JH+l/gsj^/<ԨVOehJV}&7Q6HE3=܍̉0y'y6\׷[?&0~ﳕ$/(4EZqyѺ}mz9aOaȲcHmeQ=KMu3?_{k쟘o%FZ_ɼ#~bkߓOd]:W&bIaew2 kUl»/+ƃJ/+ƽ /bh:4w ᝛^ٿ^4 WXކvL{oDV$uxofxoҹpք-N ]?ugȸgxoRy֯Ŭ3 ym.&7Kb9DAХirD^LAJ]Gƽ]O V&C׼AJ؝Wu_|h6iZܟ^4~7WFh'A&|MԨxV:^>&ZT\;]xv?A%*=}{oΕύ{O*V9re,+)JbMs)}5ϻ.;)?h]ZlEuj )`򶹉pO~erM R_$UbN'ʼnmRaM9*9R -t83j뀝ŕ0&D,pPdUQmL>6,D^+DoDBuܸnqu8k$-ZR@RW\sXWNҸ@1LVYhT4&Bm.HN ,:[X7-±bl@\ڤ:hʊ[SRXE8ҝQݨk'u)Lt78 q攆ԴT ZeQK=Kq> Jz+HZ[؁ru6BxqJOr}UT;#yQ⭺Mrk;NdFRL%;0j#xHAtϵ2q$(/D&>s=G;#y+X1&^L(y7sM-(ep:}C.9o} 9Y*i) /*=kޮ;#ys=G [s zt kK vTp3}bݍLr SfCjVf UͿs=G;#yj28%"+ȗiRNe%pgbuI6[G=h-%)`yҐs&X P77z<߹W=?h0\VadR$\iĵOKbfN%DHmYӡR9UYY{߹Mz<Ԓ#1#N}IfSӊ ٔ%:$]$ߚfHKlJm@ PR*PMM@s=G;#y݊CɝSƔ=̱]i$C̛EtVMI$ 7me-Qm$eϮ7}z<߹RxQU:+kHq0;wbo{oRFsy -e \)b%^Wz<߹V=+Șm2%\Cny7I_$>o5$Ϊ;cd&TmYh%{I9odFjo{1qJip< t6a=3y @Y"ɲ;t`Id3\*>C> X&:)7ӿs=G;#ySv(m' V-r[^DSYRJG.*Rf'%ih )KCmA7 [}~d{ޏ57vGRb;h&\SS%<ݡRjRiVl%SYŧA;5i[BTR2$ y5߹Mz̅a4if5P?#- ;) Y+Z yDjo{Bn!KK!B @u{랝Ԙؔ%EӞ6.{pd2˂:ԴRTdPP7 llԽJ(V"3 k|i n4Q[iHQ!KtсBJ3@ѻ~Q?R @є@ԢӡJRRتa^+?a8닅/wbG]rx8`ʘ"UpRk*JHnN]h),"N\٭HH 3%r {A)$*Ǿ5q}đ~$ڌ!D^6۲]kqX bmGd* Mk涄cnmt:qK|*"2򋐥 77=L@my!ĸ'[̝RlHЛӣg^em>kE=D瞸X.J;*1} CFB!$XG@MǮo oF쭬-- !$+0< ZWN&IQ) #( 3ۙjzW:ӽ$: L&L[-(#ݒ/jI)Am:x*G[ '2,: }%Ll-JhE%'JQ?MVooX{QQReTW*>&9Cl6LIy~H- Yd!>BnؑwoA'42pނֶx7{($[$É>T[ilTJRI%fQ'5ʌ55'nҴQ*3+Kk~jr=oAJFz?ߚG[PnҴQ*3.Tgʌ55+Kk~jr=oAJFz?ߚG[PnҴQ*3.Tgʌ55+Kk~jr=oAJFz?ߚG[PnҴQ*3.Tgʌ55+Kk~jr=oAJFz?ߚG[PnҴQ*3.Tgʌ55+Kk~jr=oAJFz?ߚG[PnҴQ*3.Tgʌ55+Kk~jr=oAJFz?ߚG[PO ,OST1L6RmpFX\AJbMs* O?WV[;)?h]ZCvCjc2kӶ)(Rv aǐJˎ]*D顩q,K SOgJ޺aY⦭KJeyX`2\ Bn 4Fw@)#ވ*)IYAUbnHBN)2R\G0UQQb:#5KiBT0 ԬzKIPͪ>mDU)^hIHIJz)%'Cupݡ1wCPqjSaiqzH*H 彮/]*%3P_ls9U R0$5iė0J4m 7 P{K= P{K= P{K= P{K= P{K= P{K= -*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{A5*2/ig"{@?'_AcJX\AJbMs* O?WV[;)?h]ZVF#)|H/D-bb$vCL-&i˨W Jo`uYx暥{|\":\@ R$gS-!׉/TWap-)*Pqą'1݂UaHaY\K ڇ&,Tʢe˥թg['G=8'G=SFcG**&P m( Ƚd.%E[Ht0j[LkrTsw)ePT ЦJ{I)Zib<.y=>.yO8z0J]o! إj(a‹A䃥kF>lN4;KT#a*( 9m9laE=>.y=>.y_`bRfMˌQpSDYB޻q6VhReL*9R -t3jH˿=>.ych=ҪDYxty4̘DGi-)!n5Y#){6RL/k Kw)7ZI b3\kZߒ~ sN sUEm$ ;KNm QmԥY[Ҷ"m$(YRF#̻w[!(JlrufX'G=8'G=T0KđÍȐY)Dv¥>kXnb"ܬV(wá!KFBVT%RʀHhogN sN sTob'#0G$!i"!f]\}m1d7";PYUMNLk8z sN sU?Ĥcr8|f_J\ƃͶ7J@F'7]wĜ݋*!XChNF&z])*˂{|\ӂ{|\pƖn<(6bk` ’n4ֶ?hhPipOvzpOvzݥhhPipOvzpOvzݥhhPipOvzpOvzݥhhPipOvzpOvzݥhhPipOvzpOvzݥhhPipOvzpOvzݥh硆A&G7瞷k?Wh4xuzM/AS^u]X>c܍ȄlAm:V5C ,OSVα~> U hrwR~ )%'FHFaeMɲ@5-)@)A2Zi BBE>՞Y]s=TԠ,W\t|5(!+g>je35MJr[$q<")”it>]JPCW\t|+g>j35x[?>j;+Qq4ڍUKW\t|5)b{Y]s=TԠ,W\t|5(!+g>je35MJreuGSR{Y]s=TԠ,W\t|5(!+g>je35MJreuGSR{Y]s=TԠ,W\t|5(!+g>je35MJreuGSRY]s=S,jPCW\t|+g>j3529euGL{橩AY]s=S,jPCW\t|+g>j3529euGL{橩AY]s=W ͏Apr=a}Y~* a| ³*bMs)}5ϻ.;)?h]Z~HK\:9->ѵwr#:6ENR\Lbڬ_>'7UޕHVIj >g\yiiԔ(XO,Ԓ=hMgb+dMn-Ju!Ee)&HҞJM1GFi+Z j2 #Wcl?Ӡ@5pfj&.ƔܕiRBnݴιZ1b0۹ Z\S:KZ Q+%naz8b3,;!ɁM)$]v* @+[Wf!U+ñbGfb [^inYt-6Ttt5[C-[)Jedq(ZPTJʗH/h/f!Uuy7#aXKZgd.7 ^TY-R+4$㌳(= ŽZ(gZs$`.$G ZZbln^zq[Wxq3cw*qє*;?Ð;אX(mJ :$}aXu17r=8CܫT#Ĥ~d-Q3mE:s脝EǨiZv3|BN6ۉ["TgBKnl]ON/_xCܫN3cw* wf JV"D:r2ĸH ݬ%9 EdYzW$0#-)ĩ%)͐(.II՘^CܫN3cw* Y1;A? $CR]@ݸ BSSk{Kko! cbn_>蕏Q Vf!UuyėEPF-)(ZRMR.R>{VB]͸wB3ikӜRq/f!Uuyꕆ34OPC/e1PimIZ>ƫ$X>Zhem4~!Ȼ-D'7T6^լȾ=b +08yurT Bu$S-bln^zCZNxv]}uSLwi#œq)gk@e)aITn`@pؗ-2|IYt8CܫX!+*pAQ==tDe"db Eӹ HNu69f*fbln^zq[WMXcϷ^Cpǔ}FeE- $. ,I6TR0!lB>qҵbҮ`R$fuyq Ag,'z/X.-"Vˈ$YwuM)@X !| ̓lcoqָvdܾlS:}D]{uybln^zt ~4ED]3}m-z%+-!+RAQk{H{L5cq_ޥ5˪|3':r o) uybln^z9 qa%9rx-z29$dcj'x(SAe(Pt$2@ JըFpq[Wf!U,~P[yiR]u)ۮpQGnWBoY70=]S両!9Ӕj[A#du _[Yz)JWό:ʼI\L5-:CDi. (}0 G*@}:ʼ17r=S&M#t%CvSe$y X( '{Xܠ,HiKt7%9} йq[W8 CYzIRWf5)m[RKe^e&da6HJ/rWәY+8\AJbMs*& $4%Oe Z[)S|O|ORL?iL?iJҒ,fk @! ]!!"(5 ěKr})I%.>QeJjASd$6Дr~6KQҔܩO5_lK96K{۟ZRs"uCƜO4i"+wz) H*"uCƔrN?xӕ"uCƔrN?xӕ"uCƔrN?xӕ"uCƔB*yEPNT֧Rʑ:!NT֧Rʑ:!NT֧Rʑ:!NT֧Rʑ:!NT֧Rʑ:!Zq CuպSs s`(6"J]MҭT=JTO4_w*x5R@ }kg"j(O5XtJn łc)A/*DS9R'Z߮"uCƜO4"uCƜO4"uCƜO4Ѿ$l%#ЫNT֧RrN?xӕ"uCƔrN?xj"(wz% I)R9I\ũ* ڃP)Auimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image002.jpg0000644000175000017500000007610511665471332026762 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"T !1T"AQ23RSars#5BcqC$4U6bԃ%Vetu-!A1Qa"2Bq( ?*^kx +(%QJ;B{~rqӹET-`uq#_uLU_qrU¿6TY\mӹESurԬy4JMw, έ4藢ՆrOo/Q:k&iܢ)ӹET<|?KHN 3YO[;^7Zw(JR+3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4iܢ)ӹEWxf3A֝/R;^wi4fM^Rb\ V&rc[cAceN2fVş9浔nAr)RGgH[{l#z{pf=?2N} Tfr1FcGJ*;[\% "nr@?/jV,t%5'iZ]j:wi1ɹ1mv>cRϦ(pFCȫiN4e1#!Kv!ؠ\DS^zM__q/ESe7c 4encN/8wWƛpEw7uY|iƛ4w)4enS+iN4e8"]M__q/69nӍ7uY|iWxwWƜiMpE8"ƛ4M__ls)4encN/8wWƛpEw7uY|iƛ4S+iN4e8"]M__q/69nӍ7uY|iWxwWƜiMpE8"ƛ4M__ls)4encN/8wWƛpEw7uY|iƛ4S+iN4e8"]M__q/69nӍ7uY|iWxwWƜiMpE8"ƛ4M__ls)4encN/8wWƛpEw7uY|iƛ4ثt}ksItw`>}HKFl?X $%NUoKiYt8X+@oҬ=Wj?Skf ލ~cxSѫ ݬICW<4ڿ=2c?&p>ć/Nz@ZՌJ%f&4`*nVoV]"}1cԒkx$Fp܇wvϚ(MH3lu{XDͽď`s|~iY:ޣ.绞h1g#v# 3 p3Y=MUFͧ9[S")Ie gWOu}#Pմl延6kfKsHFll9`dUMcRӯR{XzEβr|K'9y_RuGt6uq2CǽUH?P뺅6׉ Wzy1r֯  F2ۓ!殱$QpFo?*ܿME?_WN\#F#FZWc Qv}q<?Yeu*3`A79|~?Oqu][*.2(pw`r*{MK~+ 2BpkvCDKkyQI7],JYHH>M8fNXI^c2ɷn.![t4-;UF\Z %r\`kƗ/GQsvO,L.dz5J ˎiZgWX |WBz?i3fZ[<ڃsPdMm}&K{B-lJI^\0`~|FhIpt 1i^Bq%9ZRRRRRRRRRRR:R’Yu &'Fa|^<άEQuq]= K.LW-?EkXXgZh7\_EY8Ċ)%aOof M[58->Mf(ɴsuY~]Ns^MH:BXS1zCHg&5hf^MG'IROz>"=44x㑓rb _=swKo`+"DuE$.XdZzt Nm-xWyjM0ˏ!0NF*HIY"utpYNCAO u{nm¤aGH@-Aޯm-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#':t RR>m-xSwKo`%(#'80!VKx 2Ġ~*J~Զ#F#Fg'ԧTIHtʼH_*)Wg sf>jKf6"_01d.ʌcAUH7v&]-tM{KEw{;}My?ҭu9#SkYeչP˙]!lͫKk]ڻ@-$/gρeyƶN Ue&9Y1T+Gqn ck>1/N8̾b3c8%m7L]E7$o1UCi,qy5\Ӵt6]8`rk*ߣڔ1#-d2x|)<&Osw Ccy`Vqd\T2*9،Џn;tFgY24r09|za8(uYaEny1xV "G @Fwݱrη^0JU{ ym4{i˷n3fR{R(?=Y7l!b+X:?c7BFcs'[𯛻l.5)a3"Py 95 ֱOi9D$@sd $'?bzdET,\deWrp3?rkjoƨ\oC~Զ#F#Fg'ԧY"Ay?S~UT*D;Qyo>?-@G%#W.~0z a=|ΰc{vF4٤ #wP@C729vg1"@B?k.+Ǔ%SGqpn8*g0A G}t9D== $*'fG4aKgq}"0حk+8IO0|9#St6;MF(-k xׇ-H9'9'&=u)4+3ߒ7gyrq᫿/{}M4\gh'#6jBw sk6$ؑt\c՜V[3ٳ.C J EfP"r g; Msbm„Ao)lczO"Hd:HL8QD."]sstJ:3vywV0RB &#]8kKHll6; ^\h, bczJnwq;#%JȨ_$Mq=:;]AEŋ&yN|?μ6us𼽅潶3nQWBc~7UzODI/,@r9$`*$^fۼ'X7#ip 9=V4ZZ<$ą"RXfCQyNFӒ[UHH1#;9W[[d{9EgtkqY[[^EĊh||A912!8zb@lq}6ߛUStz~qoVۄFPϸ'r,_r>W}i#!{!a+ c+9Gi/ItFb.3J\!<6gA!s"xt`` (!9 Hk=:{Nn i%gp}lgN֭L Sq,{1;0{j=SGX$ЗXRQRrdח4 xK'1N~A 9gp# K}%Ɯ5eY,0wH `׺E umt㣿(T`vr쥶r58+F\jQQ ny9 {=7LpxcqS=\=%J;超;Fy`8q[z=-|+e&㰫Ghyc;M;Wm\cpeR19vL&"&ǎ_qswY%7  7+X˱r&ĴI͖moiXEt8m <5=Ljܴ quPһ ʊ2!~{~ǭ]O%2m۝F\|?\q0.gl]n;ltB=p`zED*%"[2&m#lew!XAV?swu\wObbBkˆ|r%y=Cfɺ.nٿOmZ&r[p:]5k]q,Cq ),,2I2\^Wxv\n0'3E" _ja#y.lt4x[lyY#<2r+*碲!CDWyA f#)d'3IZ1I yY ZJWo [n紝#:Ϧ:eƟiu("Y ǂ%3;aN tI.ct<7AnٿDÆ@UNNpyy#bjL4(x@cf z|;pBL{#$dTڞZmԓC$n.J F'wU$Hz8]Eg@c?V-7QPӯūL1S&Gҽ7qᑲ%BrqT@;O>FM.Iy66}]0k"렖\p2puM9n .9z#9]B8d-Z5qʼB0*dيrNi9fq4psOc͜^2NG4 2*J3f[GF վ/{U/P ;K>ꮙEW0kk-‬HaQ3ك'=L+;ŻIJc\S9 ppyҴTw1WnAR /H/rKb#er:̐v; s 1[~,,I4fov?ҙv!WN_DEoB̪ ccr4buqL8$1#ɂNF6yH͢nl&}*{3;}d)JP)JP)JP)JP)JP)JPs #gGQGV;#ܿj'?_PGW~Ev߳*Ko?XiKo?XiY}}J~/C>>?  ϡYUJRnm,wpж3fM-ݺt倘 >MX 4{2F+?fn@ҡ\@$˂ o䓓y϶[H]7V OW>]Ӯ8ibuFa5ԯ4Y'seA\>Lf:beVe>WېpHaTK?n!4{ q$/0K`t8[8d"(T0,W 5|ڏe3G"JІ<XeXc=.YGpW ^xn#.B4l |NG.bi].]?$b#f ځ32y7sDڢ=EssüхV RQIR'@#hR <\DW#x! ]cټ!ӄk13om,].UI''#*LY`ExYws LZ-rEݜVR3-P@!_$;jDﭖ cV[lͨ$\:YH+T?.#hBRV>Vv0A+֭^kZܴ3فUPB6}Rۢ| >{spaiN<5wPZimE< N6-RIrGh)g3L{A.]\M5Gw’.~DN63 3mTP-SGi{6h]X Fm%f7xJť /$HWia##Q7KtuHv3a8)pP|1s]On8ŗIWZ@s7K<"|vֱ5;dew*k"e`獺Kݬ*ˑ7NΕCjd4jfÀr봐srw jl-}[(`K>2#m8!.h^^#᫗[JvT`#s~~g^7T0V-c+*OwS_5I'2e.I?צޣ5&mc(",ȅQC+?grEvHCFҷ @ʰ;q^>o,5ˠ\ 8^@%naˑvisۘ䓅{ JpiHEu"vC 90q 9gWV/tN!Ks&W÷ `-wOni1%D;H $>?  ϡYUJRTJ?\>vv<-E8`c>ZyC?Zq|g;@KYơyiyo Ư i%y-?ei h1c 9cCX=#KXfqj֓FZ #phzkX~֧KZA EU<>$L4!YG-e+(b2IO$Ap<Ý|ƙYZKIi IƜ'4A#>NsjzvjfxXtn-ً\]Yʌ吰>U[܎s[G.-<+ᖓ*0U/L4(x@c,iq9ۂcع#"E.r$yMYTF.Fn%o,8oj\޼j\b'm02| lk&=!o-K2E\o Yd9r;;jD-R-u i*oxAIW5}>mGO[%,rDdPQ e$r: |}FkT0 ,Ic8O?DtIi`'pG ?(#ktGS-qNVf8Ĝ'=Az"dϧYPB劫,2y[ЯI&ӟ6ȶ$۱m1aGgg:G[Ln! dH; g`Al0y΃z\Cp1KW<%YmM XNdŤpJ̨DaLdvj?G/6ZPbn`Y-L`qJ}}J~/C>@j/<|?y娔j/<|?yZq|g;D1iߜv5Bi#^%KZ5Q>~.1 cr1+zGm V խ&F! (+ְ[9;O]3hK -lS˦ @Kv 39C>+f UX%R`v0|k:zdK`k9mZ3l]eo`}OG 8{;pn{|(4Z_ܢ"KYU/䯓ɆAy eISFUd3ÐHIvAs%A6kqHbTļ2$a‰#  <%CM1=rBŶBx†n??+5Ev$nCD4( GveϘz֟]wC;$lPd+/rCrG5yg}&{C sqb>ғ,vUCJdVHa"b4L*y8R(g"uAMjݗXHcRQ@匑dtG)+Bki@ zEWz2t+V$,d2(g.pe3:Iu A`;.Y"Y۪ʛC v P&E>xϣkmaGtnml&]ˍ~XTZF:("ʐ$r3{ijNi)u0kg`BRl<ݠr9"CtAx#ۇkybW#trr6kγ4؈|-7 ʡ7M֦%m9C1 3ucֻE,lmUo$Q6h7Y &AŖK2i) i嶻3ƉS&v!NݏZJd۷;ҳ5E4LP"y~zkMSՌH\vr>X]V ]Ͽwo͎uVkJR)@)@)@)@)@)@)@)@)@)@)@)@)@)AOXOy-WׯZ{ϩo¼XmN/Wfy>jvӋUپOx7!qgPj[|J[|J̌S~V)VwHP^}*RQ疢Q j)c͟18UC <㘠5Bi#^%KZ5Q>~.1 cr1+zGm V խ&F! (+ְ[9;O]3hK -l؀&$ qtRYr)eC̳1nͱ>UK-NlE25ѩ1\X8e ! h=RKgUHO/` Z\MeԀO/$wyg'  ;[@Ͱ%H 2ǤW:Alf7TG- 0erGa{Su`ic,k"9wxh2hbWi5BēxyS?{7m^V=ZŴ6L !eP[f c=P0 ))m{% I)SpN*ί޵7pOk1Zx FR S^5c%o;尺3_<.X(8p+9Nj.äC] u,v2¾Fr`;|b:TE5ؒlKиrѹr݃= 3]35յxm 8 9VĄe%y}:V/R-d ^B0Ndl#͎O<[tIa$4,JbWuVU2 ܸ UL- w D,w`A`d$'ibX^4ĸ@f$X!PZ1Ϟjޥ [-^^qrVÌ`0{jpCVY$$@d anHe g"ws>ۼbmTa3<ϲ=- KX%gl 9X'3]Mޕ?xߤxٞxjoқDd* ,h+9PB1z7k: ks.w.@Glԩ<8}`.Ҕ((((((((((((()> wXOy-W׫-_U*'?RnqJ7V{?]7! Ko?XiKo?XiY}}J~/C>>?  ϡYUJRnm,wpж3fM-ݺt倘 >MX 4{2F+!;gǚIPE]f#NNyɩ#fu)`;pjդ&CS37ϗb~c>b.t`%XQ`!$c`u+IhYPz/ϟ?Swcr+;ռYvO;UG[MRl3]45Lg/?zVw }-vGHd`+q泡^jD vգ6X6 -O.199::ay{䏆_m*m709Q`νr1uxP֓ Xv팮k`#>TuލOwa|ֳY$86 $^zCTUT"E6fBNx8AF6;*[,4

}U*MIiݮxqrva!ksmuX,67N4JL#{F1+ޒBxJH"Fl.H B!4 }lf90}kulڕtyw!7 SiM_P=-եQ#ií)|82O禉I7Hnԥ ^Gh .0D{0F\g8劰(biyn 0Oi4{7 G1ۣ|ު^In8 %v*mۏ$[u[ZӉCcÒ}$r仝-T"IOo涞;;x5W97 qZWjsnd#DѰ #++Wơuq,W6|+cX/,1G,חr?c]3LkK䓁3'z=c=Է^n^k> MxMovg*ݯvoƳ`mݻ2Gv|57V{>?  ϡYUJRRTS3姛?>c~q% gO6h|jIj,֒\7Ѩ Vqc01_=;hdhgi4e7YA]?`7ΑjzDX]Ukd]qSDBߗy1_U{qC)np F.ܬaœ`s'hV$粷EC$in > eOqńڍ-Yc$#"eC)#TuRҋ[tM^+7w02lPN::Y`/涒;)VH {I8#݊OKC 0c>T[fCGt^V w{䉋-r;}tIf1`AB rr sZIGkin% m2'/*1_H%Y@ӡ+c:mW{s;sϗf+EN[Skf-I|ܡTW<yn]P &Vq,/0U+zeW GqAKy G!@"6cNG~Aj8oo{xmiZqn?#|I+%MA:Uġc5J Y_="+ѐCy3m=@kXcЊb4MLĤ8d/<橏C:}ƅ2&8Bpq~XsE,52ϭt &bo6UN tq,fvel+*7w15c[!$E"U0mj]iS7B%b{s.RHC0˜Iai 3ޥE7#0ט椎c*;wCu$[YV2nmWk`s’yA=]-zYA %N2|$~$dW]WܽݠiZb&Y"Ee*WC_V’C4#i(gnp@b 0T~4=:EɉE˵*`e%00NGqq J-cm)) Oa vWA GY[.ܕa =2OzFYKk;\G! ln) `"I[Q2pȰ )sMWyC*^-֢\YLvx Q@O2OS\tzjR:pM3-v2Ƥ|=A#+Y=_1DbiqqqSP o$|l T#t[&ua nr.{u7mYqmiKftSep(邹Y_1:Su;;Zx >F;y׶Fps WcJڤk*_]Cww6rd}CIY**T];y^ۢ wup6GĖ֦5 ʻh}V6,>ʻpu@m#r {*Q̒wN bIA&)QCF>ܵZvlɉ!8RIYQ!Դ+]ZYmKi #(sycgT:[k=ַI w(]ȍ PCg+}.ݝcސHц`A.HeHyVvտwZiu"Y&,g[R.$Rryً?Kt7I$=v,`(J er9HL#|n-@.q!j;Pc&^{Su`ic,k"9wxh2_m 7ݵݞx[s|'iemYݦ",[L#HP_f9 9sSJk%RUG 3̺v?Y[VaZ[yn'ۗ"5ngk!sE,ViY#q9oсV3٬uqw\1S"y]]mXgt$u"nC* AHrB!׵xFω<{ )%/ku(#y$ŷ40wae\۞uUn# >BsFf07/h TZjn @6rA9 r1ɀ,wGe$noR{^91nTģ999SH.mo!iIgy|p<y͂ly?y{2kU켊CB,FG,d#Z9I_J03[Jŕ.Ilݝ*=VԡN[X")!c!C9v9NZk.DZ|ft12vEB:]EpU7$A)>?  ϡYUJRRTS3姛?>c~q% gO6h|jIj,֒\7Ѩ Vqc01_=;hdhgi4e7YA]?`7ΑjzDX]Ukd]qSDBߗy1_U{qC)np F.ܬaœ`s'hV$粷EC$in > eOq_8=.v;6?zaYt9\i}TE+<} x&ݧ.#lPȌ:jqWȌHXZ y>ѺIfaw.7cR{ittIdgn*nI 2R6y@d\tOf!K[8f`F:("ʐ$r3{jq˽tڌF: b"ߐ6cϟg*<ץ ;[@Ͱ%H 2ǤWwX]"ڪH6plFo(MU7M֦%m9C1 3uwc֮m꒙6.>o}KY,ͦp%&NDT;~iq:4Xޓ {PpppqGYEoekHDȨ S w`ek8]GMN/Wfy>jq߳+?AmG)mG+22ϾOO³EqZ''ԧY"Ay?#JT R q|g;D1iߜvk^eߨ\[[ ;RLrKM˲1.1 cr1+;))]:kgQnV.A"aǤ*{%pZLҼybDUx$]x@#Bۀh{4 KHe6 hB1bH>l;rG_imy#[_Xܬ }43av%Np|`5srÍW0A9U@iMA<= 0P.ͥnѢΑbUNNV.Ͼ橬Yl5H2 ZA,mU-_skVëI|]rn.6g~?_5'@#hR <\DW#x! R;ouoX!IuxPr+CiV$Fh01N8}3)JRRRRRRRRRRR=c=Է^nZk> w`ek8]GMN/Wfy>jq߳+?AmG)mG+22ϾOO³EqZ''ԧY"Ay?#JT R q|g;DUqP 8(;_5jr.- &Y̹%W h1c 9cCXzT5@7+ VF 0?o MKQ]&{^Y ֌neV*d<c. m4_vwmZ6WHPgPd2˰Uz {#Ճeίr D ŶOw11\F# GYc9eX%ksZͩ[5q-)`˷q5 @s>]-g(㹔Y9F(v!S "&g{sfu! ]Yp9_PyJ9 2c#o9l5uO' k sOԧhme./.q5$sYc[&-tx.ZG-ǰ`b69 <룝K(#ᤰi\13䌞u"tKOO!h[ķQ!1lϚ7I"DŽᨷ!b1O!zP +~( nnBч1F1UC@R[{|.$DD Oa9 n4c{rIZGg=8\BT]nlFӴO,"!.!`6ygg<2x&BJZq3 b)@#>U/&ڍК ;i!N80pW= x% Ȯ$E1{Pl+)^x¶/ =hn.&h.|佘Q(jMoyÆ)@8'F6ZdvΞid;u9γ]_ow,GBD'4䏖.Bn'0+N,Fv$<$t.ܰ3n\`mgCLLumml;Cn8{Us*I^@NĺԵ {#HhЌ1C'c-fh#iI) $ULw.3r9gEo=2KC=]ic 9#X+ aI9ZwE71. j}}J~/C7-onm VE 9/Eu./&f-%G]9!_ҏKAm1b;d=*?qi ۛ{FUTPO=ϞyjԳgKbc;DCr8*~=ĶkGEZ/?W:Pǻտ-8ڷ]lzE:t{m[ӏw-~ZǤSHHǻտ-8ڷ]lzE:t{m[ӏw-~ZǤSHHǻտ-8ڷ]hzE:t{m[ӏw-~ZևSHHǻտ-8ڷ]lzE:t{m[ӏw-~ZǤSHHǻտ-8ڷ]lzG[7Hǻտ-8ڷ]l|Νl|Ν"[{VKojߖu:u:t{m[ӏw-~Z.%oN=Ķk:IJ9qnSv?I)N)897O}Kl%oN=Ķj[Ǥ:t[{VKojߖuΝlzGHǻտ-8ڷ]hzGZ.%oN=ĶjZև:t{m[ӏw-~ZǤ:uxڷ[{VKH[Nww-~Zq%oTuxڷ[{VKH[Nww-~Zq%oTuxڷ[{VKHZNww-~Zq%oTuxڷ[{VKH[Nww-~Zq%oTuΝ"gnm14WnrN<詌bU䁌6 +2I3("ۊI-ާ 6 SYSV(a|2M? `#c%$' `TMK]JI%Smt,ډYap p2qXav7O#`Jh*'?yO~ƽM}#x7!qgU~Җ~ҳ#,*fu m.( \TY<0`k_\O , DU*+g"0u2nZqqsy<)ȉt I 7#aCX1&${8<xRG${PƤxSKPƝBNoN/.~'.D}BNou ;^jN/.~'8<I N'7I?gµr#wxӨI Rqqsy<)ȏI N'7I?g—">'7:/`5'?gœ_\O \/`4wxԜ_\O qqsy<)r#wxӨI Rqqsy<)ȏI N'7I?g—">'7:/`5'?gœ_\O \/`4wxԜ_\O qqsy<)r#wxӨI Rqqsy<)ȏI N'7I?g—">'7:/`5'?gœ_\O \/`4wxԜ_\O qqsy<)r#wxӨI Rqqsy<)ȏI N'7I?g—">'7:/`5'?gœ_\O \/`4wxԜ_\O qqsy<)r#wxӨI Rqqsy<)ȏI N'7I?g—">'7:/`5'?gœ_\O \/`4wxԜ_\O qqsy<)r#wxӨI Rqqsy<)ȏI N'7I?g— ,zqW7ǔ1W`qsy<)GgS%eU0;I>f5cˏT~/.~'8<9kĄ4ð"xSA%qgW/.~'8m ^?R?Vde|Rv}}J~RRRRRRRRRRR6co}-F&`1Ldc–#I>,xS0|Y?Rf'O<)b:TDž3œ Xe]jq%%+ +X̏JK4ާLu=7dRƕ+73S'"O_?JzoLȧSzgOE,iRz?2)ޙ)KT>ך:]03^c *Y|篢`! X&`1Ldc–#I>,xS0|Y?Rf'O<)b:TDž3œ XZ;6uj82 9$›C$,xS0|Y??H~"x?㲍Cnҳ1`XoC~Җ~ҤSOO»Z R R R R R R R R R R R Qԇ}3 #)TDedM9cs8~u JLdJG!yՖDr1C'vv6q\h"w,X{@8=[ B2UKя1ބ,W"*r@T(C#ǹmp 9<7E,YJH8i>A=\?voGWA?}M}=ȭs! jr?6u{=^Ӏŭ % %2 '>iޡitK<&TFEn(䤂F3y<:_q %ڃ+H~ʰơFm?~#Lg?F2yTEAYgi!#V.Dlc 10cFA AEx*fbN'Ǘg:ꀨFdARFmKC5kOڟA ɳ}iS/PGUuKçWw7x^@jq]J `2wb{YI]dH0NGiiқCm'ZC"M<H;Pvz9ւtcJ6bT* <1M>C,wfݴ$v/3C9zM4gvA16!2l9,OPk)rAfTLR~8 H?F,:DB#G"˗hv6mE\].ô-qɈ]YBkxZ֋~&?Pj[|J[|J2ϾOO»^RLbAE8S5??N wW w8S4i^S4OxyzOxӅ??A??N wW w8S4i^S4OxyzOxӅ??A??N wW w8S4i^S4Oxyzm+\,a@ Ÿ Ɣ2#'$?|hV Ɯ)AP?|hS2}OZ)ApiC/2}OOsg?5jpiŸ sg?5=#'$թŸ Ɣ1:/[o=R)WS<Tw].?=}' Ɯ)A>oG{G{piŸu0u0)ApiCw].?==w].?=}' Ɯ)APp}_ Op}_ _IŸ Ɣ3D >'%y 6XؠxmNw.$ '֭> w8S5he>FOIL>'N w8S4sg?5=#'$թŸ ƵC/2}OOsg?5jpiŸ sg?5=#'$թŸ Ɣ)ֶʹlL,qOS74$rOOZ<)ApiC/2}OOsg?5jpiŸ sg?5=#'$թŸ Ɣ2#'$?|hV Ɯ)AP?|hS2}OZ)ApiBee1&W*W-#7"AmgW ws9 p\y@JV~Җ~ҳ!m^UzUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ Rm^Uzu[~)m^(V߻ u[~)JUzV߻ RxANo)[o:wxANo)A"E JR?uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image034.jpg0000644000175000017500000004213511665471332026763 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;z"L !1QRTUa"24Aqstu35Br#$SbVC67D(!1AQaq2( ?줒Ys|Sqi-nHiZ3<vZu%<i~ ^9]}wos<v{W_/WUsd͌_F0\F JuNuޮ !3<vYMum]!/-h8*xX̍|g3<v{Tzi+)iecn-18BN3giL!kI$yTZ.ZH`ǚn!\fx= )D3I xY; rxGgҙtC;J1 8,fc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙc3giL!g5ԙ|:&ӤpPF}K]ݙ݆oDMrC|Xm^6N?-WYfy13іa_4;ѲQMj''KeCPIܱu^,N/]$|-EvIfa%dD'b.+xߩEeblp[mS=X=цU^xYhc U2F f-wabwmX{o6LsGd$pPI8=#iMUQm< nlغ涔[SjxN.,]= U+g% !8(aK[SPT%28F ؽXD\8b2g"~S}bymܸ355Hg?Jʘ@쓎SIv}2AA.jj'"<8l#ij1.t6HN9a}dgfDA+wշbN3L3J n 0džmir")a`;pQHe, cگ_{ŞיMS/yɰULN9Hx@v;­ͤcgq3/IzSY ͳ~N}]eOY+auMCkN8'1 yEqi % @@xU[cؿ ^V򨚪`jw1 Z)DVcU[R$5vIq#jw1 )hDMUn0|5U-h&s>`kA8 N%DMUn0|5U-h&s>m5UVc#-D6| h}5{Cb "w1 )hDMUn0|5U-h&s>m5UVcM&s>`DVcU[R6`jw1 Z&U[MUn0|KD"jw1 )hDMUn0|5U-h&s>m5UVcM&s>`-Un0|5U-`jw1 Z&U[MUn0|KD"jw1 )hDMUn0|5U-h/eE"7rͅNZ}RwЦ߸Gr%Ѷ}?w\ WcyQl~p+bxld-έiAlkeLe 4c 8vp;⢶25Fҵ윓0JIi#Ӷ 2Fp~ڳ/I-BIjkJ\(jc2dUd3- i"2fh oݵun}b̌'joG .1?sTfK@e3G9T}D:եҮnU .qČ7,VUP@'`2vUmeKlnqs]FSWSD]JB\cJoךZ8nuSMfE[AF kKqۀܤ F6 hb%ь'H={\kҺH[N$R۴y5a8+K_SU&2)Vs%~}7os魰D88=MU%qG1qr]5q:#Rd0';߳rt]+[)ctm%8 tvuifI2:6]ʏY]^&u5ls$kqvс1ڭk%OA qQ+ZjAT+bS_g#>Ȼ]Ub.oUU3jC U?]p\:j [oxֲ b`㹤E̱p2 #|KIhy.nmz4ͪ]ZUѺNL~27`0v%w' p8 ^v#kqwIETC.LF989AuzrR;.){biv-6^Τw$/8M]%5(s炮asI `=,qSlV4X6nۻ 쓆8$7XKu-0|Y\ܑ֜(84O5.ů2Կ8ӕq4E~KŌkϖJ'd7 ;ZUAi5y.- ێ;r^l0iNDlq55RQ!qW1-@oڸauU]֜iUϒ XOv4E>cTCd27 wvKp8` 6>eI~SS ^lG4 DeJx`3"to] mڞ4":Yi8:Lx7ہ;{:ÀF}FpyՒ2"0K.l96nK\˩:h 5Q+&XO#r]',԰\Yo9yh3gT(eNDXT'yZC.1)ij;tlt74H۴lyHW}Lx>n6smұx\NQ'65W ɭecD\09[pb릑f9 A_y.CSEozc#I8lv Mc 2V%k cݓn*l;LfyzvQ։L3+v-8ZUS%{x2 )EҶL]YUp"0K dA-vxA %p,5SZf7*V]'Ogn5WE_U &3nQ۳r\ZFBQm5LR x;i8t6UW &# t fX  U.v&Kf`5K(21 rN$F-)IiM2479G;~8zx}]cedNv7Dex1.vL4ͦE srFbx6 k$L ׼q;\mNΥ֗8W%cefT<++'oG1  daX z⫨gƞzXZD{do 䓱i7ѹ6􌝢11Oޒ#DDQkIB-u>?;PyѶ}?/ލ\eXv/WR1:Y^`qJ_njR͠ch v=MFvZI-}Ԏ89`XHۆ8f\]]Iffj)~H8W=kc.Q=vɑSRN#f:kfF،nh9؇ va6؜n|*O= 3UMDCrÝn>5c饩eƕ&ID%b+8=p2VJ;֖ē[/"a 8oAЋ' >Lfa&6qص^mԴuu JQcKUo5 @8rPVJZ-R29핎sZ@p(c$TܨቲI] #5ΐ7ƵmM>#Db+7y4zYDT9O~pطx=rUFakᕖ4;Rs5|*"ɢxůckQ[2=KUn$1I+R*jGCÉ{ҵ.$`I8uQNȻ]Ub.z~p+iYyhdOm80$Q)#u;h6M4! ]j8' p' Bj1KK*tM9_ز-"')8e7_t*d pXzܹ*k]eړC8bQ\di.0 p;9l}U TrChO%Mz,1Xaeጀo-Rv>E'(d`aT[+qkQ+w߀ P7dc9imlY0 nӽOtޭ2H= ]ֶGqQ@/<Ŭh=ߗbnC,ePk9<:Ӹ>\hjib3 坘0>ͶW[hh_SQ=Ic+5c7`)D,x;կ 6ShkϷcy\;xTҥg#{Xa Źfq n;فTi9tREUEKl-Gc*NU>kI8%7$n>řv@tc tAݻW9fԱ)jMI(.$4T: _$MJr%Ͳku_m4:H䉹R5421ټ/y`k4rTakɎ5P^7R>:4$ZaǯoUb1=M\rk`G o&rxzC84; IzŲ}]š̒p8pP.OSj]"H94H+E*[uWCr{$}TpɁelnݫ*4RǿI&61ph]Y9s`#nSNJ_ڛ|4Q Ve3\2v`0WW u#dTHfs۱jȑ𢢟2k[YqF7d:WHYqL]X⦪R*!vvlوPhr)T3JLdk0k0x`ߵB:Yizh2#ڂm56>h#x\wzZ9(I aU@u!p;HÉ*8-vEJ]$A+ݹ#Ϗhܭugvt7:N 1.t2x)Kj jgK#Zj+FPvҥf_PzSl>u>?;V_g#>Ȼ]Ub.z~p+hDEbJjv<1ĒN$bk"SY,+@8wSBiN It ?;V_g#>Ȼ]Ub.z~p+iI eQS:ZMldn0%+LR* ltCDCYԤhjKu% 5*pF6j[E5,B5y#ao)d!͒k}T4nЊvd;pQ IG:6+$t7|amt|ͨVQ44NINùHr2D,ikG'vR I{ 6GL #c~;*`TUgnlmy8>fAqH_ o`hsea8qݴo png[sCL`8b|xoGGmU$V6Se6,{}΂ D}5<φ'H'3IjS^cc661{^U&cn0km-geC2H7d4ު h5,k2p۴㳩GhjaZO͇ 7*METGoe\pN›2{[O4v2&:)%V]7*M jf9czX8i+c/Q%8r7H뙊 FR23söl8xG\$ d1HC7e_;Yly`F״ppմ( z>T;)8ałVyIUM4 85;!,h,.av_𞱴ymI։Z6'qc01V,幔ns'J^qGRG;gBl|39E 3fj:zj%u(h 9;vKs{;s2p6x/n,˫)rs.m[/Kq$}1 /T+/j}RwРlW"_g#x˪_Ub.z""" ""Kj;Tq-zȗFE2~p+Ecؿ ^7ODZD@DDD@;|pG>_+> iE"( EA5IۀnV#p8)E{SgnIc"7I$1[ lƯF0س}#Z}RwЭ>''} _+> iE"(?TD@DDTU1Y|̱7EikIBHֺT*Cne%2M,--4eHb0l+i`',KMRƲEKG" fǜMDH;#2'sb]e@'|WLu%fS8bB0ტa98^<)]El΁^ugK}ؾx#m//r.@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Q?j?HQ?j?X37Y|̔VHֺT+akIBlW"_g#x˪_Ub.z""" ""Ӹp3_϶ʴ]"~*~*f=2o#ܳ&(>u>?;VzSQFDz6ϸGr.Ucؿ ^+\ q@DDD@DDp3_϶ʔ]"?TD@DDD@DDD@DDD@DDD@Q?j?HZe+{d-fG7vObt;LKD#zSl>u>?;VǞ_g#>Ȼ]Ub.z~p+hDE_϶;@-vR,oxsKN'fdZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉ZtMJ߉墣gYң7Zz/vQT4Xcy,oRc.b}cv}ǒ".'+9UzSl;ϽkIB<>ȗFE2~p+Ecؿ ^7B"(d[T(<>ȗFE2~p+Ecؿ ^7B"(DZD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Z}RwЭ]OONy~mpKlW"uV?]ꢱ_WݡD@DDD@DDD@DDD@DDD@DDD@DDD@DDDrj,b9M 7 ,b9M 7 ,b9M 7 XrohZEG)gg(d[T(<>ȗFE2~p+Ecؿ ^7B"(2H{3aKU< %f. J?%7Sܒ#W(ϒ;[_t0U-~_/#O[8U1TpD.2_rݙXa0K 1G2l61!r#HΎ{7eëww@l#?aƙ3Ko%5owIZ"`[_tlt_4TЋx!h6ƻ%[?s<I~I$Vty}c3=sSj%twLl4## 9َWu"R1,2%5DQRt/6贴6\Դ'ך!3E143- >hvLk`:Y ݊wj3G~mdI$17HpS=-lw:$2Th@+dÁ.h<i2$eKR)y_k[)c2''} ;wV>?;R/"S4UIPf>VCi?6Aٝh k\[Ch[1ģjOG|_Gf #DlalVӶűi6MCi?4?׏ AP SPz>/'ŏk\rN>eSG&SGq>?;R>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"X !1"AQRaq245STUs#3VdrBbcu$e%6CtD£(!A1Qaq"( ?ݼ,4XJd%=鮼XOS/ !)*6q U!횬ΔoGK2~ g$jD=# 99Va9IMͳy^V|تؤq!Swrf>d 8a A)JR@{v&a)--H) )֒crl\=1]+5MD>lSV|تvnܞc:w܎댶g^@k!=",zm:#\Te̥ +ZRIJ ]b"k^B:^ 'YbOs @oK[hC0Q}懣>ֽ{h1`%ee̶'8P<St:n 'YbOr6molCBiD ʹAawAr\^q[)z 퓟iX(g͊pQ>*ϛ췀`QuINgUBT94Qm,< ) E1ͼ7'Rm(g͊pQ>*ϛ_\hr~fr[L6Vۭk~V&j^9N}$Y~+tzA PD\]D>lSV|خ-9X6V(ү$~VnƊ6G:+V=^d<n[iTU9!JAPK8$G+i}u\O8(g͊{s3 2qoQ)I[t: [FbR[L#1vaƔ$3tMjZ: 'YbOshR*2RAj6 `X x; (0?,F1EdG(9rtO8(g͊1l[`EN$إ%:]Vxkݩ/ c?4 j\pQ>*ϛ|U6+b~#V2!c%l.{c<ŬtXRKQs!%.%y@颯nt{AD>lSV|خO ÜlIZp6VEHqzNj5Ub8yie.,1]!Ԃp|U6)D>lU&`T[ zV Pa*+He$j.f>6laTReH#-+:Rpx(g͊pQ>*ϛ M8Sŋu/%g!  JšYTth{􉿵  'Ybv>eיKJ@-⸷>4[_+JoVmokmourp>{F%g2Z_5ۥ]Xlj U52ҝ\fr\ z\/ [r[[5eםV{R$T;ôڤI Y(Og^pOQV$ąÚ_S6J]<):hREX>'0e(i]㇙*PTI'jvnZT-[me)Jm $f.(P/+9:.G$}T1a&,XbC@i(ꄺ}\] B)6OKz&bmy]>#\Ks}{Ȩi!4gfk[Bo~؏"c+ bGSjWLݒfFqkA{óH";?*6;%+Zon,O_ͿUj= BjJDwæKͷ(iuحBO.]t;?)óH"1)Fu>-Aa(:P3 fX51,Y銀!Z,YrdgEP]p>#芢y !X4t¢?'Pנ5⒢bAlDtI'unaV:浓PyړχgExc%Jm"Ym6BjJP6tb׽aέ0ױpiחu i-| P [ -#J CItЏkw{woU\3[d9[iRŚ"Bqh’pBZL<$ɺ:#dAIP#V|اSҨWsëlBSl^6RG"(F DDm0QR 5^: 溈.Ji9P 5+-^.ӹp)rCjlpa l6lP/d.tЌ$e%*I u:ڻ\?r],P*>NS8y7n:RO,#Ay8<Ф*XBT sn˚\?r],PNCp-ѕҔ4Ы;!RpgSa% 1~8wW1`b*º>>w.Q$b**KϖQ~4Jȫ ,9!eͪ9߶uܸGN>Xцs8B+1^-69{jAa%yYk^ܯm/]r];hbfnJr|9tiR:EgU[.ӹp)\V)em"PAaXϗpJd4I>w.1&?@um)+C[vT#G2<'^IBӻ`\n.ӹp9Vp=3L%oomk򮯹pˇ?}u$# DW"#4HBi<džG/ӣrpˇ?}t¡E[{iHs,W4q[fΠYXZkV \ZN>w.rp)Jqm%KHO!Y?aBF W[ܸGN>TaУml[_Փ0bFBVZKi)BPHH& rQܸGN>E u: n 9mN)u&{Uԟ"y \ʴvwޤNaϡ *QN Y!)-5CJnA I?7'hRBUjօG)-$IIS$)i ɖ MZBљp6*Rs zS(6"VqDpJMlyk)BBCAkw: r|Ven;VӆoMlWOZ .] _DzCedclW.~P-y39r E^ +Rv(J\auz#%-2| 褘AX|28,Tz,*TYK)qjR.B@R >k^qw.;Z6]AI^!܉%ɲnMkTd<%:Mڵ2%@&WZ%xZJRJA';kj !26.-kiU-}ӥ݂ڔ ӰSf11yZqg5HΨ%+9s$(ƿɒ- Q7֧i:W3 r?](ay$I/e(Qʕ6w`í{[@i7 ,!F-*[e)IIRQj+jF"HV+wtQQJ/tUʍ#npc+0NC{[o- cۅlAU3;$:!M}<#38sI)SQܯYB-)J)J)J)J)JTغ5K hYQ[W9R7&D}2I94Ccfa3ITVnΡjm|\HL3)Kv. u|]]]j}3j&57JLu)Kp6g*6I=y;uMN܎s$Ԍ\5B1(HkzY (@ 퇬ԎTSl9޷pn}}"')\IloXK6Efa/o|ڽi>wϦLiZԟ"jg}O}V)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@gG{$\jGiPhMd.Xߝn}QUK*{ITԫs%+rJoJjʫpTGu":]!ą%YJ[ 9#V)cĤ%6qjT qjT<LiI>wϦԟ"jg}O}V VJ$%2\- ? 4f3aEH&E$_V-5+oh?}9ijD2#xEP.M6{];whjZԄ*0 5/4VO"T=$5e.R. &5ms;ˊ҄6M}e6!DH>/eJx %,C )B[*'f#FnKآ[iBӂek<=WiU'Z!yiv͇JE k&UKHq|7 ((| leYkߛv4giQ .AZq!mKA) 7'hqY-B89UT. (-)\T/3m! ws C+wxyGMlGe]k\\h$yn@-e*m; s"LvR㱡>PBR-? 9}(Ej;6 % 6O򠿥Rl0b )Sle aGM說qUEv3%qȫZȆLV&3Z/{R!)HJR,V7}Nnn#NjV]SWnv!bl0""<HR\AM*!ՊfbMvlx=KE9THA5#?*{T>.Ysʼn{Svno|ͥ:EEGShǟXV‚n$zH]ܟ=ܟ=ugSU\87bqw$'), B\6m5s0Ni5N#d:G-]WwTW|DGNt>.fxF0$b[3Ci !n-va9q3žv4i"!KJB 0.Z/{WoU**;#B[ L\R}2L0M>0!ot{w~}7*w3wUWcA>w/M%11҇K TпEKHq9*upqYZWeϦyN{3*Q3w7 aQF gbd4R2XkaWqZٰDY~V7{ou]_Us=YF9rp)%'YwjgP !@iӮ`s,4DiiV)-UPߞKʝWToϽ?1e ے7 eq"Ĵ(BUb9a--SNrZR,n-JʜrZl4K\I'0K`(\Vܯ9^?g;# Vԟ9N >r@ڥkp_H9)P6iZ2>{s#b~pӧ N~{~Ӧ8ot῿{zT$,$Rz)'K(kU6"p1nFbKy2*WRT[RH[8l(I~R-2u0{19$p&ֲͺBݵ;~7FC<-·_i.$!ۦVU!{j-?Eg~4)FZ7JYI&nf"JsF6c kM_ T@lΥ$\$<wG=ݜy3‹c]Z-%JۊM$|.[q1=.6CkXwwp +6&m-âB\JYe( Q*v#b;ȎEeqͼeM<$H8qV܄jFto28) *2VjlqTܑ4rҋq-YJD0׶3b9ͲE4{&Zڝ<&o ' :%$%4Ъ#A䤎ac.AqQ[\ eGKjED¤ ܂T:Xa8be.Zw` .Fe_CEk.Q#iJQ[HK`#l4ba D!B1Yi(F [ZN-NL^0eC)h;җ]y^B='.xÝ[-)FPܜt5,}ᶦ{YT$+B5k#MlO`b \H= i9CG-%aq8TRs`2)IuU⳱W Kw a)޴ w:`#[vg Õ5i,:ޅZjtf2#2Z):vʱWs}US;L =Z_iK:BSA=@-[XM"cMS~SYT_Jzu~<¤I!G`9ZJ2.T% dqsMOUKHunD43*Fb@Z p1|Y1|Du̕(C@*K$yЂI2MH9&6iR8zvVJJ:c ;sZumO= SSРX77ҬIiM&#6RbINZֶ!Ḭ$bBm+@Ib.i=HsQ$ƊApD$dkk26hcLBbIWYfjO2ꔨy_eND\7l8rc+" 9YBC7 *C{h%pPXYPK.NqrFmWK}~>#LHdȎJº@NClX܁npE%&%*Ibnˑ:ډx6䧥 -U| eC|3b_sbqasz)6m[P`'Ed᩹8k )*i%mhǐ +O wl nd3$)ȋ Xm̹H\]n@6u6eDâǐ%Ze)Z77 \גp2k +(pe*HY$Eru𚚈f;*l[ƙ*Ki 7RJ@+" 騪<>n7"*#g:ԧޜ6*\!+-e)1=Za8lX+NE6)JTbR'\{I"k &I}Ki le7Д)$]Vm/⪍@KF2l$Bٖyn.z# \d+JeJ*7%&M)xf=4#3+y5I#CR4whѐ$Qs1@O]ZؖcxcD`Ku)e<VavƾW,-hC$)nڔ ԛ/ȫZ6#3? 1Jd̸둒X̔kś}9 h8.+h7T6§R9, ^H|\bNb$^܄(o ͥ;kX;KN^v׏jbX[mfR I*БϕKs`ۋBRI );Mh 0lC""0&[xmd*JMXPZOjT OZlM6;/56e`Q v D[iaZCTM댦RZxȸ%Gt HpMMK)LCgqDdr4*s74Up-nkYxP{1RSYm "In/u S[%)(Ρ(Zu ܿ|{'w1;m>KDYK2ZЂlٰ6!N!Uܩf ;lRlc)?%o++%-+,eUO3Rټ.d1.C(RlSaA*"R!SSk=qYq1R¥%U mA'Jm,? [(yK/Ѕ)K`$-K/#ÛBJ3@ѻ}}D֩<-kJtn72e\/iT8wX4%/% $Y7g6Dl>$N[x|VJ򤂬"5+1?!݌  )ADu]MoM4 JH7(XA5Úgw 2-9hK%˺Al3RJ8bnhmqT9ʛSE2 ěu{7A%3#0Qyuj!*H*RJ` | ،W;oƬG? fC SҋI!)h!ZW=k[VXYm%m>3y))ʠ96ֲVaۡR&?qJɪϘ6RH:vV[? F-,8!9A݃0N{izETY+*R7m^7m^IK}4tgJԟ"jg}O}VX3a;po/}-;f"n%IZBBEűL; x/bSBmpJW! րkXafR6x6iWKpȔx] :]I[+r>ָ 7Hz!j?D-M8Ru)V飺;fmKK%i7 JĎNqCލ//~Zo?!0f'^nQvS`ƣ098͢nbұ2tVu$<٧wJN1G;B$ QS,5{fR2\d蓛{ئ־N&ì8KeH蠃mtzP)T7.dk6jnXݛ,-$'f pgb}#6﹎&tZ@չO8GNlKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN.}T*.}T)O8GN⮩AKO8GN񗶧}8﹎>DZAU.F=#mTU qjT qjP|O]3$>Vi'>ȫZzdUd)T{E.22ӡesgZhUSb,ťN--CDr 5JUB hrSBy$d @ tov֮#8s%9ŇeklȊm%Y 3 |XiҨm#K¥HÂΠ6o HH249Nԇ7L10aX-p.zgڎ t̊Y(ZnE.*{S.dONqR A:3Z}n-{6Х$0e8gUd#ߤbyR2/9Rmf ~C8":H') p=f̶$>-9q$/Ab8`Fm'=[\.qn!>PHbĪ=g@ا\TǸg0Z`ۆtDiI wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wv#~WTv#~Nj~Y>wuJ ^j~Y>wIR--Kal-Hœ RJIu _z*j_z(>y'.Ғ}M+CzdUUlI*ֲ+8b FJ\D*`$וQ0,>ܕ.L=&)&!7OYYJF`z$d;f3:sQkjmV6v{K,[ $X2HwϦlI*֪wޤkY˯SH?MI>lQIGTTGEFVSb/řbqyvR;Tmsc-sVi( an>OiIX  E(ʴkt!-̋Xz+:cqab!ʝE%*JYaz inڒS{UZ8L.dGKAi/Y6767y^2Zm`NBP3+[vjtܑ0s!C {tÝy;aDAo(B5Zg}I#YaHp:9jbCfp:+.Ki} pRPtn"jk]s9w$u6:lOFۼN|np풝 Ęx&D, R\uV+Rs(~:Ip=Iq2Sp*l6U<@<ҧnM1fj3 DTaĀ.IMW[7"CQٝeKU^݇i Ncx`Kҝ2e.!efh!C3V {^;Yվl2%9lA5-jjvuPmxH Rt|#LqX\!{AJZ`:snf".Ăv^2s(n͒m]±.Z\T6d$$ABRR!D tF_388g͊Dq% !%VO,;*j!Y6)>lTԠf|اSR/řb_3MJx8g͊pq~,ϛ5(!Y6)>lTԠf|اSR/řb_3MJx8g͊pq~,ϛ5(!Y6)>lTԠf|اSR/řb_3MJx8g͊pq~,ϛ5(!Y6)>lTԠf|اSRU,M!iwʐ/i1J1KKIRiN(J H H$`:E_5W~1%Texwű bSKeJ1W|[_/4V#>TFw;ľ8&!V%[NdV/ZţhNC4 󶃳(X{+þ-M/TW|[_!bdC[(p]E]9Cexwű 0F6+ 3!jiJZ:m)%E**,GUh;)CSݻP]T2ͫST2ͫA>wϦLiZԟ"jg}O}V?:>jLqÐ[R.5F_W\~:OΏk i/y1A%oZZ%ŇBH\e"R B\HPibx\4)wҲ3dgVeeOis>ʞ rFĴg$`WT)oxJIqJ*M^A+&#/=ጴx dJJ7[Q/o1hHߠ8iĐHRuXqU"ħam 1DU$:[tU6)箚RKaeJq( 9$-$ig!V  sL~:uGa9$ERX@M6L~ zZ˶Y)vBTeod2Ԟ$X;8DZnzi帵0 @s9%:jj[0Ǧ*XWe%%F;o%N :rL:8<$fA6 t#5Q~*ae^<WbF`\i;vV~#JvcQ\E2T y$vګcQurqjp, ww$a[9jn/g>L <& 2-4:6jMlݩ_0[*u{nֶi~HsaeaQfhe2!;ǖE)&`^ÕAgP6EMP6EA>wϦLiZԟ"jg}O}V &Q@4+KS>1&Q@4+KS>1RNXΛ:Ӷd喇M%6M1 *INs|_b#l4ۛJg[r'ciiaF2xɒ(ݪ+ߐ%`oHv1BY,[9U|&Ksq=}F1VRwyHFm2P,E,Haυ6!KbRS.ؑb뭊+ aA^LCj[mڳzԵK/6aj96A#dzT"nψl!T,:]>Z He)ԕz)'Ιg/v"J R|p),p0Ą>^#ϰ}v[ 6A#+*]oٙ#†Thad:^t(HW=-kQc blы͇J3κc\Q(%JQm&&ǐ:ʯǰ7e6ap\&0'Po6RCJ( HKRI(MNv{m[i^07iAJr%DKf]Y/g1HH~;{ǚTBQ_feN"3̵&KU[BiȄWhqW wzBBw@1pmW7 C\%/"#Ok[2v:P4wZq7*ccS֚<' É: dě m{D)|_DT_bBq$ҷ BJ̀4Uj/aZC+*S'@/<ZD_Aqb?Љ ٙd3$KKiJTI! HV`%IDfW*u!ΊTI*#XA)ݤ_z*j_z*IK}4tgJ6wޤkU[;R|c습Xta5JZ_žta5JZ_ž񎰖rtA-x[Cc\d08Ĭ -ʀ:aSߓ `^5JC},d!fSn( ;E626`JLu1!m: u ;:;yNNm*q!(B dzog,*ra,ﭻ6[e U--gd1f#-܌VA!I١^Ub"vM7S áK ծL3튀sWXTsS 1iRL>݌-Z [d Pz3-{AKL$ٕ9GHuI"&=}]Fasf;&%D/eҥcc k58[\[t$!m e6BTE sHX&Ǝr#JtP)|W^V3h's0bj"NaKwO'VmXSV VWwy_Ynmȅ"cO)%( BF"nP`0cdZ,:#%`3{bnmc0 ̩Qgd}%ԔFjͤ1=^%->HYUHU͒qH*uM0)^vJR* ՊcD<%][FԴE)JTdXv =%=!ܴC8&7QMc~&:kv|3eBU6ɊlCIhm{ VUUaB%W Axb ۻi<[̧bwVJgFvT᪜_fσ&;̵*K*Ѕ%ZuWSe1Jkq +miBx|0@lO2jF]DlsYB}ŅRI}\g R"bq$2JqҴM#O\CeŶad-¶)Tm.gYR>vRJD$w6HOVKF +q̎ښ(:PVluA[5x,Ck--FhB-}o~zt#RRRRRRR-)J)J)JWi~^mU/Қ\]8~-/KH@*9l:ڃ\^TkRt 꽇VN*9*O?VŢpXig dKW9:[Zѳkn:x4T-T I=_'aӇOea19m",Sk֓'<0-+t).AVVFZ>~H 8}L? z!GDx{Vk*SXSe=JjOs w h!IRІAc! kzXeWeWtgJIK}4g}O}VU'>ȫZȅIP"cnnڑq5>:c~t}3X[I~;α -#x(~,:F-Il!h X)9mIk k(nPy,S$U56(p(,4$5;xã9 q-rʌT''AY@Adr(z6Ѵ8"#2mfN7tH͠).po [bHØ SylkYDp56:3(L!@F,ť t$ q]L"AN6>V^u-)$23to'mÏNOo?8潿[_~s(0I2^˭R*F}Tڹ(Vs<"/s0V]K{m/WUl; [i)rZhTU:UsfL^u$py QзQ =&)v|F&a'ye'6Н:Q#%O}ar-GgHxQeq,.Al'2C)NG.(ߤ;SgL?u uB%VP[W0E8%p^鴄?oGTVK1l*:TZ%Ĭvӑv:-Ғ87wC`/ncxC/ø$:6ڤ )jMv[5ҟ`4 _]X :!cBScc]*)J)J)J)J)J)J)J)J)J)JWi~^mU/Қڿz JVf#Of{B!Z[/S!!%#K!WU~>#11؈[i$tJnPr|sHIZqTRBޑεUvܵ b;U7`(YǣknWV7 /JćR=#0j©s y; ۄCIB"UsZvSއħvvSއħv"ꡗ7m^7m^}M)'.Ҵ?ԟ"jg}O}V?:>k B=W~1?:>k B=Wa-E$齬m;n=#*ZI II(=ɅaqYS)[[us 5';|>jkwXhC̦+mhP`vlemx4bBm*twuv#" ozTY_EBP5 Ӫ&bXTHYM%[vlAZ:[[bF[ \%j.9 eC~GBE緸^38L1VV;f +#c)̬H y *Db,D5=AkTVG^P,F뮐-u-ea )e|⭬3n!h ϨؑqEr6rkk f;-aaqj(4Vr@[6a,mIF bZKKJܸVXJAyiZTWM8g <8㋚86 4Gh1|4v"L#xm:MST6J<0T#[@KIEqW.Qީ^ 9!ҢK@ $c|AY}mfÓžXmLHB|V6>!#+vo-+6(:+;M/]Yd)QTv2c MI*wv#ch#[|pG Mlݫ OS)F{# ϻSw$a[9jÂ)|_D{# ϻSw$a[9jÂ)|_D{# ϻUAErL֖VV[{UYb?Љ ٙd3$KKiJTI! HAmP6EMP6E$>RO]3hv;R|c습>1EZD,~:OΏ{vpԋQA;&PbK]InoZZ% ŇB--_3I>Ą Xc\Lg7=t Ry/w-}*Fa-R$d5ǹue*/Ҡr ېFz䞍m+a0&QL՗ ɻAY\Jr(o M9" QzIQ)&S1!#L?ĥT.nڈFpKs |tGRK.dYtǒ[]i^x\׷16zcI~+mő!8jZʑU# G8LDnooɖK[8F [x8뮩rh*YPVJERfh<)hp.QзQIH{M J"6"2SRF/s'`K58 [qd(ΐ񋊦;5 ˍ\sKa ]I QK*$ҵXkq8J)$VڽN?ˋ<'-%?=z<>ʥcf4-0aJIYRO1dK-[l = 6#AcG\&̔^A[EB-r,uQ*۪ixTRAJ_ d-GQqHV%WD'?3u "IvjB㺄kbc`觜 `iKCD<)DqҀn׳^ʍC-je#8uܻ!IWPQvgfkvNiM+u)+mqbr^LλBal4xu PlF܋ާa|;ChNBJJl^"窡臇d5DݵHȖ4Rl$W"*Ke䒩-OIH A[[pʚq)yePJG]xB: /"2’ <~D9pF$K-3 ,r;knlam >7 $%[a{d7:_6;H-&2XiIJp )_[ 1 <.bȄ*JB`/"ݢq؋M;&PB vom~Z<]OOfŀg]WC ,hJlmV臋hU.LxOBWkwbonZ kv_F,5P8WZ%T^_Smm[+ISjHA1Ra˜Imm+*Uw㾩,@ّҢI]Ɩ"t֦ISym;u ]EBICk$2D>e}e*JE$*GP$C6±*lR JuQGӞҔ((((((((!_SU{WCP?ݵVs_4JjjcJ29X6V(ү$~VnƊ6G:+W}wMDpK&KEY7]o;㫻5N:.iAaLݪ1y(BBM^R`yQbƺl'hqvvRZZR䵝WYNltsκ68Lal6 uiP7 Qnz5aL- Bԅ%IRK ntNϻ3pw\e#:^cQ N(BiLq%,!%k $Kx.aWsH#6BY Xkap-. kU9-#&vSއħvܻk&Ozڒ.~{詪~{>y'.Ғ}M+CzdUUlI*ֲ!c~t} &eGa$c:r Y[m;n=#+bRBRob- w-|>Vkeƅ&Tiܣ*-~BWHX[&ou98v Vm X 3 s(%]J!wRmav17"aE*CC)ʒEˆ0Ȃe`dBao!+pYRMU켬?dHjNFuW(2K}z:޻o >m( {ړd_ۃτ`XTACbdqw}#5ϢᱥCAwP !:( 7#Kɱ+RlugښJd!~k oDM}o2^fShtJT%*˭Ƣhyh0Gڏ#vϺ )(9F+qM:[J))Uyq"cdsMFq3+lkq嬶NkT-@y! .6Vd)e@=+[^\H[>Dym% VlknAV m"S56xɒ(ݪ+ߐ`oHv1BY,[9U|&Ksq=}F*Uu6՛X %\0Ą:^#ϰ4}v[ 6A#+*]oٙ#†Thad:^t(HW=-kY # JUL +Clτyk1<A8sjN8kߕWQ'1nAmj!̦t= 먵V=xb9=!$,s(ߥoꊚvkzoVD#nV}NO`,Պaͺڂ!IQ$E$-\'D\:2SM@Dl{ѐӀYKNn_sed+Qk`觝 I5km6 &XBhtSI>[Œ"N!-oӝ|Q\68؄q*w#hYmؑZ)/|JHK BR Rrt}Rmc5;9ϲm.e`.Bd$ I@zwېqpsԉ@2fRD&r"͖3Qu&QK[W;kjwcr1HB#8RJCi $PS`U4븵7Œm1p./"T.-Z5H7L/@\J$)S/` y[vW3c$4fBnK2CPBX%~v66eLimD\?}noew]^FT-W)nk^F+:.(/aͦU(Ca6˥vsl4+"|pVAN?@XДpm*K,Uk alNvAY7Amn_Ҕ)J-)J)J)JWi~ד!E",ʎ峴ahUU/Қn~MaZ{ oɬ#_WTߓXGvv[k"()}Eݧݖ?ȵuJ _a-5kj(|TE۾Fl!  I?7m^7m^IK}4tgJ6wޤkU[;R|c슱uԲA6Ҳ!K C% [RR98׼Uz z 3^+So{̯Xqw qw >-2U8׼Uz z ϋo{̯N-2Ua5ޯ)5ޯ(3^+So{̯Xqw qw ׼T^+Vs]s]>-2U8׼Uz z ϋo{̯N-2Ua5ޯ)5ޯ(3^+So{̯Xqw qw ׼T^+Vs]s]>-2U8׼Uz z ϋo{̯N-2Ua5ޯ)5ޯ(3^+So{̯Xqw qw ׼T^+Vs]s]>-2U8׼Uz z ϋo{̯N-2Ua5ޯ)5ޯ(3^+So{̯Xqw qw ׼T^+Vs]s]>-2U8׼Uz z ϋo{̯N-2Ua5ޯ)5ޯ(3^+So{̯Xqw qw ׼T^+Vs]s]ځ*mIS<k[k_Sk_Plҵ8+[k_Sk_Plҵ8+[k_Sk_Pl2ͫF(/%W}M)'.Ҵ?ԟ"jg}O}Vq<>ԉS0:I ssͬ߱ 5bqmǒ˫oۥzJNr!cƕT!ITD)/AAJ2~"ț-{ eMCIq1 ZQp SWY ,齽tZťJ6|cTcc=n@t(g]%c+*$i8JZlWGG6I̢R MO5򳉞w}&$B IOh!)M)9`@@HaF#9%S#Qr`G4 5_V'&3__oש_%FY}sgD&LWcȈj]KMI ʼr:t64#j0“18}Q[ݓj!J[eƚ$7;K M`E*I$.qViGHJR R R R R R R R R R R R R R R R R R R R R R _z*j_z(>y'.Ғ}M+CzdUUlI*ֲ)f 3$D[K!E*VUZ(נz32̴xʤ,*QZs(H䔁uJdWw_?:gՅ)qةW[;:w[;:.;-yNa7:ߥ.;hwS g׽ouJ\v23|t1濝oR5/̦y[qK?K_νRR㱖t3濝;5ret?38%yۥ[ɖ7^ߚIuJ\ ^;Y>no|mR[G7[4?6+3iB)L ~/w8J`k_++OJ`ApЧB0!?wӈߣSRߣ^wԴӟF5-(#vѦ*JPG~Jy+:To?%3a^JΔʼy+*Pc'^_i{J)JC/o|ڽ5C/o|ڽ<LiI>wϦlI*ֹ5o#ADHHM u b/ncbT :M5MƣTҩAݦy{7sJ2$CGp8Y-slZ<PQH~k1u3%*C}Ck܁Rq'I̥УoEψTFߒiqBRHKz/}v U6y{7/}v.iTDhN7rmYgJ4bA[*C*qj;”I4Q6R咢%VҮv(X u6JP)J[yq.&7I6#Ethn *H*X=`PoRYB F4JhX@Z! $TRG*KAݫBM_ 3Aݥ U#$41' APl\`=2k,>oiBDP)n{h$aQLKxdnlMkJR6J:@ ГELjY}աsJ91"F$Ewh$l$RM&lFIVEkB TFG" (tTl>oj7_H^St7ޓ)BM21IAINe{VBU4=e)!I)"c4uJ/}vLǗ%Ğ.Iݣ@\>JP-+gTaUa)lrG<|>ojйs$3 RqP%ej )$^{l%oiBB.K<]m)ZFW|.y{7sJ/}v}6ܭ) JWǕpM-^svALKH'Lְ<Ƚ0yXs%Ǖ܈]d B G(uTl>oi_ (\ҩAݦy{7sJ/}v}҅C/o|ڽY_ b5')JQ4K}4tgJrnɈ)l(֓V>&> V [KdvԌVFH*R@x~E%ˊKa,JZPҒ{ܦW$7=7ޱ )R#2 U@!dZ^O܋TȆf0&Ɯum,-[o!) BUcz<\aPZK3qW8Zy4Is+Z%*էFr/oNE55dA.ۇeNMP%%_Sm̔bÆRږNœm! J\u_"ÍftKIȽUY0H0c= iKn)ltN5&([hwF&_ ɰAӥ{߮$ܹ̔X|W5mΰXXk{5ɱv`%knniITiCS'%َԗҶ͊] spTTTR@5Pf!J 6 BnD\hEN lyNB=TI[͜A)fSP]y-6VԜuJ _=͉r^ls$K}YWkoZW+'eȽU;h|gll[͸gHRA uUva Fid.CzD7!)Sq |, 茚MeQփdYԢ 76 /=ѼzXs 9gs2XHu[RK7RaIR`PTnl$HmQ }q+%*%WrH7qPF :QΏ)qļE&&Hd-k, .{]݋Iם~$fĢD|Jy,WvJ I7֯}=ѼzhaYWDx\2V5 [b .W{7º0_86e%?%Յ,+t V7_V !H2mA!ԝmkߨ/ѧ/wǦ%Kb#ZmJ2>.dTq%cbwE>mJRRdXqJ-jBHH";}܋S{}>>&:pՉ%-R <Vu )$tŤe1/bu-YjQokk`u{}>wr/oHu؋4䶚)!+\93tɮoyv\k[>EȽU[+q/n(%kRuB>ZثN9;RR¥ˢ\F1kiYVnG]ԝ܋Ps[T.pKmuEo\B9J MBڢ*db,{KJ[2ݑllr] s- )Kvwk[mOȽUHKyC!*;4q$Kye0ᐱc%%Z/dT(imʜ\)RBnɲRA)uȽUDO \䭖i)CRA6wimx7rιs_5}/}+7Ri):\nE71[Jmڳr:Gg%NN%?} cSq: S ? kϝZF*V# -ܒVUΤ$ 7뻹 ښu)q)*I -MؠdD>uYEj KN&@֌db Jx)Y-iuܻKduGCεr/o^r/oK41 nGO*6_m9SʯQ%, %NolҀHj.+K{}>wr/oA&ۏl"HS-"䛫@*Q1fTW'kJAK(9@E5vq 5+$xjNEJ'*qvbԷ_(̗OHs'f(LbE)[RGs%J]gms ;w"}TG%tEMķhq)nBBrpB_  oԥ,{'8 m3Nc{}>b+ k)*z= 3 I"[;szRT {:Vkx滇6J[@yONf+$oltV܋U^$؄̈d( Ԟ3emQ#ԑѲ\S 䄸R 9mEgUh% IYQD^OtYR{w"}UeJ^O܋PYV)kC{}>XU 5-(>V/(-pTHҨuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image062.jpg0000644000175000017500000003744111665471332026770 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;E"Q  !1U"3AQRTat2qr#SV$5BC%46Ebus%!1AaQq( ?].mYK=T@ CdŬiK}f <A o"-o}A.# e?Yڳ2 Zv&Ftd3_GckN6#ڽTQ SX [:3xx,>v8Eo榵**loyq kNٳj[z!j]jt()k Y-t7q|˗ki֟SMNirpTR[ 0ct!hp#-'( +s$5nGDc;wl)}jV$ jt\hJV z X灆h NeK/ 1&8bs$q ٻش < g*ETЗlHlٴ ऄhqmsC][ܵht5leqLYLg޹'TZ+OB溜Mʯ[m[:#^9퍄 m~OUu2QP]?nٌiL _((x_Ÿ۟/(lSO fHx{[wyѢ`f6[=s#9gEn<*UO%ӕ2Yy˜ ?ZMftѩ)2I:3p-\uQ署=fsϲOE1Xngt 4]$yۈΓFFFx;GFf#-,3?dd Tؠv3+deᒴ- \8/ymƾn?.zAh۵jL چR+a|%Œ8䃑䓝TYgdykԢ`fh(LD :GݓH۳pش]SgGR))B; Ύ"-`G?Vtw'|YԤD PN)BH|YԝSgGR>)B; Ύ"&}SgGRwOJDL Ύ+:;OI?Vtw)0#+:;&N EƻW"|:6r2Hƙv6M2v;\+}uSh{$IߝUE]t<\ԭss?oWjv׈K) CD72|Ex?_n{X[U+<i~vyt1zK =#E)WHk[< Hv$fsRq x.Mfۍ+jG}4 al/;7 KW>,1ӈߓ%`IeQmqI?Ǔ3Wu%RN"=n?g_#橯hx=ه ӂHi;|˂ad]u4]iq8!3=vmDesYkIT`M[U-+4iq~H@6:g8 P,-cP9o}\ճ19]<-txi }w%YĴ] @##g%c}&64*Z4qI3=78~nEAEOQ$>G]hihن;?kٹQîTUz:riLK˄nhlY > vmpWW%M=}-]<0.09ń#sO#NKu<Gdxoka8.6yF[oQt)xVT3naw #Y!XH9a+XkD߭җzb i{D;@ʃW46e54tb$lm1WhctAK~=E]nPOJi(uyd~sYkhި潴4ԭB}wmY@١AN #8Sd?Ymx`/ |Zݹ8@4ҺJ"kx3J|  ӌm݁ō|ә5-|1Dd>LS'#ci] 2exF<:';g_<U/*b,杬~A6q93顒WXmll/h y qŚYUR㞡0t`š+YeŹ@Cm#-p2%EX_A:/ph~v[ /m[e|tD;'H6a?)YOUQN8ix)IfF4aFᆍ󝽵55Be:2+̉B{NA4QX#Cp40vĔ־8# hq F'rko52[]IցkKHx:[twvjlDxWpss3<+I- 5cHv^p0F#v*K` v:xk OG>8%-x'"LTolS7:Qr HEp^B颷qt.t2MOL3PG c$mߐ|vxWM,>==#- `|g#j:jc`p4otC{0X TO-M@jd{ms,52iF0Z#KgNx9t!$T6Vcc -?ha߃lNW%k / h;GVMJv76L C2ccN4iF\=Ԯj k\c"&ߥ &ӥy⪦i+FAڤX~ۨ6J6CN膡3\tGEf]h,lGڊLҳGHiqHinq舠""" /5xO7zio[ВX|{*R|{*ή:($>VF4G %fyT(1W~"9 P@L@БhN1]j" ""TIcBQT"-5K|TDf1þ oP[k z?0+Y*;g.Τ_z?0&IP;g.Τ;:~IP'C;:V~JK'Ck øV~JNY*,W봞 z?0+Y*;g.Τ_z?0&IP;g.Τ;:~IP'C;:V~JK'Ck øV~JNY*,W봞 z?0+Y*;g.Τ_z?0&IP;g.Τ;:~IP'C;:V~JK'Ck øV~JNY*,W봞 z?0+Y*;g.Τ_z?0&IP;g.Τ;:~IP'C;:V~JK'Ck øV~JNY*,W봞 z?0+Y*;g.Τ_z?0&IP;g.Τ;:~IP'C;:V~JKYi{爴~Qid42(N#hkF/.xO7z%{T lçAF6oAa ?\0.W:{s**Md 2i@vYmQqXhMG6E4-nB"HLZJة'v1l:ncRE.x':^>r.x':^>ȸupMx':w"׏yé5pA܋^>׏yéT\:O8u&}H;p<ԚO8u EïDRk<ԃ}IDR\:O8u&}H;p<ԚO8u EïDRk<ԃ}IDR\:O8u&}H;p<ԚO8u EïDRk<ԃ}IDR\:O8u&}H;p<ԚO8u Woo^W|poMc#s/" ޺mp Tp RyQD@DD]OB'k`x|Xloz>o,\k;)ybYWhes{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] N[?wXvU es{-募ge] o/s'?_+s+Z ȋG|Nr=8'x?6[IL؛,I]yZ}[ק?d/" ޻m/|{*R|{*nyDP6?=LݿHDEqHfG|Sw.cK#v*豣;/.xO7z*=Gtl>=GiUWMCNʈf4ٴja2()+i.⢊\HC {N7" ""vG6?=IȈ""" """ """ """ ""TD@DDD@DDD@DDD@DDSA߈U;Vq輶->߭Ԫw^[|po -ǻ(,SZyYQӹ{ZƷi'rAWJO+ ]0dmA)kq,{vK\6 [eB44qpaƫ2 8 2c-sH p+3lc/SC"ɟjiDїJƹ 1 IN27].N/|UDΦ1B['(- 3':-΀n|zm4LIJ5sv?XIbi墅Vs#sF㱣kvn'` q]J;(KLx  ܆ϵkQN}O-Ht#8n'KNFӏguX߂2vGnE"," """ """ """ """ """ """ """ """ Gڵ#pnEio^S~7爴~hIl,>=Gtl>=Gt"( AP߂$TD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDSA߈U;Vq輶->߭Ԫw^[|po -ǻ(-ǻ(TDECc~?ADPTD@DDDAg$3FZ`,-;q\.w`v}3"zGk˯" ޽>_'Լ->߭Kaa ?Ka ?'@DDD@J(y08h44co+YOO^h 3yI}5yߗ#Cû}vz}5yߗ#Cû}vYTכw~\wˑ!Ag7S^or>;I;.GЇio7Myo;w'pBz}5yߗ#Cû}vYTכw~\wˑ!Ag7S^or>;I;.GЇio7Myo;w'pBz}5yߗ#Cû}vYTכw~\wˑ!Ag7S^or>;I;.GЇio7Myo;w'pBz}5yߗ#Cû}vYTכw~\wˑ!Ag7S^or>;I;.GЇio7Myo;w'pBz}5yߗ#Cû}vvV<猑sWsA'gRߗ#Cû}vRkZ$:爴~Km,1k)݀yZ}[]ARŶ7sǻ(9,ma# VurT]RۋhupvP?cx@66#WH{MdtT$;G™;\!ivMpc(䦅L:/kȌ,ϗo-U :;6?=Lmp>_U!`D !?)"Z~#8u%E9í5!h%E9í5!h%E9í5!h%E9í5!h?TQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:XւTQkC:Xփ{~爴~S{_ZAw|/" ޺mp Tp Qt즔DcLKù=û}vt[W.)'YKʒ6Op<`68Ѣp%a6흔Luڅv'5 0vpNñQދk RI[Lڙ[ Cs/}Ҟ cGD^ֻˍj*8]hF8SLx坍k\ǵ;K#nlڻ۠'YQ,Gۿvf0Pw"+ax)'`Ƃ F>ȧnm$T=4<I '8;}OcjbXEK}rp5qڽnR׸#܀ѝ#y%' -URGxb( 3N۽2U ӽ̊'9 IDs\C-MG/U_M%֝ ''w-5=Ԣ'~R ёf`A܋m)ED Ӗ#3tnͮF_W: M]u58h񲵘qEŮGT*G@M@l&7we۝)"kKc~A֋ETA%D8ad/>#ujSp9b37N636΃[IgS2;4cn~9uQجVE#G.nAd0 }GnF)lvi|ns0c$1xVnV&fS ╕ciciZ;ykDK$c&t?c-R+3=( nRW=5x "G1?DZ@6W7nQR4ONb浹/8J< sNآ-Z7>5@.2=ҵn0/s64vU+|TpegJF%nA,nﳃ_6Z tUpkcVHʨ9ZtFAoAoe/&_ݿSoviN&_ݿP|"e8viAo#LMӐ7 eIyZ}[ץ/5xO7z%{Uҥ{U"(8/4u5SjU/2STmMš߼*4J&7 E @n̝'a`;)_ D $45c['>O )P:L0症cgOJ&\ύ̨d.5t/HPX5xThU3wqwu,t?pNK'w~)HW+B*PS3ߠ4N8 Տ|sPVPC1ovsޖjpMqqcO8§I`cx4გƼ-Gkp]q%ii?CuZմRQ E<>Rh,pf rW$me3^xַpv%h#Dh)#-4ͧTca .Tnc,u42p9n#K hK2Iqݒ7zGo&*,+[{t~Ԡ^k|poKo" ޺hIl,>=Gtl>=Gt<" """ DZD@DDD@DDD@DDD@XeÅ=zR( `:E ' -(2o"S|-AԢ v[)'H $(-ݾ I u;I:DJ wo’t?NRNR1WKK'eken mDM%siΘ`i6.~*nsY:D}iNZDϑdsY:D}jV>EG֚ϑd$A[NZk>EG֬nsY:D}kSF[lu1癘pvyZ}[ץ/5xO7z%REEV q9ÃpW|ޯrݔE_;zGvQ;{|ޯrݔDi^)-7ܿ4we*ZoW~hwM/DJ_;zGvQ;{|ޯrݔDi^)-7ܿ4we*ZoW~hwM/DJ_;zGvQ;{|ޯrݔDi^)-7ܿ4we*ZoW~hwM/DJ_;zGvQ;{|ޯrݔDi^)-7ܿ4we*ZoW~hwM/DJ_;zGvQ;{|ޯrݔDi^)-7ܿ4we*_;zGvQi^)-7ܿ4we*ZoW~hwM/DJ_;zGvQ;{˭*Z4sKGuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image054.jpg0000644000175000017500000005037011665471332026765 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"L  !1QATU"Ra2Sqs45u#3Bb$r6%CEt+!1AaQq"( ?4SSZ$ 8/,.gPqIS:8(-6`s\2rݔX^:=1Zr fM^53N[\qm(kqx(̴٪!2d75 ' !lMU$6n3\i,excb-zGkR=Iv3a3 |St gmә{5(򾂒IN'8aݳnTYluPS=sAxa7pMCg{4vaco$`5A;~GjNz 4V.GhٷKo_VwAn;ouƜqm\V2USM,ZSn[W9gWIy;ouƜqoi: 1BcV )WSJVicg.s;ouƫ6~V'*&]H48hf>YZ\ Zzx*CD;k7yNgmtA sEp)b2{5D-|o-s[#Ymrn!s;ouƴD.eUs ͧGŒ0!4fx̍~6 \q3\j"(kknODcCnvIZ9Mk׊T:=k.ߖ?B=yNgm֟)Q\hZ٪(Th#I*Z:Zh$Q;_$oiۼ0QPGQsYYhosԽ:"a'D[{ ?E&bHByA_]m fE2V;F 7PdӇ@ZG '㰫?D[{ ?DoaN:/Oq|͋Whxs]`p%j{#wjGqFȤskrm0-:ޞ4Z:~UI|;]N]6 u"+M|J,"V=sт"a'D[{ ?E0+.m|p4aFnۛDp^q!!1*:"a+J]u+hnOcYg{D4IpQO_IvItV>~1GPV^C>l9g~uGG0΁{Kl{\sIGhoam0r:rK&||A kY9 gRw 1;vV.~\{LV+ZQT# ,=S\~"qvmZCv*D˃Z$lWGX:"a'D[{ ?E&0rv: k=խ7|CSo$pQɦЇ:"a+ %GDۤtQə..oi;4}K`ވ{:v/:"a)57>+0x|JfA/J@])kY{c5cC `ii L+D[{ ?DoaMMyEoۅ5=Ք1F|.i  "yN-0umV~~H6nBZn׋ֱHfyy$rҋ:)i 99l~NHʵEN~CX9%sc:D"cfpw$+o:]ͮ 4vcD[{ ?Doa$pU7ZJ E3Db=;vWQRw7*k|Mz"a'D[{ ?DH SV{d®*fOI`I03$׏ltEN~51SF&'prW8-pT U(r6N7ʮ3oG[-bdcD8] -tEI>w$o)-[}%3ilkV.ih)nVRWh6*o-tEWOWڪuWWW%!muRv斑 O DhL|IJtEN~T{'wyAI u,OK_Nf`f[\“iE Z2*Vş8>~[ͥb.Ե5qڹD,0K'0U[ !F3l܌mV^~J@ nWs^ M(KKø{w c[7Yb8>Ln$7D[{ ?DoaSgZpd.f ȓ#<n5Oq VV=kpGx+GD[{ ?DoaAj}ͷ ;&ІFwfbkl$,Wh :Յioam0"VZ+M==34R7;yIVqAQ]m0-}_AQ]m0-Tؚboam0W_AM}߱EtEN~+&آ"a'D[{ ?D}_AQ]m0-`J>(~0%u~}WD[{ ?Doabk>+-tEL ]}߱5~:"a&ؚboam0W_AM}߱EtEN~bk>+-tEZrK54o8 sNNݿoam0O i9xLYJPx&[>('.y ;}m0]--it*iѦ'7.p/S?#PV?#,5$8aipepZutijD< U~P[-TSSպhD:8nt۴UE=œGւ#0:}ȴ"_%|n4Yu9p-v'5x}I8;6+;͓Ʈs+ٴiߕQyL Kx\u}4J4<4ZZ@hvOB2EM| '5>&J lZ@ Ð RM'=0IY 7H;ZvmJ *zK% edB n;qs[g#P騈n_?*IFܿyZ=UG4DEݗ@װk# c?)$d1>Y\4;ᩨGrvHK' c'f Ҳl(8=$rKr5q?CX|FM=cwmUpRɤ%Ռl:#%AKg@)h73VSQU\|ءs !e8koz[~ǢAW6)%sKS:6{m5|QELҔg';CYtMֺG^m-' p4 ѣRWI;_%LU]⪢V>Mk^ۨ]I;,1S&ah!v(#%jXidD`$ßw;'YXUP: !|nxyn;>[GUt44ݭ$ EPOnh0@hVq٭M$70N7m ޖ*0H$1?-1pwPGXt1:Zkd2p䕴X%kahQH'^"(+΋2$n#:lpk*>KXad̎lѐ#3m;6[(b `ⶀ'pNPjT(k(Q3Cdp ~^NOY桎Kt.LhsV|W!+B) zo 螱[X<uO'$t- 7 ۉ(.wcv賒1PhLahFKXqމUV;]T1A3{s J5Q얂'A,xvR:.~Z`s[$x%vN?EƓ .nl=U^袒X{Y ɪonHH+6Qk[RxCL#%[dfF]m qFܿyZ=T~{h.c?)z_3[ @፠( KV:Ct19p3)VWIAUObd-}D.iC-n\sKٽjӲ U>MͤHִnu yw~갚JD:kD,yP8%tZo5 j*mC 1Xs_l9QEQM%:)YL!i9nYq[ia0s-|md.RƊwJ3#~XT˳rK,,aw~â1HrbEֳYKHewZk{d!q3D1 VoeTM pix$dĄ(ʗfKJMccB`$?L`io݃:]u+k"@apE[#⥭M[ nQPOT> |[W'5P*@\y-w:F:Q0UEF!/w;p9ƏW@}TIq)ґ46Ojsej&hv4 TEe75NuDg.].q"?BJ\]s*O2{D5Ǭ4EYzvhwdE]W^ͪ?RO9`YkK!~d7^&B\5MV6IYחh{K:gjW 6tRf)>\6+զOx3׵tn xpwY2o:;3'(NUE[S4#Hk?:;c:M23DC1܌qsC="4%YwS&v>c.@p_!TSS)Z*3 ?STgIMcwW<08;hճ氧,lAG4\֝xxo2iց0@ݹ^r;*\kተLa+@+Br_Y:d:xkT+,fFp\N}ӷK~Y~ZZ*ndn^\uz74M9 ׾Iʟ3:{6gfή-}'Y*ju@=L/ƙfCx*i׋krhD5^ݿԢ=`1- 7RxcpZ(kuQ~H91i;% u]6u2~܀dqq;7)ujjរ&>HnϞ#e}|$=Cnӷؤ;իzhI anN6eM:6[\emS*d/sj$eWU4`Y+@?^r\cedJ=mi|ix Lz|Ryv6w~ڵ\{%S5&kqF0I(㖶 C,6K0E-ٝkfCM89tO~IWTag Ex|R ۣn1o\ScQ E:F:UIqGqvg7:Nx1'pHɜr4}Iħ(^PCp7Q 18 "@InZ*|IbGXcvUwD*4H-$eaI}m3*YQ { `ޤF=eXz cֲ^pucGg9#V乘kLs w`oVa{JFTC#@d-’7KGW Kp] 9LKQ4ņg1ý,!:j)dB ]+ѴV.QPUTJVnA{ͳ6u$6]stI8U\j$C%i%ǤG8#nV5W#suTbv7$3~Fӿo/n'Hj8~{v-l6XFᖹ#R1Bk[{ܚcaGV01P\26j"4H#pnIǺF^4v1Hx>֮<p3MLe Eqv h?}D\840nޯ8N8 sGS~T%j |ri1Ќ {p- Xck3'Dhkst #d4ʅ _neÜ; Uuꦨij9 $шy;A#8$e78')sE[mUΆY⪞Jy+("r!:406]W5NM\2hvK~үNv|IΑ*JAR>!;dL E葼u#nx}fYk2e  |'8A^sL*ީ14Ulq0H04シk}8:t1bNS$ t42HR3@n̅!_t =ţnq0U'I#FKLN2xcc!34X'aK4?8GIӍs02"t,y2;‘EJU]cU]L9`K4Q!t溩t:s W[}(k>/s\I[r4K~K KrF¬HsX졒g!<o}ΥhiuL-iK(lay aiqد=}>W\ꂓ]bwigvg|m3o)BhS)2`{qڵ ]=.o| C`*ǬgMc>6ꔺLWyql:.$BzKtSS,Q5$$<43o&|ANJOOPTTt4, 'Jxc~FFϒrn[3a0Ldnu+n|A5 DMUmϖm\sHxq$;f l diE4q$i8{I~ϓI۷jXύ ͈$%d0=`wGղY5=|Hw6 si}X5 gR^uA[Gh:.yݍ 2[5:N\EoE~jp@j#{nm޴iV0٢{e)nF۱[u gU:ASSl gVIL nΎ24=JZ&YDzPZ6|A5 ݯTTZ^**CPVDy{spݷbYLhgyw4h}lf3o&|AB$KRQYW~Fͫ§%Am{\00JͬgMc>676֫ÚG-:v6kU 7XXɫN"~ AݑOXૡTӱ q{kXs͊GXύ |mdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6k騱3o&|Ahdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdc>6kdn_?*DFA;Q/Vcwe,G2}$X"+Fd [UW \ 9ԑKmC1>isI/ђN32pm-ǚ+M+}TѸpsAvgڭͦk681$rqiUrYYOzz"˫i 4ѹv$XRPiXn˾\~R8wq.V[\jkU.8 {~Bѻ_iGJclљq% kNG`~YdqhgitIdy5MM?.'<U;n>_HpkZַ#DsֵIImⱜ\r?E_0JKWpέnnPFCʚcs敤 ?#zTj XN/ɞ#oɨ4ltdݖ}$AW-:W=hkɌۢhjnU֚{"9aռ!b?O,e(FAѯyműzMAqbN=v]<6uRC=[eDFؙېF}R:2E{:.lg~iJIN{-+#`{qo'a|AR&ɂtIYPG%E5JڊWV@-h\3U[~kZұkm+ q87;#)1SGV[!}E] vK^2xGV:"Xu:0a=~?udCZցZZd>Hs}OS@؜X]++4Ԗ|d>atZX[g'j/5qIu[  8 ҮcǍ#muВ3M4gDw|WT]pc:X9?q;@нSݨiKNӵsgI/A h? v4C82?UݜN0O7iۻ'/ZkTfzN47 U%=|Uܛ̣ѦіAbOtx"'ul\O_6~ed(kz8##hٻ#/^cSiRs驭qU ә9ihFu{Ip\$&HAv@[~jFbOV*Nӥ~FF=ɍ6pxi2Vï^`3"f26笨{[a*ڗEE_Q15;gzqܣF+9Ll h8U`UH0IH܍cxh1Ƅ4c'Gi8UJje 3ZM4iku8:96^-,Q5vs\{rL-ZQBrt|aaD*&Pd|.Im &`g l2O-c}m3*aIE)'v7lRZY-}]E+j>&hN1l8v煬[k\۩sp^)pFwq մ69-'?EEhKl3;\Xƈ[c'EIAtAK:;0V &'CSkdш;8w;xMee%549SwmAU_Y5VT[`IHGIΞmW\k.2ZXў@ 2U\YI5Q/eHHA݇;hb[k7B_w6'cG_ I*ie>fF ߝ;[qRG "-X99Qڦ Jij$c $SVYCVɇf GzP[êdcce][{\r|j dXDg4t\8Rm>DKs~c`nhA?eFoV$W9 FcK~-sHٽ?*P6djsUQI5PJ&#kH.;Ճi8QZy*l416CaWnv5U} >:h]Y&N6ֱ\bH%Pq%;ƖtHfv{{ث|4TCFO%X!vϼtr{ɵ(*kfssd@Yڮͺ2`Y'> dw Np8Jy#ao03Zw%1%dQUPcU%@,'-V2ȹj驛{.1 }-NO;qwcWԛ]+ETV?H| ovO$9Y-Is H5aY(k6۝),ζ_evP,=";i$4\Z䨴T>U+iC# kXﷷKj\idX)sLZìp}ݛۄ|DAs^b'#ΎϏ~FVEK 8nZ:DD@DDD@DDD@DDD@DDD@DDD@DDD@DD쨈#j{+O Tڡ_?+ZG4DEe,G2~YEiXld v᫖aׅ a lP[a0ą쨈#j{+O Tڡ_?+ZG4DEe,G2'r=,Xӕ-8FXld upPߧ{a'9 ^#b,P׳׳BO^#^#b% ={8M{8Q$QP/V$n_?+ZG4DEe,G2:G2:jD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD騈XM#".{Z8w-h]ni$QG{EbwLOh]ni$QG{EbwLOh]ni$QG{EbwLOh]ni$QG{EbwLOh]ni$QG{EbwL[O T-he9A-\vj}b-\vj}b-\vj}b-\vj}b-\vj}bn_?*DK Q/Vcwe,G2:G2:jD@DDD@DDD@DDD@DDD@DDD@DDD@DD騈!y`,nAfjJFL涊!'p;QC6TC}R*_!6TC=e5WXXy-GQ!^FwV|2T[`I!{si]I.9 \<&١zry5JԽoR=5WF١tF=sH޳y஠dn*V,ͩ{/DԽoDp26EGP\S?ݕ?TGy?/YA+{OTg+"ZDOY#`spZj!0O 7r=qXS-/~Hq=PMQ#cspH~Zg~7}W=Uqe5&-,VN4o[%m}lJ^D攽-5vt!-iK١җCNӖmsJ^D攽-5zr/j4mNiK١;lOc ;H26F7@GܿyZ=Uz_-殔UEA%Tr[1 J5tJ5USsDM[wrTNJ5"l/gtwrT\d}%]ܕ>k=Sg戛 K*Y%]ܕ>k=W4D_IWw%OT*Y깢&-J*|zIWw%OU6AnUS:J*|zh tJ5USsDM[wrTNJ5"l/gtwrT\dֽwrTNJ5"/gtwrT\d}%]ܕ>k=Sg戛 K*Y%]ܕ>k=W4D_IWw%OT*Y깢&-J*|zIWw%OU6AnUS:J*|zh tJ5USsDM[wrTNJ5"l/gtwrT\d}%]ܕ>k=Sg戛 K*Y%]ܕ>k=W4D_IWw%OT*Y깢&-J*|zIWw%OU6AnUS:J*|zh tJ5USsDM[wrTNJ5"l/gtwrT\d}%]ܕ>k=Sg戛 K*Y%]ܕ>k=W4D_IWw%OT*Y깢&-J*|zIWw%OU6AnUS:J*|zh tJ5USsDM[wrTNJ5"l/gtwrT\d}%]ܕ>k=Sg戛 K*Y%]ܕ>k=W4D_IWw%OUh^l##u.tbhuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image004.jpg0000644000175000017500000003321211665471332026754 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;D"R  !1R"3AQUt2STad#Vq$B46r5W&7fsu,!1Aaq"2Q( ?]%qy!`(I>/ OVq:c HHkM]D%*aTF@ʐ3Ѕ׵i E\βl>?>KSGiҝFx>yT5k|di2áKXX(Q*Y;^0yȱmI$-B('mr0b\/9T4p}SRɦN!Ff;7q” jj u@nԦ.&CmEI )ݪG\sDL~NG1H銿ZqRRa[҉0/.;)dl- $x*#W*<7LRFe?Q#FCqܝnb%T\S:/0UTܴLٰa";L*mBIBAZ8L~NG1S>c؝~lT:QtM ' ra qҦX} F@)( 9:]8>i?Q:3}r&Dg%*SEe-H7kԇ)o4PG[T@>8⬩t^r8>i?Q8c-pդHn6d>뒂Vn7yWVוKXe&+oTiZ7 8V [֓[8>i?QjZOj\6MLJAGрMI^;Ę6ӎ:U9#x8qzi?Q@ WDS0p}SӑL~W]N@aE?Q#Fy ']L6\'ef WH*@iBPk4qѦ!˵MaF=.R2FdF񬏐J#T _h٠lANFuDt|0C2mS^} mPx"gm-0R(G@HA8G`5SQhJQZLd rJy^=Mk}ezg?F> QtKkZ˲6oݚһ-&M0$nJ7\2TRH$ւFZߙj|3nҵ.4fR41(Y- *-pZHʱ}S eN;1kȕ0LEdy*$Wnm$鸽  ZTh݅}%2b)S$ -[Uio!Lt8Y9Hcgitvۄa1!j-)FNyI|s!,gϓ ,6/%<wzkjld38'R7!Gv1UKziNJJִ$ICiRd u+}bbgZ;bahwX7&%3K)]R uxrI?|4H:A.Ԇ`8_mZ+JVINq5gW Zt~ʆmRښة2-:c~8feXld7&] -d)HxWPDM!h\tk1m(e.H@>k+$랄ʉY ;Ɋ1]*Ʀwdvv: aH I $tkW7o6CD'ewttѩ׽V7Bʽ9zrS' u#g>sWIdw}Y mkJP߸3Vݡ(L}*I;hy%\HVߚ2CC{5!wI5&>4 Wz,)L2sfƑ)oj-)IJ–IF$`}۪&eX`jRLvH@_Y^ARIZk].&m .h#:gFNuX-mm!r213s>"]6^f[-^ԩA>5-;\|*=K45l\kDT͸j^~!BY8O?e~ PAr#'Y댂8xzkl4HKry@ P5IV4P[ЗitU8e'>zIo֘E5ɌJ/d!d2) *BQt6&!4짋e֐Q:g;r6w$HL=)*u' 8ʆ[?T:s}!vƁ&c7x%mV@QBw¤iׄCш )%ImZO'jٲZcf;6m2ÛVDt@ 8Fi0ENxEH/O??ϳ4\e j,'3@Gߪ߀+Me#^bZZ]D}^"VQU9ٍljurmɎV菸*[%EIIH$kV;BBT%N(Aw `|g5bk?$Ƴ>ԥ*4RRROy-rt'8 >4.)Y=|tL2h{!| ˌoҝ))JF2(#;Q藗{!| 7'.%BjRr(-9fbVеi0h(xN i\r(!C8ǟ~(JRnHD~~<}.xEzυ";3q+ 0V֝mu!;Wv *`[l::_UJuUk%8:Dd*бiSËq!rZ[)д @ ;T;}ѥ;nchVԸA 7_HyLL8\Ca* q!K9l0wbn&4ul$K$';ʝ n߼upγ[u >7w[U G%%%Ja/pNswUw|+Cҝ>^ZZBZ)QxjJy5Jq@t:T6<8'esia! p̄/Y`kz7ԆfE@bK.6@B²gU[ϊɳS)Qf(_8I`k!;sd6c-9h5c%fJ*W ]{܋qR%I7`-'ѿwĩVQu jjsxGMͩ]W9˯LyL ;HH2kE}*Jzh`4nlSČy"936m@Jʃz tY&lT i0N rSoMHhn`\ʤrIm(P `:'Nv:"t\J$ r5$]%i6y!{42*gwQh]R BBu*x}Q7sP_y3R)(֡I$[pMPʜwer]JQ\xyRBVڹ1SO@8Rw1*\VEĄ~DoNAL-۳7gYҶPJc+ P\:!cQ/ 胊 =pŻITBOesNpc'ݬTBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠJ t$W;:{+ TBOesNpc'ݠZT^pc'ݧ81Г\JRcG£a^5uI89w\vBOesAݑ<zTpc'ݧ81Г\ֳO#x3`7 D0eآ4&$8(?E[Tpc'ݧ81Г\1xDhNT܈R$[ۀ7wthQR@%*Gq4 ~[Q!;Ue#g@H;1ߜIwja_{琴~5җ!ikzWUKa;R(((w)OiLϡ ʎ7t-v4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4܋HsNE] gݥ4釤h-F|bH| 6RPFR ٥TF{ƛF{ƃ+ѿѿJoioh9ҢΘ!(C^H$ T5y O'])|`OƺWl,>]^5'H\qҖe*mZT>cQ>]^5k&;R9kJx8eLƑ%06Ӆ11oE%e_tTp8oWŅkŶ=c'ᑊηF%!ZSN$77vt~#[^R R$(9Vk†YI)qJuୠ@o}+Gncﶄ1A6`Q*\K,+0P.8Ze(d7WT;j1V p3E SyT)uzy1Qx)+To?ϳh$="CHqEnASktR7a#'q͏el9=-N47ZY*%Y /+TDְdRJTb %de)³*A* |Q߁䥔ӏLsˊ"FSnXRrM3|oԈ7TNI@ =KA|;Hb’Ҝ*J_B5UdE 0U[˒mpTr){#_EO۶ԍ֕˔7Ӕ7ur >t >ti\C}!9C}!ZW.PH{NPH{A֕˔7Ӕ7ur >t >tZW.PH{NPH{A֕˔7Ӕ7}ɫj}$k >u -)J Fn٘1gkM? /.U\8;W[\UVږ)oJHRF nOK55ɐAUB_nʈꎄAK*l4@I@G o;o5N-or"Ԅ8S{ V|Rr8W:Sr\d˄EkV FRe@)Vx)aL&aZ6z@w}nCPCK6+99'}Uo B%$9 V'( wYY>.n95W2'.zQ2N\H:&ДB JPFAI=jp>'6LՕT}6s s:5mPyZ}?K琴~5ҽaau{?q)JT R R R Tn:#:[[k\[G*G1xb;R~~Pja FJ=.:$F(uqRzA *ǘo9RjWc;;CK\ySo,vF6y,$# b2qxw^7؇z;R׍!ާ1xbXJw^7؇zw}wc+1xbs׍!ޥԮ).`Bv.lF Д(ZT\q5L9ȑmںp?DWx1yУ󍴔QR$Q5!T{BNHJf4y*Zp8!{}!ǀO$RJ5Vr5% 6NXJ7G5VބvP=*bX[!%j 6g~xݾ.l,ȔXCͧUD*AJ9Q;voz:3 B[I))N10WF`4a@4F8 p jԥ( ]~gۺ7ܙrS*rڡ$j$+i_>urbrˁ̄tD2XIWzu{?qŻP[G)X\ok15[1cU))8f'AywHrkvŐZ?XJ8'  Lſ@\TR74Dtk):):°ŘÅM<+ȯs 8Y u _J?MaOm;R F:[D,'g< # 8, h\[\Z֐CRNܥerEjh뫤z鮮몫G ATgb\m enζ6*W $?inQ{~ ~MW[5 kz('V3ee/gW;OkGq "C v'_e1c}%Aqkoz ' rOVbsNPJ3~y4FҵA.:@'p.jDa|E֟QY!P|kz鮮RuR|dWErOΨz-,( R@뫤z:G KVp`:$)4w%[퐵%RQc#*@ >}”KyfYm'gue ֵQ&.-%+DFij$RQ#*7 #EJ=݄$-$#[Wje# !>.s DDz3z鮮믑 $+%Y$}g8~VTk|`OƺR->tD2[dIa*Vڮ%:!V\W;C:av[~s7/άYW;C:r\ ʔW;C:r\ ʔ/˹Ís3]%9۷#LCYVņ*۶2B@>MZҔ?\ ~s7*U9R>u~s7*PV\ ~s7*PV\ ~s7*PUELB\JS~3VIROƫ^6˥t}s#ɔ}6 #R(5(eKu N{G;C֦n{G;CӞQ[Q-s1jiA-s19Ku ZPc[oH.Uh:&a0Zq#rVNrTɒBorN(8o9 _s+9}ԮvueJ _s+9}ԮvueJ _s+9}ԮvueJ _s+9}ԮvueJ YJTfk[)nKn)e)A!ik/B JC)H( kBm)L-''ׄrQ]RB=Ewi,oܿTWv@xK/ݧrQ]R,oܿTWv=EwiJTrQ]xK/ݥ)P=Ewi,oܿTWv@xK/ݧrQ]R,oܿTWv=EwiJTrQ]xK/ݥ)P=Ewi,oܿTWv@xK/ݧrQ]R,oܿTWv=EwiJTrQ]xK/ݥ)P=Ewi,oܿTWv@xK/ݧrQ]R,oܿTWv=EwiJTrQ]xK/ݥ)P=Ewi,oܿTWv@xK/ݧrQ]R,oܿTWv=EwiJT ˭돰d4s)JUGuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cde/image052.jpg0000644000175000017500000015256611665471332026775 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;r"X !1AQ"RSa25TUVq#3Bbs64rt$%CeDcdEuƒ*!1AaQq"B( ?ץ)ReJP$)95?~J.&0.P: /BUV]=u7_ljVS&N@iN#eԯw!׫IG8j.*ʒRu%x'4:;>etv|;+;Aq nHRqUvS$F%mi [IQFtz;>etv|;b) E NIN*goooJX.8}GN9RpLGFķ٤0#ǹ(^))D^U2UץHw[x4(' XVbdsetv|;LeCNH(ԣgoRc)HuRӯx␒NqÇN6wQ({F&jc,u+aSLjZgH[)iZHCXCkai!mV pV;!%E. @)驷|ySu1ѡB<1D+L6g%=[6X$q[tڤ!()IzlタHV@+<5#F=S&cva( **I@uEU>=LQ cG_]niˇN*ftҭgr1Q%>qPe%O[He˪1qOFԠrjfm!IH0s[e[e\hJ:R{>/Ep3aQޖWW4ՉfMeF֐FB JIyq}o2!"WYxpH:K n (`Gf4a" P ҜrӁPbg]v$feJy4$ A*^)b׫UQ$ԆlVߚֹjup\qGJxWB1$džQ> B.-)Tr!Uðg]s6|CӏLy.iP$%9(X@d}_\h}h~ jեjO?M$dQsȁ2⻦뢖[^9*OUMErͽ%;NJt_qL!@džBx|+gxF V{HulaG\NƈB*t4j'ȯ`KnBapTL%NU9O ܢ)! ń7@O4JJtpSٍ<Q.|E $6 >.4'|7{她syȎkm %- ph4z$cO]r͕ [̌ <}Il\֤d-mIVVeOIR6zc1E!Zl|B+v;VzxY3G LINщ3GBԧT델l$`'8=dRRp\-$ m?|d%` eZR2Nh4ݮβZqH kpH<2yv,6[-0HƏꮓjZaU>>/FlZSdJ!)@)0:Q^ tĬ1ᅞj 9>W]} mChŽqq_QChŽqq_W} :E~Q^;(w7PyE{>n7+|oWAChŽqq_W} :E~Q^;(w7PyE{>n7+|oWAChŽqq_W} :E~Q^;(w7PyE{>n7+|oWAChŽqq_W} :E~Q^;(w7PyE{>n7+|oWAChŽqq_JCh©]II="Z=^oJ6oU˳F}J)Yom1S/\#|$GĶgPJ+A5hȐ@[RY$jL{;Ɯ=tE\qO0+S4M*+i_RH _{Ayhݚ--$xsJ+nϸ)!z҂Ug׷"kpn\}XK$gi.l]JPH84%+Q)$ Y'i-1`q#[>8“.qZ%JL^Z*m @î.VFu4!pgG~-iҚTaOn+sJiHYB #1i)0r }UGaDť MhIK9TŶ'Dvl( T;M"۱}Le*KA(GdSE5Zg$qՐ6TVɵR.2S*,\tA#$֢ /)TTP RZˌ+z {|Ker[} 8*mYҝJwYy{eOd+#ῢM.6ebKB!y@g:Tߕʿ*8KEZr8|T2DŽŸi<ֳ=u+l#H3ϝ!]'66utyz2I4oi.,e*I"L˅òE䶝Je'Hq}u7=:-8PϧfDHo1\vryLx%9r>]Uf6XHtI*Q8) f,3]pXC̖8Բ. ۔cBڛ 8~Ni\d5@%%'#^̹ `~Itb/]^5244/֦?#Ng}o8ڲ3SېkAVU?+9K#iu)_|!gFb&8]7tN[^6;qV+wV8Pq(I `p[by7KZ.[bRNp=} -xHp|͟!/!:q`u2նZ#DUCR >YzOjCZad6VI1M!jTOS3RRƨ aJNG ՜,_8Mtei )!"$]3<1*oJ!Hq?gJ6SzQ_ zhK)* UWg;6fsCq\YZZyey {-$̅qB񂒧\kR\sþPcn4~$cӑBZ=Xyז]rZ ILxLP΅j DVΊ5Y*w 7)E'NU؂oMJ\sYe# 4tt0H%[ЖF8 #ƭ?1@;=MK֎|1桷l,In)kilIVZ (3,lTtl})Pipo_K0tFҥp*4ڊ ܍r:,ƞ G 9jVNGA=6zrgKXM(Y=z rp=F)CL {$ HZX@U6|nM2 )Gslۮ& !TX'E#F̨^ٺ6MIN0:*6[y3\.o4i(?5 #Zn7fR5ERq(jEf̕9N2P O`OU;ұD=\[Yb<(֕$2*{ƻĭw;WқKZSio=nٹ QCp%ljR 9e&qˏ e֥yJ99 EPQEEPQEEPQEEPQEEP-QAR8KJ+mEKdsB!RuB.!L(Y':xVLDq33j@شD\zZ[pZQPB;Ɵ))Z C\Z(-<#8Ey+a z5+%ZJHgW*Nw:n)#81~BbS::Ii(OOQFZ=^oJ6oSz((((((((((((((((((((((((((((((()F|Z}~oJ6P7h{(ٿGM),zT9XAP^ lڋEQJp'QMi[/!.6RdT6K}:m+QR9$M_g[lZOܴ4ʔ@êUA{Itm6q@V}>jvu`ʃ%ќq:E*R{6Ѳ>yIVx0'6fًFw7d$uBr%q# XxJ^ns ަ"{r]CHPl6}&^K}PfCR\ 4ڵ;9zEKDDGw66gfo4S[$[Yk!Ɉ[mm.xÈQB#*'`.EloYڎ!D30t]?{" 2HۆJ988V3]i͜qT2h< lE!@g\;lvvDܔw2Al#E2 ژ"7cVx8rK&eYqɵC%Jm’RQ'$Gw߿VLb[K;N-ZRutW zi$/SQ]ã-*[m6-ii9>H_9˝ PKmljQ&Ge8Jm\K !Y_Mb86'qҰJNIo6rI9MҞBeme%@z_ףcN1k,%AKJ6d6a~Hb:C酼urzH滯<5]7nR!m)\  zlvܶz| :Rּ+ZMl{((( (( (( (( (( (( (( (( (( (Ii(OO@lţf-u7Wxx)H:˜k=\Rgv暵H6)R\v++u&:I#VAȥ1lw$n9/(Tϊ1,-sWF}&oiXq:m)QJ8x H[k'ꚉȓ?'+*kI݂qg'vi?*SrRكG~ O 4x3hoڹ@@[T ψX ԭJ.Zw3)C$FUm5v}4CڸSJe4/t8uKn;Ipj%7s )%qO>UQOv}5}UY[q @Q_bItb:HX NJ ^7gc\폐h ;;EX|v=©VeD܌URG*ʶC٬;QtX̊qG=#f3qb.So:tI*ݷĔ 'HR>j>+ށ{wV&Z◃&h qVURcD$%˨!սH8 Q#XPN{wA|]靲Q~"ie;  $(zA"7U"-X[N*Io?;{Я?;#-0؉T)h 2[Y iG]ysm.kq{2syP4Ww?`+?mZI}ו!''+)Ƨ\噉2i 2 άc99<;YDzD$p:.Է\W$ ۊVT8GrO؊v 扡؅oVc:3]g Hea:7pxpHw.9'E{n8'3:cr[ /a#Jp':߶֫ R6C\Gb/i:!IM:@'%DϮ-q+7%N622ARxsʠybM`1IWToނ)([GVǕؖqR q$zALX*"S :(RRۋsVqdr9sp>Dmmq)a:OeW_)g{7ZBuJ*V@EYAgJmSLlр 9է oW?((^ԝn?zW d!)B˒Gaɉ)n^ ԏFUk42ٯwom{gM RJRIXYIǍ~60~[ (#"-t6٤ ڲ: + F ^ Ln3졡i!cTA冀ZF8S5>;oK6]]r[pBHINHLdKmKBˤ Zr˗[8-.ždթ[ )@QǍI;lnEaSC;ɑemq#%IV3^SB]Tc!.%d'P#_5c=ush,U>_zbPZKJBJ I!~9jfKl[/"dՔ%)ɨ$Ѯ#E𒵸0-xpy&3)-{7z[=:MPky)[ה($i)N|QR wSaL_R!° ~yT-Nј.eJANYR5zvxY+u9VEHq4av+÷EC.gLêiI_iIXf8S fad6[B CQǏZZ*mK$-L[$rL+.:*P8lw,+6(AqRq<lڊSam7]zBn1s}3pcIN4r >fD "-o>JCM;)zgpO*L.7,0'G"mE({T[L!e#)1O͂m'ŧi>->u@lţf-u7" \f>ƷJiW0FpAً4%jb+ [Y'#D8UiJZu'Ȫߙ:;A`Y"8+먙Li0Ґ V3k?'Gyh&aOQC+Z8z Aw#KN W>?'Gyi`BEӍnT Ԭs&V9/4VNt;Hs4~g?\݆1:+e6eѥh=bɳwu3 5V{:\g?:;PEgKu7[ שũE8Q$x+l <ȀSQ9I9N3twƏݢV[SIJj1NR4?twƏ|mE&.Khq`̎5RKͶ2۪Yp|l$Pi(32%6(A q$ sZ2rڴPփI(44Rb`Z-4P*J59fRe;.!6Z%G*/*֨!VZ<|?u]Shy~C!#O9!JćTy!xR} _ 0Ett֯Qn{_R*;֏wO,\~h=t*;֏wO,Gp#Qm8&н oRc Te<:=7%åNQ'#v0dJjml.KkЬ's`Kw[NJѱT{H]0?ֵhÙ~ٳ4}l[BW;9֖Gϝ_Q*vYnPǕ3{V+˷\^ 1":IQgI%ȾĐҦYzBA ^H֗_G/υ_H',KۑyrD8-IL5j 8BH OfЙPPRk5O!V@c+ĖaTۉ)Zz70ޯQe6PBP]"j',sv<9+PmD85ݟ_ϝ_Q.v߱%˚ԍQ2FBv-2T8\`vEcWL'!#V3ǎ)Jƍ, AA$}UCVRJJx' X2\_en0 V!8utخIqsmG:F%m8Ql[9e u:д%$gUX[PoK`X@8aj\ %CmVIѫ98ZDgbYR5>y\JsIn' vΨ^l̒-*Oe.+P8hd(rpş_'8rG!BH@$qqFIѩT괤쑐?kSYy}VAJ6SzQ_ٿGMFZ=^oAWR)3ppbc8yV8Zg+Xͦs t2([X֕dd窂LsXzrFB8$K-{p8 h_Fy j (_Fy h$ޏ!~/٠ JAiCBi_A%y hޏ!~T{/٣z<4QQGfIEGB7_A%y hޏ!~T{/٣z<4UIP<-(h_5y h$ޏ!~/٠{}/ٮt|頞z<4oGfJ*=ѽB *7D}^7_\<-}\頞z<4oGfJ*=ѽB (_Fy h$ޏ!~/٠'{]fz/V;kӛ܄:V:@>14?Yػ({[ػ*<#r-th7/Ozobob7/Oz>℄e.iH'K.GL.ADŽn_EmxFZ]ͬ]tͬ]2s wdn.$@[]wkG=w6˱w?Q6˱w?PqkG=}}}3k<s3k<s p;Kʅ[u QO+Dse]z2W(J]nk*F$% R3%O2@*VxRUlqJ^!VqWo;qlym*qDFTG[[Gmm<Ԥ+lzy *e ♯MTXa!C'P^ mU.ܩ[Z+BPx)i8Od>[i!k FG {UfDu! Vyz)<}-c"C-[F)Y*HNJwݏd[nV н@yqò"' mbqrs$g끷V~%).\yHVK40؍#%*RTA`i3Lʺm`OTlJY#Ɓu">,AG<yTlL9om.4r(q) iuf'/||+Ae֤֐GQE\_|ɮ{X-)iz_[%.HNI49N?Kl2"|6Q0up>lt$nW_m SdBMi۝1mx΄㊑R5+04烛KjuM%D8 i)c66cߵ.ZY .& s g=d8L|>Oj+//ϳZ)F|Z}~oJ6P7h{(ٿGM ?#J8z ^RT{F,PIEGkoT{F,PIEGkoT{F,PU ɒiJR)D8]e4im _,)6+iD00M%c*Hm)Jj2BH)#4nC ө JX5moː*amhIR;8umFl ],QkT{F,P-,QkQQA%,QkUIPJ30~?&v{oݓVɦ>J?&Ky!*|mjv͔v6(!1GTiҏɦ>J&z! .$tQ CV=zL@F)#mZ&Ky!(c-9qxCӀpmD"-j*x_cIf,8'S-X6 v,Ǝzچɵ f2@BT N'Q.<+TJiU!`?jnVHGi}rZ{F`7FZ{9| ʸ To-{yiQ+<ѼGp;#O}yiQ+<ѼGp;#O}yiQ+<ѼGp;#O}yi7*+Q]姾F`7FZ{=n=Z{뇖'M^o姾<{(Z{#O}x :Z{뇖“頓Q+<ѼGp;#O}yiQ+<ѼGp;#O}yi'wEd(q-⒐Z J֦Ry^K{ŠFSI<=2MU*Ыєj_Uj ًG̢: [u-KiYFSI<=2MRy;LsMIj쥶Nsc^ݹ_.,t%[ J`E/_Txze?ĚEL=wr5 Dlu+r9嵌WF1KJ =V$8Qf=2MQєjisJm$g@P ȫHєj_UjPh>b nZJu@V;?5 Q_ҍZ=^oJ6oSz WdsMG\.ҽn'7_jK.JYS RIpF9U-iOc5n}m”p?Q8[]-S޶4ْ%ԫrJ8*=r&K-VRJ1G9 ϶!j-5 [9.HaH@83ˇ){Tď6#[lT@Y9nOZQzBR#ˏ djcM4vGJAi`sFn'hVJ}[y v!='1MԽ C*AʳǙ<2$Lr a)Oj+?f>B*RtJ}?-(OOMF|Z}~f-u77h{e*+*m^m=WTnZirכOuwE{ܵ]@iӻ-H %J="G+VjcܯGYߥ%΅c"O,~]t9>^O@JQ#=hV1$َTJ+{jYenD-y\GIo-]^PBm=gԘ!fA*%\sÏBl.{V䂓A%8 uTk>PrV 3d+ vqCee> S<{ڟd4UAp 2IgbѬ%"ZDq'K#xSr B;"^sLx €PӎƝ˚&}ɏJ&A*Px PLp/3"fI`KQ% HKa)@$Xr\[d).-daJJxsc3҉b3!oK*0Ǐ>CWy,[OJ˞74EImn%'rHRqˎyv׻?o규%)+/ҒusHZ- :DX21F="G+TRs(z}4+ycmuE*qХIF_|O 'TT앀d{jo}vn-2kփh,oZ*Sbತ J9?Mzs*nrJd3 ϳhCmސV<*T:-ʹZ&(Е:RrT8;M*LeB3_8Rzj N_F+}>C%[@֥.84 R<}j#~{+WWn{hЬcIez=>r+?DWvWWe~>PB'?LvԱХ>A *X (@Hez=>}tX*3ڬJ?D#{55ZR`U{Эq 닽QPCm6IuЪ_ؐ̊¤9 e' q8 ϧd*[jmzҝI-*$*9+)\ AO1--%HCdNG5-ZmG`:. ?]Lj1PcX KBh=bC2 0ll6; sg+|QS{ݭuY- Wg>-7Bp]aT2$8fPIRT Oe2IWgvTv$[)ly$yFA\ؐܘX+8[IRt9㮒Lntv6i **VXǣ5ciֻr'7 Hl>O01xxGWϥqӮe7jPišiTs Ieֻ4ȑm>kJ-+JH31![灓R;JY@<8X#.nױz~1-F;(9[WD}^mLX, W.3k!H.la oT ,ոpWz+4ݎx,[X%rINC)JpnU"Va!!VD`P#qF֦DT'Xy톷]I.SZ:7}?GGDVEhI CHU><ț%ex괤`f1> ߾W^om/EIRޕf7q㫘SOLJGFd[8 V?)5z򙟣WZXgŠ?mys^A7i,V?)5z򙟣WZ j6y@~:zvgqc~򙟣WZ?)5z?|?nzBhOABmK8}Lѫ?[ Pus^ Ao uc򙟣WZ?)5z+0o;:Bq^T ))5z򙟣WZX\/˖Xq1hrBp/H-c'R[KE<ZTHe>)F|Z}~oJ6P7h{(ٿGM+8?W#RQدh~^SGGbFIE{v+5;Bӷ5Ze,*ԄSRP/jd ;l F@ZET[MC?JF>SnQدh!S.[ٖ R]Ca`G\-܅.LÎ0ܐ#@R 5q69*9FoTYܐI g<խO{~״hܣRQPGG{F?k5%Q^ѣrIE7(hԔP@H (Fܣ^ѡЪr{F;(WkZ@FFy==F w9mQΡT4YRQ3\Z1Ć$}#V< j!%ۮaۂ˭KҤ3xi$dK'hى5S-Vq)RXuUVaw өPIԑ}bJBR(J@~2)޵(Fym8~XI6MJsS$+]YH- GZuӨ5 4HW2g Ń a)Q#Gb$nQدh׻v+5ۈeZDužQFG{F#^ѯJfRDH>Vp0q6}ȭ0:Qlp鵦JTKM mHb: [VkBTX].yXy3q )x :j;}mr_rpQҭ81֫4Nv+5%^:}%{l?E:^( 5ZmͲ)"b2g8ÅKqxП 1O! ڴ`}uUR&ƁhBGM*ԂO5+ÃPSRRZ1gcdC# R UA SjGe\ Hhilux!*Æ){ѳy9ю|zb5&*(_/ϳZ֢ Q_ҍZ=^oJ6oSz 'T r8.ykp~0G={4nhԔPGZ\[Sn- )%GTPSjXaCQYBxϣ5%yk5%hѺZRQAҎ]hURPGZFykIE{4nhԔPGZFykIE{4nhԔPGZFykIE{4nhԔP@@4~W{4?ThѺZRQAykp@#/oMOQ?-~ѣt z)k*m'ŧi>->uWҍzނ FҝZ#@'#v3Ti[zw-\oDr$hjWp qNqH ^+52$Ȅ?To2"5UIFO ȥ :c]tƻe}+Β|8{Cޘl?1_f 礟8{'=LkWٟŽl?sO{'=LkWٟŽl?sO{'=.[jA 5+\:I󇾔:v3QgzI󇾎|c]tƻe}+|8{Cl?1_f 礟8{'P5+GLkWٟ¹?GIP5+GLkWٟª|YNu,U#v*VP5+GLkWٟ¹G:Q󇾔mH t]tƻe}+|8{Cl?1_f 8{ޒ|zc]嶤<6^}$Jƻe}(v3W=$GI>Yc]tƻe}+|GI>Yc]嶤:OQO{'=LkWٟŽl?sO=t}(ug5+\}$J7% ezm Zu)H$$TԯUd*DeI 2?6 9PdlChMz%l’ߌTOگ{Xvڇ^`w(ZPzJSsv:B%N(vҋ3U4klz&E(<{c+9~aCnK3V{sN>ƣS,)>u+29)f Ay^eGӁ!JHsVۿeڢGNKj@ppqVqudJ.W+RcyM> x’#~ ZVxgQ|Ieĵ&#.in#>/z ȘZv0)PFϤSg얉;(nV⨜ϬՕEMSlIBԝII\qeo(RR[F9u+-"UME<'33rηB}usl~4 QG-h@_g}'FTBNIP?5 Q_ҍZ=^oJ6oSb@'=ijlG\:P]k;qk9amڊT=5^kݫ\ HH}aIaR4P' ˃)PN$Ȁ/pwgS܌ׄ&|5n >|w<$ϟƴC=_!OqLׄ&|5n {f$ϟƏ 3q./pwgS3^gώG֗wgQ3) 3qLkK3( ׄø&<5n {f$ǞƏq./pwgSS5<4xE>;iwq|{C=žS&!YQx's>;hJ HyVwgQ3))|w<"ǟƴC=_!OpxI<;cZ]_!F/pkLyh>|w 7q|{=5&|4xI>;iwq|{C=ž>|w<$ϟƴC=_!OqLׄ&|5n {f$ϟƏ 3q./pwgS3^gώG֗wgQ3) 3qܙq./pwgS)[d6RyKNO0qƺ:ӖۉRx'[Dl 7Q<=³j^Z^=E,YBI> |m8L3'8VwgQ3*NJRzkvJqXlazsVRY@҂@wYRd~Gl'yix-= #g wݓQ?0[œo姾<'ٟ-vOGvn qG7@;f~`}?3)Z{#O}d~Gl'yix-= #g wݓQ?0[œo姾 S*x-=o姾Q_9i>->uW+JoSzAg]t{Q]ЌHx)N:k-JHZJR!)>b,+mkdٙ.I H*[F|eݯbysCxI-7"BW$N3<)dwYW}a6CYL(NSJ\Y'7]V[=)oHT?uYW}wҍɴ\ԥ ie!CGkӿ+l"\f<7SI'˫9#3D/Ag]t{HmͲ1g61[aG!hi%aތRۅ xRƏخ: =_=Lt-*8ӋKnN_.UoZa.JKqR?rA,+b<Ä.nc +c7MVΩZB9Ck*DrCaWe^خ: =9YW}wՊ(+{GAg]b wYW}XAg]t{V(YW}wՊ(+{GAg]b wYW}XAg]t{V(YW}wՊ(+{GAg]b wYW}XAg]t{V(YW}wՊ(+{GAg]b wYW}XAg]t{V(YW}wՊ(+{GAg]b wYW}XAg]t{V(YW}wՊ(+{GAg]b wYW}X 6V|Z}~oJ6P7h{(ٿGM9Z)*RH#[pmxeED'MVZVҡ_m*מRɫ`w -#o7AĨy*"swҤ']Uӌ:} 5<2IVx4ng"}-blgr%]N!ܧ4 }y55vsq7H.%䈛י"a>{9zY3G\E*4p_{Z e!)o}V18ϢS?k[\ʖtgv_آ*({vf$eҖ1H΄J2C%)\UZð)-ԲKTR~'d fq/M;|tyZg8Nl{3t܃i0Gs g ҉_b5g7\ýmCʘ+1#8 I#W.n·˻Q-QoR~RA |٦T45.Oh\_44x2w}|;w@ʊ[ٿ; ~v{ h>tw (_n/7}A~e|+ޅ+=AvФ+އ'=Ar$|dWG˜E*E" TUn"_ pU('ܻw rA5>7NywPKEG_=h_=Q\hW5yf+(׸=E(OOMF|Z}~f-u77h{=l6dWbTWy!':OL,MKDyuq:E٨-R|1kp'HP3îfd) %At 5QWݨ[-!E-4%XihQh19QV!IJRzJ|e l4{Y /x *F)A 珪L"E1Ȇ#[$1PQ0I7CC HZKn+h+ cU{O,%}D!$=|>SqTRƮ=c8߳(qjWe>dsNˬF Ci!2.~pu)9Áڧ23d2f8 wwdֵ:gCr\zZHfc\NZbo4kVrsW2O:(HEތ KF訤IxvKn1nK̑!Ǜ[n8末RM@0f6ް:]R1FA39R*-\~$vT#5ZB퐶[XEZB< :FH<{iR_TZӇ܃ȌglY-PKm8e*ԕ`[#Sl:Xq__tmT(PֻK-c%W,`T.lRP22SV\)@`| k.sԠbHOY{ΘBH`_-!Hq VO!mй6`ڗ&RZ7MHAHҝ_#W]ni!Z RJHXXWAUR^Mř,%T $:qò/uq-C,dxF%C ] [߸Ciz|k W *:q-H:U :s4ā5r[RTvt0R<'A TCIX 9x`d•oaU(1DmLIn.S %!9QI8WapH9Q`ڞR v"pxʮ(ݯg$~sG>|3Vn2a* HC9O9H$'Pe)}2OE+BA@s8՞xeIuiJce VQⴳvyJka:\KRTZ#I#JوY=(VAΩڶMM&=! .E%;q]dMfubUK/9,4JZAČQۖNѦ]Ȋ2!r.8ڑ[ PP@2RL٦drc2ߋ-Na$ℐ uTq16yx':WitNrL}m)aZu#jJU*C0(sR,ȳ jK4nidή.C*()F|Z}~oJ6P7h{(ٿGMpDTbNQ܎GY#R8w9eB5Ҩu(RKXRQ`g+G,Z]8:ώAIQю9l-QJ0804𩴯bpwK}.s2 -̩B2T21@O]vm2wB$[JRULn"ƹRc628|l$eC7gbh+ka"(A$+q$Zww{);eĶ 8\OD]@ c$T\%B1品XZ(*M }))RJ=tENtjdoZPH+ZbR8}UպIWQJ `ZQ+1@>S-OӉ^+I9( (kEٻZ=)ˉNO,=(((Hy ĥ3$V9⤠(W-߭IHSe'YfAkz4cVE9QUm..0t4t(;@=GחK;4Μ: Bq4s+˪k|9Պ((m'ŧi>->uWҍzށљrmC/|Qǎ:YI.3k_I6* u⑑D.0mI6Vx鞹"Ha.^Rd.k]nۮv˨K%qP]ޯC2m * s@J H'ꤻ{s]j!Fӥh[<Y'J{H\I~ZDqC+|h)X݀yE"D[m ź$N )o' 08+lX+im uHm$q.~6A.u&tHa&TX 9WHwM.jd ؼRP6BWH0xh^v2Uri4@ uU؆V1jеv^.kmr :2zxHb ͺ-7+MA}i.7Ny4`ЖԅG9t9pR0[2p Q zPHe-ZR@$޼Utcqߋlcq.C̼hV(RsOGwC)HӍa9݀ys-1 ƖTB՞XNrkgCPĶS'8P{9zlKiGkDX[ aY^U9Wz]-?=O:у*ݏ 8uiO&sÍ eLX8™{lo]mc|*Ӿ} R%vZi_`ʗ~vdϖLAtK(ijSk8s#mCnÛ>l9#S) ƴv),5yy) *$ilK[X,(FԀOY<ժKENP%^)SNg~e2b:92Zԧ:2+Z4rUĀ593#Bc*KQV\9r2u񖐧R<}T_>an3>s0NyZ Ѽ.{}uMIUAq[l^;S 9Ӝ,^?߶`߸B0\sMEveHyKZң<6ۯ-KJ dj: 8쯣9vvHZHJAx:Ne"iȲ-$ i|*ҝdEy["ʸK눤t˰v⾋E[ɵ>pr qT*Rǎix =UasdΘ tjQN@8 W+BACJy DCYó$Li+xc#].WQMFwC+Q A)_Ke5ۻl(,eeZk*#O dG/i# ֋8hWث%[<{-)3%^`8Vq#֬4nDc";% eddg6xuae%eO=H`GVgkY?NFO?)3c<{vuE.{s~S)RscwI딅onqĺDJ= ] S֜[?$`-)Pq6f\ukW8IƮlϻm#Wm-E8+%#`( {O 7~IH9f"lʻښAKZHI=<8_tɊ#"αmyԅ)dQ_#ƶ?$`}'vJ.֙lJ*Sk%I!ͤÏ>کpO}m֬,]|i݃ sH:֗}'omS%D|+Чza'&.qJM2Ns˫I'?$`MW ɻ\c-y)^{jKJ˼m)H' -0QO 7Rٳ6vZ-2aUc'e P/hNVpRr V}'o͚T4v2R#NdH ;oi EYR c<|\}'oxIŵ"ܻVฺ0@Z@1¹MRf C(cTҕ$zxDžk~IFO?*mC/lه--.3A.pVķC!%MF@[ϯYI'?$`{bO 7~IPX0PX0PX0PX0PX0PX0PX0PX0PXmwd@O@QEQ@QEQ@Rޔm'ŧ6oSzQW@~0GvnOz3ZliWT/.% @XI(2E$V\wKrDg qR}*rѭHKZIqZV#:܅)#Ӏ =WzvsD:RJJ94չX(m8KφiA>1NJA>䛊matyAKKKҌ$(`g Dq_h6)-@p\9geZݣL$%efZ\0rqch*ciMJÌSmJ*֤9O<Z$JN8x5BV|b'SKo|㎽KQI QYQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQA]_#J9>(SR8jWR]ٕAVԤݭ9+{Qԫ_]Tu! ,p;Zڏ?pwkOS}(ܡ9[[Vp:UԷUm4ZHZkOFUq\҅.Wl9ҠI8XԂjVkOYy}T(OOMF|Z}~f-u77h{~^]IG^3uJ`++_g렖f3ہRTR[S]m8ԴAHHV)ƍvȯ:-!Dʓ$g*hNCii8̅; یsϽ?ha/4I8V9RFTBR_Ce*)}T:QHry¶F<`u׃eo0,Jî!T@*#N :p cØ!ۑQ`u]6f8^uय़JuBJp)K B Y$ ZsfKa;$K,8>7?EkdxZ!2AtiH*n,q(1Z)GTOƹJ !kJT9' M/OEL$% i\1!ܕT‹Kp Jz* ,pe]S9oxD" ;{8KykZ慹.;гj rOV}5ZgmЈizlbl_!R4-.:(`QmWn*ZF(-Q@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQ@QEQA]_#JUܫ20G$9.6RzPUu +W>--nε #<UN?zWA$(=YWҀIiЀ4%dY osx'e~m5SJQ'K9=}tn!XUG?Gv[=,I0;Gj+9kwFeCr .+NF *=U Q_ҍZ=^oJ6oSzҽ⺕3Wr~0GԜg1㪂Z(/0~T9w:b#MP'@+h!\Sl_)49mx7:ĝSz%8fߕ=ARXy/W$I=B2w[ɲ"ڧc.F;i^)9|g!M+ 8[b\VSǒsOYO|lKnD$%Ĕ\6JẂfDT$J%՝JY*GWmb8Ft-c"k ڷ 8{N:Vsj2.s .Rߊ 3iW=oM+w8ILA11NsCWK{38|Kxxz^jZ &-7:t˰Տd[r3::Yu9AQZ틄TT)Ki=Yro d#Is\]>X tȷ:iKR VٛX몭;J($`c9/0#.S[BmSͶP x}\iGz5mnzeK/<5EZ՗-Q@QEQ@QEQ@QEQ@QEQ@QE?tx;p؛# P e|`+)VrʠvkJV@[#Dm.X:$ >._]Ty9)ݨ~c9G4dh+4T!+u*v3l6PI 29#Sjeo0 8}y<jF <jF t/?@jyУGZYJ GIѭE@Rޔm'ŧ6oSzQW@~0GtW3iҽ⺓A-x%+Q)$ #JPW>ߧNgiu Z :#K^lK{5k}8S+hs:v8c.ڂ{C&58[d gVmw(d{BĄkl:N>ʿk?u("D ޔ^ʪv %n)ޯ#pY$X}ok3qlj!Tҵ x85bq.NOD5 !/!ŶHQ_X/ .c4$hFcd+X';7m%JQiuh"T{RuFuR[(N\VIl!YNUqzl[7"ou1BcauR+5d2+RYQSn)$p>sf藗pi gXj!♭V&lCם>/=Yoq7oirР(PW9qM')RrC3rxR 1ΛUETQEPQEEPxC H#(0=Q@QEQ@QEQ@QEQ@QEQ@QE-Q@QEQA]_#J]񟙲WHY[9A eJ=~^P_n~̹w+Eޭ:՞jQW?y*nN ٟtx[ifW: /p?ÿ%kM5mM_*w$ʏ߸U m7jGkg5Ӫ(!YզQVvT}F³d`ⲉX]P\A@@Rޔm'ŧ6oSzQW@~0Gԟg1]UWW\1M^.ǘo BqFqҙo !nqH<UrB pB: +Z[AZNpNrBS"Raо8'SڂiA1P' qJ..&2-Nٖ2 u ucWe#sԥvnsu[J)>/duU)CN&"a%rZl%XB2É{݈{oh#wNr+rm%my]?w(#\$>>@|"8U+3h63} Cﭢ[or2%Ecqؘ[CQޣv ">ٸ#q cn4^[`*|#lA'e:Pr#Om0v*#&蕼ۇ $-d'8pP:L#[%d J8<Pwhl0D>gb]&+̐^$! NJ#䪵)}q ۍ:RpԤYoMki/RJ:OeךN1Udq7)iZH1#HN:*-lQXw4ӥO6sܠ’+|"uFJc6T敀8|bX/~5KZAީMᎼW7xR& h(*(RfCl%* ${=%*HRT0AU8kT$Ea*!suKj]Km%$4dDOI” V;F:R;Vl<(^u2Ps p%[-Cǐg(C%IOYx{kqDfmx6mJ@WꞪ[s"<*] YKW 9{3®R8j$mZ;Y~+ )Zc2TBP2ׁX*$7\vJ߂ Jvk6i3U"&e|o$)+:Jxp׺Ft ۠m G^:`ĎvGz+;j.W6Yf r%)[ I)%IG]I#i--n R@ l!XP.dE#Tg5kEJbۢ )NUs~nNqP#Cm8ë^Vp98+]s+6KXQxzRu (8ΤgBp|͊պŪN9jC \sāƭv7n7oCadmIET阙IJtucV3WZm:6䌇R ㏮@~Ci6ȁz6RAJGgWUKfADXͥZA qHH*)ڥ2l`!l%@c8#M3#w˛m#IU("n,v6HRRBIњ6 Ž$:.:; jnd#1'QC-{p*Vil38]@QEQ@QEQ@QEQ@QEQ@QEQA]_#Jmjim}kCr[-M3R+~^V(3/w?cw/W/ch(Mܾ\ɏt~Mܾ\ɏu?7rUr&?7rUr&?ւQveƮnSg.&n'I>*A<)Pi>->u7Ii zޔlţ{{+zx~0GԜg1]T\姾~WD[$jJ@A$shQYU.خ/*DoRT5˅@ck'dO,ǏUhi6LJ!N/|A!X8<}U{Z/B1c0ސ[Rc޾ZԱd` _rC<%;֜)R4AIL$^ATfD:ڊKrT^y_2^de֔R2mОZ޺uE p&dI}չؐ $rI#` .!g6HTR1TNfș{)9mQYB䨥 ':FPnBW%*;+Z8πSJ)QEEPQEEPQEEPQEEPQEEPQEEPQEEPQEEPWWҽUu|`+*EPQEEPQEJ6SzQ_ٿGMFZ=^oAWTHP)P`ne /]^i]/Z]IL9KnJr#o#bh+f&'D֮h`urWRѨ`xqvF;Q=2}%ĆJ\:\sZ̎GAGyab{34n)6JR (Փ]seg3!rwIqԘg^1@sO _2;/~XJ[M*2@^0=dw: _2;Abbh1|4(/掃̎Abbh1|4(/掃̎Abbh1|4(/掃̎A-_#bh,QU _2;/_#bh,QU _2;/_#bh,QU _2;/_#bh,QU _2;/_#bh,QU _2;/_#bh,QU _2;/_#bh,QU _2;/_#bh|`+*DfYV QϢ(((()F|Z}~oJ6P7h{f/Jj  i) gZ 9S**'T iӫ"|?.ciA|?.ciA|?F/69j<0>PwE&]ke!1Vt)j=kq4ފQ>v?Ǝq4ފQ>v?Ǝq4 .cj4.&BGR}@/k2([s?Xw;@ފQ>v?Ǝq4ފQ>v?Ǝq4ފQ>v?ƣzqe[*Jq=gE&$K:Tp =5R" JA4Rq4tGRq4tGRq59QZ.ə [ґ*wE&n|[KȊ(e*J zkq5h7tG|?@ފQ>v?ƠM`%="#-*R@OM-}2ƺ[_^3v*GA|?FTV%en'JGwE&n|כKI2!=|?Z .chw;Rz)KsKul)9ȞE^pٓ2;;I_ Ab((TR d([l PuEPT2Sy 6YtBTV=\J:]#ׂtⲁ")RFJCg#iA|?.ciAsXd"+Z3dGb;c+Vj39YvOYC\}( lRNpftGoJ6Q>v?Ʃ]ҒƄ]pJšE 8<+>a7pи)֊@:T7d,EhkJ!7@#^7m3=WD'֢h&{h 9&9 ;"ܗ]#9ƪGm!1! 2+kto)J!g#qZ 4xV {jkUz4(XpOFrO.S֗_7+V 徦S7Zy$q5ujb2HKn@ڋ+oK(9Hf8cҢj9V1Yd;'O5__ui2PP!!y=#LN2'-LTZd GRO.}JIŖq) RRՒ2ug>ΪѶ8덆ҷc'HWv/ O2JX[l"2@8iLh EN\z@Ӄ8>DwҖ \!XB( ش#3tj+VQO`mE"]s!kI׫Z$ Z)B+m%Dp^Dr^0쀞!Ns#ɴY&LPb!8ËNT1ʧ:7 iФcO䏨B2mL8j\6$|,ǀ52]L!׷mC8X1Č*hTTHJS.cd.3QoYQSmpA<Ȣwz+`S-j•RGp.}$qhԤ Gw1܎X2օ':Өa(BZ4@5m ޼ZS$)Ne}R.op8 *La BRԜ'Zy!N7 <Ӟxv{8򔁄S Bo!MNZ_ Jytmخ9"4K\RV=D֝mH뎥|R{WZ,1 3m%< Iqhʿ_ɘC2BJ3.;<:RF3n- #87RԞpT8&iۈC) ltsrge&_UHԓuA_}kzߖ*i\Ty}TX 5:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oPF:hE{ί4oP^ >>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|"Z !1T"AQ5aqs#23UdBRVc$6Sbeu4%Crt&D)!1AQaq"B( ?2$v$E7 ! ҕ ߥyM@˳8$5G/s5 JTEGrg"z_a@УCJIϞ]#qc_.lq wnYmN$+XQҴJrk'er;H [lJU]:)A)9JRP^g@[$wJA q RTpuɮ~T|ZkXu>L}e}%lin&#Ɛga -mGNsOFx!pSV B\ZRIJPXhVc9;;ɖOL}ʳHOMqXm RTK`6>oc#!/>n !/%$*oM7cb*\ۑeKu\ЂHXZB@`y:OZ:?&[o >y2cxIW2Z.qPDt8k. z(#x,7r_"qsK%+|H:Ӓ lڑ2cxISɖOlw*J"FDvd $-kY[ 8vTF导_.Ю:+j_Nzi8>L}e*=g+,1%/-q#jqBb54kM"L Lg/FeAyt@ Βs#5}âe-7urcv6.eZnCI <͆%t\5w~l7K qd">d ^Og~b:wɖOL}ՇĶ+<ř閨RzimŻ RtF |NLKzۈd6[ ڇ1+S}GA8tL}ec\p$C_WV3W_GKܠ\A`CR\/JG &ps}ɖO?="46O-%);YYz*,- 'B+8=r:W[qն5c^t0FAH SDb۔VLCv(՟ T Q;>bYOJ;Nφ)آwV|1S҂v(՟ TDb'ug=( Q;>bYOJ;Nφ)آwV|1S҂v(՟ TDb'ug=( Q;>bYOJ;Nφ)آwV|1S҂x,2PJy` ϢU;w=Px!ZsNsq7-A;3>_EZWH݉0NInDRҊz,.q)P 6UgQ>ȫUbfxPnKj;)e:IJF0~hNI[mBRj8V* 3 [!Ha-$!$@n{#9-nBIq}ժPW!ЈmmX@Gdz|" $ 9PНϮRvb%rx4Xco۠q.ȅIZTIQJ$6#'ѓViAQkW. c䄲c$l> CH1! OOWRVkS!d6}a\C q@ QI|Mxbe!r# ԷG:H' f)A X1-k- %Y՜zϽ@ݚҥ)lD*n{QK :󺞾WiAx~`/+A8;q3wr:[h 1jܥtC@`@KC< PRvUUG [fC([ԬsИ w#PǝJ k28Kiv+M!);$$$`TpmnF^w)7%$4e6-Jym8?Z2k!hm)+XZ XR'#rV|>K[KM4|`R0ksxq*طԽjuP**rN3jI!9piˍ8iAV<.S K *Ky9R fS3%rƕ9VGCN}yA5;e^Иj=Ng?-H,Eaj1mU^w- a+S`%:I;uӷ͵H dHuuBjJP@oDw0-Ckl6J0FA:yc~ե %BuWC3 ߥ['zg;> Rmޙ;lNψ+~bw|AN3 ߥ,`v؝SLK'zg;> Rmޙ;lNψ+~bw|AN3 ߥ,`v؝SLK'zg;> Rmޙ;lNψ+~rt6\--:NG楌~3 v؝V7}ȯs_Thn 2^-D{"4)sBJS$!SRZj+܃ ~ӚJHJդЭQ.AqJi9Kk ?6?JL!NjH@V96?5i WgFeۏI68ǯ5#%,HQPmDFw8 wpVWQ)8IשBBCAk=$RaW[_Ux0+p ~qDg6Ys-Jï>F4۞Yl7S.nTUU']")KVp>W窨!>P 5)줘AV2d-Jp-\`p0*T)! ) c'W%$c5Jb}ȒZK ,FmG*2WZuħ%mc;zRCQLHRˁe FzUULZJRAJA']ZLI cVy fioImJf%:D`ߜTόRRABP27՘|,LAB vCq0*kHNޓmC{α"I{IBn ]]M냚BsmYG|Y%Yp-N8+-,%QpƭBH kzrV>l ^<H<9Kj*~jTiKu5Ztjж/MZ[XԄ`j`Xbfd]d6sR3:;CQNX޲!R NF5OJCBZq87PZMJЬg՜mR96;nZFTjdy m_Ν8La.D%ID@(咕=1ը)PZBrȯ|s1HՎ׺RRRRRZ>% YeZpW8ޮB,OTaǒ9R7=wzNIsTڴZuA%#v!Yڝ,*gHȡQ%0aClcÈS*GF&&bMxM*SFIizANۤg>ŔiV!`H|RjclpPPLjVd 4Ub"-ƝmM' #RSXc≯VZOd+R? -[>*EZϊ}=V((((((((((((((((((((((((((?--Bq01m^J0R09ҽ% '+˖ȫT UYw(TpT2<8$iLgŠNHV-5+o/scnZZ"L%->ZXhJjZTJP 5/4VOb6S-%ơS- <픒H8nqo@v $zm<_e!>uƎ."L7W)=T 3M 6X(k12$mE.;%*:t(uGPqgpuD*( QtrIY(I~S҃~0ۊD$ONpS9EfݿtmbDO4Xu*AFqU:V+_dbBXzKE1.+NQTAmPa2-e@A$P AJ kWPI~;oV*? Ԭ$OBճ⨟@dUl'#j1X*Cahp}R!)HJR0U9Տ1pbGFV3녢 VdG9` K) qRmWMVؓ]7gÉq`5yDY?W$gSry6Jo­EU{˒?D)WqmASIi.lT? 6+rG=pl(y|85g'zz>Z_|o?.Z{yJ{Cl>y/M%11҇K b~ #ǭAS@з kJgɟL¾7/T騙˛ õEK6f)fL>sK%!!CJ sPdMWg郞gGɿžN_f"o:}#{9pӷJOjayjgp !@^2vDiiKjSyZ]/-!>ЭJOd(-[>*EZϊ}=V9%Y^,LBKn-Zä$7 -І 2m lucƐF~j Ø#o$PPnDҶN}Gt7 Aqe2QRאpU'Ug5Q/ |@9B2cog夒 RUt$ 6g]Ȝ hRѨRޭa VTԒ1ʇVͶiLbvsi)[@dz-'6btI_!:N1y~ '8j }r}ZTyq&o(L/ƚkRDeVq8q1ԯ[n]6hc oN0ȵےH/K) 8IHvI |r{7j_;%գQaMhH-d+Wy'5 tZüIXHl+tXBˉK,*#@fr Gb9Ȭ;P$I\\{nn.,6%*hqRT gnP9}-.7aRrDxJ.!ƒk(>h ơ}e;0c6ʛ BJpnvM}nOjtKy!.HKI,mV2Fꤎac.AqQ[\ iGKjED ]T=&-7KOv[,Qt:yR5+;-@`a1JR%B[!ڼĶB4cPczNlvNK`%n R)\w.ߠOgsbjl = yj i.$^#;Nt!#-%[UMjqNĤm@ieg_.|in9wDo-iJye<7GfmvMnjF2G-)ք+s^d4 Fd9cnCV*U)OT&Z_iK:BSA]1VQ6-n2SҠt:Slgջۯ0*)eHa)$R6VԥCޯgT%x:5c'mM'BUKHun45*F@Z |˽1Du̕(C@*K$؂I=tm2g|\7f78tˆ| CT/$)΍ ;~rMHsKѥHhЋ|pej甭Ԩ#ֵ}ͻB`+䦔 󓝫L@b0Sa 60P3;tޫ\,6۬$\"5/% VƝi:WG$D*UVRt |dqOǷ11 %]d<%6ž+)Qzg~i9Z-ht)FF+̫ p`LA#K<_(zt9׸M4伔T˺4dtVvv~ ~=dzLHdȎJ¼yj'A60r@߷6E%&%*Irӡ;]D5OK]"Hlń0Rq%nĈ,Hxִ Sy м8I~[$یy-ŦTKai 8p>,diLz+a 'SHRqץZmz3˷S#Go&\;(D9 )jt+PRBqB#o^E\j#qHۮ$xZV$'~mr[Ko-L疧J3t-يTuJFҥc$` y[Û.sKiLtӡ6CAa+n9/˚ˌcXʝB<1jFۯLHyO;AgR)=1/ɱ;Ddr{m'5'sվSfd@-jnMYe4RdNucs&I%NDXJni@s%[uy`5FaJvTKtX$L+Y''$ ]|hMa1[.YJI%@SShoUs3.VcGo,)M!`jVFqXvq:l_YZӤyiV Ym K)H?5WbmQӡMR'$0FT~ K&i"sԗԽNj8YS{ BNFPY."l2d-IIR5-X^3׺ErtE=JS.TQ)8$q^-aٰcIr:2JJt6;˜_]GD\U%Gm(8B7}9Ϣ\luh n}0ӌ姕92]-2AR[m-@I#>qrsUfJnIV]im OE+|dn3?87&Y2"*Sf9aI)$QJs41R SkII YiǔTybcPZjX8R'E+}ToLJ(69ۜS:_Jb7GDFLw#N,§<NҬz+} om%<Т0T*#9P5q1YD%%y% VN9 cWNg`O"C,Їq-hAQIQh6Aj :܎- 9VSmF}y*YB )`흳 Yakw !ZA:;Բn2wlyJ%:ԴJPJ܃zprɋӞYq1R¥%uFq'jqe[+e%ĝq푈O6 Z0M׌jǫfEcBn-ңA@H#}CƦгMvZKȈkFKH Nۃo𛅡q1Wm)*mJ1m׮kf4,7DAVvhP Xq[ [.RV=RBrBzOCݬt0b^L6cվ3ኩfDv)i)H'ͷյhԝD=/vgq{>PCf|1N3ኚ8ٟ Sb=/vgq{>Acݙ;^φ*jPCf|1N3ኚ8ٟ Sb=/vgq{>Acݙ;^φ*jPCf|1N3ኚb/vg5(!q{>cݙMJ{^φ)f|1SR3v8ٟ TԠb/vg5(!q{>cݙMJ!%q`S6| 1FRKhP(W_U]}+٬'? ? /|+wk4*ݮ»wv3K곢^}}(BHun *l$}5 ;E^xϒ4~iw9"dmf7 J 6Dhli:8o``X "ΘH-jҨTB($yJKZn0Bk4Βsj2  6$ -i=}+Ó[[cչ8N-AkN(j=#(ҡXĘvҹ.w|kX_ 1eR_.GqY $)*zgYN\]qQK\ m(OgN5T '&.51 R!J!' =}U-::DĐ\ )ƟJH9$QXzwkm/6$[mRRܑOMKYH}CM7)rޛ(!>վ˥{cIq\yFD2R6k:N)r$y#ЗBJu}9韪>xœpdvq-0)#N-f]z>P/eSl2#Y$;pm,Ǟ D Fڳ 8Ӎ""+R#Hm)xpaeo05n\a 2JP9IZKS%EB?(8.;+fca;+[vhmQ _B()*Jr7zL4FVB8’P;8:2޷-q\j!n0[R@BI$j1?s5swԕ[?s5p' K2"0[ B[:=](,To; Ս@;g9|K59|K5Q#\e뷼VCTVۚT0 PH+H=p{Eܷn!z`Z6Pd|K59|K50? pm0:RVmE uSĿ-SĿ-Vnm"+of[zXa};B\wq7PKo!Ätc]MeJOd+R? Vϊ}=V⨟@dUX4jjIQ&TRNΜ;ב-E$0qy>qA-eμW}Ĭx J=ja9S磊?gc.cv)!2Ї1MVР= z7@JLu1!m: u <=U6qNm*q/!(B IUoVʑlDGх4}m)PBAhU&xBe_:ӠYH h9>;>㶬iwdm7 J'Dhli:8o`X "ΘH-jҨTB(a%a9 )iם$wղlp[=}@ɭ[1jLM5'N F5jKiPpLKI~;Ii\ t H;M^j%% 28KJeayn)`RH;6\4Yn},a8##[yIr4cjh7(F | \\N}Y3p o 6| -iPP[ ®LtEJV0yNp=R>ֽnҔ0]ℲP]m J6@A~N.Jg#[`u*Nrk&R&;̵*K+$Ѕ%[zBOL+:—׋2j/u˃ yiƠ $6%FZ&ŠPԄ)D$D}żڧGT8K8ZB' $+NmD pJU=Ax~6ԩi&"NRrue$'Ѻ~\M6;|YM)QzZPR֔'6d|Ƭ5ua 0- -(-?{@4Av 2%Iä0P𓏖/j0eAGPKSjFx$h7297h&#+B9mmwX8;7;lfҗR-E@\z"w k7E1cOy-(K%*I;'n›j;RCihF}Ptn8*Q>q: ߲lZB}i^.e _Y[um..!A BFv$1W++PQ䕶Q8y Oփ+%Q]m*['eC#JS꒕,T 'إ)@)@)@)@)@)@)@)@)A O\`pҢ3x, $h R:p}C<ۭ(+ѫC{u*[bJ8&mM!>ЭJOd(-[>*EZϊ}=V!c~{ ? 'GQI:c:s co^GT386h:a_-SsS6*uNo(z_Ս۴8ƈBƥ6[kBQzqw-*i1ąT%$$z]WO D:5ƴ< * n '5UZ*EFZ}lA 7QT W |nFZNYe h ҬD^xڱg [[, +\ZVR<\lbHx:b"ڞKJHAR@I JNpwhGE%a9 )iם$wղlp[=}@ɭ[1jLM5'N F5jKiPpLKI~;Ii\ t H;M^j%% 28KJeayn)`RH;6\4Yn},a8##[yIr4cjh7(F | \\N}Y3p o 6| -iPP[ ®LtEJV0yNp=R>ֽnҔ0]ℲP]m J6@A~N.Jg#[`u*Nrk&R&;̵*K+$Ѕ%[zBOL+:—׋2j/u˃ yiƠ $6%FZ&ŠPԄ)D$D}żڧGT8K8ZB' $+NmD pJU=Ax~6ԩi&"NRrue$'Ѻ>9 2CaL%!$A;̭^!Ĕ.BusqNqcPMssUI y2^S#*)PRPF=[rWw/*ڐ2 @HДrnWk"-ElݡXnKd$qHGeFBdIo: |_D.ۣ6mN)ZK8!'վ=#jsk{qT)򇜸}UoyQ-"<1]RNi-38U E.܆ڌY7Zf*[/u\z:$ ?G_XWcLH y- %!CWӌ`9tks[$P!m(G#O-uT2H$UY/Ŧmx*;HVI1dMۊ9Wqn!C8ss-ѣۮ7%yJH8,0H(\.+zV.3T9ۯFvmedaI m)ŐWIX=vE+S/rԉXQTe/BN˥ܟN7'9#cW'{a|T02ܔ4\2BW >1g2Sϐ8 ^t 0NX:w(6<;u+Ԭjs/cg\#!i]S *)cZSlRw޺)J)J)J)Jb~_JkiROtJWҹ¾]nt\&"!ImXx :4NF''M;:{j9CVq束??aj[-hQI zZq>[VgOXv~(+Hs}J %A 4넁X??ai.෴C7;tDZ47h=yBRGZ'Q9 Y|I jV_|C'}AjTOG*U|U습A MMPi?J= IӜa|z?|⥯HZJNpF68?XYw[B 2%kH (|8`c'#, *s|qC fq W]9[РBN=Im.\Ƕ) D- 'JI #m@&j%\%4%+pRNN~Jdz}I!:[agPuVw􎵏0bNv"ߐ}!P\'߃τ-A tAC12k y}<ؑ|z |t rPy|A$'pA<Ӓ6=&ƗHyc՛P% BF38ޝWSq_[̥iQJ_P#NofMi}>iKgs$mjj½E\/%QJПVGEr.ip4g 1ҶVZ`$Y!%Cns]-$5%մ*ԅ,e#7֓Bӈf@esƃE Т@lP@Fg91kr8u%'ms7XvWYkΈ I֕,’r^ዄ'\\)O8R'H gp#a,ᮎ!r'Fԇa-ږrFwFuCJɽ[F[R9iWJ~JÕ;qيnqKHeR=MD ]ٌ m.4̵@V ![YHtjP+HLnӾ:օrraH[Iq`IԡDw$R.u$vt18A#׃-r gblaByRulӏEGp=2TmLg1ۨ+!DzW `㬺nAl'RC)N2(?=:fYn]qЄIA*V3w8ͩJK78ny!1zaY,eSlAh?n;|q^xf6FS 8CA)W:FBB`ڋI˷ۜCJZk^bBR37Q6DWŌiBm҅+W@;W˵Wg"2Ԉ*C8T;k? I3kd*0 n8jA;)YT7x5PDrRRTJpSMnDCHv̄-p6]3\Su5Ugxٔ%G3iRbKj!gOQwI.MgJ-hHp|rXƾ3o%Z ! <'fH(`_LwVӭii[kHRTzkFtyCFEI d|%Yf4g_>/gvu5_>/gvu5%JOd+R? ճ⨟@dUl'#j? 'Gc~{ ((((((((((((((((((((((?1?s5p' K2"0[ B[:=]+j'U{fn JiQL<(%ԥKm=1AĿ-SĿ-Wq3R'W="qT{/_/_\ԉ;wHP{/_/_\ԉ;wHPxnam qq\qA-NIюu5򥽶$/blV(Z\jK)?zЊe'2GY|I gQ>ȫUVTOG*,~Oҏa55B(SP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JPC*W=XN7?|/IU*W=XJW0| RUwϲ;2u`r_8muNXI.*Dk}$9r\eD nISSsһw"Rrr E&jVv%Ą,:PRA#p{W,ʛ,VdnrN4*=SMHxp*L䀦Q#>un>~Lv7om@BR')oA.Ya.9kakaem)L[Q9%'wȫ0eȏˎYiנ!)9S9oH;yڭp5ٺFCN!q!guÏ7e3VЄ|FëHJ #8Oj(V sQjRXd  U/f/ͭ6J<2ğhVe'2GD{"U[gQ>ȫTi?J= MMA1?s5V}u}/mfHqIQ?s55/-Z?Z| oգ٭Pb oգ٧-Z?Zڥ/-Z?Z| oգ٭Pd|7cm:҂!!@@؃jRY|I jV_|C'}AjTOG*U|U슙AJ qATO=N JU{U;ݗڝ}wG~9wG~xNev{u{N{^;So쿷At{GSt{GWv_jw/P{TU;ݗڝ}wG~9wG~xNev{u{N{^;So쿷At{GSt{GWv_jw/P{TU;ݗڝ}wG~9wG~xNev{ut{GSt{GWv_jw/P{TU;ݗڝ}wG~9wG~xNev{u{N{^;So쿷At{GSt{GWv_jw/P{TU;ݗڝ}wG~9wG~xNev{u{N{^;So쿷At{GSt{GWv_jw/P{TU;ݗڝ}wG~9wG~xNev{u{N{^;So쿷At{GSt{GWv_jw/P{TU;ݗڝ}%IgII+RqTO穪jw/S;ݗ,ҫv{u;So*jw/S;ݗ,ҫv{u;So*jw/S;ݗ,_|C'}ZMJII>YI gQ>ȫUVTOG*¤TQ=|"Tv3P8ӀwϢJXH V1ViyTUԇmw8i\e%$ZR3>z,e]/b[$oL!zYW,86T3kUiG~Ur|O֧D>ɃA8Ӎ>vsMs8>߇QěJ)՜:ӁH88; mݭ2۸EZ%#)/$G4 9o~<\KV:5Ql-s#j6ѤW!Sr*ma*H)Y\PI9z8>_TL9qJMa[5%jSAPTG6ˬ+C.9եIp*rGpfDyڟRQ% B yۏ]u#^JR R R R R R R R R R R R R R? Ԭ$OBճ⨟@dUl'#jS}Hflc 9j>sQ2ѥjㄯ,sS2.Zyg˗Ӷ\&)K _NqW0J\pWqW0?M^.8)G?^vWK QS^ڧ-5v.?wiT>;ɧiRゔL&VK T{gpUR&wE};R^|h>_rUR }N|h4wOX,WI s_X,WI ͑=)bl1Nl1SҖys5)bcbA1R҂.c?)?-(# kwIJT/TJ9W>e_k(>dO҃O? Ԭ$OBHS"ǶCYiF: XI򝿿FS﬙Է"<zok[.^ǒ˚RPWyJU }Z_7}yNߣx#jXsYe+8(oCd 6dIm%:@'kvOS*}̞&;<ե; V t>Zc>O>yZ9ٜ-(kӤ;PoѼT;~\|CmuJ,)'R@I>HF:k-4.Ч~}zt^S*}򝿿FSa'KJqŸwhӐ;+;v%/Ao i@J8;c[yN%I?;:姆 FDIM?CRv稥mHnm/ۗk<A9II$)?5N{GEJvOS*}'mС1iVЌ#'NQ<C2Qt$΄9)IBviC򝿿FS倫7}ri2% x꜍ܥb S*}򝿿FS﬩OҷϿȺa"6M)#)JJ2q8Ƭ8)C򝿿FS倫7}s]qr; @QN5q L8q b$0ޝJd6>J7}yNߣx L&<+zmҵ_AZPϚ I$~JWcme^29˱bq(߬+oYJ7}vOS*}&܋&!ARPX '-' V(^򝿿FS倫7}e//QYF.4°)i Gqթ pNUO;~O)o>,FW/:RXqM`iIr#Ѷ:xԥu ĥ@jJp8FP輧oѼT;~\긒րsRW=RRƥ%9 8I Tѯ%r/)O7 ZNDaX$pzҬnyNߣxvO'LkG1y)R=g[T9{m2.-sG* Jqy*'IJ7}yNߣx6Za/8JJ:8V:A%@ 3KR7}Fc;!AԨ$4iI$0 I$3֣OH%#U8)lR6>ANߣxl2аyȚfjDu6<;Ito{B=;f"M= ->|kD÷+&"&{:SrANGR6 b\K-dGTNǮ|(agAY|b"fK綩qí(R25V4(cL GK(N'JS~îےw %X~D>mKjp{rmŕ,H[m(-Y:qkRs5#tAE{l*nW=i ,6h  $NGa/‰}}Q/Ͼ-Zl/)֡Fk1_Rւⱄu#*RRp#m}Q/Ͼ"`A\v8[唆2O5*N rzv9vZK9ZV6R]%C+$~K3‰}}I(qCa%ׂ'$mNFl[%UZ$xňQCZJPZp+2˶‰}}Q/ϾJ/PK,IK;X\hq(@tPNs ^r`%n2p3$xcQ/Ͼ %X~ձ5B} syeӶO1ך8yWC!ZXkO1RްVm@TOן-Jbk-M61ۅ2bssCIoJ57P u1粼3u?H.4.5YR*O</Z\Trd^(kP )_ mr!q}L {imj)(+P#e6MQ.4.5 [QũPX<-Scm㘐! d\qEKX w;|˶{og<],5[˹7sM4W?/**"yx{diRt{:$E^Q/Ͼ %X~\xQSy v1cmcBN3'u+Sa ѕⷞ_^J>O %X~D>mBnD$b֎C$,*jplSԒtg֍y(NVM鬟? _u}[ 7#a%nHNN䁓|Tys?xWϧP¡#9ݳﯿ %X~Խ[UeqP,%JFt`l$;큓g .?q~PW ,+%_W#‰}}Q/ϾZa;0 Ñ㡴!D6'RNq\d4|?6SEh0BՅ-D)cbs0MZQ/Ͼ %X~QueP%-CpJ$8-yJx)N:?'JQ/Ͼ+)%* 0Alձ~DY R#J`))SszX^wR$:0u25Y:|(agO? Ѹz{쩹C-!+Zí°W欐ddPpd P["- !i:'WU? _u},|"ejmZ9Xֳ*=vN7==kT"fCZQ ~ҲK3‰}}lj/QT;FycFc~JV `Y߅? [,6fM[<ڣek[a#ejAN?=VEi9aEzP%nQ:pE? _u}iN; B8Tz_RZI%5+` ¸ySeuaA˚NiI %X~D>X?(YCr:r ^un!#RVZ\!iZ5 IFyIL8`g;6}D> =~ec[RQZҠ,,HKf][-8JD #8>K3‰}}b1W4\'}-$֣g9TN̙VZzhJcbިsrƐ0AĿ %X~D>%pa쭴#,8ږ2֕`'ﵞ БQ/Ͼ|'+sFiyrurY-ʕr9^gpˬT":q+a A+l| _u}>K3܋] K e.t;}d O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~!oD<3|)4ӲCxgiGSi!eپ ҏcCN|!WAOȆf'DC?ίJ=+O ;/>O_{W?"v_} :-(8  ?D47?"uZQq_i~#- _^Oi}k Wv ~ ,EMr։!Gf aۜB49*QW웊')ݮI۵{_;ZMZ4*%OOKG&cmb Ǎo.UCmkq=Sh"G.BBgwRk.irEx|AciT{o=tL-_ E[\hs"6F1;*2(+S>:47ݯ X h."MCGWxr"tl:0>'<˰ua:UhYG>YZiuI;f> gUplgh(a%RS&o:2xej<0؜vS(X [} _'pLʱT3Ӝ~BѣNRqjEѭE&')ISwv xm..?C}e.%M~_* +ܿ[?.ܼѿ2|=o9ÛzBn[]|^ϖ/{;Yxz߈|:6a\xXTu]kNX-ˈ3{?Sq:dۋ%< mjxNX.6EVXP'8ab(JtB.zX5x^1Bn^ƅ:ѡMXFhJO Y<}Tz $m|u x$>!ѣD]Cq~'R(ZXzѯ<#j;F/R)sS^Υ:_%HIJ**W曦N)'R.mRJ,Io) j]?]Ct4 Y]}n`g&W[͞(EV竘ӥ|>Q)QE7J$Zc*P~2M5ORx>VW_\7-ƍJviQNf7[i4-OQaexowɡ{_I=ki}ln[IdڳKo_ Z6ۥ?mMb#R%rp/iԭ'VA R*S:q p/<הUJtKHJ U!^TҪJ*}%}?ml|m˟wqkOhbKC 7,6+V3 *PxX'YJ>::N,w,oft{:O5:~z{9kR/Y{']sYxOž=iiΕ$MqPi=eBZ  UI{Xrs[2ri9(s8ŤWQrmh{ȓy/K?+dIoD*=`%dIoD*=`%dIoD*=`%dIoD*=`%dIoD*=`%dI<> M;Et}:OYk66Y]nkB=WN-,LeZx:tF3NKwZݣvO(ɰHVBWu+aTAEs:IF-NQO9_N%pn t=c_dV"oi7Z~][lc/{ճ)(ᨾX(?zyuVӥNF22ζoj%ru:s+I&MJ ׭N/ !jf>lG3[^z2}TxB~)Ҋ#QQJ(1i-:-$`C-xWDk NOlpZ|+_ k߳lW~ K&1M:M:=&o[ń¶qIpd!Fj a 5*Pxt11)PUMRU"xh+ޭZtRsT9Ҩڧue6FuSehFR1iEf;5wVԵ}.iڤ#X֖7YnIy5xԁ-67ƙ^qiha'pXֶ3qE,NcIqod8~|]YF8M'[l _ Uq96c,./!`2|6gxbKW Wy5e԰aqtj,_?3|J|LXO \h5lZs'VѡDX a-Vb.%_^qDjT**UJjUjRIʲ(Stx)WβzCe*[#[ž/!կե]xF״[&5 +N_o>hm~*8*U*<%<.eVEYapUw R^tN(SQBJ-?RX/kZ+8Fj*,^4ꪑcB XjJU:u+FuXxMgƦW儥UT'GRi~mXf\8ESX8hME̩⣉/mNH[Uʽ%υ4:6GE#ᾍx' ZxxCS9t+5kXh6x]V4¦镓4*ɪ`:p[˞WN,1[ JQGSTVqJ~ UG3c<._?bңV|Jj̔ͩ*WiԌiӟI{5/]sjZ7/>7/t4ַOD::ƋZoSN+y-渍X:3Jl)ʆ&&&U"oJө*TiG?x’i>u?eUׄ.4qs:VSZ#!ġO3b>,M:38`'V fgRp:):f# B٩>Xb۲g 'R;Y}-],uO|$swgΩm['R}:=v=&H.aV^JmBSogF44ַ{uzNdi``k"1xhcZrRNo$ޑ_ޏ-r=J3ދkoil5-"]gú~ <7VP^i|OW7ClQ[spᅪ)/qXNū):Z)+K'gA|C񝆱]|)[YjV7w ď٭h-U_)ƌ3(2@EKJNQi^[]סѭVhi:0jDе[[{F5-/l/L;IUn-gGFV;TTcW7Nztg/{I¿C)k_Zx/K'S=N}c:گqem[kYo/մoǰ԰Trp暂W{EҔVٜNUG G q*ƛєZ" {i8s֦FY⟁>+ZK_=/AQs~Ѝ(Ӭm!yiq@#gGj4Il|EGpj ;є#wAdM;nqiS.gͰT >"aO49T4.VTRʔ!8U)KORAq)sïMq=0 RTi dvUCJ.W4zROA?k@;Q:?! _K 溏swZ?_?g5}NDwR?t.?.C#uSAqs  Կk? ?]G\\9-Gu/3>OA?k@;Q:?! _K 溏swZ?_?g5}NDwR?t.?.C#uSAqs  Կk? ?]G\\9<ߊn|A5MB+H/FamSq1C&rDmR=5zJJ\i}m%ŴfaKZM# ωWKOJ0m6Fj_}$IkNt]Ok/u/]̷~ikh4o`c{6ڤ( <  ITaov4W*)SIʟ,o(~S8JG .7U1:I_k:xjrmh&VU*9Tt~9qU 'oaY%1kOsRu^O˿^+RiO|O;^9g] [^_< ^i YCj/câ[4nڈ;0N)b )|NRW,c쓓;9~W8g`KW >TN3RS"7pTR1|5?>*Vix#W6Ńv<}A,8b8׻&ߕ_rG>'!k"wZqW}3!j^cս-k]Odmm{o}fi΋>cii:wojzewv}i$^ rG*:3+mym[yX>'x__?7$m<mkA_:|j֛o!}Ek"Gn]^WOoo]G?ƾ֙>ۛ]/Rӵ]𯈴MJ+{kѧx¾)tkn j} %i=Eky]0 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ($?^0{Q)?/hO*z X:,7r`>'!k"wZpW}z;\w,3/>fjG hvj?f9A>Gӿb-3KѼ9o.džlt>-qA{/Z<:'T_]JV[xZ䲽ib!R[>^+k}Z7}ž}='@.Fӭ/zVit7O>] 1ꕒ]I;Bw 灼YheQjڭ_ygMlcݽTM io#>4>3_iZc ]{CD9oM Vԯ~#]6PMc±kl,5]i5];EiƗ ktiP'z~ڽᙼWB״h#_t}co+b O4ڋYasnv:vJVkdڋe4y?>sK K:폈|Y'Udž<;i/ xO׵&<3KsUk.RX-a*VtKmm.,z=1P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@|T_/=֔OQ'=Ko|^_O90߆4ڟ-/Ok.>wu_olmd|\RMQ²s2[\q^G ! f²~UGHH#aq乵HM' C 'pfԓz+zh7Kx/秉d# 8% E 8%f▭Q$a%w6 dx7Ka,Q\!G M/z:?ٯMaSrtG8Y$a/_,pw2xT*ZTBQ]ZpN-I6go{>6߉u xRϠx[LSjhqpb2XSRYWB2nTܭh~ʚw_/<0 a]WLTeM4!EƗ &G_?3ןsø'S\)˙LYSO 6')ɹɶ8.[Y*pPtTV\)TI]GAZVKeJघaӎ'ӏ=ėR [6Z;{o*nd qwd;Ucpxx'< KXКWvbfᓶcI^НښGϟ(|@t_xm'@>4[Ŷ'Díèvv5LhV8nmn$pajaV08c/:)΢9NN^u;9r9Fv/,(֫Mԍ'Յ䜒\JJ}vmy@+-J=3E|Cv/jRxi7ua}^qk ս.(˸|PȲ/Sb.7G*iQ&)Pvg}+>XNiҜ7 \JoWL+?~&xA#fݵ_c|[e/Z.ux/ޡkk^,ӯ-5!G=+XuX5;to,.˰ O8b)F." eE֠ 3r*j0bV2JJoik%dh~{ϋw2M6@A_:5MR_h} ] P*G=7l̲<$Y2q:獩U֥B ^ʧ+M)+]w]UJ1Qy.O1 x߅t?wϟ^6Yi=*95MkƳ[2ӯݞ(-WL$,v)i<ɀ' jԭfxT`8`*5 xtʤRM[YrWVLT"Ѕ6ӲuVn_|wm+pxvIOz;\k~AjZ]M'O xY8uy t<ՑZ^f.8jf>igJpZ,>!k{0U13’ԢOMYN wf 4fLji/y]x&? ~:x/v(е[M7Quc^o♧mA&<+XDpoY4P캾;$[^pNB1QN5+̒bB*^ utms7yob? kƞO.>~zut=lxz׆4MCDmC_!6FjzsŧJ\"[,V k.~{ ueWS4!!SB8Fj-4b=en*6||qQoV?sP|n_()𵦷} x#YuO~8Iּe^h:}^OnuKk5+[U-猭ᬟia2 І3 %^5iN!ʪʜ'Jn.M'\ҥZU 8Iӕ(RPi6ڍM5̯Gwxxĺ?%mK>")uOfzV,HRU('b~.ʪppgc=#ViTJiQ熉\rETq[KVzlxK 0~Nyj?eZ5; ޛzcQBdFbf AfRVY2K.1Hrܣ%%}a*(VźVrl<'V' k/%𔚯m[]V֢-K|;mjrܝGRx/a"eT3n< 5S+j|WF#ʝIB;Pmbjו e<'J.Pm5{?y5ooV>ּ':%ܚW_7x6dMwxIG=ܡ-rx2^!V(bVcR+ {/XU+Xb+QwOƖ9Eɧ^ovΟ[Yo?t| .ӵ 뷞&Z>[EK6OjH>'5 '.LfyT%*uF(#(єRmC޴'7ΥʮXG61Ò4IŹ697̒UuH6k liKW&-.47U)o0|BC`i=py{6cK''fWPW_WJ\֍p8y)SXu^_ϥ]յ._o _]C/E?'ÿB֭y泧k:.F{M^PKy=2xk/PBʦ_JְX{tNlV"7N)5Y]ʱ%I?bWp!ܴv;RxQִ]SVӼU.n+u;=2ḾUMSR)[qek` ;w`9}*3F,]LxNj0ι%FF\~TqYTU7%*qBJR4|YY{=/Uq%/Ös}rK>!|]k>Mt}F EX{2kSzd;R[ n*)PJƖ'u %Qtb5ҫ}#NRRMC.To_ux?ׇ~a4g]<5^XI)\!ԅ 8ųmxn輲;XcVJ>Z(Q_~ϝ'v/,Η$!B:e&u(m;u^R_^">ٴ,t6O #m¾mM+_iծ<_wyM>;4VIf Ɏt1?BRKO ATZ^utJAҏ+I<9qe,^#bIr2R7%;*LGƯ)|-i{:=9~?mC¾ns2mNf-s B#ldžr|$a\18,V.l^qURㆧSR|YVv&74xTISU7W;UJ6~LCLxJ-s㽕.#~Ά@;|BOi;#$[<->ȦpR8G-~E:םƭJnO䩮jQuh:Kn{]9u^]_[|-oYצu:_xil.|^ͨ-C .x_+<|R ֮[N6 ӧI)JZE^R.䔥f%%ERB5]=X6ݴVі|IH{Ǯj~ ?ōG/5]x_ZxKNJԠmG2O@}'nTiTs5?f:Kߵ/cNJz)_ozWWr6|h|I/ _ЯgYA]F.Tմ wHμ|=eYI2OkVev1y2x|58zU縇jQ`)ӫNj^qr%fJZ*WyTS]Z߱#^x?cݾÚ<;cuۋ]so+4$rY^5a,6&S ZtJS5yV# ;zyjҍT6唢>f-9VGϟ?eO?|o[Ld+EZVįZ%RgGD𖓠~ |u &[k/cT×POF4y4J[Cn]P(i12:<5u)ʗ5T(~VO|~,<:ԣhpTe{G^,ҳAc6{߈_ k?d?Xjϩ[hj)k=jOo#MN-4zUN9~Q1OtM~;Z] Sqn;oy=c?O~.~h> kƚ_j1YdxDl= kum}mo]O1Z<,W]xepjPr:Y\W2JR\F~P@P@P@P@P@?XiEZCCJB{?CoحUɘBOًP׏iGF,( ( ( ( (<Og\\Oz2'O/?YDYƅfW-cuHĊђ6r _̧έ&=.TOW}tLx7R~:ETU5%&y_浯wsT0Z8$CHDHhyjx^>P8o%0;+ƥw~jzJ\q5iT: p=xs4]u}0'RoQi譡x[,쭠@AXlRPi%crMo + QL 0xsGTRWe(I~,)J1vnߞ]oīEr.`ޝΡJnLe{8#YΥnif?1> SX^K1khyj)SF:1_q8YƗ澻!SW.u**TBR5kBET^)_jv>:}: >2ZK],rH[e ֿqiefl\bXB C;F 8(ec|bkp.j*R8{9|xU-)7&%&G챫eW'5(\F[ɷG2Xk`Çу5<]NRlaB3:0:x(ZFw(3(J5I[^hh/%*+}$KO5S~?Ī?>km2/D4I.RM2KXEZ2$bXX.=,7rT_$E(KXSBN:5vcV*Թvzi=Ht? t/.+K>km{ X.BMKPRIfkrs:1j'R>^R~Ғd٫F1pJ )Z@#N1/ _IYr?׬/OVŨS5վ5H_ZhzQrg]Z ٳi 5)c%O "9ANp:>2i{XZN.O$M7^t-sxKRx NM'(v׺͝ ZkVM^RPԮ%mf]Cr%ػj9oجBRTk^4RJч8F Z&bx\?,!쒍'ZiwNnM 0}ֵ-GXԼ=%ƢM&b7k:}4mh {.13*xY1r6#NR!IQyyeIr5((W+}׳m]ܹ6=F;|ҴOxr4_Zh~0R@h }Rݮ&j+"ݽI F3l."x*J0^ѧ8F)(J{;r(*:xƤ$U%5{+6|ñKMo^RnumWX䷒TEƪs4eZ/G,NIP9&PTTewgi=]ޡL:*^rIVr5մM)j=SP5eݿeQs7 KeՄ'Zm :G{"Tę*qO0iqJ4UH'g')?egZQqRXVtSo͒{Jn[_pC9&]j>=_YIЯQXLSi iLf-,'o5,1ѕny%99&i6TiG.Ej[;(8~Ο<+7t_YAxSRt8Z ._M26oZE__$W˦!#R'J)thJ4kǖOSwk@[t(ͽ~(|/rMo kVw]5Oy_6 >7E}aW0Cbʎqa M屫 5ƻxj[@54YG|?džl7Zt96-(.&ٛ͟kϘ#ˈτ?Uw_%/_B_ժo.^]uK&v'h]k? U |Mm֤q_ZCom^_Ez+].]|w_~f׼_`xB:r6A v4PZGYH{Q-[\UtP :tybfi|u`irٸܒqЉa0椟,"-^-gT k7p_j^Gရ[1e\苡_.^\ۥwJN> (ӧ`?\%'lO:cx>K*N0kX%ug,+]%_SE~:։iƩjZѾkXi!e$qXaqӣF;ԦIΓ<.%'l$uxsO#zg|j{W\ލkYizTAvgook_ƭh%T=<0)eg_U4[[Zmn&^ Q&K&:_ \m,43KŎ-M KL@X ~/ Ξ1JsEjJn8R[Y_KTΟSdzYZds߅׋ouo^#lSoE/5 o|)%$Q$}:)9!O8N* ~ʞ"UvwKH$CPnmW)o>FLK_mo+|L+ B=G\XVҙ57Nش˛im wncpRx<7-?zV9˓qҟ4v%éEI)sw{&kcv ;MƏe+84xmVTd|a^ꚍ <{riaT.*15gbG ZVBcMIFեw,=ESISUޓmߖ;~͟tz7,uKĚFckkWSдB[ "u+#y綑Bx8xZUʜ(?yNjIENnQE+Fi6DpxMN4goFvvWJև|(_|M__G?<w gZ{$IѴ;Q '6VbY_3.`hRㆄ'R5R*ԜU9䊍앹`eJ:?ܹ'4.gbnǾ? |5nݔ~"E ֱeJkg`;Y*|WQ֪iJڨ0)lI,&q%I8\Zn|k> 0I5m$xwA-|7:I4qkiuZm^Ķ jBMN+25+a哧V:r\Z7{xz//fV1֪j*miaw^3(/o|#)p_jKk`LmuHb{.ds9W0#𘚾ڥ7474\ۊPTRU!W)ǖ.HV|S։o>7ץ7R[k[+Sws5ĬGvnMF;"OIQE*trJ)um;ɽ۲*sp+}}=g~s=# Ztog ,q]j\(DLaъVqc^TG:Uj.ziT'm|Wz =N5MJ1Чc>%xIo^cSj/ioq~A]!a>ocܦGi&f\xO7#ORpw)TQUeJ/)qUj{UM*}mTY%}՗to |?x H#gc|05}vywWNukg[퍱Wjle^:\\<b[?{ \-(}-v(ƚܠw3~&|Mw^Ck:Υ~ڦsm}o%԰_7=Mm.Y!dtYoʫ'<}(7 mTA88FQJqMi$(j+n;[|/W}o GI~ͽk\M IOjstM,׊X6acTCSV'}=l .HRQe}Svrfֵ|;l.5V:#˭hzF\Z{GGi촨l̆*iԔhNceKӲRrc*!e:r]r䤣̜^{j)J_k"i~яût.Irzt˛eִKf5)o,XI˞{LU_51PiSV4Ԋڥ5 r?S(>rҿ*OVy;# <9xc֚MuCwJg/uK]jE.eI`}Ns$$)*xaʭ ߩ&b?Ke kE?f/BG^>;_qqC>¯8 ( ( ( ( <|+gxsR|^\OKR2''xEFH[XM$ph&XVAq,1Xw\Ɩ' ʒIOqvNPiV7;pNS'kcx(aaJ ubptUHT:XV*5MھcrGjze I`\^j%fBFY#0n#*(x)T:OfҡrJQJя4a6+O38vM`sZxZXL)13r r&[⥄x]n" RQb-_'lm"It_9rE"0## H<&n\~js܆ q4GGUmxrmOx"S)]\\J~1p?3|'%|_C* eKRi`SF9,=XQ6k]`e5UZOVNIxRIF7MɹKKݳf߂ໟo|acw>5m-Y -F{KG ߩ&b?Ke kE?f/BG^>;_qqC>¯8 ( ( ( ( *aEQ-aw7ְ_YK%;+xo-Y,J!dpU:QiRRqIu꘥_zW|k_ŨCeivKЮ5o{3ᨏQ{m&ԯ֊sX"FޒjRυU fr!,,N Zj5g0ҡM0ܵcn8rSg dc %luFNiTcJ9IFn259JJ=5~Ñi?.uEoZ=ih$yKmlb,\Ĥ($/) q{*T,VbᇦK*ptaSQSb> УxjA^ʫ*Q*ǕJUjӧϏCeσu/h!~%&MᏅ~dWXb?~{kh ϐ K*_~*8upq|=z|Ei1UTC ӣYӪKU5q?e{rN)/"u:X*` OX8ISiFp ީ%~gڗW6#/OV׵ ]UEcc )c;X s2d3V =\^7J0Tg*t,]Zy)hES3=J[q.?=t0?۴0PᰱRcJXzTƄUYJ޹jKj[$.7(xs+:ױ4dj|~ %OR[W῅oӓ1"^#8!aWXP@P@P@P@P@y/$xQN?-/^?o[>pU5=p 99ښ@76<_q=ÄS5Wce{_:ԣ {u~Y\ASifqQi* e^mZZ|?OᨵJSRK"4i:-s۷گY85-&CH[3ѯ'FgMdXI70FeU<hӊzZΕHr) !3\x90Jw\XʕqSJtp\&;u[77?g w%Jq',rs_Q2.0aL=,z)Œ^E,ULoqoq<;zU]%6oCm4']k:<}3P-WKg gp M⸃3U<>c)ӋrTj2eZ5(Sof 6KgL Oq=qX:ӖT[Rm<B>Ԅp59Ŷ0ipi'XoJn j[[LUUz0JQwjNƧ纺Ft}qu[6ɳ 6&ymUZ2FM'WgK4%\:)/?'MCw||BգZ(v_\i3@&Ma?0?P( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (4$wO-R'=Ko|_GSNL~׿~_x|wO?4_}^qa@P@P@P@P@|U~HӴ[B^0./.=mkko/=ij:F,kl;PBMR 촒z;.ˠ3? >=;^K|=懣[ |OkN twKQqV[XR8L.3¹pW.5̲LqX,X|& K є+e9kUi`K *r*z$cùf7<6*VF^֧ ]u*Ƣ|*IԓQ/+WsGmXe>xZ//~vVO Xmcbw5|xqpO 1C2Ͳ~aQ瘬sSXWVIqZb)ReXw3 fQh{ yѮҎ1gUSON1)͹NSs-owƨ>|K1b_Xan4Ivsk$3JC $bٍ<,C0RUe8МҧZ~ͥ)(NT/{Fn Ҍ}79x?3<޾/ Wfkf^,k&gFLSJj1m&s~ څ|ۥika` 񕓢=g6"H_YOy3<9ΧHF1HBVJ<Ҽ"5y%~?#3j0q' 'cJTstaU8Su0{LF/WW*Fyes[oC/h6r\%R2OC XW`5?2L~OxXS¤* ҫAr\VC.(oc8CnK'q*ң %?c2c1jkT>)3|8|Q,f^hyk{fO)X[\GF⸍u(0өhnRvkۡٞ]SqJ|E&N7%(IRNZ3~Ĭ HĵvOw4P@P@P@P@P@P@|%P[xk=KLXxj>z7ëvVαk=VA\[wh|Xj ExOWӼqsK#/>$CM5ZObji2sQ?j/~7O; mMg~i>#x{U4 ]x'Í/Fuqyj?~5;M#u]v/_߇Qj i_b 5j2ٵ隺YE a|M&D>x-i)>6i|?K+x^OZ4[ cDi]ZLX%>qYRqs麦G4_W>5<}KsΩoɡ-֍$o{c/?uߋm MZPo+XլXږK;b9>ECH>+|e14|A(>9zi|-u<V3 scSnيona6 Bտk 6 j O |Mk;¾;O xoNFo|R]xHѼ9-tV=>k/x3VE?GǾ07+ڟK|d~$U _k2j-ZoZl/iiC7^ĸ%x?e8ByxrǗzƍaAzu}kKb4<9.?)M&Ѵ|A/.íehZgiu}%mn.mm N̊@P@P@P@P@P|h;cɧkl?) ſJb?V> ߩ&b?Ifk[M[[Mͽ&>h߳^"ݷan:nSe\GFo[Kr>,? io(m/Z[,?[Kr>%eϳ? io(m/Z[,?[Kr>%eϳ? io(m/Z[,?[Kr>%eϳ? io(m/Z[,?[Kr>%eϳ? io(m/Z[,?[Kr>%eϳ? io(m/Z[,?[Kr>%eϳ? io(m/Z[,? 77ז'@]J:P õA$ZVbd/ki2Qg_ YpA-?-}KO9Egki2Qg_ YpA-?-}KO9Egki2Qg_ YpA-?-}KO9Egki2Qg_ YpA-?-}KO9Egki2Qg_ YpA-?-}KO9Egki2Qg_ YpA-?-}KO9Eg nԭn~ uo= j%MN;OQI ZV; կBԾaf5 LKԴxIt- %~GΟa.%+cyy@Fkn,FyX~=]/<)S]5{M|Sz6^/?|!iZ-#߼cWIyf5 _ uxQ*iiw>v׏-oleO%;).K5|u ^_ -m'YAo E!2v;59S%.9,FAr_ osKh^63ſhMƻr.־FW>~XxIcx/M3AzSh`]=ncۘe[Uф f5 ?#CW߅_|=OZO5iVRi6 j~)յ]fHu N5[$rtky KMz -|U煡oujvb=cQf-axZ5*Y|o"/G5sClRxOE⧖YѼ y:"L$-^97^#<U Ιy{j^ywY5֩uf76}ݭJo DQ%ebtky, 5 U~(<&%_ jV^>,.acuxcpO{׌KCv^UHkŷ(~$PG$@swOv&<% i>]%I|lXu9Kbnt~W`fȽ/z5r1~}"Y`^Q[p{Z4%,ağXhzW5;OsE jR [^jxW1C6,vub`m3Pմ?U]NPS5-R;c4mfP/9Me}kmso x9ctSa>$u]گĐ}j^|^myþ*nW!$'h?@7(wzΓu c"_ok3Ɩ3X֮]d{i`ybVxboV|AcOu cK𡶰>4Kꫥkt$KXC=ƋioM4o:t@=R (9_MxFG|=&S JM.gCiss7ē$7Ʋ+E_pUP@E/OiwjnoA{?u x{YyGA^x ܠ(wqibe:riM,4m˸P{{[eDwe P@P@P@P@P@P@P@?&?DkC) BSԿVg῅oӓ0w|OPb_ӈ~_%pP@P@P@P@P@P@Hg' |1Og?ccƞl|OdռZ4}V̺Z_fd7 >'j%~߈Dž|={j)sgwGKm>;;'+?_wn_r|qxz !k$Ox N{ƺ.ld-5%gϷG^|"-7Gw?d?jKt yW?;oZ$ԯ> x?_/6:.'wsq/ Z]/1a7Ϻ~ :i EMW im'\{x^W6)/,.-d}o~οGÚ|_ x^|KaoWGPо(G~92wZ׼`&-u+oZY+Zy}; o׿u{ٟGiu4ԼZ|-E7ËmDEқv>šTBUBMfWm-ۧ{|>_7ƏM/i>*~ WZ[#υqcxE;T&MA:ַ_ EWYM~kmjtC<⅏R5/J/|;5{P?ۭiۯ`U`R|q>qτ~ |!/_x|A;Þ!>hCr +SIewV^Ky𿇬ʳ_-Wn oŝ7:go<w⯂>/Xڿ/4ψ91_\>4 }ZOcn]7O{knu)~*o_^i%xFi_]x#?motڒLVgWE] ZibL]inS{xڿïA~?ox6㿆7 k?lWM.i FUBUեL*t}ǣh}_?W1h>*IƵ/|Zd B=ğG^ѵiV%-n-|=Gů|kk_6W O\owst\zy%밶zׅ|Kg*?hM{?m.W9+Yn5Y_\]#kuuŪǨFҵ_ݨ(ޯ'~!xᕏ_x~!xv_a]_JӵV$-5-Ϧږ[ G!ˠ  5C yY_=DEŇ_+}XsOM4\M{I([_^gD'k}{,Qm [4 x6>I>C'zۿj^$?/D8S\eSEo⭯MkL٫ikof˨;ƻڧ:_*]5?!~?|3S^A,t?隿':|_; w?غ/u}jTɲQmm=G̾~ xs{᥍֥g7O3m3$:< h_<9#iqE_;"%enEo5/ߎMwǾ Ş#_? +ωG5m=>N<'?FesO֤iǢYieo-o`~|mT#'ug_/t_ᏓS>/o u`Rở]:Ҿ5Zq[KirS[itÏor"ÿO|>4[x_oi_ $|%-JmC⽾kӭ\Z 1Z6Py·.xN]/xs-Mzkoݬ ѡWJ#i4f}g\[\ULj:ZkY+z-QTykV?>;Ok<C=3Im9 [ſv$u]]߃eeOZjE>/0>h?wBoc[N𭦋e=kMt_hE<'}6{]wH]BKi:=?C񮛪1t;Yk_ۮp57_^#ecÞ)^+ݠE?WqG{xWҴn?,ro.4{{kMKGs鶥o{:8+c/ojshWo'ADi-ԺXSpshzeuK47EgD:'_Y|X_xP>1s/xC| ׿fkk7z^w=<{ UZ-3{f=EӼo0|6<_ y!此$7'k|8KG߆KZZm/mcOk2H/;E$dOԮm58I/`::S%?o7;#Z'jfӭ|ۙLz|K[6Hxc#䬆.:/././.9U/?6CۢU?$yo[GfO<7>OEl)[tOVӴi?oI5;-==֟awP\EGՂJא /././././.3Z VBuGOm;F:=VJnt=cSizQpIX$yu?{Q𞓫ǧj8υ-o%i_͵;-<뷷gy+!)CL Zto5oPj/4x.PwdԟRPbӵ6Ke3*iw݁:_tt]`:_tt]`:_tt]`:_tt]`:_tt]`xB:Z.Njiڮ2YfkQaZ4[I::)?UХ~oQ=[NѤΏUҴ[&XZ}޿AsqmkV +#^B$.4?to W ~K?n W"?=}o?<ߖ'Knvn_? M+ /#gA?پ3h?to?to?to?to?to?to?to?to?to?to?to W ~K?n W"?=}o?<ߖ'KnvnP@P@pF?'gO %OR[WSNL}cB_E?gB ?#N#Hu~GЕhP@P@P٭k y3~8x-gUO|A&o?:.tuMiZ|1Vy o#v%Zu<⟍~,K? a>w?{x5|#77Vtkk/UoWIƺVJnj;SMkXlAi|=iǨk%q[~FǓ?;wUtmCxn?mt?گ$]̓c[ύ>'gk?o>Mi5(O|C8_O$+?^)~s լ7(|i㤚>(|P޽ V[ML\ M巂<[Ꮙz~p67z[^X|cvXU^;Ծ7g׎4w'|5!Μ|l? o'| cYm_P>2#3F]AuX;|a|%XO'\|X> x[lj>xZ5 m_>%MeokII|Ưnѷ6 o PZ 3_~&ٻZ9ҼqϦWR]ꩩ6que2yd6>4MGş>(xo^-||kۏ&Z -g=?\8tzoƀ,>1ux Nƞ&x{_LR+S?QOě+-v?w~]CXoGŞK}k__`⟍~,K? a>w?{x5|#77Vtkk/.o5#>&_|S?߄<#Vx{Hw,? ,|yc+kQ @fy>:I 5etπύ|q$[x+Až?gcwMUX:=x"oOkI_j~>>eeG>𞋨kMoMv< exKߵ~m8jחPx?|#־ho$0X-k50׎< +5oW[ Mۣj|5p|AnF gl?׉cAh c?Mqc\5o'w/j^(,f:}~ 5Y]&$:QF z|!:,jzh S~0i/$|,>4|A˙N>i؞#">eeG>𞋨kMoMv< ?Sʼn~'? ?/ofOotfs?΍xe>0ޥ?qp>8x}K'!+N?]+Úkě?3~C;7tX|Qo|j{Wڿ-4|E|4D m?si|q.Nqt~?K~+xOw}|pxzO_CZV6W5={L46g#AwoxH\AE?|3Pxƶ6[.m4?L5sWm%xnּ!k'txxzjmiM\E]YLY6 ]r׀o"]O?t +_ "tg43ix47PfYWYrv^47H=Ŀ|pbZjxτ~$YkO<'ťx>,[]Wjz]ΛF>kgwC A{ϼ6O>^q6qt{^ X|Qo|j{Wڿ-4|E|4D m?si|q.Nqt~(il_о&럴|-C#<[Vx{"6>Vwa, /-y{*R, @@k%q[~FǓ?;wUtmCxn?mt?گ$]̓cgƯ闿}xGߴ_OG 67mJnm_xJ!fy>:I 5etπύ|q$[x+Až?gcwMUX:=Oƿ%?H0;VS??YoP:5i5 3ſ0m楨x_m;:?~7_.⯊57Ú_v OiWSvxEԭͼo#?|tQg׿xjik6{|IV'|1>O>^q6qt{^ @uej.)տj 5ZVGvZ~:/ct:foĽƖO5? Uml|I7$`x"oOkI_j~>>eeG>𞋨kMoMv< c /_]D‰M/P(5x[_g^xkKe? ~~+l (|P޽ V[ML\ M巂<[Ꮙz~p67z[^X|ch|Aόa>(x;/~ W[|-ycS|a|5Jxᦳ=r-~̹4Yaɷo+Ƴ xWھO ~ l/~ ᧊#SoV߇muM6ruÍh^ЯK]x cYGeze_'j^w)xoÃw:}ͦt:Ҵ[[hW%ҮH~V?UO(^a1U:CIuCX `|_5ѼI\Yy|%i/ŗ3|,:xZDz J)SNCIuCX `|_5ѼI\Yy|%i/ŗ3|,.*B ?/#k?bwK%bdwWV??v!G|ky ~7mgG|wQ*Uk/ @5f)}@\/xS4v hxƶ6[.m4?L5sWm%xnּ!k'txxzjmiM\E]YLY6 qq|l5=K߃| {?\9o-S:惯;Mоx>kiڍ{7+kKJZtt0Ю J\+iJ>XI)+皱x<*hԝ.zؙr)u9a -v5#(-,kaѿ#ptry?7?yu\ACAs_uowB?<:G.OA ?;:!<<Cd{R??R?k+uow HГ;?˔~/ 5 'pa~$pr}y ؟r[(~2xHvK%7Zn?;hO*z X:\7rcw|OPb_ӈ~_%p|<)⯈OtxKO@jP]̾;XO5[XI.{V7J/6 j/ 5ޏ O>M7^aψ D(}{7Oi*=IKڋۦ߇5?h7 ֙Ih6:G>$k?_ ?k3~}kOv?Z`4mᨗlzO+5 /i}K[O|*ewM-ޅ=O\uz47ڗuM%tJ[{K&IRq?6L A@P@P@o|]]oڀռgxo:.U[Bu?eڀյYjwouąͼo# ( (8 =u_?+P gE_js^.}CL}{Pz8y8]Ht  XyGa@)v?CM}@y*io_C|; 7WEy(( ( ( ( ( ( ( (q߳ާ6T`?3 *"<; g>ZUlfa I^xǽp}Z/qj,>vI_GGڍ,<x5?|./_|;/G5 ^EK[[Zk0i*Q+8~iwӪ[?+K=7m6wдwtgѾxWzghkr³H xxo'us:m.Zt촽Tm5zyz8{kki^zF/?n?oNmľY h^&5޹gx{ic ~Ͽ߷ w>:qWͧyK>[}zu]LVmz,OzΩoh>e|#fUӼ%m_f2\M펛rn[z]}Ux7tZuי3_N^մzBӵm'f/VYj [jXwSE۪iZ]Y[8۽:? Wzv߼|Y:*qTĹ[ihnrqSgo?k_o_aҷ?> ?_+|3c ߩ&u ZȧV^^/}i/M<--O[gM?%# >WggKi/VO캓x U2Qxd{*| )sh?izmDžVMx.,巧o:sbo{XơU>"kֿ!vw5|QO+JӭumK$UV^sѴ6#/| iXֵWTcIjE'|[Điz-NMbHtM&%Kv8ckIo#>)-:۴=?z>,58>ա^6Mi[J%䷒\-~Uj[Go }o-׊$DvEXq? #EѴ-r}ZMKKtnM5k'NbvPz5P ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( *g..6oԭTmO}z; m>iwC )ҕ쥅_GɀӕҌV]oe^G'Дdŧ=8dްkc"H[jkxEᶹ} 3I54oouN׮Xo`^ž]?VյIkS;>g<;oku$:Vc Ggam4cd_ͻ^+W$q1ܹTw{Zߕ\A{Ƨi O5?ڋ\Ү0H־(V4Bܰnktsaa%qk(=SM=,Τ,N>Q}gJ2]ԢԓgŸ'=Ko|]o?η_w ]? +08!BW P@P@P@X( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (qfῊoF⯇?O,I|I ڀ% _mմUPcH{,.;{RVoQW_/bg18,=z[s˚Qn#K5~kª(^  G_k| qU_>QB'Q/"?3,|xO& R8UQU`c eX=?  9QU`c+5@?I+s W?c77 ?Wj?+/oC+/!A|>9 ?3}qJ^[oj?AR/>(m>mmmmm7$VƪhEmʤ[mݶm[oVʡX6I+$I-KD?'=Ko|^_O93_w ]? +08!BW P@P@P@ >ϑ?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#K}C[UM/}oTr? M4?տ%Q?4PVG#kAP@P@?&?DkC) BSԿVg῅oӓ0w|OPb_ӈ~_%pP@P@}?-O:OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsS{h]!z"λ0BOۏEv`OG:? ?羟n?uـ}?-/TZ9f^=qȴsBa@P@POIo<_Z=JB{?F~dПT/u{o?~G?-udSp+X/?4_} \&@P@P@n>)u?yĿeV tH \$ ~>5-2Ė?ڶ+ӖBvjzTڌuܺs-?UoM s_=EO+oYz~O(g_ 7?eg"+?*_y kZq@4KP5K SvCLj<]_x$^ |'g=->9uz뻍{Oߏ-kioYzڭnjt []}@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@[ R8&ꕂϰh⨺aO* >>o=Qu}gٍ7VpnmԎh9VA?>i?V?*h2r˳vo/,?Qul~qѨ-Դ-W:lj,uOG|!=JMƅij?>ciu} !DfbBluZ4][Mbz$"U֡E> \:=2^ >K` weceuIhwvk2d3H|>4 $[m2r+i @k{wnǿǠx;K͊{h?eS6o#P/\6?71Gz_> xwO4OzXxW~/xH} O:&m=.W" c?L/}ɨK xRj5cY#<uמ2񭼚0O5m{PH|UAKZely|5qV[(CῃO:º[U1xA>&K-7ZTү-l/fYl}@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@[ |A?>-i:/ntSt 3M}r}>10,+a(G - Rzy*$+,1b1-,UibJ5\aGZ8G2iӊOg?o5_QUaЫ ߚ^^?m=/_ :Ǐ"/ueQB/~kBv Q_#eฤL9bUq:28 3GviӣksbxErԓ!u+[o?h is3O|Hm$B^Skmv$n sT]jxQI/i_ Q\')Yw+,oN.NJl]ݪt1UM_-8F7>?_+|3c ߩ&u? ZȧV^^/}i/?'Uc"8G^4/lo^? a/Aėmy^Ϳ?xU5xo⦯OKi! 4/m{C_ ++GKދct;ݯESO<]|bx6\.< |EidoXxLb?SSx-j-*x_o=W4o|;%2ZΟ{oi>ĭOJ'WYF ]75~AV~7|+~Q¿<>k-Z<5lν$3]C O:7Rk[ӭ~z6_S=;牴Ms:OCRXi ?Cjv? v[O&|Jr|2omt ˫o " nf?:KGx%_}:gO]xo?>&xoWzn⛻Ox߅?Yi>XWt=zmrL/ɩxdksڵ})﵀ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (< u4߇p7ǹz*'so ֧LKpBOVտ*{ozW/]NKZܻ+|-^7&iڝǂs6xſ|3<w_Ow!yi+Uyaiw}SRw<> /y4R]i1W^%%{vޏM]vV]K⎱|Ltk}gï[gqG|gdIht/H=Uˮ S"o/z˫KNտ+]i[[OQ㟆>9 _xrWE-}B->$S_45ƞ^|0Yh4;M;$<jZoGB^鮪_{kI$qM蹞oM>Ǻ~͚ڮtx{Lexg_ 6i6#'u3WIjMO.j:m*-ki_*ˮy-?:vvG{oƭRK|m_ז5I$Sgծ7`_a<ҷ?> ?_+|3c ߩ&u ZȧV^^/}i/M(imƧuc]kWzͥƭE,Z41&i6+<[m2+h o"P@ xk-!¾~xoI[w-+Kξʉwq,6mcr=P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PV</V4 'ϯx_e|O Zz׍u=6HmX/wZ]1>/x6n Fx{ϏQA8# {ϏQA8# O | Ǐ$+|]ۇNl&е^ن͛ oxn¿}:ƱuᏋ';i,&|]]u4y$zt:.Tc1E$WXm*!zPM/gJ7&\҅8[Nfф SIJY^JQO^XΣQ_SحU ߩ&h>1!k"Zyx:#J4 ( ( (kP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@xn0 ( ($7/Ph!=?2hO*z X:7rf#)8Wa_qqC>@ ( (4?O jq)Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]KPˏ9Eekj?2Qe}ڧ Yv_pA-C.?]}0 ( (8?L~#؉G ևR3'حU ߩ&`>1!k"Zyx:#J4 ( ( ( ( ( ( ( ( ( ( ([/¿ ekF5񉿰KW>-WZIKD5"$w~]M,_ip\}r gto5 to +Zi9u쯰xGS׼=ͭxRҮ,5)aw_P@P@P@P@P@P@P@P@P@P@P@?&?DkC) BSԿVg῅oӓ0w|OPb_ӈ~_%pP@P@P@P@P@P@P@P@P@P@PϋvaZxOlj%^ZjV]WMOO@9Oa}sKi~Wlj#ֽwxI}b[ Ez<9]7¿,F^'5ox.U w/Nq{][ὦsg[j7zfƫa:i6VoO!."}/Uĺ Ś|B⿈ZehS~cI; 7:KB<;x?]ҬKA+[] GT( ( ( ( ( ( ( ( ( ( ($7/Ph!=?2hO*z X:7rf#)8Wa_qqC>@ ( (9L!C_yUtO@TO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q/iG [Oa?* $xC K>Z*}s ATl? 5o_%Q<_SCO a&^<* "\UH?2 ~T}O@TA ?k4Jxȇ0GL!C_yUS-o?D>?6e7//k!'Q䎒 ( ($7/Ph!=?2hO*z X:7rf#)8Wa_qqC>@ ( (='ؗo11#4􈝥r!@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@/饶wi Ƴ4BH4r#AN)sVӞG|U> t|oxoMVai-OT!#%Ҵ9V) K=坭RF~K_ _⼾>4+ Tѵsc͍E9)o]8%T/ˌ1^T,+ ( (8?L~#؉G ևR3'حU ߩ&`>1!k"Zyx:#J4 ( ( (~;~^7_r9p_KHW)P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@Tk57N?/OKt~>LG?WRe_x^/&4K= YX/Ѵ:=NQ`Q #MM/R:|lV{^]m6I_q|>о<:/-5mRQj<;BV-e+x@,spg `kܗmx\UO%MWvP@P@?&?DkC) BSԿVg῅oӓ0w|OPb_ӈ~_%pP@P@? Ŀ Ư?L/yD+ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( xg= ʮ\M&О<~S mPW#j/ _6LRC'#x :_iZC-.̺eռ -RHK4LQRWS| xTѷbTN ( ($7/Ph!=?2hO*z X:7rf#)8Wa_qqC>@ ( (='ؗo11#4􈝥r!@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ZgWiK_?Ɋ[3V&= MqbƳSV/}1SHg!\XP@P@ScO?V?GpҐџ?'=Ko|^_O93_w ]? +08!BW P@P@P@I߀KjWK˃tך_DNҹN ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( kAK_+-cY&8cY)|JFLWz3c( ( )1b'+Zǣ8HOg̟Jb?V>w /~/~kGF+( ( (Io$_%[Lv5x_~a/"'i\HP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@PV 륯ZRbıլCwoرվ _a# g+TW1P@P@pF?'gO %OR[WSNL}cB_E?gB ?#N#Hu~GЕh>WSԾ7׾oÑj6xNR<3h:Ӵ ׉C杨 .mGr`񤱸UNC 0ԥ93dy*SҩFI等)қScR2ܢۋƿB?<:K'gPk@8O.G#_??5'Vp/Cxy.QA7{\0_[HГ;?˔~/ 5 'qIo_mCHj/}sNu/Ij^̺|hZ&u ?dY*K RjUJUQXVƄ9N4)%Rt$M_P/N8-: S^U! Tpzp2Zv;=='ؗo11#4􈝥r!@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ZgWiK_?Ɋ[3V&= MqbƳSV/}1SHg!\XP@P@ScO?V?GpҐџ?'=Ko|^_O93_w ]? +08!BW P7e͢wU-;>憽LŠ-_ϖU{[{p׭G^=11\VgtK/+v Ҽk7oV5_YK௉ßZwE| wx~"xZ@<:uyZ$z^#6GI-oWkq_ivw[Gh?mu|I&ŗ71|K' '3ǫa[_qYRtQidۊת붏B_i[zϡN=?GVK_1^)|nb] o'&q>1!k"Zyx:#J4 ߅ ޔ&\zXͩoXGq5m..m|UxN&g4?>!\1ƾ<;O i/um/K[[SP/ɨݓNJN櫮ேWvZVOWĞ*𦏮w_xX>Vo'Hoĺ\oZv}Z['ݥ}_vq'^w _umKş4-G?U>ɇiF|եc kvjqZE(aMtxHx YFFU 5pb)RvʰXȹ[=P='ؗo11#4􈝥r!@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ZgWiK_?Ɋ[3V&= MqbƳSV/}1SHg!\XP@P@ScO?V?GpҐџ?'=Ko|^_O93_w ]? +08!BW P|7oѩxK@5x#!BGum*o-UT*8~ aU|UqLN ^VFe[1?H+{ o3,1?Wj?‘%DW?GoC\oWЯ  9QU`c+5@?I+s W?c77 ?Wj?xkTr3 |}ž./-F- 荱خTq\،n3XxjTQ{])VvpX7'Q9+7J)7&tu? Ŀ Ư?L/yD+ ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ֿ?tҸ+J_LR٘?z1`Nm5"a?atתC9 :€ ( ("xQBz?~?_+|3cpɘ? ZȧV^^/}i/M ( ( Nb_cW|\\"vtP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ek_ Z\/|&)lKZȘ0~'6M[0R0bO!sa@P@POIo<_Z=JB{?F~dПT/u{o?~G?-udSp+X/?4_} \&@P@P@zO'~/cb_.G. ^i;J:B ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (2]- җƾf%ޭdLz?xōgH?_)c?1_B ( ($7/Ph!=?2hO*z X:7rf#)8Wa_qqC>@ ( (='ؗo11#4􈝥r!@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@ZgWiK_?Ɋ[3V&= MqbƳSV/}1SHg!\XP@P@ScO?V?GpҐџ?'=Ko|^_O93_w ]? +08!BW P@P@P@I߀KjWK˃tך_DNҹN ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (W_]NVzm.l].cK;,19 Fɪt*Kս5^\򡝼HG/-τ-˚6G\<GjNs3L+OuSHej:€ ( ("xQBz?~?_+|3cpɘ? ZȧV^^/}i/M ( ( Nb_cW|\\"vtP@P@P@P@P@P@P@P@P@P@P@P@P@P@P@P@p??MsMӏKS~.՚O'r .;$ڭI>TMR TJchgH.o:58jKf7k_[G!|V– ֯SՖ'Q衺xfP9c2GN0>Uz;utg_ି^+2oڧ­bXUkD2CZG m\+y:Jz>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9o)SH=_'aϫϯOH򞏪G=O/.}[}~ G+}R?W s~(?sS?_zOSßA V_ =Tz_\ďW)0Pտ$OG#?>>?#z>?9axfo xße, u}> 'qafE^~/͏vͻ9OsI)[jowiGMmc|eQ.t߇ӯtۉn[E@뜩K}4Iif[?uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.jcasgen/image004.jpg0000644000175000017500000011455011665471326027643 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#"S !1QU"2ARSTat3q#45Br$V6bs%CcuD,!1AQaq2"( ?ު05$05Hlanl?Zn- ynwgq kp. x\YQRzؙ-;CA\޾X.#u3Hwe.kFh}KwM?A\va:3xx,|q4ʃP*UFXFo ٽreti p:i+2\r )06`Sjjn]m͝1[e:/Kc0+iem|22 XM F`ӳm>Q)Rx4tC484:WQ[]CD$s@%lk a5.3ngA 6/nRrg""!GM?ANC4b`*Cg٬~Ns߸ b 1FSP`Z,P#ջ)hpiI<_ej:i)yoy1JZ )6gsNbCCu;X4 e{!lyAls6Vm;"˯,XM]#-^,ac'qG1}%92272]{n6t#H;)戢p9".nI&3_h_˦W8i?ŴJ ūR}#eWcQx"Fl38"jcQ ^m+E?FzZ>OSvLqaRG`P.,آ kgycߐzrtv]y1Ky%I$z4z%OtSlfPۼ[z.Rڧ`̳{d=ܺ9HgKW9XX$LT2L/ *f{3$^wUz6H)4o,w9RK;Gti͐w?X#dS49f-<#:WSP8X_sM."[tl|L'ʶQK3͕VO8_dV+p1_dS͕VOl\ n:g6WY>TseU[(͕VO8_dV%seUN:g6WY>Up1_dS͕VOl\ n:g6WY>TseU[(͕VO8_dV%seUN:g6WY>Up1_dS͕VOl\ n:g6WY>TseU[(͕VO8_dV%seUN:g6WY>Up1_dS͕VOl\ n:g6WY>TseU[(͕VO8_dV%seUN:g6WY>Up1_dS͕VOl\ n:g6WY>TseU[(͕VO8_dV%seUN:g6WY>Up1_dS͕VOl\HcQUG#I+'͹#eےJHU Qfqu|l1-N?YJtN x]KE74kA?Ⱦ_>B/F<Ӫ}ϒ-[@9lll yR>QVn @X X@.;?h pڊJ JT6CMI -s H߼Ehn a5ci#;j!Glֆ,,@W}tZaH"%|q+3LƝkCm\f6\/:E ] UQTOC-Y-#lgl]i?Ki08[ Nƶ7Ml>ztn `h,/fo/+}~,u3%MT1; e\Nfs3\\n*4lB6Fx.!EL˱,xg@0 A-K2Jf9_e+{hMDwj[ѥkg}5t08BeP7&v^6 %CD+0m%S.H<~# zGԎyhL ,ܹ&EP`G [-b[k,:4g4z> jf`mTgDa2\5-;ǧdtaJ |/|ou=޻MMGCM%1 DiEqkRZ67G4jkvl&~ClX-mMhXo8Zr$: f<AJ 6IkB,DEs4O<(^ֱ\NKDZjQAO)ěE_`,_lᢳk f*x‹R1h8 %@+cC Z]};d,O|O}ApA'+Mhcƛk.;I`2 m̑4L2y/>C; CK\\mvPB Zf&ܾ_GWgv9 cK /.gDo`]2?suFmmvޝa+j<'Gn?VU 瑱B׸xDS>5F/ JUK63$k*#so6q4mva *ӑc2捭cF`r XJR^a}tՋ>2JY#fPV11 ǖ3+fPMۙh)妦s.b֒l۶o763%߄T䕾Cgi kAe]MD^"JIx1ݶqo7{9維;H@ G)h+e'clNɰ v1oK*)txm 6Zxpm(nx mj$}\݇eAK{ல m=x[|Ƌo\.tksLܭ#"i#27F ;~:6tK /.gDo`]2xpeR=K qz,"֝L8ik41w kftCY:5D#"/7U2\CTn]Ϣќ*heߕ3mԙ&1S0fdn(5og68"Lc+B CoK /./9':ȣvwlpzoD Zqz%7gbpzoD R,>M3(n"މM؜);,>M3(n"މM؜);,>M3(n":7I7G#/:/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(thnAGؚ/܏(tk;(=[P{%(_2EpJr>|}ԋ; ӻ(^ih|b3W4uR5*5cZ KI28lH^^燹gΌ; 9;7߅2mcjn^=ѐ6{v*)&&unOP[O^kXA68Z9Et{ tts\{,470+l6 : 5Zx;>fՉc{+i40ـ^뼊羂^R Y9 I9ѵݙ,,"Z*)FaԴ,i2e2OhWwEu̕UL!Vii a6&1~[ߥ09Qs>fDT+;,lm.'P53YurǭkM@760&wJG3璩N0J26c]i;U8Ǝ7pp v4=9 qq1&θR6yxUMd-8gX#Tfys3,`v濫ƴ#ðXOscq^ré#dڙ_+;͘wJ9_(Zlms䁷ER20:xk ϭ\\\جMvC=4)S .s8؜s}'66Q#5{YHlVcNf-mʱ;\F)ӾG2:m%+)˙`Y>w\o+)M1 즍T=y}ޗ (njb&1Y5bPU1LH0G#3d`9mUI@ktwiWfcQF.<G1*fRuP8%8Fb̙Ѽ:zL5̍c#sɶ302%2A nmYձwضYa=Kv؄`,GOO;;HcNahpB4Wv!U.<ϖs弆VXx3?+٦Dz56WZ;fCw\/1GU[B\du`7mفe4T6-u4q)k ZNcik%j!d7LYcf;=ĩ)zFE]Wj1kvy3C2W]حn%[Pd.o d'! *5<2YqF9n !rv`@10u*5\TGOpKQJXX,w/;Ͷl-5&-[E=][V2(bYfKF\iqֻV8Nm7~zx e>rmFm9 * lEQOsFP{.OzA_+^*lUA4aiۂcr:SUt.#l\ؘ v`\6]r/>)b-17TS=3CWZ9 gI- LjGN6RZӲIٴNMd~`{`<Ѷ$MO|.Ey\p/,nEC lu=5dXہp^x1150DIx?0=⢣E&?0=aM5BKF`tC( Xm}btRdΟsQ-%LBXju@pfcc p>!Rh>!Rh>꠭}L8fn}+,{E)9_!m쫊)rFr$.KI:}2COI:}2COI:}2COI:}U*(-~Ȉ""" """ ""53)0~z&x8.`?N`kσ{F ?V81ruOcv_}g*1/w>dE9`P iGEGO$kK>ώ.NyUm,4ETfr=t-Jl.}|-Y$:E=s7a"ָHTgvGMTG]_P]Xt:[#3mp+ZAWUA lr"ҵkl^ ?a{+( h{f{־S} SPB"q57;W5nj2kZ#yqcn&׵snR xy.#}LiZ-ܛ4X\uCq6ǃaj+Vg4$-p7..\ώmTWWDiMC1^A$a7pZzFܴB|5kvXkٲ03fHܭs˜@R?,tIU-eyq& I#ZVȇI£8lqͭ!̳(kusbw.529( NGkT3$2pi ;FT^+q *L=2C$ćpE]7 ,Ӽ!ՒRɞ)"k˚ecK̍yuŝ6M٣Lm̒#NtqrX[`|4[4xPH^M1}8ܓb7`4{.=)Z\:XdWj!%Lvx~|qQX_*#ia$4 { 66!Ix}CDSH$Fe!cvbX\h)]T )s7N;RKUdpX*_Oog|߱~y1VS.Ä3TE%H;\5oz2f~T=L6,U34! "Nj .`6F#ewIj.E.. j&'&7S$5 Rr947I׹6<+.xoEj ')^ u \*{7.f6 ш <$5Jx&?1ì )ln +I>R:gIIWe idf}9M#r);i]-?G6E;lV$S"ss{v@AbM *)e5œ仚+cx?b^v<4[-XdcdnlKR%y}}+_& $@@Zƪw 2cxTd`͖ŧ(Ϯ 96 췤+ ht% 7hz7AmDfwXd;u}&#O(bѸ87G&2<*: Fչ a{l'>D8gO]NiC呶hp=YfX;9dccfױb8v)L̬iZ, Im6챵鱷Ce`j^{wfNE-Ui (XIdf;4^ő>% n[ =L!e63r5]-FZ&$,{vhXNA6xUi}G+Vb\g@[6WmguO?qDF@"wyG3=+%(>wzS;Ҿ"PQLJCwyG3=+%(>wzS;Ҿ"PQLJCwyG3=+%(>wzS;Ҿ"PQLJCwyG3=+%(>wzS;Ҿ"PQLJCwyG3=+%(>wzS;Ҿ"PQLJCwyG3=+%q*_+If¿_(2=Do?=lvE}q?ob~G џ.YnDE`8>#80Jlȁ6l;Fӳ}^#H'bccds@2j ͔0#1m7~zx e>rm#t➋Its\cFӰ\mSAA3_@Ff^ٛ\-2ص41JaIq$sbw\y(faS$:c$vPs%%ĐH#?򙷫|0s3<~_aNBZ*gܑT:& \ w)Q0TS>.y| cظm(}G)ȉ\ r2h$Ok48_i .L){ymna~U;\wTÆS g-Ö<ټ[3*稯n* Κ-taj5as޸l-G舸1cCH m{!KIvg9l,MbTV e]<.2lYZ[t)o5TkqeG3]8ݻw.ͻT@fc,ä}\nwVאi.@H#eaNh]E'yšI&xBMӰm)t>"wX5mk _BqUN3qinfjj="7S%3g&X׹;mOBM j#E'yšI&8Dp5_g ,r$M^86vx3\Pe7{ )0~z.싘ӻ(Z3~ő;>' \a")ͣXe^di{@>?^gy#;hϪ?C=)flXih>F#1. -ޛnмamѽ#(,ƤU cHݲVIP@6ҡHLp4=)2b(sX˶>M E.SҺh3A6MvXrxm'CpOJt#8 \M#Gؤ-<ܾ##mFm'CpOJn 4X =S.!f!gX`4mR6P!a7-66ļ6ҡ8m'Ca6Ql-l--qcO(Th(t\;F0fLc!< !A^ݡi=*zT?/?Fd*phj┲8"L]'D斞 Vʚ;&Gl XpOJᴞ 56 4T5r#|zǴ 6ON}h4Fáy%ہ%\6ҡ8m'CN}+pbEy+* "m(8ho.l9N;g7UG1M┲2Wb}-+cQ#]{X lW_VˋP4yg` h]mivq9^$Ša:cƁqH<쭒f5k!/;@Ь>S?ȯs 0 .F6|nەn9N;g7U -ZzɦĪk%-ΪO<>G5M]O Y-侩־\k[Ǻ/}s~!\xߍ_g ,uf>چTi\fnfrYPe7{ )0~z.싘ӻ(Z3~ő;>' \a +PRtMKu@<\l7WTkh(n*YTAq+!--'`崊l*jV:0wZ.leV~UTi}G)[G'}V©\> pPm4/q0R4؁kn7-n' =$'X ՋXL-->ֶS;<2i*~3icc'OC;Xqd t*V.К,iTNCl7 sMvJ 17 ϧP[SM"X0ܰ׽_rڜ2NA{S[FF 5X8#{𹪜?VK#7l6'OETUTSS2' 2C@A trړW{ǧji:8(b%Bg={M]9]SHbk%s3[+N[;i@zn' =$'[✤U#&GJ'su4a-mkg+K%<-fiĪ*n֓w6lqC|[]f trڥiKz]Y E i"2Zfa}ݐ@ 8qlG\3N#kk|msbCeo`Ek-' =$'[Y2NA{SI:OjY2NA{SI:Ojj4Qgp9IN' =E$'8dEw trښ^OVrڼ0J yݶۦH|?T??p\v=RcuqE_Y i.ݑv6+OG$>tdΟs\u q- pt1~׸fxmZm#tt,cX,C߱ls,>!W9P>wF*blp ᖅ`\6x/}Cσ){5Hlocx;/}%H>!WGN$iq3ck)hk(+'(Dk"m{A&`{ N$>tdΟsXZA=\OEL'ٔC|ChfAEwI;9IhFǼ-讃$>tdΟs\^ʊ4SCI1̦ym@|Ӝ:i)稟8h`sd-vvЈrCOH|?UcPTh+u;|&ێcrJ Qe38J\E*up;'؝ڕp &qOa4=Esw{+_F|O0wQg[6dCWϽQa?QPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDG,LCG_[5OVS[Bc+q%pH;Uں9*m]U[n U|F*94zLL|na,[#93H⸰ڼhPװk[J֛Ӽ:m7ߕ8|F؆Lj"@!,,<IR Z vۚ!m7vv^-g؇oʜNv>#~TNhE|Qk5ݺWhWVCz45q˚kAm؇oʜNv>#~TK_IZ:JӖyCPGM.^hEL vevvoak؇oʜNv>#~T":6HUS;6X# =?+IV KQI1ӽ+k5nqk&{w!ߕ=L*<"aIldx܃ƦWpm~poکq;S؇oʭ;'؝ڕpʒ m5_ u]MD8Aȣ3\TzMi7{ ;#wQg#w{+_F|O6dCWϽQa?QPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@YpYpʃ/IS`M&qOavd\~G џ,}q?ob DYD@DDTi}G*_>F~=/anfon+EMZgR05G \ٷyYtf S)LT5RT)nӘ]͹.ilQi5lبke},&kKߒqaA. A=x5 qY|Hٷbu94Fc-8,֭(i-c[TblQI4ԆIfi=~6*aP(H#asLy,G}{"K %G8+ҨSܑVSd|Z38܃+{rN['g*(!m!4.SW$mc䵮 v6,=/z 5 cc˒u~WX1EkUOS29ZC#FAkd)_\/͹x?0=?et{k46Y5cZpU`GNiEt.c5vkwl;G{ӽYMd~`{pX*q63i&!MHx@iõk|q;FuX@k>p#\אmivXִ;d~`{5H#Xֱ:f[XAq79'1 B6%=4b,3gy{Z 2_d>?0=wqJ&MS[\#es!s;ݝ"P-[9+ZE!i.6WPW¿_(?bwjW¿_(2=Do?=lvE}q?ob~G џ.YnDEDDDA _>F~UTi}G**8w4Dn bc(_]b͚JfO6 ldF\Fy ׭£MH5p`ԯIh̥aw׾$\*}tQq$]3K!Z9-z*x$Lg "F;.UsSRV+f`޴KNSfx6*C1(!YSddyv\`"yFk 2cX˛;D)gs͋5{)X+Q+5$;L.+t*XsѺĩᣫM ̉Hռl=a캎i3uMF!$M3k1u ȴѥslZ lݠyW.YIY Uo Oa0{'/r.6(Ekc#-#˙6Hݟ-l&\4cM ;Խ̷1?ϕbh&-5lbSe |hiޅ%lxϭ|0a0"?kukvs-OPm[)7cku֐ KopX,rK- } "tc9œe9@h1I5f9[[N=̫ ',Nsz:.[gʝ̷1?ϕrU5u4RmQ'D88JlVjMY/mbq 66+bKMPu}jJCPSBh`6)hhy,C|(ɣ5o{b1ߔ//f%kkU1; o vm=*mbq 66%6:!{E|n6k^ޭF4^%Q3AkrYj 66'mbX-MGdЛ y^6 afC.FfpiӰ+|CCʹ 4F~UTi}G* 142D]=pK4CcisE}J% 9wN_H.8s}~"P${Ýc؋6>7% 9wN_H.8s}~"P-L3覌IW18r}oU$Jxs}~9wT(]pRDw7ÛUI_oU$Jxs}~9wT(]pRDw7ÛUI_oU$Jxs}~9wT(]pRDw79[,enF͖ZBCX]}T0C5=3*j$}IccCw{G.OʬC*6}u3!KH旜o|n4)ehؽ Z=Kavz"+i]!05eA|se.]ڰ RG YG5稚:!3lX.0r#9m޵X$&lٔoO!ٷzN'~6+'~6+2=Do?=lvE}q?ob~G џ.YnDEDDDA _>F~UTi}G*#DYTMXڝ]$TϳeP#skwp|h5Qg_6 ɬ*X]ٳZTXBj멩@$+Y`omz *G„TNCN٤׷,d7;|k&1 ~)F~Sj fo.ݷ[z ȲmOEu;L0f{Ivk-K{#\ݕ~Ѓ" """ """ """ """ """ """ "" Ւb6dtQҖ :gXʴAXʙ5GIfǼl{a*D5GXʴnl{a*fǼ$AXʙ5GIfǼl{a*DQYX)^++m+/IS`M&qOavdwQg#w{+_F|O6dCWϽQa?Q  D744es@I<6,2z:,8b&Q#8IpZәz6KMLKkiuSGG+")9ZBLb l23,^Ǎ u]7nU5QC,qL|Jܱo xc\'Y50bN(Kuf1楆(dH6Fg`KbԺ1<@SZMKm,eqt q76޳:]ƹNj[4sBQd#ٮFBr Ql`_0Em;-!_Ys f.c\'YKSc\'Y50bKSc\'Y50bKSc\'Y50bKSc\'Y50bKSc\'Y50bKP`65ϫ֍I!{c\'Y,\EOYs f.c\'Y,\EOYs f.c\'Y,\EOYs f.c\'Y,\EOYs f.c\'Y,\EOYs f.c\'Y,\EOYs f.c\'Y,\EOYs f.͌RT8N-̮Qv4XjM+ZZL~klt2) yݶۦH|?T)2COH|?T)2COH|?T)2COH|?T)2COH|?T)2COH|?T)2COH|?Tͯ3\U*n$&fqt.bT_/zMi7{ ;" ?V81d`?N`kσ{,Xm"""" gzO?qWv4L>x+p︨lOu=&)59$tlwz8w46 NaxUB(Ţg7e.#e"Ð'"LUUf)0=7:m'f4\2--miEh,~X]4?56 @0vl8loqbvXl^])5AԲ'JK[f,@ G=]Vb=X+D2Fk~]}=edugIR76Xv r#0qv;;C\Kp["j6R#louֶǥ''/tfK<>*9rױ`8ށY4lXX:Hs[=Fִ4WSŨUJC{>xUQdvb-5#1Vjfъ4}S"_]\#=W$GjFO )) e~K6vzlf]6d.c.)dќ&JyZ8GD[)1Z.FN ]#G0)6#We1= 74 wm6ۚtjj0_-[iy6s 'o/N<a")F1=hŞNao ZV) }Kbo V%. y@VgY8gI6 91J9:@~`w 9L!l/e}ڼH,N\f`BjH ׶˥&TrXݲMS,oz NP7p6+K1 hR0:a|U~$l-9[ z|M=,PCPcT^Ń'|Gz~D:*2k&053es[}܊A8-DŔƺR1w~w5Wi_Nz:YT#,sܠ7)k\ ɶaVm.\cl d2dyCbn EܷGOONx'9sI$\N-¡m#)I9$!&o޳DZx|Xs:d,m ;3H7 LXXW4E5}M,JdqqcoZ/ё/ ZM]u5K $1ee_{Gtz̆[X =㱰B +]+,3iA+Ittaoym۾ʽ&VSW$z-3 Eip10 =f^qjJc$82Fւc͑nE@Kfi{:B"}.eQH:ȳ:ԇ1!k4Diu|ÃDlkYb[3d;v}g09]:B}Cp C]9ULFFHFחl,=VN{ӎ dBKǶIa{`Mb!T,-$.6NGoL2YeV3wUw Y f:F9̤DoD.M5)dU 3@1FWn&۶5ەYFTVjild9{ū %M} S!*pHpCA!ȫͣD-3f<\,fM;Nݥ#߻R4FuulZ6$FկbuUUu4Uq@HSX>Nbݮ͛M׌SGh** 5rTgv^y}nV* lHA|Nn$x.U@PNrl6\NU8'Ixh/i8ٯ>2q^?c-Xni 'qcux??pQkƭħê#̀ӶjF} fj ~]$Δձ$]!lWatE$gI&MG\,RG+E;,0ƺ@Lq6 (بif&SI), uVJT9Ծd`<񰱧hq%Wjtv)_U u]%CdVM5ͳoٴ]sZBѼ=.cZָkrwE:-6 ê,ți@ɘ' \a ݟ}?^gި0UT£0/wϭ£0/wH" """ """ """ """ 2{ nʽU\l$Ff ,wG߫*/M*sR'UgV[jSpJlC7ZH';b*q;V w!ߕi" ';b*q;V w!ߕi" ';b*q;V w!ߕi" 4SiSj$՘ƹE+m+/IS`M&qOavd\~G џ,}q?ob DYD@DDTi}G*_>F~#l>7+Zlvث0Njxጶ8潀hUW=,4tՌ ey@TIh:|>\Қ ji eDmQ.--jt8ݤƍo_x Ck$ñ8qO;;8\TeT-V֓G;vvm%o񨩴8ڜR sj ia$vIuxOÏ}؜8' A!uL ~B_sr4Ucje}Ack'w2 "ǐ@>N|Ł.`Ի,16c+H nEPψDíZi|!dÏ}؜8':Q7/7h{I}ZsZerNʗ5QM$}a6SAÏ}؜8'v-. Y2@K 7$8 { 9#=d{kHcZ>Ibpxv.uUGKvE4wpӼ/e,E4sN]?.W@>N|(um-,,{&Ұqn֜ _a6:9!|Zc}ny T |>X2i&G%Kk / ;!Q(um-,,{&Ұqn֜ PqO;$ñ`;HhF-6.g}6{ |6u4p~BI snY"&:.|>\:MO eD%u<4]ofiyV)9$LH 1(lpxv'>IbNw׈Qdn\2f4*T7]nM_% |>X-L)[THm.H-HPɤLP6i&qp-u4l˙\\6 V:|>Y s#tmִM6LafvXlgxi{(t\8'Ï}ذ,.Yj Kнݗ3){zgzO?qWۙmqeQqTAKLikH߼/пJika$/('US8.mqȞW@p0T\ҖѵnPckbF`JC@6k$Xn-_/((ql|ltRѐiͶ40O$ؗYkvݸJF,RGU <ҙ]iinUXu0׊d@_ 1=R]Nbow8 ps Ysh,@PcX! ښS-%d|M#9p#.ElTNJ2* F) / ŷq6 p=tA|sk x+kɫ檠MH߭n:w~{ro͹#+qJ::५@2)w> q mlCh\@d 2'yuݳj0WRIe1oy=0|2,Zp rY`q"ڧMJkDTv{57al mJj_D6 `` Y!HnciW \7V޷1z'%) Ue/׷}3{m<:H1*8eFOp|n ٬AvfOV aQƶ2mqwe$v'XHfd^B( upcDs50@;$r/7ˆH+`'2E ? xٰϊ$ b"Z #cl>+n+n[%sR:XSg֒$w53 6m̠,BdG8k{%9Y1s@#hqL9ӿo88٬3m6VYf!ġdnݏHbDۊD6 3._If~i_qɾi&%. vP+<߳'snz<6PgDأng:7Yh1v0zF|/lҸDdkٚF-[ѼZ ]Lk)N0z˳'a-m_dЦpi#Nr50ӖsWR9tf vWE5lki4\ 5q[(oZ0Xz gi\x=s`:BٸWQQMdpMoh vRv6omC2B"ƷSe%3Ԣ *lXtJ#yKchX$Ém%GSYWD#tcln!$6IyC=A "6ɊFYK6;=iy )F_2,J[!^6>?y&USRɉE-)L|絮m+& h"2I5d6$' 9F6؂n:Vq73)iE]9jaL?j{ HsC\s}ˣ3&6A<_bnnQ8p0T\ҖѵnPckbO' cLz.ssbI2x eb:AVܘYJ;,;+\I I9AZaS]Sٹoskuyw#MhD9mhhMf̈͑ 6rYZK6rYPe7{ )0~z.wQg#w{+_F|O6dCWϽQa?QX . MhG D2{ɳfpadaqf145 ޾f%$rWԵotQ#b2[X[)e3-cdl cD$@f ᴑØVr,M+5H܏Rmb\V3$yK6i^5;|cX KK[ഋZgsx=w!t~ZcY2ϖ{lR[zSX-+?WK &J_Fᄡgޔ3oJK|0_Eᄡj4?ZO?q_)CM{60,h;/"Fz[Li.s؜j4΍.Ij1:~G@xkћv ftXGGӺ,#ӣ#fxb`lnV ,? i(1`斐taN谏Nh9ʚ,G›IMHfeSg+%dH}Hڷ(Xh+りh`dcZ䁼[rw=:?aIt~pҲӸ!&ki6;fceIYV-f  *deVyd`ul\;kx4pj 3ij548tOO D[ms7H]wtXGGӺ,#ӣd| H0}DIllؿ)j&+W`SK-%l!hs~ܶwEzt;qi`*R|dӱr׸qA6ڬ谏NtXGGղH{=:?aRƒ,谏NtXGG5otXGGӺ,#ӣEtXEtXEtXEtXEtXEtXEtXEtXEtXEtXEtXEtXEtXYpwEztUưKPK!poe]&qOa4=Esw{*<>FEWkgKXHR`?N`oǮc;7xc.s2 YH[p̓Mq#LmՙC}׶ճ? v&j 1إ#!8?j 1ؙ|bIL1|~Z|bf2૎jr؟+;oKIhsEOA)5GPFMd~`{5YMd~`{5k#*VkM&U<&us76VIx?0=4Rk#)xk#(#E&?0=*j,c ɵl:WφR+>HXZJ -&qOa4=Esw{+~gYbGx߹``?N`oO߹ruJgwzWRW1ML09]b.9 j[#G[[DcQqXےNUbUpܔ3/X|,d_t{aIl]LRwֿejECň͈ڑr6 2kaTcF)4M 77QAi=*zT? _+?ևtbcT`ulx́e2(|ko (ᴞ i=*:CCLuujʧ1<>:\6:X=C# ^ AΖ0ֳ)nk;`qMMJf25p /ɰt*S`UI|R#sXn\/Fʝ$ 2MDj&cA v۱Đ/}X1!좚 Zj2$mf\ٱj 8&S сMDeڼEfhm8};C̀D0b;l"ϨGp*Lv9FkZ*+(OHJx[|Z֋zzT?-LFo!|umLD;#5Bo?=IS`]wQbpdch~1;]PNrJ~ƮoJgW?:[>eGڜ?Y:}oJgW?:juseGگjusoJgW?: eGگjusoJgW?: MC3m^QusoJgW?: GҙΚ)\GҙΚ)\$EoJgW?:jusz)\髛ҙ΂DQusoJgW?: GҙΚ)\$EoJgW?:jusz)\髛ҙ΂DQusoJgW?: GҙΚ)\$EoJgW?:jusz)\髛ҙ΂DQusoJgW?: GҙΚ)\$EoJgW?:jusC=%5V^OoX}W^szS:W73A_0n-N(9෱XLM\ޔή~t _3~ {\ޔή~tLA_0n-N(9෱XLM\ޔή~t _3~ {\ޔή~tLA_0n-V'3Alښ)\髛ҙ΂aK[؜Qsu/obҙΚ)\+FԿg7R+)\髛ҙ΂aK[؜Qsu/obҙΚ)\+FԿg7R+)\髛ҙ΂aK[ح1c֋5r/:)\髛ҙ΃o?=$k1@hf_%.ӻ([Kw{+isDE5,G8yc(笚c Q@XHcM24Qf'='O/zO\ $Yc?I}8K\ $Yc?I}8K\ $Yc?I}8K\ $Yu%<$ȣisf>2ŰZ\-AbإIz>ؚ=b4RjG&yObX=z>ؖ#E&yObjG%Iz>تYK H/sMi7{ ;" ?V~G \u@DDD@DDD@DDD@DDD@DDD@DDD@DDDA5n#kGO-BY? NIbKSM+%,MEGxӭ\\@Oں> '3X?;]lNւ6 I:UQ71cYФ)1#i&h͎66#aj0^sP,A x.'\g$ o]\TZJzeGLכ*H7HVGпSPM"YBLCAIH4ois`Teng8jbج+Eր7eY?/n(2=Do?=lvE5u w]jq44g8|vB*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B*|qs'ojq4B0J:GPb ]ml!g8|vaIڔ0ҏd}ES(VG]un4g8|v .紣YQw{J?Ց[qs'ojq4C (VG]u;ҏd}EVaIڜqs'ojP;ҏd}ES(VG]un4g8|vPѝ$'E.*4]QDZvDROTA7pK$٣TT]uSI=֊-.OԢB(`FnR{2Ny(o+A.R2WQL3c6^;?9GM8i|4K<}J`vzx1)[,gͨ b Pr|.)q[!z%R<,! <$uNW`\inXĐHȄT|3=2ʹ7[hDXɉsTXܮR8t#'#EOՒ2 7p|xlmaJdNZSf<׼IC',4hRgS)Yr%DLg5͛w ԭe@<]5i:3v}~on?AT+]g3uhQhba-HdcH &v=CLC\KWxð6@u>;"RlI(` Rruv/fL,Pi f⋽[qyfCCMi=7+w١eERՏf(6 :#RdwV޼j]5KcߵDOul *_^}K|/>qS s ][>,PI|DNUmOdH#,;fGb 'hKMȻ* /ag+HvP[^Tl}OW,3zAթY3\o|i8zv}5٣؝`bh|&厘)p}t ~P}%1jN4U$Ze_/:vlD90?KFq ןw{R ϻ[]""C#=` -l/_fhl|Of%Mk98bTWhvxժ޸`Y:.IL/eNo~jjj02F`,7!j;#r,@W>,pI9rJE]WeiK0B:*8$2b_UK$ܥ_i7zPYыV*R ϻ=~o#Voj b+_8䤨>)@>t>mPvF E;^"9 IcC6ïGnNx~?Qugmzǔ;2rf7{R jK,1WG9]a]$f|Çj%Ԁ%9>yԸ#NU- *_^}n@; bg;ߛ7']$]09o_0!ȴѠ@!2S0_ аQ4||g] | eMpЎ̂2w`Car(HFa5 9nUeIMjt?|ÒPYC9~6?Vz[(Kh4+tVNC_]nj˫+JƲ5:{R ϻ=~o(zv˭XY33ӑ5XK,<꨷k$ Lٺoh 1 mhXқW-JY㳋jpl#Դc$@MG_5M|BXL/58Ug\Fjoa5x,1飡m׶ޤϵuDSO2J$Rz"q ןw{R ϻHcD&>y.QfcP/ELل$o J>[khĀB 8@H*ՠ nl#G#)^wvԕ8L)\JQ!' f"&@|xҮ0|VO|Y}HVRSDY\Ѥz:M@%|UhTMq ןw{R ϻOvm #lw;rVi9;VJN9kokCmbeۍ^I[.sS=CËBk*At].$kLBWЌ@~zq-AurQmy:Lolso4?! qt)>$ܢ9(zJ9-5mYU8.dZx4n?ATx7[}y{:m v׹FOXB'˵nPsB-^5GC1%%FoKwX 8Yn "0h;r谲^a}*P@B:XNf8:e=x_5GMZf߳)sJ'qr4ӳ5fsݪ(gU60r\vDˮLeQOLٷU- *_^}BI;HJAI"=ֵua@WJYy(6 ?$!V3ɷ0C-\^@][%}SH\v&4'LɫSJ7It:SE˖frl4$SxڻIQ9^ER𬴢?yҪl /704ʸ@mtLV.2 CVbT5Ծ̓r0e;u=4;]# :Lal7]Jk__O9gݕ>#-:[=c*-xͤ >av[{|ŜN{9Sq=3t~ѓƿ.l%=۝&'D) uuv֡ Ts`Sfѣ"K##Fm+v.b1; 9V%ZH kv2Mkո[d!鋞l9%@0h\䒸bV,n7g"'GFJr<'ݴ6,o0O~a'??蜡]߉#'٪V׊~#tӓVxRڹ=acq_|=K͋.|ijgaV}=+ 9мIa!+Α}??pSY([1~#TC綃O_4A}[ALD`IboG 6Ә_K.Zg0u VnWXQ2x+ !J9k24ּ^`(LXu1Sҭٖ*;;- 1ְb.mq+&Mϔ#4ܔFLC0,4nlU%$#؟O_Pb~y[Ettc[vwK>ߴ!?S=lX{12PI!34X]`}M'NؗTROӑ_ nϡݸUXZV4%bokבʍQ*ĬGˌ]H"X ve %kZX1zmfݲ6פRԛ8kOaeR)" +Ej$RjxO{ ?O"KF4Y3>Fs.F0L5kѣE#%2RgLCZ+}K{X%6<4UwmU9[Pzcَ6*W(M;. U):omʖ:HO;Cu  b^ 8βDbH9wgSLUtuM[xO{ ?Oem/s&mAtJlQuKH"n]0+gs匑ѡd5t:+8\iK(\ڏjZFֈ$dM`{\Ҫzw/>E$vr>1BB˺$ p62՘#;+:g *Uv`xōɻD%qj*Onr#uv\XUC`u9ܽ[> >xO{ } pVzFy^Oу:(4g,[.rl $#Ⱦx FO8QC8}5|Km? 흅aKRPum[]沫2߯q'RTZGdSkӢ-S;Ҟ㎏vw:ƛUXbjVz tT;o4.CUJHXR@;5ܓ ?O<KdIQMU%t5RİMD:m뾛붻c:s8\ b7Esrs}\[[TzTG624Ce?0,e؉4e@!("UU-h-gkXّ{]#Yw}KvB;9륟YM -?,_r:RJ*sQ 'ǝIGD&ݦԝdQ/5U9jƈRNƱ2uWj!љJbΙS!J6<. ~C= -d8MI\ɳ":i=w|kƸlcEh&b3̲嘩s\5Eݧ^K*ﮚcu>Gkk#PE}F7a=$>rgv/D[,pk\^]ޔ=akgͭO'rBg%3zS=Җl<&Q.fk2*t?^?1(|=Z'g3{/#Ie$/rtF>Ÿ́UEɟ*uy?+n{4l5:,fdj #$p|"Ʃ6=5 ?O0c]Tё7!]G̱M8۸0A]SvMt 91jݛtӆ';cV,1҆<8C>:[7<R=Aj5}MZ lqI[g˖Q%PFAh9z~[i%NmmQElU@*&rj`7<,~ZUS+Gra<  #V|c]:e4LY6(vH%@8%dMFڿn#B7l|ehu#*v(*!&B6EGk|#UՆv.  }x։f {z ]G\Ȉ; 䱇3#-ۮKf`j7p@QbͥMh9+|bQ9W3*Q ڌ{6Z+&d˩a0ɽ65w˜=G !@QmAD 4bz7%\E֫ }F:Rv;X ]j:~o FfͱȊ8}w?*4aڍUf (*G)Ş̤zFT h<#I`l4ҏ9mzeC[>TR; P$p3hƳgG*h1022- nsAOqK/ ΰqѸ ;_9J>Hn6~Mu^Ji6f]EC!WԲGFKP|>I%s&eJϏl3r~kGJi}Nky?!Sv7cO*73=4ثCgV44x3w j[?돭 ]~ ]uN$TkŌĂN̛ &"5W0#`SVby Vf~n7ȱ9)YQ)-N8'|Jhx*bWAu2Uwڨn\U7 c "@pG# k#&ZKY–`5"k泴r QEoV/ B*j7@:~tyvkH$tnXȈsBFi_ +,~`U~^-:65azQl벶$ 0;8 e(8Mךxe'G }>_c|?c'~Wϴ2w8uGr +m$+k-ecaŪ)3j!BTj6mO?0V Fz `Z_-_%ׯ>?Ń6ջTuٷ)cո]IY Ed71F̢NF>To*T[hU"et^|ş Hu+8İyL5jęO!r0ݰN2\H%nS: 6gYt6-c#_X*ʧlDy-Oٗv3b<|QWOAodK#t+EF[ 1uM1v4~SQSZq 7*l\5+bEޝh@H]>[0o0icQudե-\n6M'Hw~0W* hIT#6kT?Y'ۧ:t*#Uw"PCAjʎT& YDх•pO& 6<"Iקr5. , 䓯:mY!]Klsqc7Jioy]/+eUmώN,ةK)]>1_&LچUQ0j}qO&f"컩"~,jԷ88IF)DSn]\kfb&$%g,*~ԖnTM %+Jr4i-KBRc ۗ'&3?!$ؽrX)M"YmbcfkH*dS|c;mu;c3g禷κ)2R<}tR >pz R5i[Q2c C߱Je7[]QmQMaDOg_8|&sz_/c|\ysPzמSdXѻE81G`y4(9xG";k1T 7ebP:T(9,sɐ:TF*, 8HWcJA š'+9׌yF"DL_Q>WLFHY i@A(&qvqDv=ܟ[Iy~M9ge_5qib:gWrP]F}~GgV1鶹λku38qyz[\ϟ?xgwcOt dX(:$H}l\ݓF&"<3')xb5AditJf;D*ꀴ^O6$0A3\IM: -SEU5gdS|c>_&s_&q'O8ϓ9D0 ֜sψfsTegOL Vj)')gx:t{ ̟gho|c9#=򒚵8As)3i 9뭩m$˖E􄄖;k4_?#[G=Z'w_\ =?oюpchC4rJJ:SP C$bi**ƝYS;H(H"&JsW+'M}-5G͊(Ohq$HKyظT rPTZ ^j@ye%lMt\iLGӶ*lh|@ϞfI[Uk^ HiUl^R~~suTj3vX&WvL Q+;2@ jE_w_\ \{l iEu!WMҖT) Jm=Bhp˻QihU| gBk< Lƃ#Z\OUզ4Ԯ`50aJU\\~_Nq8f2RU3r*̍POGnM&G)5!i7m-6JM%+3õ>! [ ?\ʺyĔO|{_':|\y|_/ˏ/qf/z39̿&:4_)ׅI{#^eHaڒ;RACl#ԏ=r>T*34{lқy[!AZ+mAn+"5YwA'In y!9}#|mM*gc4.IP%xkǪ@olE3{% ]I&p AG)8x o<9UД/T<3u5m6FEVwѧ!mGgM>W2hߧ=TI*r" _ Jj~o'FlΜp);Umޠò឵LgD5N3w[~|{7SO6~xz72|o׬}=3vÇ֫ rD5tWzG|NڵeMJ_V]YˢZ;ǡ*} y%/.GeT!V %NL: #@zGI8sw(JP: R!As޲}VLffʇ5,=>l^Cg 5J:^7ZE`'s7HT\X.N(lZ7qr& 46*mjhT5ۭχ~ HŇq΍)[MEKHzzGp҇i\k)01TdgFDuWZ8ٛ(HSݩJ#Ennx QS깫tXb2Pb? nr>5g76t5mrIFĤ#7/9E4# ifMUR2o Y^ X|i !B@VW Ή;F+ɒқ) 衕vA肬) i$Y|u kΣi }D1F.&V`B-(@v ӰW0DbBY')Bɐ&r!n~]"f;8zTUjÖ_]m@B[5*ݩFpfB[>W?l}E =JT%H>OQYX*sX,IB{bVDQeOHW58&z-ݪNݼsYFďkiq~m|+6oVhCJ֜fz;3,I$Yܼg5AүkzA?/z32w{yLU}QFr9[u.x_Bm{ǚ ԕ`>a6C2zV5ۓ%DC%v^GM=4d+v}h_\o&#qo Vmv;oDomp:|e.'DHUp*]Q2`ᠱ,/M]p^"}&{Pt) we'qoAxlmiBf34vNeXُǐ&r+ $n>뉩l͒e-FamXWK~Wͭ`&гZucb3rMjk,Ln0HINQl8v]8>栺4+EMW#L4WF{u>s⺅}p "o4V6~.a"=Mjr=66uLXꂄ8ŜV';mIƇذB#IK}^n [6|n{r4!B!+5iXlp9GԩRF#%QVXqa[:餞u6҂t FlvdY=jY~tV\jhQdիl>nKqv&ՕfI322vElD NpGTkѪȴlo% _!Xy@CUa-kͣd@`l뛂""⹻P9k SDM6LWG|I Ԉsx!%9 ^/~A~O|Tf1JuƉ;Â#1ڽP3AE@PhõMٛLw 2aЭfH cIbNo{h\p<&R3FUpk" f}?Y3$ 6"QP0 -,m(]ꂢmDLtKb/m,Vu\CBYȚ˚C>f,UTJ&mM$RMszuf5CCMG Yh-M(iK&xFIEra꥿3_L+u}gs-35n{p̴并J=LQ_bTåy=qL$xϵ5iK=fV$Ç#8ppÇ.q1s3)o4Y9[p}wgn?8s0m1^ H@9/qkGW;@{VXR~U %7Q$ٮd[&0%E|}1kɦHoCIє{ZI#02Zs:)޷Q6Hv{Lᐁ6c T"_ck) b;3Ew)*Ҳ*DB$m*O&$w p9BHJq } 榎s5#/-ֵ^Lj=m uMh*7q^O&itdOGbq29@ hz0Yxhe+y"'2T_1[#209cGR;0_ua Uh+54gH?$~#_SK{ԃ:>F@<{Mz[NC}6t*0*|xL/7 J%$ITUP?dUG=˜qg91c˜1sc_Wg.s?ٟ??ٟߣ mmכj@qb-X] c )\BGAl',qj@ݧBJDNV!Y#!E$M:Rژ|ȑI>ŇcKG-slBKulM|09 &g YM]T]s5 ,28Æ3r^"s-l$ZUe#4rQ:x=Q:_/ITutqfՃV"J{Pcz^PiҭIvfŴH4mm۪ Z&d\+M)D%!/\%\  uw4v6S (+PiUfB^J /6Yo:YfV3"+NZJGD&U[u2q.Ѽ>a*hx+QrT47llM6;tKaMSMMٕ^b<0t Pr4‰ ʉ h-=LmPιP!bG]-yƨO\z .Gu1[9otδꚲ DV av=nӉ`qMsf2X 9i 1'.ţ7r0F,t'U5L5{-[Ř6od>oS`Oڝ| L5|f ~W+&`Ԥ7Pe/4W$::ŅP1&mV_t$],ލ`8*H0qKpa¦ [&f9-$A`wQgٜ[LIcvItO*cU-( RpSNvrS QԼTne(ze)HX E=}7t`@햙]YT,AqpÜz8pÇGQK$8&:*3΂ S8/PvGF, 2՛uy|֜!)nk!!,j ^ he& YW6z}Qz<ܘ#GK }DL҆5`f-JeMxBi56>rTDAćDAQ | tqFAM (m[jvxf1͹y75tf,|yCd+w/Edժ&m׺1 6Hom]*MFv \FϢbnVrRDsf >ą#-K/;?FQaj I;d+]{E0p{ae`IP3s!/k5=P3P>1*0ץ+`IrYMVR~B"R%Nsn'hVoY>`EWޠGrj}M.?Rƪ"@ , _+I*JâqO wfr# n+|<6?/z39c/z37svθ[cκ?'g1ysy|o<_Ĭ=@|iSE&Jױτ!Fg8ske+HNa seib(ߚC>i҅LJ:n_'!u&3i:)+K+i>aY)_SW`CEg=#)-Z̢vX+̪Ih .@zHn.˥5cF6ɪx3*SMOVMY. E[2Ƶ3yy VWa}ZhP=ȳ:_ݛuBw;Wv2 1$N wxW&pY}3h2LWtg,NO*{# ^f~mt0^bE-&Ex3L61'{,̬ުf,T,) 5pgQ}ʱ6 ((UsƗէ~JׯT๏crv %.QL"Em7wKRrt&Y=&.Wa%'iӽjlqǴ^I|207йHџ%R6ѿ,  -ӣ+j2V t<9HHS]A͙XRn[^O61W5Dj#SN`НǟZHreةsSɣ"P1& Q98ydY_}:d#qeH1QJڮjH.\}( |=ZhD F- YNEHiP#*suylP By8qÇG=8pz8pG54gH?$~#_SK{ԃ|+pL/1?[_Wg.s88~y>y3q_Wg.sN(ݸJHwTI|9*͢BG!Ȅv@\vD4OЁ϶*l"NHV0y~_C9ȝJg 2󄹶8ls1.s19ьsl,]Jh]c|^lO,̙tۿrÍ=OC8An~֗莙i$w>jYpIlŋrZLFEz`m\N |F{V-x:Ty&ڮ4:';+7j.>"D ERzq"=[F5CCHbay#OBs y$/nh>uŜ쏅n],WzK,)=W.e{#V_ͤs<x \#+쵚d+E& e2zޕvFi~"WƉMM)R(\_ :hߌ{-K3C]+7`EYp h )&y!(7 ƊIWWAػ7{-*Ogb2ڄcY!8m?F}Bپ3.FeQ&uP2[~>erڷ~fZU?''Ne@ruhz^^|wa{Z*W3j=T 3-A>897k^XpBNj ճt%˪ i8?_Y|U-?/z327{AG ϦqH8}MȤD29Uc5zi&*{I]Ջ[-3 #Z{~ 6|[*p?{.} ;7xZH|h G}s.ѦŮMƥ>Ѻ8tJGGBxxO+vXQ pe$ضWh h#܀S; ~,}iO{wp@l2H[P2ZO{&&8gr4" `7CE}4WHSrtW3 #Z{[4hy|A9n;VyJy2юPcnuls<|n\:SVژ}׎9>g۽eUC|Tؚf@h ӵ3ztliKk֭r_x4:~a$ɬvظ KaHK# 8/B LZ#^5^K ~޹z_]RY%rd'P?Fe< Y2d";6#^qHh:Gp0k՜QWM0!ۑЋ$a=r{3?4}vL߱>ϦGYko(@5@(|4a:[6Gє#*at; %I*,Y J*O۹,5/UILׯnO(DӉX=?OU\_ ̂b4_g Zٿծ,xINL!d` YfdI3XȺbE;n& (λg^'w@5z휖딍~LlmĢI~Ȼ>ѓ,ݮ4rYyi?ܸo$)ӅHӗ\G+>&K˗f~?p'\ L}6e[fUl;x.Mt4I'ZQ_!yi?=z~+@rW%7~?Ð[4h=o@?׸}~r_ؿLĿnGghGyi?>?z/uE_eb_7p#3 #Z{[4hcs\:|/2/rghGޮK_z>{XM9HV^3 #Z{W%=̿K+l6IuFR^5QTetY6#$l:h^h93u7eh2BN:ٝ"#_SK{ԃn'1m5dBG/,/ʇ?wbtעj0au+QEM_q<,^9 p|zQ0b@Hg5#pܲoUU3T$H?AJ75UDU¯_!Tw55Ahv;vkuϓ8?Fs]O ~T#yJ]U}QFr]? GŶybp>~>^֞A|o/=wGvQ&A1ߕ-P}-j.𩛐)8Neڽs ɏK+[G\Lm;"b0v|)ġQ/1I왂fp زCnVWlՅ+ߎUB&&zQ:_]NVgil b ufA[08tЋwW*T`Ξw!ȕ gJge͛1Η\ѯ6["mC瞙sssvxRן4UPR;L޸-Pߕr{!sR{!gMa*)`*z/"#h)Նz:YwuẖaEc=R#rT4?J:D {/+UwRX6d87u" ڠ&9alzxܨ_4yz4Êhleh wNSh51l˓mj|!nct4g0h[FQc'pQ5ߕ-PS_wG"!i6a}8R7b9XQ$?)qptVC1v.4fN.)ҧ!> rV2N(͋sh!]:;/ u،͗FB#@,ޟ޻tJ,l-&hHb"y֔TsxT,'cz,-.p5ʙgV:tn(.y-en>xfgX= [-PߕsWmv͛-'IZUS,E@fg&+i0rL5gPZE.~^;9mɑ 98{W|P=`j`{]v '_\H8R(z18pO Զx}<ٵ~3M>">Ɓꮭ,?Ibe;Y?rgѧIqḳMū_|O^IB'Efmkߕ-P):h]ReENK X!p&,OYԱ(iP;ؓ[oD,87&% |Г֙ѺR?S={90ݴܐ~U[ZvB䠲FQʩcT?UmӰl u +۴ꣾf-- *=p[\ws=d}p[\*poʄ}so\G?ÇG*=p[\wY\G? $EL.TW~dwY'ɵkM6ǗmgN1Wߊ?WS|)Sdп!\y毳?q\_zeqy_!ޓl9sy6uιqg3ɜg33gޜ!3ƆNpб}N,T. Z)Ttɷ!`IDbD4Rl)kfz#Vz\s+웞"a"f>9ˡv޹l_^)&wW-GCw ؅CQM == 6ia /Ͷe4p{B &S+SU]TJÑ[ZrY"Ô5~SAI HܹuVl׏Fg[Ob|HsA>n8Ͽ9>Gޔc:)9Mf[g^Y+7ʟ&JV%j=㦣‮5^Q [1=5P [7JoaV6gh{8ϧW:*)~k<;dYl8tSF50f "b)$z#V׏F$Sw$S<J#2̂5)݋²Vjyl{ٻ7xOmhJ{4ܕz^j4u?Yk:;g ˭.7IjgW uܡ;]K×f.:~$-}y(jGBЁ2e%D7.UQ3/bulk1xB3W k/׏Fg[OO#YVaHgiNseh ^dheeЬeQG'elth^i*4^u7c}${51ɗ%8)C2mHXlӐOD$ЮVm^v27 ;%7J:Rzddem"4ll'/w}h5o>]x<jߺ|u7rC-\VQUB-~@Pzz=a|ެ?qլ? ?YAS<6m9iιنY\Rx&⟤Pf<+q6aGlr)4:&MZufS;Yd#kWDzQzwuVbJ9左_L9^N >GL ^s 3eҵ-\YYq) g"k.i"bŚUQ(H4MI7EΛTBW8aA2bSYwXΙ^[#3&^MM 'E_hپ)]Kg[O^>45^+f Z:RȕnAjn~`mY,xOLUaU>.E׏Fg[Oӹ/ି\>_+GԻÑ^>4w}h5o>w%3>_+GԻÑ^>4w}h5o>w%3>_+GԻÑ^>4w}h5o>w%3>_+GԻďkiq~O]x<jߺ|NMQN'A>'U(eY:!cINuΒn\4[]T_O|.gzBfi8xyj2)n8 HF#sMܰhf f"kU81~ ^l9rs[6*s8l8>gq}8)[ ?\뾻i @ɓU sO b-,ڑB㽓H$fi(̴4Ӯ xaA5'EumPfͲ>$1|Qf=]X #6_gZ֔>ufM9~ɅN|j%s b ;|V9(vCyVfS,I:RR:f(DrcE_%q>=-ti&da@5}1%RӁF<9C JFLVQ˝Bѳz30C9m6iT<匄XYM]z8M=lQAOc>KZ$l_lcb9Qk|Zrp+^NZȫY;@4őL+x˟NSJOZd!MIKm Hc;7AJmrG{`0d1_ ~ʙ5h4?lu9l)k  l9%\9Qdrѕ*vpwr>>V_)a3vpj{b=" ^=:<3r\fY|۸ϓ%5nc$͒fYk[Vձ}H{3;aV愒Lk+PP{:VSEPZ$m\ !Ūjջ JV=]lu4o '#& KYu%n$Cmfk>*t4 D?!XEp :KUFN5(.%àZWNd6c.U ! 'eŝi 3A"GOkrO Ţ!#f~Nz۟LxXsK1~bkiQpzVL7z8xCU*,2mͫ%ucݷׄjM.^s މWdSp!p&*^?`5u9#^hiK9%XF\f\gUbp$? >TwDd=ЉܾԄ̮ɜdVFL>9E$Mt\ߛV(@y~~u~ifp*!a{!M]7\CUTM55(*ud؆ι ɹ ''7KK :N$<&F5A(7I(2^w ,i:ɓ:r Og!X?fIF^7~{wyϳMZL3SZZPT!ĜNYKkih Ŧg5Hd g)Ƞ75TSGe㯹7d?©)dPFM٪<~߭Xğ:ۼah1o3*!݇;R:JF]bTu[o.a]s*!!^ƈeVLZIg*7YeGǬb;=65lE[ e zqSsl76Ie 9qnujڕh$>!j³A G4/W%VƷQK) pᢔ0| K?h]rc^v\iw?3[J䎟g K>"2Ѓ9yOZ-CC=vײv߇z8pÇG5 w8}M.?RIoI2?IoICAU_TќSCAU_Tќ]ZοGlgus}8>|LHn0 ÆPIyW` P~;gdTca9Llc:^8!E+TGC `XvI79+n G #K;MU-=FA>y;*n֭nJ]Xe3KF\K N1qtWl.T|6G_eQCu_Fܕ|~;g%$"nBѐg-DC wzӧ_U>2;ju 6T7Z/wzZ>-%M\ go;Pi&.tO?9MrrA싞 ()hIiivE78M4}5\g91眘)Nvk]55N+WV:^Usi5 ^&82GVzӈI(,>Q-Sǚ"ZG<o`Qֶ# º[V̞9]?LYᣘ,nh4.SDMrMK/ KL H1x*\Fe˫Ce>I*S[pjxB,9sk.uK9kY.#X j.df0>o<[(!,i% Ӗ/ƭ}_'GORH^yHrELJMUgĽ^-ci1 $hJ4_YX; KwTkuN~S()=egע4+pk)!+$&;J4ot']isy? !m&HpFKY}9E Y3 ]X ʰeZϖѹfL#Q(ob1wJl,eՄ1 hT&RD׳g) &GjVI<%gb2;]iՅ3Yj'G,ɜeu kMD˹D%e,m831+&}~>ڐ޺8I8jRf)J5†A (̢PdTr5@@tA!AW (T 5 |hW]TOmZ ]辝FX]'aڎLQpTd瓻n}aJ$v+5ՌjS`:V4݆GBi+g6ƽA<2yPݟz3LIVskY)PB2s3*Τuf&a\̜LV̼LMI>\͆sl)UsuG%W@1$# RӺ)exna#YdABǟLg!# VZS" i:uY x[ [ȣl蚊F&h8bVDdzx'ɼO%#@`zy.(8* -L|w"KIoc!yTEd`o]::%?nM zMxE?8sF8UN7aI5j}5p '%k'dm=$fZP+-&q [olKœԫgXTR_=XR ;eY 咮!* wY\^QC2w4ҫ g+{i|tV:;K[uh> Iv tem<=ytÇCÇG=$~#_SK{ԃG54gH?='¿'/C%#9v4Dx]8cvЪwct8-}f?FaR);4d`ͳ{j~fg?'+[ ?\sq1191c9~cs-q_5eq-Hi7)i#wƽǥ̫gX"J':?<>}D~ڣ_YITk6 =I9C;[X2^3ɥܵ ^XY&l2:N3f۔ZUD5p ?sWOo3x_D߫e6FQD8>>KVP>E5HlZVUXhA(7!?c 4qJr8Ü`Hk?dvUTOiӚzU. M< #*'d(ڲ7!e-K2EWL2SqxFRDRPHvxn/K;tUm(t=:v:e;Sڑ"ͿfNڣ_YIwDŽ>|`xXɣ  P< L̀ YǮIV(薛mdVwȪ,ܶEUUbx`I ;>̪*fbz n$H?A3ͿfNڣ_YIt鱽i~Mj.amԾ^V4_"pO#H~_6󾊿6~%H Jܦ`J ;jC) 6Ӑ=0*|O@z=z?^?/mQ,g$5jplaɱ F4"<&i*>;3ņQm_܄RڷUTU&Ut]7~'\dnVC~ eN׽'GUͣuwUƝmYF%.m*KEmͶ, ̞ڣ_YIw^7nʎM cږD6A3]Bm-2#v#C 2,\<9Cg?U E>GՄcE~'}ٞ ;|(gfv(bI=&$}OmQ,g$5ôYbŏbhID h܀8t@)c@-ѐn6pF W裙!HD[Yד-/~\(1C)t'BuBRlG<1Dft΃w((=Qm{3pͿfNK9wxm#/u"ͿfNڣ_YIwwxm#/u"ͿfN']ȺlgǹyͼW(>e]oiv 83&5VvڶZȸ}M.?RE8gx+K7<׉: LR|g4 bfo ~Vc;T?/z3*q[)[ ?\2>-K/|t xwא﮻ 'sZ2\zuGO<+fDӥpaf[U2ָ;g,IlK/ʸk5"TP ˩ 3X/ͭ|J;z.5{Xa:բPR b*F& A݂%UUbKu7ØMf4>$zz<_JFi_eo^[Y/+u!kŘf~"" u<_#ťS]X'`=gh|v,[E&Yw 'xMKIV1jT-{e$3l~!;N$ F'ҹ)(_G 7+Vro0:T,[X&TxRsߕ5ikw h4/n3cO:xJ ;"r>w3--L>IqZ_W|BB"l2G~0\b͋[x|uvN"‹HNVenK uOѢLŊKX3];Ou-Z=l/UkIJl;$@?gwr1\ x!J梩ԣ(B7uV@HlU kE"t\I'Ƕ Tg%dI^Qܑ25Vʵ9! MQ)iAp9 R<:K(yWNNO3b6zocIiu=JvUu-s 9[&>i7s@kQxFVn6;5R̈DpfUY.x.Krz9d+%#~%(Vh8Hj 2 t4dwU$fQϜ'4p) u-~bF'󦝻*LLQ-uFv30oEXWq,ʳQ\YgXi%uK$IjOobWS!/~W}% |ye<ϙr|fDHh+KtSYLfM;mc6C䚢!ybtc(E#H]ְۦ]diɦN|e)AH*L# WhMR"LpoMXcS.1y lr2m~BN,ӯ]hqV=Si>Ѕ .v.gFM:ᯔY7RŕKG\A- y˲tiżo{ghU pkm:Bza݂X}џҸD"S fÊWj>8ybt,^Ԃ?nQn#:* =ϳbMR˄)2)y{tQ%*NT}q[ڻ}FaK^gG-^4_έ7^YIYc5q&Z:8'\GT+Y𦇌=W}[`ӯzV۷B\nv{.˗0vA_5U:rPT>Kkrytߛ?9/yJ{x5EE2piT茡L>Aj!΄TWnρc䯜RI8pz_=$~#_SK{ԃG54gH?='¿'/C%'U}QFrMv41b,f7.p5j^Qqz!Al#A7z/aGIe hNN՘Ha ɾpX#\TVOH"9lZC/T y+3cF$sPWLFIc]}J;=aI81$9r 8ppCp-7|H1g`R!Ulgw< q.RwvG:\)ZvU!r1!qjO^+Ǎ@ۇ<5|ݦ=1YwE>l'L=B$="yZDɘZrE#sC퓸, .me rTT%Aϴ2tͮpDii#56c#zїKvNv1)|rj;\2ĈX HYMVoXk٠AHG 07鋅ƊT'X,q7kVF$xr3fg,0h ض z]+4ej|pyZw,̰jW$%9ˇ\|RCEѣ-ڢ*SRy%EYIVhJAߧv>s`Ӌ'耪rc]h!T(4Z'r(A@eXɖ>nƈm[Ju`"Ud.E782GQd&[ ;YuvF)EDhAū9^@':${a29Dڭs= bΕ@ J6rI#֒R^ut13)4|b)QX9PbKUvt.MC`g]aYzśGM@陬y r ;kB#:UV\`LgAV`OڥQuKfʖjSL$XiRE9 Lv&٘r]Gz2$mZm2g*Cs`3Y\9 n"3FŴ%)#[ l5 |Z{(b(VNṝ0O\ ."F\8d 6a7t'S©ԫגs Tłv.#7 {o6DG2R0##+ÐZm.rÅ7~u85SpQ"W>S;]4Gn5z y5NYvF6ݪȠv8rt#"E}u}99 oIݷ'VtI ?ק6VoSG*x4M1kg>oo9?ߩC`}}=wďkiq~;HF7Wޙ}e^cW$c.fͻKx}NMy SQ_6zܜz_Oc\?^|h&kӐW 6n$~yx&ğ\=6yG1^O'׺oǰK=>>_.h,!v vԴxVD/#&(1v<ܼ_v.+a=U6|NcQƉJdA5s GЍSDTؘΔ|]U4 cUM;sxAu`k+I'J_{R*G=+6z2ځRұ$5@7_HzǰK=>>_.ll%܂曀fˉ"Aj.7h5z:y(iJm0z!=MbeZ.٦w4\1bdQo\" VθAW |ue=ĉ)r[,Cź{"wj,LCŋ`7xSh>?Xi~zǰKTgfk a)^G)%;흤+c@b( <$Q$OETʨ]TFى $&(xlyuŃĉ㲾\p525m}i5CkC?aUo!n\[4,9bjא!e1O׮x.ʕ)0e J x/]}eXi~zǰKMaw-FY8niȨ2MbXjDMQuQRoX[4M@XB%cpߢ%.bE 338q35ڽ޲EԢ"O?{} _Xݾ%g=*1W{@|} \=c R7a`4F 8j3HB؏ HhU,[gmw^s}t-"YG!6!X1 2jA2tf39-4]/8oE8n5-"+t4Wt"i܅@@&T>_.?)sKpa¦ [&f9-$A`wQgٜ[LIcvItO*cUąZqdq|&6 ! 49 ]Xà}h06l -Yawf7MǻebJ+!#Y>_.oQFY "a Ԯ 1W7!Μ.peqsl|>{/@@`}c+WH >| _B?G }D^?)pa0(K=_G_c R`Pm/—%>{/7?⾏ڿ1SzǰK=>>_.K8|_n7}/_ӵb"a0(Kܫu&NW'[A<\7f_y׸lI fj8xnvEďkiq~z/6f>Ux|E(S/2y,: rte'CАؐ="}HR9E`Nnܔeqf A%2)QYkn(E m Z|2!^ducN'Z[w1BV Z<2Bْ*lW<槲jN!FyH-WZc9h%v;}w {=#~,JUsTI4fo(K4@|<|܁xa닏1`y`y "uǂHY|t` '#-q%MG#C/?VVsўB|K$>IuZv*LLw9[䭛͇ēᕔn @^yMer.E$t$Zx~Q 5f(ʩUr롦x5);lVPY=4UDܞٕW|0:OS(`wx(װC#>ϡ m`9 ~D@ sY)5Y,{)f)kyLNuzƝ~ldSڥ7P=5=F^UFSR-6vpb> &1MR0u5e(U5Kmkvدj`_ڝ4'-4`nYE2+c-h6~c+?h={)ȄPRvo vn6xUX9^7?342zチ0=`̦=qp2@ _VATy=av7&MacD[cf?SEsp]@ɫj^@y=j%,I(TT?QA?{9 8p=OÇG8z=HFďkiq~zON_9?|KzO D#,1BrȊUѓ6uep+<ںmc4_Wg.s< xR>Ƿ57J;Xy+u!=tGǪ)u~' a%Z l& UEmӍ;v! Jn- NivRtN-$|=7ePzGEÀk[FőɁO8=k9;)Vj5"HBLCRnHYcVdz):! %7MVC}o9u! Ffnu6,t- )#`M=3-[a$FeE41~VXF VD5n˛,ʕM:73U^KIĹ>F0dZů}5Ojy(T(a qw;XyeF.E '!+ S& `>ԑ\v5aDٔixs$;+_o9tA͜D<nP_kSlTՁyjvTAקU-IN%E*xL'eAM;2 22`<t ]J_`58cEIwL\1;=tlEʶ1a }^ATmΑu%Ad5r.{Sڟ)>B)톜fhxo*ŇeήԎ>Y* Fst4/v4zKb5=3F_XdX /`|o#ο+3(z:LE /XHf)Ar'5ʎ.+;`~'*mU5@#EűQG||TWs2ZZ2n޳Ȭn>|ѱās%7za)(˜Pvm4m!E]*]P̈́l IVN vD i$ YѨwtt)ΉiKiRY PlxRB0BbFjK6"c]GV `! -n!A6I(G P=hl@?Umw!O3db̨JvJkxL8oFX6j|s٠(RDwMB/ѩU"}5MMvK"6SYΥ40&ѯ=s7xe7Zh Q c=U$q HT?kI\J"!o˵W]M{uiLki´**ڣg;M0?ZQBL }ԯQTec=]de0㻘`ERo"ꢏO6dݷv%v-ts(+a r*63Q9j&]8A*GpœUbaXnH ' Up 1fb~6t3)k_ihm,vFVT٘;8 >ٲaKYLrWR{` ,ʵ KVz8ήbDWՏ<oΦXyo2e~lr3/aK$[[5+">A 3[C ibdeslɒ>\P1z܉mJDz$Ȓ|պK]gD0 >} `TtTe|DOy9{^ȧ`xP:bpÑG8z=8pq#\?=jA> i8?_Y|U-xc'3 .HREʿmnm`tr 3b9HEڼoe_]Y ܬl9sJmtly<gqϣ~ kx>(M?U:7~SNZԀ|sNQiu%TNtoQ'/.׬߆ndh^~ݦJZU-TKgDtT9=AibU+76$"ldkW凎* $:vc4*H`:8 '"xUF͟DWxMLcj.3v ÞyN`FUUeb(Kʊ kfHݷ7*]e@SX}~wf3p[%En#MXIc oZPI}$Ne$HtrG2 `dEnMO+U ɶO@b8.¿tQʵ"DPd٫4՞IͶϑϗu~1[7 E@'^+#ĩ{$T1jif߳ϙ@h>] ps5j[%Elo7 b,TPLm0zYUo][4Γ[%>PeCʵiT\d LvEJlķ:=< b!_e_]Y =~wf3rvNNg'׋#fPlCI l(Rt(mIm$U2tWu}u?b%|!1X.>^\LF1qKE'A˚$&W"dųdr-y.[U%Ƒ7L@TQDNl+Rv/{b;oFj+|lj_(! C-^Ξdh^~{-zfed]g"X*:(<}fH6p/LG\2pmmAŷ\m+',,. k *]Nܚxڻ<6m&2!T'-oPn Ln#][2t=y6e[2$.ğE\d+y;!6K]) |.c5F=XU9mLSXþfaDyQM:DX]i24tUIi7J!duc{-zfKu7ᛒs]_n/e_]Y =~wf3r]]_n׶X{-zfKu7ᛒjp}'/~Ǩlo7e_]Y ܗxpWW79=D^dh^~wp/Rmo.~ZٷO94CYpzv2#Ǣ(ZF;|<tՑq#\OM>,^m><+E!)Sp JORlV Y/ 0m$m{jGʰ`T='U}QFr鶾_'m|X y C8|o]sLH`cgȼM7#Pâ- !+⬬v[Mt_/7*mֱH6 V1EV͉zůqj_-֟trti5*)"]<Ͽ}hucSU9ӥx1a&.NS F?9=Y] =\k5tQ}kQ,Yѩ6[gz#>sxw"p˶}U6K̨'.f%g-U߽wf~m+g/JTpFbGN)1P0O$vtzxp)lnFf&M0jNgCz6̓%_d#fUwinpvU_F=dRZH",chaE9.$M-#Zt9ee#ME'*DA!R`Gj#*]EhjɇrRjw?eYCHHs(؅Wŭ69s3y\#d*ݓ?WF.T؋uМg f JEg[  t~,zl(=%\̜UN~OD])'\ ᢎXvQA)0k z!K#a?8Ü (tӝAgeF 헿*/ylݐ]-,#Xx~8\QMaXf@Uxq7uܖJ^I&64t |5/o37^D ?Vg=ʼnfc~w,*> "uc(E(Ĝ8p}KÇG8z=8pq#\?=jA> i8?_Y|U-?/z3lKSK}ddcNݱ_L\lcd]s8ϓ<~l9s_m6{tYaW+bn&ӣq\ʤ%u߳]U$QI&MkyXpal(]PDP39LpÇÇG8z=HFďkiq~zON_9?|KzF:s;K;B]8SX)hS#&d&)I {|9Ih8W]g[O_Wg.Ysu9E\8qgmgӌ?N3%۶1hQU(zﯩ}2usŽu"3v2 2ߨg[O^>4)˜juF{4 {'keVU>.MeGJN:vʏ&\A 'fyPۻ+cc:Vh 2K1D p90ʑc %:kui!O9.ev.rM0jM:"l^ywQ+NO|)-W4[b8U4+-Go{LM't:&l@]e98gc10wL7X\q)LY=:z:y r+ȑyvV\7uW^L,Q#{tg\޹/LiyM(eJmYʌ3I<{u@|~z#VËg^/|//z޺y>տt{u@|~]cג{W_Q^>4w}h5o>K8}~_j8C"z#V׏Fwy^K_>GyW=D^]x<jߺ|=޺y>տt.1~_G/gg[O^>4%>?}y/׵K_^_{u@|~z#VÇ<%}#]x<jߺ|xpg^/q~y3E׏F뿔5M~)MTC>bzYaV\5A2<ě?Jd'^/HfE[uO{"G54gH?=+O>9>B\"+SX8eՕvV NW:{3δMǔ״u_=tßq#t*9}ğvkrJl;4yg)}\,CT*IH=W>HKK*SR:Y3miWO@dY aɀ; 9Cw|V^3 Zy{( ͤQ#5.7y+E9 &j 63C{+op&͵a6Xrf&SRSFOXE7lvd21l@[[H#obZPV,+cɕ,A.d>7wi=@׹! 0p'M#ޒQR$*k_'z7wv.{fbY$]p=@׸{Cw|V^?od_z 87wiC.ghy}n?o$"3#`\9d>7wi=@׸kGIEgGsy}n={!+O?p]p=@׸{Cw|V^?}'?}{!+O?p<_?O/?=vďkiq~s3 Zy{IvLCat%VE=goj{+Z=w秇ͷx߉C(dcE}v;;uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/AnnotationViewer.jpg0000644000175000017500000022473711665471334031003 0ustar drazzibdrazzibJFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222n " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?5_Xx=OѣX5w0%C䚲iѴ0V[&dwlv3D. bZL9[ kQY| q|0,n2zVJ<Ί5'9YNLd?rI@CȆ`Dl$mf7g qЃ'{SM-䳒9XмQ;TE%P?/WVtMKSHP.eiQZEN7^<ivI{חZl8'a^F-_(!_0sE|)Ik-iװ: ]*˰dqeYt e1>,˔? QMS/#_/n/nm&Oxcd!&GP$9yy< JO[.sa RWoF쌖PJ>, _7N,_WZegwhp"h//i#ۻnc-KMHMsoi-̑I fS :F\rQoL _"C*/ȵҬwaN2bUr H1ZϤ> DRkRk2M +>08N%)w|G*/p!\_~$MB;mZ$r`;FopGqQ<(CR6y3q:89Y _"|B2/Pƍk %59Q` 85h~G%Im4N,+hp8I’W42/_OKUtCO9Zy! A(`q^ޕ/ahy#ԼQhCi d?gJxC0ؿ5)nEMM7OӴmPX8fX1$ n:IaHfO0S kwt_2E\}8}+OOs7s05)6kZp ˹j;Ӈ?;&*As/w0s.1MrOs.˔_N/{T}^`tcn/pL\lS{Qz}ϹNM/$>~K?J:z}ϹЏH/_H}bW_W^}HXiG$?MaOsoy/?}WzQGm>$?M;i_5J}W^}O?_4᫹1 PW=ڲ ?yE~+>Qz}e__(>In]b܍X8oVUNOẽ#"'~gng{c4&N3W c&?:wȽk{%m"Ρ8Q#=8+o*"]τJ>mȐ{.p/rw9vGӾpDSk9# uQT?+"ymVH2@7*pHZ6,% d`-ʍF88CvBGP/屙 .>k} 4Cc;y:]g٪ľNウ|mVZ8fWh[$a9S#V?'Z͗#kzWYmrw|9HG%"<5-MmvpbG^8-d)[ aٕe6F#u|`kKwGӠo5[{73\"G&v89V^q$58}hxvDT"xĆLİ(Nҕ#o ꛢehѕ Ty)ҽM\ǫ[Iu`(X5 U_XZMbJ!2ra 8K(=j>.wgEbӒ`` if`Jڬd?^qZAq=Ω00I*p^2V6v0]kYͷʸV922689}n]}z/Ƞ>%>Ϭ4>lYGlMzKBc mߌkߡK7WSqD+$O@j5twӣWUkww" o3688oCV%(w<H5j1~N36;gUŻCi\>h^%2e@jɼ%xF_n ĂHb ́ubΣO$hD*B.GF8ͻ۩<{n|uۆT-Uc"e ҽ>ĦoiD6D۱!dvP#r3Z;-͜\ hbl#˲82?-u3S;ݝvN*8cՠv$4g~*ܼCA(B1+נ~3;HSH[{&TN)>daڍOzno2\tˍQ$#-HJ<;K4hGUZIBڔe0: T[vF}l!܄vpHM{ ՅW^Aioc*4TaX 키ًV DC"7:ҏKGK6rJ$UWjQ  Hҙ"ӱc&E?x ׳\mvZG,ʬ ,Qt5'ۼ?`<߷񞙣~Zv:eYS ?VҏKf7h^%2e@j$մuHtu D&MZ4%uL䏕Sa΅/ in/ O jX.{![O0ϾxϔثLOԌm AHm6mRm.-BS|2Qx9^H=ij~A"y۬SiPotۭe4[g)9v&WGʸ3'8Ϸhg}y^ټyyۿo]=3G֧'h_-?_]}4{;G ?xR9% u䊹&êC˨Z&2oѦQ+COI?uy>c {gk'ZVf&-P7h)Y3>e֫6YM.;N]uuhr =s3n/VMyd|SvmƻZ@ŤRŰ~vOƢѬ<3mp,:t둃#G^EWa'4V^#"a#I$ۉf`81:w>٨ߥ߈w+6H"B5pĭB}J3}|˟A=o! jw2]7 1J$\M&$?7$~:/A^mS)\q]ҿi?t H5ʫvjřRC> !m#N\`PJYo-!h=eQbX pN)">͕ws AYܐȫpFNPГjbj?}~Sns^53Q[׸aLK sn܂S[Ml.^ݼ̊ sFGq@<;wzgRsOG91gX{!G2`6m]-ƗX#Ԗi6FACݻr̫FpHtoqpu7ȷHy>ԛbY19 *O\yi}ŭim=춎if@NXˠkY_[q+֦rX#1ڙ<wҏzF nM|NTHˑ I wlJ5k69n-o~2s#uG Z]kEu=>QNlg>g?&6\t>"Z{eѯN$kTvIyzڗl֤gv'ٮZgd\z=m9m.;~b-,T YNFM Wq̚hYϝ*:G̅?rסhzƏ(,wC, *A"v>RYfo, 6J7A#7IJ:֎VRtd]|:,`KH EF)+-&2xR@]+ZķŤ?rA##UM QX 竾6j:~=\^ݛ8)'a 9>>aWnum6;{B x#eVfr(N:zN1I|Zi$33Z<)ux%ݑlOoF o\I-嵥s49SxGVH6 p D|C5G 2m'u0rczeZ֋Wwzy4ʍz|)2j(yt}ZIJ6k{{ĸE7##ȿ2aUn9 %m:bu?Ҩ[F@ !<z6A_G#y4H@(N:$!庰MBdHW^yTG܁Tu;K-!S۴r nZH+ R 8"洺Ld)c42$Dֳ4FFABz+'4xuk}-^ % Ec )g* ;r.M>oymg4]n<.]-O-J9X{76bOyr'o-)k!Pcºih?m xy꓉" ';OqgD:դF{|W0.뜪5m7NIPHfeAB<`@' 0p8[D [{-n=B4f[0JJ@nJp*gdy&Db?h#!9\T ~vF7=ƻYysk,^|sIpTo N gξҼC15 ,B Jf'J}wPh" wu -pNC#~Tb39zFZdvBb Fc7 #h6ǐAq苮Gb2E`fl6pp ކwGӠo5[{73\"G&v898wF AٹBPx8,.Sds^Yl 97(]~|q[7na2az#=7gc=]gAu F n{sq@~i멝IΗ=[o ş!b]UͶɪj6H_Zމ#Dr8-y3cj$|z |EZX}PDKKq9 AέGouZA<$r̪X iC@=σ5?\[,GCpVFOc' @[^Lt7R[GeD`XG H9 IirLiJ*+rcFi5j K%-p 3N=sv^mX짏M{.[e2 ݀e< 3O_Ac>xR;n# ,]W錯 ^{ikƗȒ:,*T]FO!W{Mjl::\j&eʦrG܁P/w˷׮"Ͻt۔ %&б'9˜!O=p>ndDo< MK]˩Qyex(Xă93"Ҡ{K(R1rL F7r (`yi}ŭim=춎if@NX\;XA-nYaLms=u~D_]îh1j3[IuuYI\d PG4x&VUNi%rpw#5_wIkR-A,c܌N(^ tm68Wďw*pK2HKtIN''$`czvMr=rQ|wb4Bti^&a$RH4[08G$y' 4;;9mu[uumk= ygpFDE+hzƐyd"D%v~R[ l? ;~z@uY|YxIԟOu -WX?֖S6g n\^Jk[G$VW%m,ݹ(z?+O wy}=* 'h Y[hݲ@/@8=O^)>$9Ke*D㸒EbS~W4A 65_j7^ )#[;+bqw71,lBJ1 dn#ԡYdv m+#H9blu^ ~,m'B͕IQ:4$>`$0P ij:Wθpu9-Lc27 lSbǛo-C Jo}reeKwjz:U\N2= UO$q>ңl? ;~z@,bfʓRoAskw<%]ΓnT0pw@3EuY|YxIԟOu -WX?֖S6g n\^]t5V}Mɸn]N@$cO XBꁝTsܱ@":c/SP@TmZc/|UZ-8nO<;vu'5Z8ͷ` gg!;b?t[By?{o߽^UJ4v4";$-dDNĮ#[Bu KПJ͍խ.OHT-N7lYX]xQit緺^1kTrnQ <_mN.IEDfU sv˨wۭ$hh41w|#gO^)>$9Ke*D㸒EbS~W4A :K/R(f7p\]䳐4+9&U7$LO/7:n{5sGo ux]@и>{R8 /RBvSǦw=o-n fi2@U-igHCi'H>k(HoXEԞS"&[ah<6݀)ڠ! 𶅩:]ۦ>55ë[\+䐩l[*n(( ?K?ٲJꈷf8niO$~Yb# 319$9$]PIV ܕ;o[L8h`vc_2AҸJxbY_.4LMy yz#N\`Fk]B 4LeIđsEN8봯u5MkN%^(岆TIw!BoFy"Α\Ir Hēt%70PCf^4_]îh1j3[IuuYI\d p7+$|rV#ކ* t~hP:u9 xV]7?L/hfC]I}cle5[]HÑXJ-]ҤL;$V%>lGIVdMBѠwKe+ ˇ9•q\xMiois[j$e9$$8"qy>4L uվHGL6䁻vDxcˏ /2HӼ/w+g?&6\}R&owpAdR,VAs*9 <5=]HR)%{QUC2m^T1,YaXIKjFY;*baۖ]yAe6F+ť-:EL1ͽ_8ٲE98{rsh:ZW—VBʊiUa1̡pTt#oS]KMn4_2Kش#G:rAh]>lgfYJ&ڍ3P]J)&5M Ņ Iݍ&5m6R.]B5 |V2]yS9#n@}+Ě^gcoa{=LڼkQ1&GAEMʭOgk\ϰŏ=>YVU^4lUf-*02|M$Şv]kO:<lH#9 >lWbhdYќc鞣֧W+)隶{ieOyKF$sxF;?6YxBjf F_eIĈ!IhNӍ|Im.>oLWq`X+L$.}9OiP,,5-q gG8h-Y3YYO[.g.YPFI*&'Z\YK$y :3* ̎ڬXʩOX%i,Y tJ,h])#q*s-YR!vȰT9sBpV+8 vI+,g YGc->ds%j1᫬x- n@,Q vrZq `Q"ฎ[K庂V)VBB7a$F%kKˋ}N+iaBU oRI`2 ssG8=×pMe.1F1VU3:fm3rfIycKGQ"xQ bv76H๎Ky!YWQ@4Mu8cV7ɿWze,yLbM$۞Aװ+y5+{{o`IB:-nb ldYi߲\ɧqY@ȭtoȌp$\n9 I__5XM-q\y(gH)ge`6)෢|:쿳mZkyi3 e XWnUy> {]+y"Y#Qʍ g̾*GдnӢ^T!]#ONi\ֆ)V*V0 9DJ | bRM{:o#.c ."VwU `X*F7UํnDbg ;7:(WkY>{ij|N ;w+ŭƝP{ֹX4;^?8(w)gagiսis=칎pTH>i6zŌnhۘ  A@%ӥm?we,#[E~J"@$`g#9wVƱuim!2 u r"Qھ*w1\7zwp]ɝA GUtyj2gnϙɍtPg~5uh/ij68IL&EX`U@P;C:~=,x@-G*c`@$`Lա[u:tcoc>&kH7.' 1P>iz-ֵ2KHfvMΖچs1oL7E,@$$ zĝH6' ѵy/T͸*rQR(p#Y=$OHcǖKs-cam6;{K- DPC1a9@(rvarG= $rb蠒:4GUC*qwaYYI<<Т:_ij sΊ1(]X gܠg4U?".J@E!)dUe?oyz#N\`'S׊Omt{+I#Ea(wJ0x$XM&PCxm|A\K0Em $QCI$曤A⼎TP;Je  }SotlQG3Dd~lFXA 2:׹MݾoܾM6 I'*]7bN lH&5m6R.]B5 |V2]yS9#n@}(R-fKeϸ,m<9qcӸ7w_iv-~ *G0O3YL{@38Ç^!ƥhv׉qoΜa @*$!,P7Zͨ`3CpF *neu;]Xbhx\&d":̪xk]F.cҮ-t-bVVeWdAC.;0'*:vu kwDIXb$I )a±5GijiqjBYʋ,2GqDZ=!-$|i$WtLc ,$B}뎢3/ 1Hp]Za.s?R_5DKI!E>YBGu2Y$%= F}wRf@6Hvc0:*Z7ۼVOmc991Jt[UԵZKI-FP쨲۳|߽'<%}q /lĐ K8pWV7sźfs^;ٌd{  XJtz-c..\!fg@hAsKq)%Fiwnܳ*)ˠkY_[q+֦rX#1ڙ<%Dj)$K[&*?y4j:;={Ʋ/ʑ*J8U }&wc;-&5FdS&6uTi@RQUw$r~]!6x/omc6w~0r ifhC}|߻g=9Ӛծnk]31D˂!;sh.Awm/F ؟.{$f3p6ly $'2-Y>Gs*;nF8%*p1IirLiJ*+rcG-6Z=yˈUYԗ{ƀ0%> `ѠXGDdrC ϟ9Ѥ{X\BY$(qpNK5'ZpսдiUXGs(h\qDĞ ݜ֙/3w+A m,Xsna%孜zWq Y/4d9e'# XMHH$lSd2:QPjyY:y΃rSfu޳aplI'9”oxU{Itu`F[+2)XN_jStjln٣?fsscku>b}6DK+r/FFG+g k 4ᣥ~0O IbO\Ȼ n^J 5lj{~ oe;:/n 6M|y_[_=6 Ξx 0v>`ל Ժ]7"! '=!Ϣ1:G 'n}vUs^5co`4~$dP.eX>^%d%g$y ][h4井G0e[c"~f 9]jZMI@%]K4kf<~u%`+jN٭-&=7h$n]9e +#by|Ah\i]T,s=I #(\ta3qhjiq]X> odC*/u^H=j|6-.'#`ARz*xwP^- 0HRgmH+ ۅ21l/l65auuH׌,fs H'1"Ŀ.sGx0b[y xfU*vix:8'AXnWS,U.D^]I\d3KI&mm-s S"KF1VLo)&/xuHtnP7h מU: v>}SL[_ٽʣ9e.\R{0#4mΜ.4o\iv/MbkKh2}y1QukC[Il6_U#n XR Whh۪؟y~.^V3w?.˻=7 "[hlcVEm 7@:fwg+K}9xFfX&-XBg_NݣN,cw)@Lr-#`Ĭ ujl::\j&eʦrG܁QͪMŨZ> ofS*/g |ǭqzg5 7PqyD*޳1ec"2' h ]GKe, 1|DVPaIP>)}2[KWZ)c 1`TQVX6h/̾c2vsB_+[|./o( #^# [rJin"4O ^+-˘ŵ?8C/qlڤ\Zme2&r̼zv͝g/7\l8p=h[j2e2EAomo$D\`ٴ >uARYxj{2ruӨiIn['%cq1 .Ưi]jV1޻%'+$& 3]6.i$$0Ym0! ?_zdZjw[)` ݊)g^BY!Lc0<K+$PI 뒿6==N{H9ݮa9P|`|9PG\>(e}jn2YJY5 O|v4Ϧ{jޗ/-f̻VKc*x 7u[+8'R[ĽԈLXgiTm1`u* aͪMŨZ> ofS*/g |ǭZݾhQlX Q@UҬnӞXlHEq Ux_Tָuռ:d͗-YKlqpHݎH 5m6R.]B5 |V2]yS9#n@}*5֬quvqyM4x9]+W<eӬ?9zyV_^u'5;]@%KUVͿt|l,Wc_үkϚ,ncIrPoP5jZ][>#E 2¢08rI(M4x9]+W<uY|YxIԟOu -WX?֖S6g n\^i}e:miA5݁h #!apXO5s h!rKYibvXF Ey֍\hƖ>@$d< 1)OG fPIėҳ[ EUt{;nDj:Gپold:&zo^zO5uu~M|Y̘qbLxN7gnje6zEց giQ+OCnE$;V|SDNxGۙHGRcאcEyk\$};z2۹HUZ,1!3 @^>OҚWmy,m{UA @ "v1MldP7F<9u jnd Jh о{t=YIӼ>I<ҼMB]U6Mͳ8#STm#,%F"!6p[~faHw.JqcN#.Jcn9%dw ``㴢<^iK`}ގVpˈ0Y =y]nbLҢ<5b Q#0zC5ero%aXy2` )"by|^mX짏M{.[e2 ݀e< 3Q@f-*t%Q𽦌̓Ehef, L99b×oq\Ec{) (KxMbNs1Bz|P?_zdZjw[)` ݊)\Dcgi?ON[pkwGEl|$.H(.H֭Y,$I|K$fH"s[X%`+7 e[Ymc[iZĩwh !Ia="F 4k}V*E/ߵ3nlh>#."fH0|^4EڤA(Eq^mX짏M{.[e2 ݀e< 2xKԧdKI.FW{i+rH&] LP7[8$-ݸX.2aO-hZDwϫIh7vG>laa;(6zotm.Hg-#/k '*W|(((g4U?".J@E!)dUe?oyz#N\`NxTY +cT3$ zo.uդ>tI "KrԼC71ڤ}wT$!-2϶l^jnqko{Z[Ov-eF9`0=G\{no6WGQ Wt}BYj76U : n%EszߎA[;>w"TtvHI }.^GE[̾ULp8Ug-" +=^E}DRK{ $l J# r IMҦKyckxGS.fXU?^Ԣ3· n'tgH ̪@bRe=j|V? }uzgZТ^%8]JbOFF~xC‚{VZ8fWh[$a9S#P+.j[\ W!Zv3r,8&Gtx.lR#=-pK* Ƞ *vh _*37'.|]oʰCH̑.zEcGӴ{o׊9l#]HPQHjl::\j&eʦrG܁P*z66h)[ELrɜ/$wy-Zo2dQhDnY qºw@ckjf~v:⤟SFUI#-.f ; s@(gVV,Pnf_1P;!YXk.Uٱn󧺍PȌc yR9Ǿ%5E=~;A9I2x X# eylRġwb +>]wG>nc>źsy|ܽ3Hum5o AxȖe .QUῳ .vpQr3֣um7Yk/P\Ik2ʡ RFpAǸ U8um6AZKv+8UsR{GZ"ҾϦKqij+ZE5a, b>BÑr(R?+7pm핝W,y /z4?!6w˩A;IS~٠ J*iͻ\iz KYU pJ3=S({}j.^ʑ)6LlG|vEW{8[L;d9^#5^]伶lf/>IFD,7r3oC@Vz;+صp7 r}5-[MѭT-,`g]L)lXqh|=Qۻ4𡈷`,}2QHjܳ֬// =M"Ygxxq`Тjn%itnUreUwa>-ncemgS  J*մշK-nI!v*i KtIcgyawݬ4 H8a~b(g4U?".J@E!)dUe?oyz#N\`檾(Ƴi2}14L#rل%yȜZW:qCm7P-.g}12B#ʜ>҄xGQ fү#U3]$aon$,pXTt;دI4?N#˜'D򬈌= }twg%嶫c5QyM2$ya8 q#z"֬. {Z(gx7\l Ҵ_[Y9-O8wٱ2@ePHqk&ou]v?쿵X]ťwhl y&FVlݾ~3Yjn%itnUreYw7ݞ͌-wlGe-(mBqa׷wMuo6M$_nLblǝ>>Ub9ۚob}Ť9n̒I,laQ!*E7`ynV"}ND6}yWnzDG"ӵ\-B]t5V}Mɸn]N@$c ffʕ 2G۵_Q@v.<*4"NތEiV HLy!׏CYе9K#]R-Exh?7 1|xfy)cwJmއk)AYv(梁5Z%䗩*:ux#.;NҪ>cCBF95WA5s mgzΣ_L?JQ)ѭ[@pq;b8$մuHtu D&MZ4%uL䏕=[MTKP}B-̦T^9d@;Z9vV1r$8S)ph7Yw^]VkZ7+rjʆ ~W=[M.. Kep̮жHÀr*FM[MTKPMBdLW^yTH[;J|>}=ǝ(\7k.wf) 3>r6Wp}[gtU>sBCI+0loaX<_Vwzfyr2(pFpɵ lb|pe1)A <5[TْK>{M&mѤ.Xss7wvuY|YxIԟOu -WX?֖S6g n\^ ặXTeu# 8 sYv(梁5Z%䗩*nˇm0sxa~F] 3yeډV47$bqPSzՋ=N; .dɠHA#/LJZpjLȒtgEaa Iw˷׮"Ͻt۔ %&б'9˜!O=p>nzHoyZnۄ?fsscku>b[8%h9܏ yR<`s@{{Qu G4jio"o*p2_hqjZ|눡SV3#p˰.e<,NxPmé2G4W c61,7~qHϿ~aj:. uq#vF:/ vL {_wޫPmau AthV,ׇ,lfUWe&yUO4!p~\"kiEq̪Yjv!AHhVf&-P7h)Y3>eր9MG޿<|棲56k.[ !}1g䌕O T 3uZPsm(]ȁ`R9YJ-b88q^1'Gh&M*E dK{$p]KCT `Ÿl/qg+PծK帵 ʳGe7d+giսis=칎pTH>xj{2ruӨiIn['%cq1 .tfNP KWY`߼t]`~lnn^i}FeC`qQyug&bVak `]9U'Eqv- 1m v9k[y܁dV4%]I-5;B"e3m>}ht v౓tqD3N yOL8ި nڶ?ٟ~߿{x?K鴨<|5uaynf!_FdKP{I4vvw7k?e[,nkݘyQ=W=D!n|KycmB;crr0p$OUm6mRm.-BS|2Qx9^H=hf=Q"OkqлarQ ¨),dH xOO i"1@51'$[M[tmB@tkB AzՈg ,rvBeb8Gb (|gH*[#)䪔_OFA^u^SѐWP_4jgg]Hgf-VRƻv 8THm+FcZIi[&hY;ԋ2eÜJH8z]I]Kĺb{}8+, E,-6ܖ  &&ޣ5Iq4-'t B8=  Gb2E`fl6pp ކVn"-&[quq̬ 8J~C6/-$3b̙#qIrs#$w.4f[:Xk{*tȻ+ Cn2g"zon<}6IJc,sT5_[fwɽrfpXc1$X`8m/s{.t˦(׎dAR\ɞ0C+Qúy.C܄W  uNQս|#pܻXHQ@%[\ZB#;9-U3en&?w(qwԿ^ga.)N3RsCs;{3ðO#Ɖ@,Qt5z=Q_@?]M'<()'h szxMBE.J^g ƖV`P7da5)=GïhST[̨=H9AAt"u;HV@ltW@7r)8~m PXiR_C]Bʖbe@~r{M:ol{ree@$PNT߶jƛiͻ\iz KYU pJ3=s@},pͽ%mTpY" ?1˸ѵmGTuU~ZܼD劑,0N;pKl7ۗ\}ב=EWMwG=VB^h$:.rˀNGkX7;yYH`,>˒b$at9bGu&|<Gp +A-+k&/|̜G_0 W]wClg>g?&6\}@uY|YxIԟOu -WX?֖S6g n\[^mX짏M{.[e2 ݀e< 3Zycȕɐ?"ltayg hlbrYFdFa۱޼<;wzgRsOG91gX{!G2`6m/<;N}kjJ8OrZbzoeeBkNOMs9[hlcVEm 7@:|=Z_ ΞP+y<1G|'6>ydgr]R6v]kw5[K6"2()/2+֬-eMp%H ofS*/g |ǭraW4/SQMJKM,X(>B5{{PHJ{l^rq1.СwR6e̫"zon<}6IJc,sT5r,`YdV8Ϋ˺Xq@ ]'.m.']:*xQbQ!=7BӼ9whSttPv?1+$#D:szl-%`I*s=#xnP8ҵ{K%5Av+)qtsk7Mi&:O *[(+ل21l.&2˳^cEo o3ă )ٴ.p`2$xMŲc]i Ori^:gv8A0I-}vIRHcs9EePy]B"=-R[}Vh\Khaqo"i80|B}Q>j:D֗Q.KkK卾a Rb|׼k{q H&upNX5 [_68bb0YYG#{~#Pd Ҡk+ׅ񥕘#)'M;XczMU Dz;A&z X#'20z.o>ek)9Ky20s _"SM_]{{ۖe仍@$aڀ=f/ k7FXxjD*%!Uxo/$ꭆ_cRѵo^sh>MDkms4R4xM(bR9J6㥽ɵ ?#%RW3ׯmwqMspXpF41;@#\ۺ??gC%A 5^du%wH8jgOpl$2G:a$ ۲$@/ԓN[ ^ 뵳%҂^[m(qeQ&Fߕ;}"/W`:DɨirCo7LV%]I-5;B"e3m>}(𖸾ɒ t}0b"u,I8.kzkPkoJͭF{!R2ʤv /M#iYɣ vK{!ʷڼOXazm✺i%Q7ijg)qx%3ͩJ}z%s2-Y>Gs*;nF8%*p1hv{Y#+y!YW@4Mu8ܢ<~m5iƣ}}-%gB|`S{`6Tksj>-5?2pmo4[b2HEy^ O"H-$_ ^i$wS-ۜBXОgjZ|눡SV3#p˰.e<,NxPn{kOol< dÍcq>xsIk|_Yeyo_ɚ#8^ǿO#]px?_К#[rIYDW(UW!A}8Z4 KnِZZF䍥id27˷W߱Gح?+COTCtk?p\/FMm ߽|#1`@IM #STӭ$ /u&2Fb&N@~Q> wu nѱjZ4}ڿ%i}?V {dO.<8{kqT&]hZ&Doq%-o H$qPȸ>aQ]G7[8$-ݸX.2aO-tӬE2^y;r aqܢ ( ( ( ( ( ( (9?".JVgH*ESѐWW!)dTW:qCJX0sSE];7 yܜ(Rx xVe n;pܢǫijiqjBYʋ,2GqEO"XjOFLU]w!8<^A9r϶t{{]Vx[f$N1 (`@P%孜z]'nѐHt\84ESVf&-P7h)Y3>e֫r]>qCshJʾX?+ԢɫirLiJ*+rcD:szl-%`I*s=#\QW^dE$JIĩ\0 J:U "\=6ÌG\nquoeZ\h.cevF9R0}Gktcqc:x76sP4ymolle)/&r++Hg>yfnvXtyj2gnϙɍtQV> ǯzPLjߥjݑ-3*`9$++0= S({}j.^ʑ)6LlG|vES}N+mf8i yPevD\n eA?_V3~ОOqׯES}[M E-di,( Xr{V]nj{? !:ټ=yv-1f8Uc(麬okv86% >IٽU:v߶i:i(MpNF'ܢ|QϢ-f_*T&P`sʜ*3TtEqas;pʁHϿlcQa$x.@.Py`:g͝ok evw!bgp:f9 N1Psr=2Er~% [-wO=+iwplF_%T 9 NVu',5 K#wX&W*/ Aѹd{oZ -]"chNQlmgpF:[6֢jlw Z4Nu"̥`dp8R1ހ.QUo;8,.໵;&A"6  88 ¬PEPEP3?GSEU*ߌiO%Tה2 X27=wJX0sU] -gJӴ=>(Sѡ(\< 0 @{ZW:qCC-*K{)e{ą[1-F!m`6i8izi%{537vw*O˻%wm6Ӓ ^,Aq*ے\%fa$3AgjvpM:*#2 S|õ2 dImF[i*yw/ݎi%`C:!vJZ2 2ee'R}>S[d_%`ZYLA'Frzu X潺Ui5E,'wFI/5OMpE$2n'VuOs^mX짏M{.[e2 ݀e< 3CNsagܖ Xⵕs 3؏P\mvZG,ʬ ,Qt5'ۼ?`<߷񞙠NH5H$x/-IoDH~͹߼X|>m˻GҜX R[FY!8,m7P-.g}12B#ʜ>Ҥ}wwg۞34sk7Mi&:O *[(+ل21l.&2cqwzh#Nw _q隱+U??mp|~Lmnҏ?O=ڀ8x[[Ӗ).,4Ite#0ab2p6ʹAƭ{w[|O4rH;.9 [M[mB^;%|e@$eb;Vom-5 IrE21!8b9 t F :}2OH[4I_0y^avbYmMSͤ-m)Z["X)%T9S(;C%λj0B$68']O&~,Ҽ:[N8^7ѮL2 f$6_JQ)ѭ[@pq;b8eawmE#_zΛ`ŬpmQFs;}Ȼ_gdܺ/μ>a(E#<$ 6y~uqQ@v.<*4"NތEiV HLy!׏S^O@< &aĽ6/x[Xo=nŬ3C$r#lneXJ22r6OY;\]CRqszf93aw[鑑.&ŷb w퐃6G  !M5M$YyU`e>i2#œ0wGձߴ'uX}w_tێsvЭ,/4OxdxXܳ! J ao2Dl>Hܘُ;||s=vh _*37'ckjf~v:98L|Cz5_F%+A#1lWZrk.`>v><ʼniQ@ s#$H %=Ic^uKK՝~gp>{QxMf{x.c[ywQ.ئhYN@?Nb+bBe'E(/}Tc˰vt2;ߒiՀtq4 x*T X+Ehs@d=:q-P2Ik*pp#6F[Ojs3̑K/UVm ;YNbz%]I-5;B"e3m>}ZjiP[5xp޲] 3yeډV47$bqPSzК%孜z]'nѐHt\84xwUŗINP m|ie3op)4%]I-5;B"e3m>} KVtku5 K,S,J[ g{7t]e FVTD90y?_]kBPوKG),2 }_@n)Fɠ=mɌM󼜇ʬG;sIirLiJ*+rcD&-#|<ta$*#rGm8; ϠoM6~}=ǝ(\7k.wf) 3>@k47]T >ݨ}Lr3QE?\RFarUJ/ yM :EC)^S+Ψtu5r0x?S_ I `%-N$6x,eQ>>i]E ꑈ4F'˞I(C 2 Ǣ]k=yϷɹ97 ˵u__F:R/EL>CUV#,[ʟC@ Fmm#yτʎE[ч!N hrJ< `tVv)Z]29EW Zn.?>~C %LFx6H͌mˮ>:pڅ$3.օ@- 9@Inp?t=u39çm,K#J~RYYX]xQit緺^1kTrnQ;+صp7 r}_ϻ/D'||;gܞ>ShZDžF$Sѕh"Ba O2?:kI4 >Ә^㨾֬4+#c̛<#`C'@~8±zOa-^+K{iiEӴPи*:y^Yo"ߦA7Lw>}_e=Tl>72\Ϋ)/I#iDsU2WE@uu~M|Y̘qbLxN7gnje6zE˻_%pE2n4ی9<=FN-5'DmI ]npqEy݉5xmﬦmlj7iC͂l=w|ᾥ$wQIp6d1Ps&H@@z(OյkoP綎[KiO 搷)eeV,` qxK}նo3]BXͳA&ǧ (ZlRjA.mn焱km>F_nHjI,n4ncD-`^)iwmXcQ@MwPk0M쵻o|:2lL8[!pr==cJN!]+-f@k* g( ^i676sp$bݮ62 Ē60I"=]->I#Eq~%LyMre2,Lb#Q@j?iK}k.,~;[ʀ#mONݣN,cw)@Lr-#`Ĭ vPC6$1Kk[7ڍyYv$QX^OkkHE5ܖd`Ya}TR3008<wTUmRDi(oI͐ÒIEм// :%+fߺ >R6 ˖+Q@ߊ-u,EuIbiG KV|eTšZ1:rOw+M>|[f0d,TWoQ@]ɪj6H_Zމ#Dr8-y3cj$|cuu&vZzmdn6&wyꭐlmaQ@<:f Siim-y/cb2è%Ǫi֒XHXk^#1J}j xJrJ(񾅩 !hX!&>sP~e 5ee'R}>S[d_%`ZYLA'Fr{(Ѵ-N R)t#oWYc+p4T8 >` ǟ^)kI6_$Hy!RAX!ap1J(u{K$Zv7aIIVbCKda]bk)t]RX{o!gFbAyvU+U8"J(>ᆃX,&ve*?g5^ú,$OjvKlK)~3H7.XyEq^mX짏M{.[e2 ݀e< 3.<*4"NތEiV HLy!׏(Uuoa=##j'qy ]-<-ڍ7iZ4ҡF7W1 |i]r:g(Tuɨ]\hCP5x 읬1=&cqiiޠ@wOsآ<~m5iƣ}}-%gB|`S{`6TQ@Q@Q@ύcY,l@-9G 9yy!qqqӃɮ_c_%~~3]t {֥r-$y83\uuη9ݻ^vtzW#\ƶ=wJX0sW3TіK[siֿo uUD% _7gutW:qC$3Mk Qox-qK,0t6<ɩ^7/%EZuđ#ӝ9 ~fa.63,%}"[GӵSOvO̳/:?]$vl16,ͤǒ<ʓYBǧEr)ҵoILdUel~T1 (;Xe}N-Y9Ht#o*9crR7P+!c/yEyޕb[{bIk COv(Ž,_\j-mڊ1$Dooxspn j5ww3x$s䩸lcc=Y%>M4x9]+W<Q@W m:}seNVu {-B{Gs3+-0ʑ}*;]wGӧl[7y0#ѹ084(x|QkxCcc,qIy4Y_8*D'm7ehZlE{v+2() Iwu\nquoeZ\h.cevF9R0}jl::\j&eʦrG܁P*z66h)[ELrɜ/$w{+Ncn#A- ifDq U^Hs@V^7FҬnc}R+:X!lA@^3:h~!|CeŅlo ۗS, *A"v>@U=7Vuv K4,$g{?tuk}-nc[ndL9PV&ېESմBP\ d8*r`J-j+ x'ab4(}N[{K(nc- PWaV$մuHtu D&MZ4%uL䏕 U8um6AZKv+8UsR{GZ F桤I}wZ}^\6ݒyC6(pmΖuH5 It&V*q00rs e05;a BnBK3 vʰq-%tbDRG-sp24QA%֡h%B$vrw%p! +Aѹd{oZ -]"ckR]t5V}Mɸn]N@$c +OڤEAdNr9bN$-c+u `w:dQHFr22ωΣ7nTpnTWmK{cskE<A+˼dQZ?$ڋuuq𽽔|~y:QAF@vU>my/fVYmW;&`Z)A(ĖvRkQMi| {Qv& qK ʲ}0>oJAx94 ]yIH rA13vgٽ t l# בކ|0XJ.6sVWbϵt{:}FUws wc46rA+%(.%[rK7$28$F{=wG,喫csj%X # Y@NEڭnO.>o|g/ݎi%`C:!vJZ2 2ee'R}>S[d_%`ZYLA'Fr{ KVtku5 K,S,J[ g{MΖچs1oL7E,@$$ v^mX짏M{.[e2 ݀e< 3CNsagܖ Xⵕs 3؏PYV]A,Shrz}&ox%[#\!O0ǘ) ߕmC^:bgz#gI&TI#Ն:Esuly|񧒛$}ۈd'V#/Iփ%y)uom4-a] -VS<ƠBX–7HLj'm$ԉWP@^y$z?xr1;B锠&9c~bVHGr HC=d 0ogea=Ykr>|p_AyTʟ_r`U$~&z66h)[ELrɜ/$wkX7;yYH`,>˒b$at9-.55;-+AY{L$-1ʪBac$z#v^k4cHXʀ+"vK.@Apɫ5NʬIw#r?3@~`5 -?ϊ9bJ~Wq1āʹlhFMk E2"$3 !F@^(b+/?"[m%I$`bT~V`jHiuU$E{,ȠW-X Nrqܺ ׋[/̱OG,4lN0 vWTN]]u(Y]4Ƶ3fp%F>;m[MPxDxYp@9K#អt}BYj76U : n%k |=txv$cد)u-V \(>^7lsswY=.,巍.YGR2 Ivލ&ͣj˩iϥg?li/^QysiiݾhdFXQ[_IZֺz~8Ӈ+G_w\MQ\6 Z4L̐ܙ$bJ~F:e:5ڽ8Y1fSd!—e\pp\:Fg%dh d?B-mfӭ}ȍ3d <=k9!;9[].ҙG66ۮbeS0X 4o %Q] m*M8%nľf叙c$zЖ,m8^;%d ԐG`5}:=Eo4r%3aOV5RȱMɩ_'uz?Gcsc~vrtvZ7/D d)ȭշœ4NIۋ'G$aBۈQ?& z|:ViO-8p$rP7tKn 6 {vI &օ@- = KtCCM)E_vg6a[-LRGWH˜ ?2MwzZD!V>_*YYj(uVRs5 {$7+YG˕Sc@ wvΜY<ȏFYIWrqO} b鮌77t]$EgwaHQ=ው_Q<ɨx}4Kq7;#,爞9Gڅ։BZƟap-ˤJ_ c *_٧H$̀lCz`u;Wa%Q{m5jՎ4^P-V[OuMNkA4krg(nc!)g}2-KQ|,Joeӭa&%c30wg8-E}ldv!633[>NJ4}LMF{ P0 |1n#qzFo{Z bd!C+yKOӬ,AAHV{y ʊЀBWYxMf{x.c[ywQ.ئhYN@?Ngiսis=칎pTH>[]$id خ-,e_CX6wc<^M3 +DR}q&6Yz~n{(? xG;Vi-tIO_ne043.7cg ⸸T ,"y E7zC5ero%aXy2` )"by|c^Co۵ޫ{ٙK7y)\cdפQ@w?.ѵ[{s(4{72V4aSZF584YۈG@DxqEQEr82NXJ `. tR޹-3Ykf&z}v3QE?\RYY1XlL)6jF1$9Oqe?oyDz#N\`Vz/}Ҳ.`Sr$3괯u5iYnquoeZ\h.cevF9R0}$h.4Y!fxief IvN~{z+wMI@[m s)br=ԱZA,)-y3@scgiPZjkb9|l#0 XS)[T ?6T-XN~Vİ=yDLymS;>'AC6<MSZIxrN%@! va [ q?_G L[Đwr7(N3:bo6B}oMкP Fq0WñYсiqiD5ZmsLʄL0b ?H\Hƚ{2vI Un!D`q|yJ>(u-F/cӭ>q#fE8es}qW#մٵI G!M,eELy#>m SQ؈SK匇w-3e`a5$N5}[ T$-1+66>AמL5oӵ}F;G̃go 68 3f'>n._QHbS<"p@*8VE{rDt hB튩p4BM'X/ɿqflj4ɨ߄$5䒴KSQO}cBQd罇/$O9'rOl[M-mu KiesL6@r,o%xQ {[TCyHx0tYTnldoMr]Y 8މ>-SmFDD,A*q~su[iFe2NyQ 9 Rt՜]ZDg<1 w\W9oĩlm}PjFAl#)~I [BKԇ-3{y,(# $IcyMSO~zEv&<#nՈRpx m6YOZEvQ\@*VqP{Z[FԿգkkibmYv쏟p,u!zK3i#/2DVlG'ǠCgq" ~ cr돼:8m7JMif cC*AVQP7C VS ˽rEa$ʱ<䉉cľum>[fo6-bH027tۗZݾhQlX QUq %rO:(+  ^Fy.q3qoѱbĐ|ݼ7 r|'?I/"+eb16r@_V3~ОOqׯ\k=w:64F]z|(×w>&3-F5DK& &zsROj/zJWȋztӴ|!x8K[M-mu KiesL6@r,./{He1'Σ#?BABq;sf=#úagR{KMNPmvv|Oj (nVu',5 K#wX&W*/  3Cgq" ~ cr돼:8|Y]M"Y\Gw%&y$4mנ]vitxVNMJ{O\6i@苈j1fR ,W)o n3݌gˎkVnoMa 2W1p'uVo.$-'78Ved*ARg'mѴѦ=Yu.^R X4[HvM9ȸ j:iI%g 6Ayb07wjl::\j&eʦrG܁TWv>G.X! Hu=XMrw:Fsa%C)#OӖؔA!xRFx?_uq4Vvz%5A6呦r+DPz_hvy-G-7rrK) ?3|03$!fծ4Ȯ C+!f1YWyug&bVak `]9U'ES_:^~ 6q:+ub(Ro K[Ӧ;>/ 6O|&ω1h ofS*/g |ǭZݾhQlX Q@˻GҜX R[FY!8]ƞԜzaeLY%|̥X ),{ m6YOZEvQ\@*VqP{Z#մٵI G!M,eELy# U;-[MԞD-.4`\Bpx r(մE {B'GxZ ĊhNm[MƩ>iQ\]ʱlm;FyȨ5;˝VYbKTxxbpW.=>uEe!|=e-jo5[Q,q7>F7FҬnc}R+:X!lA@^3:Ee~!|CeŅlo ۗS, *A"v>V4[MmK-/W(Z̲lTq(Q@όiO%T~3QE?\R"C)^S+Ϋbה2 +Fc\o"'~ku x~L;O'"MoK|&T$x] hpG'Ɵ#vPj*k $Vo92ݎjd wP.vH]X.٦3%r#*g9EлkXmH hXLs76#lw~׶OqUMG:fdsR,e_V`[,*Bq.sMەѼ9wtZ#c\^#Wot jv"CuEi*Eq[< ʗBQwۏ[QNT][-2\y[vsڤSLpp@9K.Gm=Eя򲅾5Ɵ<n%2.2,ك0&OkkzO/eO4S[/"KBsZ"7VŽŸBe]<@ qP_zֶZխwv%Q"6 :? jWf9Z8 kzee49$E9-ṅ![p vpņǪi֒XHXk^#1J}j xJrHu[ldU FmX:}dRKGy0xb6:Qs~ގF,4) a.$r I6d!G!7?N/GMۼP,r)'8&ą=J 3QXr@'!ң{ 67rp;vXiwtJ}FIt)me{w)rG(1a%;Tͫ?<|}Zkg -+Fr">R9j@YZ9 [{یb۶E@\$1@r7^.in429EG*7'r3_Q@oA&gg-n^gZ/5XȔh67erU~x.teKiڔj.im6"ɓ BU>wvZsDKJf9d 9 D{Ěn6q+i-fYT6*H8BSI.,ch Ʋdpq cGEXI~teК͜}K&C'p8]ݱqx/Q>tm |)yOPL{nsI `Bz/uCE?Un˳r$a*[qEYP]EVWWW“ "w *T$qXVa!-P7h(מU3>VҀ<<1h,|vi{]Kpe\ȼn>jZƩ  w.^h}Vc&a*9U!մۛei-FsLUlvIAhM[M5 F.Y . TrA;/xr1;B锠&9c~bVHGr0 <~!"Kg?&6\}@tklXcvbHKӍUua-*9!Ǖ6706VdMBѠwKe+ ˇ9•q;+صp7 r};oFdԕ.9gCc5k(q3ʬB~ xsbBF"u D r!c*c`@$`]/=2gD-5;H-5 泟0y|U0$m=յ`+EÑBtwӣWUkww" o3688oCEֻj7|#pܻXHQ@~-@#E.X&P˻ >m*2ß@mF[K֦Ί~b…m$˓]X2,qWuA:9=$cVnoMa 2W1p'ucS%#UOi$D6&6l5-) Ҧkay 劰1I!|lboYM;Wcy q\6yv#mS9bq\:-)3'sl0yPkPӵK:J6m FK0U6,5y=ƙu{iw9:n?yT-Ž r/xS\j:|c"7$X)})@|& ӵ(]D۪ dlE'7c36u4%]I-5;B"e3m>}(^|%Ai"RN,#m,#7G<\[S%5Fw%G5\#Ik"prQTw4>iKm Ns">$s'j r7^.in42nr k3Z1]?PenH_PO|(ӵ n[]>py fi3fIU:o0$U?+ߴi'|>DZis HxU|~fHEBmz_G{FbkA%̬i(>h9v F6VRH95[m.HcmT3I IEph7e:_qm J{x5%71b?3 * T{Ko id 2^\$#!w+OQ@CRF\E :B]s)bs€ SѼ9wtZ#c\^#WotJ(DSLJ4Wۿz7c9Y|c(`:/B}OP𥝄v2G< 7Yػ^>yA-Z,m#`ܹb})Ōq:xPe( EXl܁qq{VA;tZt)"3]}Uv1FYA (uekqz/@EcpDkcKqNIU-#S-W[&+5y#esXx;?p~e=Rjڅ,wS$ZdDH% JX#T%'.m.']:*xQbQ!=7BP?_zdZjw[)` ݊)g^BY!Lc0<K+$PI 뒿6=2A5{]JKRkkK3mf]j+ <q躭g-^DKMm346Ϙ0:P 㼢9*oV mhp\i,6$"cV~˻GҜX R[FY!8(޹m ݯ\2 .DAu#ZMOEɺ ذO9fycP=#X3of)ܿEoB{N|okTwl 2xTg#h!ymy&Ht# ŤE.rݻV9x>5R2@) BG;I8$zYWö<Ѱt,VV נ((((((((g4U?".J@E!)dUe?oyz#N\`u d=02:2#-.gOc=Pּ\mjzU b0YH;P׋=qlmp#cx?rt}+E|qx&"]мʫ Iڎk׷ `+{{UC#NХ*I:+4Ciq$ڡTP1Rp8&$=\5KKürW9)hϚm83h>ZjQEsʓ#*l/b/-uVEl^HH8ຓKImZ7#=*|N"a\0|Lcy+c׊57^l03!UˁziGX<+3h>'-hnVia! FCߦTڨIGvdI,3DTuMfQnܿ,-GQ^w]ǫ7mLWlL W`H*ξm˱E傆 .s{ҏknFz Cgx׊?#BKC7+W$@88k1O1?M^@n"/kp$$p]IV%EtI5ķiēn1 3 sݹYQnFz7t]e FVTD90yʼn5m6R.]B5 |V2]yS9#n@}+=RN=[MTKP}B-̦T^9d@;Z7t]e FVTD90yNM[MTKPMBdLW^yTH[;J#մٵI G!M,eELy# U;-[MԞD-.4`\Bpx r(:`څwdKs2ʁI v C@(_V3~ОOqׯ մַ{- nO v, Y Ct;O\ZTs{ieZ5_)!⣮Ae qV/um7MxPyGEeBʋ*Oaɠ V^7FҬnc}R+:X!lA@^3:bVu {-B{Gs3+-0ʑ}(NM[MTKPMBdLW^yTH[;J<_Vh m,(# r2XnQYkp-s^h'T3,h~!|CeŅlo ۗS, *A"v>@V}fUhnHMq,p7zwp]ɝA G@(;/iZ&kq <~b `Jb|ГVa!-P7h(מU3>VҀ.QU|]oʰCH̑.zM[MTKPMBdLW^yTH[;JEgwGYf"HbyCp4b3«+)'AU_hayg}tI,P|Ҡyryhb>(e}jn2YJY5 O|v5sRմn5MBp%8'ƀ.QU

*8g ,rvBeb8Gb(#)䪕o4PQe?oyz,_OFA^u@yNu[o  r2勢rx$KekT@ ٭Fs91nqVVxXKWLK{iiC*#CBF9JM3 ԓCXEn.,,Eķ1d@oj:^~ 6q 1(wV!HſK"[a ss] B//+,#-,{BeIs4p+\e1‚AXj'Qu&3bTg~Jp;O| S$0K X=<,`u'<)..=[8 vCw,r@揩T^hVpKx}k%zXG~[Ϙ"Bbk14绋+a%_,nd* s+ΗſK"[a ~^h>n[uC"3 ޼:hRڿ-@irɧa;aN6άyqOFv[Pp/#)P7,GL`jC>k9|9dE=,b v<}I>Oc'tmwt@ byU īa~@a͊ӫEӊz#˴MJ>sY53\M$L@Ė(!@3ZignZjWWyr,~P\@[}>[ 6JCb$c9̛bYX6Ws)5ݵ %G},Qbz +)8ݎpkՒ}K{Mh,Ed+ ˇ=䃌woGޔ2D`fl7COV4_UII]Ée߯{OiQNWP(<+sw QT_[bpS} }I7՜zR]ZDg<1 w^ ȪNgCW{{E1gw2`(Qx4K"[YZ_qw^ +i6m,bU_Gde !$r5t-NBEiz9ڻd(d .Tݻ\}R.Yt&MZ3 מU: v>bx4[yn."HI$慁[Y[Zy>g?&6\}TO:M^jvK 'OeAèUc+=s.KԭPrElA!2[uLA#fiBﵝu4TГJ͍Zٮ7d6XO ~vJviao-W1Ge 631r0Aw$泖9HǸgh#=I>OxwUŗINP m|ie3op)4%]I-5;B"e3m>}Ho>]/b3@lcn]q^G0z66h)[ELrɜ/$wW×z:xE;tЦT)vb8}_e=Tl>7;;KS4&8'Fxd#w qGxD֯/`hū<72a3\>YpxG eΫ)/IkZi#7`BIroGVR{6)",Au6@=],YFF|C4PI;ނ̌9h[$VpM$_99̎Tatۭe4[g)9v&WGʸ3'8V[i<^$x VYB[rI/R(f7p\]䳐4+9&U7$LO/] 3yeډV47$bqPSzoc6c7۷˸FFϿz͕ܺ:dzbOАnLFF&Ga#YjKz$ECm͍LmZTs{ieZ5_)!⣮Ae qV/5m7O--}2L ր9};×v8'OL1ȷkB;00qx?S֛bbY,Bbn:d=jߥjݑ-3*`9$++0= I ͜7pIuk[WrW#i{weOgˤƶ2dmxH#'6U靍f+oͮ>6Ʋ+xG.#SMմfݮ4Br%*8%Im6mRm.-BS|2Qx9^H=h}]x~ dGR\Dѩ*H,XȎWq+pvm59Bb4̤ X"zon<}6IJc,sT5bVt[{B{m*4͐0=hCkoQH8PpbgVV,Pnf_1P;!YXh`GT{q2̅A*w OA@3QE?\RFarUJ/ yM :EC)^S+Ψtu5q>՟ZSNGHn2X9s uW\)!D|=m⸮U5ɚId*C:<ȼЂ|5Xz裇uUbuY|YxIԟOu -WX?֖S6g n\^Jk[G$VW%m,ݹ(zIoA?>ג=B; 5eKW|vsy.rG5R7dg8lql%5Uzd霒ysQgG#v3.:9@oeI eRr :'*x±]yVVՙ.\be`?)҇aý& iOmtM:HK:2O#&219wcetaFmK;k)or"XU &l+1|InIzFM'Ccm [ b}C]F^č8Lt!قGrs@0quFUpyrށ>]&n/tY>fGpҔtuY%wjw_ m1һD|gy<͸O5~][M[mB^;%|e@$eb;?nGmWf Ξ5C"3 ݏ.%H8Ô˻kXmH hXLs79gDkwFfiRgǞJy{W8p5_xOXi"?ie$]f$" $R#ͮ[x\bj7#V[9_O~HgULUs*^mX짏M{.[e2 ݀e< 3]k=yϷɹ97 ˵u%武o9Ti a9czQy[:5)<9s}kQ. r>iHx$]m3V+{&=P/,Fa+dH #,伿g>yiv6pxSAm.#[kǒo1CF'h, UzM7Joxo{MF:$]fF^x܎0}= hGi$h eeHI۞s(y:eosqwZAYV!HI’Pku$9Ke*D㸒EbS~W4A =] 3yeډV47$bqPSzckjf~v:9]ƽq~}ܤi-691 ys{Qu G4jio"o*p2_hqܺ^gCH^$Y"'&dg+МT>( 糂;TJsP${ u KQq6rZ dnv̧ʼn -?_zdZjw[)` ݊)vlڤ\Zme2&r̼zԏgٽ t l# בކ8 xV]7?L/hfC]I}cleO k:_dϨ^FfIi4i2KfhiQP7pٙ,IB,AE';ͪMŨZ> ofS*/g |ǭr~{z+wMI@[m s)bx%񦏥@7WZfsRs۱ItPF\  z%武o9Ti a9cz=?ĶX7[OM_FvXnܥ@?".JZ%9#7!rF:[G 9Eb}xrSѐWWA H)y$}? $Kmo8w'מ4n,fYQ) >r33nź3m%hPXvH?[gA; ׏+bgRVy4j #7Wo}!hKae"1G.]BO\o`Zwfx?(ϝhG!/y~_䎇?e\[>[*T.9P1,F "K;{[a3HGe̪:_:\v|.o;I>`p]Zpͩ[km&w=(Ž,i= K۳"ޣy1 ^$~!!]C8[`rz䬕38rͻ]ƽq~}ܤi-691 ystO[Ay nַzdiff..xy䧗ps 1QMwViտ>=^Bk Mn.v;Wwa;dY]7e6VTYQybC0޿#r 6[MwV><="cVZemD83:.&c PzK]ƽq~}ܤi-691 ys 6[MwVQ=h:t#x4evySPw/̋8hx[OQ5-DjuPۃjd+[e2K'<(7 6[MwVbH4I,$H,5ILIӵ߼}sT|~]z4>,\ypM$߶MG 6[MwVBBlj4u#{-AkxeG#2/E:?o5pH,[Sq[ G$%]ei*Z'%FL?&?|z.egKx[y M*"19T4tӭ,lH-!m[`!%૷. 9 6[MwV<#\~4w쉹ybb%[/qRXY{Ȋ:lbLH[8<9?t:\vNE*tCЎ.vLƎu/iItg`$EFQBb&O+k-Ժ~Hpi$h_kmqٓ]&mj20^LN?3_@+ ׷W RsmKC*ԛkԴ(rCO5²m<S8dg &J紹O'*YrFe?ksڏUemkK3tZS4 ɕ~. pa ayQ_Qh:b޵di@_4% ϕh?}F6ZyX.H.0diտ>=G$guoW]ӰDVϧE# vkuܢuw%$W/xWW6vw.KVG@^5PrTj$guoQ 6[\ kurH3U[ =b-1{I AkX7;yYH`,>˒b$at9L?&?|z fV4TT־3#E, dcc!*>f|U|;jvtY[^}iv9c &$guoQ 6[\ / ^Oq]^]Nu)-U dĢ0C{Bn#$Ux-^`7ICǪleMwViտ>=EЛBzDv"9c!ŝL"0X*nr>eAK&Tfnl7'rՑ.UL?&?|zhwZo ZZj,DQ/s {'˸gZ +{{#8!P8G$guoQ 6[\ >ԧu+X@q,Pto2:F#<i:][N9"ǒDb d2lT5Om3ǨL.fsyyҧ=KU<-/9o3~e6Ҭl}tꎞxoY#Y\Bd[/F{- ѬmԶѭW`ubm>[y eOI?m3Ǩ#Z&ڥս*j4P<+*#+!$sjpkW:v\:H"1$9mMr$gq&?|zI?j[{QFZAgo"͒caF:!p:Mft"P˰ fV#)7<;r&?|zI?himK:ZjwDl-f۰3|T1C\׼1q>'8 Y5iu.>W&ze8Hm3ǨL.晫k7zT~lLkms,FM׍4;.ݒqn%[HoXEԞS"&[ah<6݀)ڠ! ?m3ǨL.NJtN]KtRT5[g/.gtcqiiޠ@wOs&?|zI?v^ Y̟M5y^C|Oan[~BO_c;wQ$,0x2>O9EaS#HTHBk WÚ\Ka'8+uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/Main1.jpg0000644000175000017500000077746211665471334026464 0ustar drazzibdrazzibJFIFCC-" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?M1|̿ I_| k%|AmG 5FOxٵGU5gV߇4 gя/0<ɼFUI`JS ५G)MH?$rN GCc] Iì[tH_/vm?ZvIkiZGHEC7?V-I,,'Q+jaiPi8:QLOqc uzn#Yɿ2N&8g̱qv?0eBJ8F5*J_`TjI7N*i/ES`]3n; 3󐀜W$I5xp0{610p0I XJ:okz$Gͭݤ/.'M7CmծDW>'\+G2|cۋ9tՓCk~v_'+($/2~1™_qP.Cf\aܓ1j8lU'CO 8˳^m˨ViVu50qǺG O |f8l%Zk:%b~% ѿ<5Dw7acL6mcz.-nEҦ0}Gr'[Z&hEױ][\[\}_|N h oxuWLXcMNX^fk q.-UtaB_TCf(qʖIV һx|0:BubcFn7Ju#$<5Dw7g|.#Fu?|t ƛۭm.{f ],- Z;MiEquawqkmuau $/q$aO𾻮V=&iڢ]Jl5飕TX4+q WY[|1{\e O F?:[yx|6 ^28̿ exb1~',)pX68:T^WbZ6*G5Ңeղխ_NtԩV)]Y _K>t?\A|t٤ 47ڞL!Dy :6vLΑsɬs2+ <30i_%aYMwO,HR*xx> cr&V S$jZ9ûVSD,Z8V:RUX9S,=j9}] _K>?vxkg"4o7_<3_Oj._htVwwqZ]Xٳ()+,2*-ˏD@<)o#RF8.QHZ=34+ ʫ̰3[qfj|7atq8b(c!JSRSJ/zyNyR S| SX[TѧagK^ZN B:a ;uR. ,]F% ѿ|o+7JG $ٵwGT7vlwa61p'mZx߅=h׺?4;Vе:+oMBW{S{n[݋ŵ窢4'ׇ+#\043N5c_(e1S2#"~F MhTˣ5qbpjvV뉨f2I`*'a1cSi4erN_\䧋pe zݿ<5Dw7g|.#Fu z:>#n4cqodZ-E=7RZŨI5 ff{"Dg0jfZ솉 βn+q[ƧL`˓yQϱ}Xt#X̡g.Qt'&5', U7⫩{*g|;Vt'K9jueBt+BJ-7#k֦. ,]F% ѿ|x;,T~2%O'tvҠtYRmAo wol,̎]7<oZk/Z3kDZU&UQ{&q$0!P oO xwIl`i+R'/Z8C&JjtQpU͔^!a#O0xf2\xdOby?/.?<5Dw7g|.#Fu=)Ciu=\Nqs12+ 24R|WįmŨl@u o$9.Pw>^)fy V{18p燭,]l,*kB R!bZVWspee W4pyl*VQ.zhӅ* r^ҭ)rAN2s]Y _K>_z'j}4)4ii|֖yese{yeoyn^ 6Iu+-yjkswp!!->[hj\Z]Ziqu0M{k/ይW*X\y^$'8\~;>ur`3lNYʳ*؜.WbTpX S)F?AS+U Xg qL/S'aqؼfҡhURTy//]Y _K>ʹo/5ɛ#^/M[mOLum*RMJ-m2֐}L P] Khz֙D ç?AӼ_jExB]Ȯ$Hl/c'ɂ+{;s,v{UQ˳:nGGaJJO6`cW¼GBiM,ɳ ]L^t<0⼚.x:8[8QT_Jc1OQGutkC^®Y#蝾Q KB]FtYub!}6]KLuOfkEK`H `[5b {)g]\X--9Y_MKHy%Utn浚; ?rgXxqyDl  b N< zУ,BVJ(RW_?+|:1o4cbx,%ζ*p$FExow!O5G/ .Y>ƫO xRӮuox^i-J]y$ZݞqK%ճ[Zjw :_75 h\ãeAiW;Tyq{-AmծQ o^9|lrdR֧~mf>ҵ־ rXYk,#1(cQԭ:xٶ2x Ukbjasz2XhU,fbe0VsT:Jog/ .Y>ƨ% ??|e_ jWڎxBԴ)մ-^KJa6\I=`b(1n mx@};tgOl>}[[_"o>Xe}cOU7K1ꪴ:yjjcV!T\ڑpkrI.p> nts*Vsx}r ݔ~=1/ .Y>ƨ% ??||axvHJg56@L.wqȶ{i$\"4;YQ'u!qaxz=G- ;]^T>k_:{{/K;k 2=eYO_.kTRWb*ƫO ohclW'ҍgl`5KᡫO״I>6tݗvOxow!O5G/ .Y>ƫ/7CD\KC7IRNB]4(Xy$fPں/ Xxzƍh&Vꚦk2C.ou)6}6$ZKj^՚)RA4uPp0U_ 8^I.y> rs04 BX50Y##`9KNnZ5c11_J+V5:҄?xow!O5G/ .Y>ƫ9.i?%ZO KqCKn#ha"Tx-ѮR-7އw\n~+’+쫈me_$L{J V3ƷLֱwbXH,*¸~"pbHt(K1O/IV!*հ29j/ecNf5xT+Cj^>]}W~[Gڏ/$)m^!BE}gq3$m^MzeY^hu_H/4Oq#If-:iqχUㄝ Z8;01L.C2+1TpEogNFR`x?'C&Nx {  Ix쎔Ĥf8hsRN@xow!O5G/ .Y>ƫI5="+)u->;+o-$KM-dMJK%䪖LBbp,8]mҮy|/'nQgMFU.}n'F^iZXU羳YǨi+uMߨX㸴\W6^kEZ! SbӫpؼƔ>.eK R[3ypUWWVu,. fzӂui!,dEVRqr>& ??w{Ÿ!.hC&7WdykOOgOy#V^6^S/&wiX׵ SH xwK{'|sxo =v7Ecb..HOM/y%g_p73 T@>?>)_h]h$%QqH !EP m/?5sF_Os߿lky3|%C*ɪj.qM|^K9a8BYNhJJ49T?f xO¹Vw|O,n>i`\. F1i(ƾ])N8/i):^n W8ymi15;0?hث(" #Þ}S~%ׯkx@-oW ?KO8G/x*=#Zώ#Uz&7ڌ^G+ãĮWGI}?JOj>% ]M yc(YXdB92~xͼ ~q$ laG"!'tO-BƎ ~6^-Yqak2ꔲg(1kKjQoZUa(ЧӖxc٥UZi4pZfJCGzS{*ʷ=Oً$~qH"OoBA A #W?|Ϣ麮;RiZUs|8!|Sƛ[K}^h|`oBVƩǡxS}?Jկ: 'x>>;xw xL𦫨hZΕ؋;l_\@.ln'̶#~rQ7 s2?J/L_-W׾OO>a}=5O ^]W[3LN.\%(<<)sEUa3lj7W 쾳RT)SץBq>3԰qؚ1L Z:/TpK[/ĺ4+էΔT RNU":|ߎ_gdΑo>hzbɩ{RM0^ZXx}?째Q{y. Wd?ڕcx%7Sb8+IU.~Ǟ9Ҽ="7%O j_MoXūϢZ3KgC'b+x'hx'~#SO  c,_{ò.Ժ/|sP? Zյ2`wg3ǀ\G8_ 3\x>20o5 ]CQP 5?ׂ|uAixZ|JYj|1/.x+W;Qz{xNW_jZ'4!.>|hkc\?>~P 44m Fo^b f/n?<'qɛ/ψ-|;'k.6i[#-GO7??H+5*?[n:|<|{dF8R7n5渎μ^><k\=hKl77hC O  FFBt*b1kdOc1eY _K Nxz,JQc*sZnn厎n}e{iut&n|&RÚ,s[L$?:3ox'~-KV$χu '}3V4b9l4˫wm#e,: y[ _n[?Ae*29Y UVm ȣ~s9;~/Og30># 'yuƶSfYf*"5iԧ#.* !Vu+Rˆc2Q=>35 /kxr+dXL]8\Vc6L3\ das*x>:u)TOwm#>7!ֵ .Im%6sb[um"6u(8W~$/:mjG[use-SK,XV[ A 3jh-c"s ~(>Xςsbk1+b$pYyaVg81rWJP 8j5p_chK lq lFOC2X "sR>zr aVܿ/-<}y>,jI麇u4y5.oiκƏeo!kEk-2nCLs_IGq]g9ԯ56׾ Mk(4-V_ 9YZlPϟV?475cC?߳_> N[:>/¦y_7x\>PP^ y|\%S)?༻NYU\沦S),xr{o3>/5)oWk& 귩e*j .YF{]&M [ߪt)Կe GJx:hZ.}eb՗Pkx@f ?#xus|ѡٯ+WWa\#qNUCم/l:([Ӽ=Z;_T~sxx7,յB|n %n5%.wCdw| xS:$l|/isTϭVwm6~.em/X 3%iK6mP+Q|ѡٯx(f~c#of n5M0+L.e*ܟ-1YvZIPQG?o?Hl%6 8Iqs:Uqx51UʕgST¿e,5h:o~|D/<XF{/Aƽa5¾ YLztڵݤ:Zuݵ8oo5Cl'-ZΡOx>H ]sFմ 9`{/'}>jGKfOScC?߳_> ?Ti7?c ]gF6fgYa)1ȉ,Nh%x 6g9vc-43,ge:uf3/ l_WTdѣ+*L> O.<b80x-T+acE8aCnF|D3Z?`iӖ1R䦪P#:?ʨUv~&XǪ|':+iڍQ*MRPl5(%[e/ $ ;^_=gW'Ck-+ O O:/Oe+W^c,5*oT?6(k~:|C|D2xE|EXb_ZpV/FY=qauEZ m]XiTx>k__ZB`-}~2Qi_jm# xG}FGY"##*e{cC?߳_> zΝj߱ZYǟ٢{[^RX'GXNUp' xNYLfa.>z_[e8lel.cKT)ԩyw,EZy5gƼ-ٿQQp+R hc(̱UHRV*1ƜR]I(]x>WK(g|0a0+.lKQWO>!i^1ωl([_A CKӯY[ +{ԵKkZMҷ_oD//ÿ6"ռ'GR>.cծ/vhcM<-:?ؚgbuYdejTT1aR br=LKOO9!+օl6ERts2+T=RWX~Is^}oE5ԋ%͉_OX๳h&HS'gkǿ-B۶Z~Aq,p[i7+s4&Fm80\M :>VIA~I?^fc{?>+ W9F낪>gxXxj FӼK}pjN,ء0:ݼL-,,涴ߋ|3g|;ihϢ^Cpko5OǦ_ "no7\2f@?sV42ޣaA?/=ga \A7LX5^LLj5c|. *ugR1x N+BX>1s6Þ0`zGIP^1,e<~U,0Wk(T)ц2VS_ 5 7|<>R|409gO7 C51akek A8S*:j{wŗ mZxWwz}48|9u>4-[6}^j3^ދF%2:߀)2LxRy()7DŧY\MqEqE-սW7Ý?h/eG9 F~f_{վQr5qH~qy(a?8?Wn_`2 C3,S =ZXXbbVk!e,FsQ*19ajeKaq4W05%VeV5\Ռ__|1}i~H"/BxKSk{[HF麜h^sl\^Rӹ7+ZM1%~5[ jľtx&Q𮒞]_ML2O=ʋOh4mh[چ3Ý?h/eG9 F~f_{CY֯b02W'/he+-"XpLl1ڕ֡ ]N*HNexUccqe`c11S,–5<%cô՝ qMΖ/^!־xf~* ogo|M̓New{jpE`-nK qwa~*7<#}KMeı%q+G[2-އ[j4ﴵ>V42ޣaA?/=rvO=@*Jyَ\N&y'3T\F'BuNN2qF7K [FRG˛ f͆ 7&m_QJדKͨL.:օLp\;?/ 1't6_|$k^Ɖ+]}Z^Ysȫe-s̿;X_zȲNE`j_HK/`8Ryt2, Ĵ`bh`3,Ggٌ<چ6K1GJ6~ٶWxIG0Waxk9.xpU,VB<2=:ԨMUi?K4=WMV> OZ»_ YǪ/t nPFZQ\шMfGC/i;u/ ]Z-!x[]7S[-J7X>SWtgq;s̿;X_zvC\)fISQkUL,M,:#0b)b%IaGJxzݘ~ C 6"IӝhdI^: )SO:(TSJ*5$?ZCML/K;D://X*.LS!Uf{z> ,%iakXiɪi)n}7es {2au G+/|}c>.7=8w*߱결! AißEN*agS Vj~gq'C q3!07(43mF2HSbp<61P ǯo ꍠxbh-'HgwjVr?/m p =NJ;t._I7]>>oX 'Y䯩_x~ݭ.uT/,t6  a37#QInR"sqxm,ij]\åii[q4ZF9=9 F|? ?f{׭l>gaqoq}wa" 6uӵkMOӞu .i|I65ÞggG9 F|? ?f{c/;K-q|e!U@#9`HOSf>?=$%PE&)&ѓ[sH+ŴR9qF7oߣN ᯤ1o3UxK U R\\zSi+UUz^#qAX lhC.s5jX1ç!WJ0*9R*7~vf-e4zm߈5 ;A1qeݕ/ZCxtK'оR|U干4{^siXѮԭ47^a5cvP^nU?s@~(<Yχ$b |-Au^1|0xxG13x\TƎ#0˫q{<>;N"X||pg*&|uZcJkN̨զOZ*VxoZZu0ѩ >}KTzM3~ |=f|=k[Zh/ ?R.. _j$^yuBw&x[gI?%qjw~Ոү/Zwyg)ÞggG9 F|? ?f{0X\ I[PX^"p_̱ن6>SRL2Ac`)cO#4g )ϖUNhҝ8O pp-\-\vaG ^ S /R7 W·v dl CSWjO_jh=|2ֵxOƚ ӵ{A%i7;s?v0?1tqK|*#qyOy&KG3j.Ib1!9G<iO1*|VQӎ*.#S뒪ah~971Y/UCUFL2ipɝ+¦FXTUiVTѮiok4L׉p ;zxjl<*r> 㜂|cb㈩ypl0(µ1|b~,?M4k}gߵDjթZèCg w^[Grw1*'C~I߇_~* G<JZ!KMே$6ǻv+\]Y]]Y&[=31zc<=) Y-cO¿$? x;ojM['.g_ ?o>#} eb-wW4;U?]XU:&adLMH”e[>Ãz 84p8͗өN1|JS\wMoA>~VIkϭOhuok0hXͫɦXb"}A[D{~x7+ƿ<+/M-"O_5ZJ:ƵծuxEѬt%~M'Þ | O&?.~%~Ѿ7]ԯk6;?j>6q߇^<}WQͼ\ho#"p8,.m*R^ԭ[%J럂Kr?_|&H|7(/%Y^_*ts̫2ou¬U*bbpth12>>ߴ|R~߷O5k:?H],Zs Ү&$L?hMEtk㮗. 2xO8€I_!yZ_F. ~ k |wOV4ox]7~OxA爵OhZW jzdž[ZM]ִ_~ZBdž 7'h(|=iW:_ً.ۙn-%_t1S/> ?"8ƖKWadue9n&x=zXX֞&j(lUJM2}2uʾ^%\9x+x\38ʭ UOB&XHiJ FP_ ]Sy5WC~˟>|5q6s@x:ޥgwۼ@|}c-H>"bX1jWRi?_leoBe|1>xw>|{h3xfGf~ߵ|1?ZމÿWZԾ|BﭯQg4?h Z08eQ}*|\\* ]TÃx/N)R*U|4f*pk]%fFr1kWw,[r:ѧ*RpO> b~|Mxw_ |1o'7]/cƹOU:?π?o|$ֵ}Qtٝ7/ڷxUGoj-*hckTK^4ST)1 6Fsm,'t *_[3*jSX8Sê*Ct{Z?n?E{Ke?~:a/Ӟ3+|-Ư9,iL^.+žֹx?]PoN*tq2Nstf+3VJGK,?iQ*ʭ*Ȱ% 1KWWsı/$퍆XCU7BR_?ಟ3׀>RYm>#O '6|ue5oj?<jNmGƿ ,[^.i^nOOl>7-o>|#-'Txo|?|GcD֟g ~jm;Kw~?;'?Ru|<w7>;:Q/x#]KxB<M::.hߊ񦉤kz~a6"M'ak> SΈ?_U:׉[٧d ?I<ga?x.x^޽g*GVաGܪ[WJ=:F[QaV秃.;\PGܜg u9kNj*êTjԥU=)~n~_?টS/ïٷ᷍1|:'ψ)/3:Ǟ,״7Sl   i'5N[gN}j5*,]xЖ2Tpr`ibgZ:Jt,3U~ϗJs81i~!? o_C߅:h|Gk0V"o s'cFe괟)wuxᶛukm6|>epЭ/m-U`@ޯX:ӵ?ZއAc?Oc~~~%'O*~8D|&_xw]K>;> JּC3P/HҼxKVҼwGWV?ѿF sxi#k\ţ>`SPUEJQa'JiԕUJ~c%BH)Ύ \fj\>S*j3peg*㾩RsyÃF~ϖ^&mXӒ5aB'^?W?_~3?}/} n&W|/^új~*a[YihZM{iB8oz/=?¾RGiy-|l+ٵ? !"ܾUXx~Fj"iV`ͫx->`kbɪzN"8,\w0J1xSSqq5Ihde ZK/Xicpa'O)JqPΤaZ4]:rHRW4g5hl7E~~ EAx_YAᇈ>'>4>YxL>o nuh_iz@n5<><x_ڣlK| E|/mV}B]kHѾxK;FO=lg¿? |]؏gnO3}"㷎&~~7$|A6>l(#mI.|K\@XIb󅂄eBk[F.Q|2֦ :U~a|5\Ѽ>-կ,Fxl*\HކXUNl _0ntqUsHQ9cJTr&xB+*wC-^_.hC__^"/u{ >xX^a,|#7Ig4[Z}߱ ?h]ĺox+]PeҼGO/ki7qsF;J+i4B^)Xh]音O<`:|g楪i9^ҼQƺy{qxR⥑tNHoOү7/OྭOo!?@k?ErÍN<,x_6ld_|!Χ>6.! 7LYMP^ӥ}[(WZӜqUZΕSQ䜰#F5s_S8F>ڞZyOb'lRa sZ:JX*u2ө|@#I3ˍnإg= ~EK )?c\~֟?eO-!u |A$uo _ǁFH`o?C&|edPG"O“p c_/ÿ_ᗁgس0*Ԭi~:|`ӡ;o+_xg~'xKI%|GJAD:?@ٵh,2Lpx,Db\07 f#BWT(G_a)ڶ.i5M`1R1CuwxgmbsxeR *Օ,5G5z.ou?x|1ٿ^<,#^PxOD?}?6>Wrk~uREo|3kZn?姅?|)xWm |j1C|Z~ ZX%~DzNk/3;x Qx5O C6QU㏌ "Z_YҾ4|BOm'~ï`xNoX濠]iOjҬC6l'b1*ge*`+eURW ^9Ӕ1SьqңVJƍEOԖG0y]ZJqK؜F:{JO ^TgU_ ?ۣߪ׉[jG)1]HcXԹTU,UAbA9pA𬝓vwWvvGmm~v9)H*sp&r΢W5e{?ۣߪ׌n?1n?1=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GU[E?l 9C}bZS=?¿ /_F|{>oqg=t4. MI# UQm`V3]6l-kݱn7;>W ޽>?x?z.?_/v:>7YN[OZӭm<'GG~о3Zoq>/|G_-m~" 6 hZFVu[y쮴O=gCG⍩ʬf4NwIF51'dݑ'MT-iŽ/ug$-62*PPo^ ? aho^ ? akWH~>*IK-cῌy?ŏ5Pg^;o}+F(l1gαx԰Z}]/?դQex?iH=\eqj^>xVW'+[/>)hw:EέWulKoj^`8bL1ԧ.|VѦ,Lb(1aj*N8x|Lh톡nWU)a[Cu\>~5'UӤ0Zw%o^ ? aho^ ? ak?hy9koZhO_/~ߴO~.GѴ߅4 [y㆗x-[EVSn]*c<9(jGw*x[%wiHkvKQվ(Nmh k~tOG~ xC^!< W8 R.eV8׈PV 0ϲ8{8V faS7b0uJ*qӣ)%c)eUR )SʼOF\&1o^ ? aho^ ? ak V^|7u۷e<+߄_> |[Wz&/=K?|-? oa}B -KB׾,]+oVZx;?f گj??ߍZ%<@<Zj:D­M'N2q~롖e9&oZtKt8*)ÚeZtO *qq*e(T>"*uʭ Ig7VTUZJGN?ӷ#ziW\ G#ziW\ _h~_M6^C>zJi_y^ L7e=Ou/P? %n]_~Gno6>hm7OC2ʳ Z+JԨC5S•/+7R %8쥋`qTʎ[NaU«OSCo^ ? aho^ ? ako?h|=?@~>־|׼ΟeƱO7s{[xhu F%?k??nϋ|c_>|bU?_# faox E񿃴?žվ$x{[yCs~ӯRgQaU4̰1xfЯ˕SQXz#SoJudU .))qToSդRt&Ε*޽>?޽>??Mc/ig K| HooAK?k&4< axG\޲Ed5%~ |GU}o?_?^jo |%ygσ]y_Y|Wti-F^ơi~/u>!ƕ¬E9Ӌ'ӝ1IJNrUiԩ*iԍ< N*5yjM88)3}lM{,M.<58ZqujB:]o{|4+{|4+[⿆> ?/s/7k}??gmr -4J46(׵]vݩj}7O#~+~ :'ǘ</MgAu]=~Sҿ4-xIqzn[ʧNSbr1xQνzkRJ9Jx|FJ.[W1! UciJS5NR>u,9d*xSu{|4+{|4+Mk I{(N?*s /Ok4w S>4z|@?éAJ_Լ5[!O#u_l>%??޽>??3E`xQ»?5E@߆~0x\y} ;-tKo Υ~)j> >;[(~-BM]k1-+KU0x-/oh'4N(IAm;,4#]a:FWC8Zp:O Sngq,]KYA7R:*a*FIisN"ʩRE~XJQgJ&%ZQ;{|4+{|4+7N?i_|A7S:Zxu=n&}M'կ6?h_:o_~Kx[?|mX+z?#Ŷ.g-Noz߃j5bZMVau4c)U+(5p uYuef_GLn3ƝXZ9G\k*4sͥS9F1/iwcrq/<> mfFSs_֣Ὲ'F|KO3GjR[|0]_ϻ:.C'&L|A ,žj5_ׄmx:[?hO "goi|ya__>~~,E+?)Ψf-vO|#e]x~'Usiot048N' 2ڧ'CtqO[J\ :sNvmF >.*bVk)J%ӟ#ziW\ G#ziW\ _/m|`4I|WO࿁^!|OmC5 麎X'_=nAu|"sx{eC[Qi^ |cUzXh*[fKmmGJ5 # x3@;FLEHҡVS<%9ENWdyM R'TWJh>ֲ:cJ\\pM8Q WNQcK%q"$Sԧ8ԅl$3#ziW\ G#ziW\ _ ~׾8h?ٺZMr^1 ewox#]sIxx?TxӴxK6_'VϋW4 m7 [j'Cl~xP:Ziz܍Z+i]\4iaPBi5:*dwtTP&KW 1UcOԥ(8֧tݜV*:r r:,A{|4+{|4+ǽS yi0ko;yWAyMxÞ1C/KK?x'ϏKY5:SJI xP1%Ԧn/?I㦧|Y~~7/ƳuĞ3ABg }o7;#_׵Zfk¾>t-sWPͧ7ZTӖ"QQjQT,MʶoZkO UӧK dJr)Ӆ x^ыeؼZG VJ*rTo^ ? aho^ ? ak PgygM7h~v+[<]{E~Ǟ(~*|,<[^ ދ ½5h)0xmZú:X5_ OҼ\妧(JsN$IԌjRUqSJrK]QѯZ#ziW\ G#ziW\ _?/D~ʟ|+J&OKOYFmx~+E'vlm!޽z>!)`guMVKz M?j kAß֩Q.%>#:׌#U~(x>-kw>6Ek)[땳ԼtZ刜aO/^xJUWէ)ti\KaUJe(\TRRaR}O_.sz|vQ2:|4SJj׿OºZ?׿OºZ[5;/Ii/?cYXoG>_S|}7w~*Ga{?{<_G>|g^~8"jzK| xhn}rQ  _z:xIz#Ҟ-.H.qe5eYSk'hG$Q jJ3ìN0%:*0~*1S2a*S ק*"o^ ? aho^ ? akƯׁc:KXմe~'/V|3BKhv'Mn>,־X{K^fGu{;M&?g?('φ^mwMg>)ѿK*.>3|o |3kG_E|Wuyg/_?$U#Yb)ӄp*5H|b+naC09FEJyՍq V"<,+y#,<- du% B$7φu07φu08B~>g?Ÿ |$A_oψP|;I'gsoex+4vMh@GiV7¿ۣ⏍^SGD>.ƿi@חo Nk,^ǾҴVo|=J;gOO8pbuN ;0`e%㏆gM/?7mg|<:ok>->şɼ+>7?Mן|- ^|i'4O|KX/GC{k$gBҮ(eψm~ Mti/x^|Qi4|?i2iQk6/hmuH)|} *AJ18p|>aGB9rZ8PNZg({6)/YWx({0OU+Yv-Bt:~ΜgRTj1T?o?8u_Ϗ%xL= [O>{<+xHBBҵkZ\[?diG}ƒ,ngQߏ7R_;7WƵMKfÖOKi:74~>%]z_+A֚.5MwR78q_QEJ9 U5Up˅ZrR ũF4ux0C7|s3R?f]TRtҜէ+ƥ9JN2i`7Rt_;y#ޅxkψm=CW~1FҬm[CJú$=4"o=?KOQ|7 ZҴ? x6 _7=S:'FzljW\мmNu<;o } _:&p/~UgNJz4*ӣN )S4!N)B4qF*F_:_3u*7:6'Z8ՖH1XTf%WZc 'cW|;/+?u N'nÚgm/Ʒ'>k~{-cOQ qgǾ"-Լ;+oE}J,"VԚ/g7G3~?frre9JW*՝J4u zH%$RJ\J38xl:Е7<:xyFp!L"0xCi?$kO?\u^+_<] ׺m禦OR|[]+i)k &qc%ŮwCurGe? Gu_O<{oxv?ּ]#($!%ַ^#|]q[[%~i[{3~?frĿt?M39Rc^?y M7K RpMӯ]Upp =ۖ59P9J΅L,eaAŧFx|;t(JET`Og GF&%Ӽ_~=O[cj/ҵJ]wH>7I4mcMԼ?]ic8x fo*?+$q_6v 5:ĭG?,,𭶅6EPU㻭6bM^Ė_tG?>?ho[Vn|SDx7O}:|7x]y&úd1siZUe8x fo*?29bBjԡ˳Ec8x fo*?4~ >z/7A.-n4wM 94rX <Rٕ~ſ3tacO~RF=*|H~|G>]xsGϊdXmCG|Svm,Z}!׵o 4{ȶ/wǃMcOÚ}%K/}O__xº֩o~}_A|5{M/|I&$kOmowe/m/5:;x./ :kէ:RjU8ӝU1+Ө]76u#%)eq59Fa:F 8TXRR 559&VSJuc |~:}x~2>khO^}Kz;xSK6> Mi'w?ǚNfK?$eE}jp2m?x/R/5|:O _ǦC`:.-~;F7m_3Mh:/H g7 bƖ5=*]85٭tZ/0F}[ ;Վmy{nT FS%MSC'_*rQeP8;ХCpIU:FICN:ԜR̩aV-X ѓo)b/m'QJᗊ~Iž4~"xS~&|Z>%j8"x# Y-?Wu;:oχ&iTm퇆uo i /|?ac?h 5O |OMx=7Ǿ t8i~&2\[iRur%=O@??&&~seAU,2{<̶TK/| CِJc kicc"Ql*#ZI'V8JW_' 𧊴OW::?o5wS&wkjZ^~Lߵ>%;xH(|OP7|6oc::#֧"1ɦ\'χM^MWU)u9u c99xFjnKSs*|N'UN"9 ʄUja S(WbJQ4'rr<-F?0x3QF6.?Z>&i<_?7&Ɛ|E@Fl4o~ ^xz{xkK4+ ?]OOgH~1k46_|MxBEK:,_ٚ寇|[ZQ}3~Y :|#{CA<+cƚ5_9cMWVy OjGYj\ׯh񶵥}R<#MSN5ݤMIJ\ETK vKe>Na,:qVYV+6ӧ:،&G#N*(PV2<(UJ*n_Rpt%GL uqXӼoijXh$l&I议|-`j57<Ꮘj$eiO𽅳h׺Ŝzkyٯ[FTum_IԬm{^?h'S_? G4rʌ)cW0xRRf 0xN%3,&-$αX5% ƭJ߼R9&EGmB{-`d· Ay"ό.> n>/&\E7h Xx>.?^?xSL_Gm8z n1hOu' D*kϋO}*Ѽ7Rҿҗ>]C>}Roy-wymoowc--wG UpL"xN ?:8<]Xex,DT_%R*P2!9Nغ#4ܭcҍ۶alUeS^~ڏ<u7)o;[i>09m&x9~ [_%ko5EfoM;?ٓu~:x+o7~\x-KmqT]fWNuK.#i '{v?T;yNOV૿^'>ozg#ZTnu/}-oxr/]]hﱂ;K絺_jTx\l,K#?`ٕ|Zo<;7ךxlfeS/e97qRO8PԨf7JYu<%:K (:rxhBܒ˲RI0ʟs2bPu-3ଖxsgï L&QW[xs7Ӵ)&i OM:zӴۿxN?w /,o|@^/KZ3`w"9~=ksb|?Lki[߇ iNQx3\M{Ş+𶉠[h]QZ`L:5'Otou~1Jࡇkxb,|0eУn?1O62 =y~aFcO+V6Γ[\9~6xJ찘֬N'UY$'zV9heP[|@d+/ئGҵ+ǀ=>űOn[5ckgi7_>(|l_u#_[x??)?Zn}xo\}}mo {¾_|3Go_}$|QSxoĎd8;=>=򼖾iVyeG+,Y +zظbb*S>59p97&#C3ʡ18kW/N:$[phN,= 2,>'|KA~)sP՛ _x?]|mƞtu? x᷈#{j7^7lt۩u(\^1c42D4:צhzߌu O;NMo^5]i5dSQy?`>+xOx _>!ɦyQ\S}ZN_zݝRN?&&]FQPT,DzUjʴmj%k`*:Rx,E\,:rVRXo+*)tXjia%RkjorNj׎5/5{7\o%G񇄾}|0/>/AWY񍦝k|kl=~$V"d_N~$|ߴƖnRAH̞rXu2kxƳb跞(?|j>g~$x@y7LwihZGӾXvח"z$Y7^*SviRNzb9C.Jxj\7*O[j.tcRY}ZM.OԞNTį%O_|uSwó^BO/i WďOzhax/]Ei}kv ati Cec=]ʰho*Uχ'ץЯnK$t]MxKK??&& j _x~GZ]u?O5??8}B/O,+L,bBtT5#f75/F1[MC T%UZ8Nn88*ɵR*yĦZcRWG ^S /;O'oiZxOTOx፮c_|@2xrvM6Va׵uῆ/?ocg5{4'χM^M9Q͹ܜWs`}5԰WɊIFI(Ss %RT"K6s"%x֨9_x k\𧌼4|y}ޙ-ׅ>+[G_]q'Ŷ[5 +kh`Oe rB߉<exoį񅽭ᇌ<"k>xkQ9'a6Se/ׅ|#_4|)ih_ںZ}PԬ8+/jlې|oҖ?/BP||,9>nu:w4^Ѽkuya5{4R%*gKUiGJI:(WTsyYFY}o R#χ~ﳣC Ry^UW R:ѧc&~J-- Em2|[<-=7еo|`|Y?+F񖓮jMxSGOiP^Žǂ>&81g?|}/ŏ%:inoIWH;O7^*&y%LO@??&&':J19ScBP0؊4"QЊҖ"JjNRz{Zu*:y=1r=a2#B~ҕ9Gq8|dv߈|g _&<1&^m ߅1>{/ |GxB_ix^֥5Hd|IG_A, t=C~6þhO"z${5Q.LEiTW-lB¼TvJ^XYJ\XZ΃~ʣ~z tN*8aOOgL1e"U9~_'7b|= _B9/|? ď|6Qmie^ڏ|gaek?w1MtAH_U>kNW3:~*`ƿ 5Ox> Ҵ]J=kGnp\]7VvsC>5{4'χM^Mi*%*ӕIxJ"rӝW^p&ViFnQV4C\!I:pt m.HJ<-NbQ`Si' xL-88zJ:W%h^QGR>xz[c ۛ \:&׍&'Q)oׇ"[+&[+{kx|;EWϟW/ xOƚn~~>&:ύ.O4]F5cg?&&DɫIZF,10TIJ3r˥ I5WQX :8JB8i*\m] ry6#us f:q؉R-e[&QY5Ѿ j#U!}7^%ٷR iF;QC |?yZF = iRﴯ_~=?~2x_h1_i w<k4{^]4݆y~ߵOŏx3o/BNyK}lj|Dڞ㯅=յ c]Yy },?V~"߳Cutzu#[J~\4ԫTq0Bw֞gF~0U7Xe؈Jk`hUN)U҆iф hֻw,׭c5|c5HX}?|)<}<;/V6^&<]A o/LN4)-xKOό? j:<-/^)ݪj7~O/.ndgNO]^|S#o<\\ }J߲?=,-բAqz[u.vi?W_HomgW+MQxN 1 MS\0ْ`խ a⽆,=5 TKi8:sIJX!I9Iԩ"yW*WZVrɽ|mְC?ω{_B? _`T>O\4;<qEY\&MN Wɽ|mְ^|3 񦁣>+Zx{iZ_,uMXPӵ 9浼X. Xt]Oq5*֡N7U+툣 Z VKߌO_CQ=Zc/iJ糩Y\ygZ6|iwh?_?e}WZߎ>.cǾ 𮭬t[s5KtWD<5ɡNok 05oG(>/ŭWڷ$~/<];x"ӵnD7;mo\ӷI˨2a+_ xιwľ*>7[?|G{/<{mK߈~m|B}gNᄻ_|>BL4k[zߏ`#⟊<]k;/A55o6z>#|$%5 ^?{ *-mntOXKmGkgK/M(PBY2L4kQ)rLx_Oidګgğ&x[׆[?fn//tr+}z [N~]hf¾7 [K'q7* O mCy|<?kûi4/Xߡz߀.5+Z~|>|eOxWG%?~1vݿtOKF>>O x6NmNo xkStImo) ??dOZ9s'w=o?=wo't|_W%.;7%д;Hz~EmkUuqOui]^Qe8ܺb*at(NZIJTrK0SGVXx W(\*Uw _X,g3xCrj_iZ72!i~9OZ_ƟY|Uо.2~^<)tCv摤u&Q?'dwÿ|[y2g;+A>9!V|o{:߈,4j~!k>@ԭ߱b}i|gO+oh6-z |Yƛ?|t| []ψ  >+ҍZźs)g]AS,e"#R^:"7Ն"5aJJYol=<]n x*W9>uV6rW5PS Q@[D&hV6?%]Y|%e"?ù~!MOagd""Ӧ#|KLxf,?<[P:֛m|R'/&~Z381)-oMsc |?>_Ś^+^MItթ߲$ړ"Hl_ağLb0ZC[oZXEA'-uX~Y>'_~RxGwK| ^0 %ևu?xcK8C*.x\IsX *VSM?a+`M)TZpU8|&gfe sCK+Be\%6g1V;,TbO ,U<M~?oxZ?uq%Gӧ.$2Ԯ>|-:|Gx.;?OмCWܚ?N5O%+x>ogVҼ1iuV[{O |gҾ7Ū|WI׼#?D_}NԵjA罵̲f>=q97ie2@< ࿅-xH|/n-l)7%|P>\|Nh6g49qx8< iڏo~ ]:ƿ 'n>+|ho1'e׿.>ouuij3R+ IR< .WQ'Vrub،V]8A§S̳ѭ<0e#CեGN*yWJ FRas</:tWiVqx昬\*q1߄u◂gؓ h*>x^W|mo5cƗ|j-Cį)mkO>VS e~Zۭ>bSßwW\񶝬Xx ow+k=kCӯO֗i?f]HbT9஛iAٳW? } xgZ5AG#4- N_|MU9?cDkF/ t)~%6H]O~*6 ТF<]Msz~aEWZk*[5&|MJ^"bNisɩf2Xq8uG!8+(,kbcVU**a1؈J41T3Fl3jqC~ ,g/ |W~߲oڍsχ>aEf_|f_"Zm -#z5?~Fp7[q'8_)[ ?_uᧁ<O>!uaMIg|J5S⇍t xVh? <9\\k2=SG]vۤ ԭS!J< JJ2[S-|^n= ?Þ(o ~:Σ/Ju?^||(,-u8; Ij}항u&ƥs\z}-wyu&VQU 9-j51LkO>ʝj5jEb1Z<]L^&:՟< 4 f"e&*08G,pЫF_/ ;+|N ~֚g'/SxEg5k|_՗Fw_^{)?eowXԼucO(~ ^4} 78독 Q~(xKi.7㵏UÉ|= /6ZnX~QQJH`id5NVO2Ftb(`SShķRUaRVj+i)O<ӫoiym&%F;*GO\g.rz;d'=f9>>Ӽ; }⛭wqL`}ĹKO k#[qAx35_F6?k+ __h>"Sqᯄ^O/G:dtZ+J] xZi&jҌ޳nGdgisSN2*U ӔgMQ^PAҧVBUoRN_iL:s dfN:cQ^:-Bmw/?~"xO෈uC'߇k ~|[=[s|#Wޝ}¾Dv?f/ a7|c8G'Í+}-o |/=4?zރ{h[uꡪv:ޗhju{ /Qf7Z][^mG,SG|R#aq_W4n&k\1al> ٧Jzjut0gCNê C Sat1K3ʱaƤ2ܷ-ʹpV ZjTsB5hЅU*?]ğEмc}#fmi,6qNӴ O;j_xᎯO^"|▟o'ozE',IW?!geO> Iisv\XOhW8!|x֭⏃V,߇<[jwĝ;RxM9,&k1Z[MA4sQ4 WMnW75U,Op@ ;ß_ 4o>"įz_]|!i=:F5\xTu&X/cU}w,Z].,vLb>K:<U{y|>adyֱLm gʖ]`Tvx(RO%\] R ЩdVΪrMx[1pj'% u"|&5%xt3FaJ[_ xk_(MOz߇u^G|-υڼ#CG;|O<> |ym.O 5M \ ҵkTWCԓz ;XޟkW?~3|{ u cᏉx?xUW"Xi.4υvҥgNUll?f?$_7Wc>_q'*2\ Oh Uce*Y18άHLoƝcZZ|M3Ũ;A/.!A<1>񶀿 tk_FtF'>(Y~ G}c | :T%>$xo4rv[pUe/2_ɸc!l|WdT Xahr/xC^7n.k_l} E i8rD(^4ӡ9SU炢^\#T jmY2t b%N4OO2խO4\kգP?>(=c? ~Xso?<5~O_=iO؃u|QmhO1Y|l 54BZo%_hS?ګ_+ ߎ~+zW|?|RWSAҼnL2:ukkMԚq՜wQʖGCVC\jsZա "  a|QZ`YUK18 '$\G|&+YƮ]dʭ^}zY^1яLhF<&JjVJY+EEgS;ԯRe΢kJRtUμjJc j_>1~7C~U&h|i7;x঳=+U}3K&ᨯs-dKvG>/}zi?KiKB17I?dߵfkCc>'xwĚOů_[>"SwO⟁</z|^־éi&m躗ngjm>ǩY_UݬĽ}i5,,j7˧J:u*EU38=*AC1T02U2Tp Q<]OmS:tgsO8zJ<ju,)V%ZjS~<\' G.xoKҼ]_)y9ixAۥKKaF}|Y5,w짤|\@~㯆vWOu?}Ŀ 3]ӛגxq4g&Ug5ڊ)bT,&;c<~ZJJI4a*%VXQ*iʥ3,Ū뷕~O">>X|=uw'Gh恦|4 x{k?`d/xc¯&x~+Y׼?g>knaO< |Oo2k\w>.=8/of Ѿ>ۺä/o կ[O^eOZm7? J)ľ,{o4I񶛣H?o+}¾`h>MWVy OjGYj\׽ II$9$rI^n*+`Tp˕(B!J"PRúu*PrR ҔqYb0kbd 8%jrVx7`'ӫyLՂ ψO!g?CwxWd_&iR}nSφiOuz_j+ív?~_)E?zd?h_/ïhMOZw~+i"xnѾ[^&<x.PywQ ԟ[Jᖡ O]x1ׇJͫV^ ?Si~X5ŽZ4+N< |H5 wzΕx>y*k-st#UִC n/7eͥ1Υ%N8OUJPiaPʪ xjy}Z$m,s5J3J1 t#+nj#)%Ss8Dp3?i}n? kE?t6OxÑ\RӼIu PxNtGNXK8{u1|?63gJ4'FbtتITRUJҌM/~NR*TҤ6ڧNR( g'G]uw 8 ?FoT©C 7$ZcjI '\Jo%:Zvz|]FKOo{|bS ) ?Wí>!蚏[{;Xm:ϯ~W0=XYnMkij ,]!\^4o&y~wu)֕is:hBpUaNR8FI5xF&0#[P/4oW\wWM??7g'Xx))$QN_ {e' _e/$[j?iߋ_/Ͼ/cMQcN/ˈ?_߄|g?<-4Ox=/\?m.? _pvޠ?QkΖC$VOo/:/{B͝&v_?^}/|O)l5MVx/5][GMPc+?oci_X/KˇbYI⣉N&J+WR𔦳JVSS(`q+0Q*텄i:o)5SF1"ubj(z~ZWߊۮH|Tw Zrxv .(躝Zx{Y'|A FړܯK>ZS^Zq<3p*?dE=_᧎h><1MoX'osƞ ?_KG<[|FO!`DWSKCUfcsjY:YN!agW, ZಊY>eP3XT1X,Fx0c_E`ar0to׫_*f,34ϝ>4[wkCUcc;߄^G>:x~ ¯ |\Ҽ'8|6p~?fIzo#w^"l|IuZ^mwXW>3]<%8D5 Ns/y 'PewĚfofx|Rtڷ<%|?񅯍O~|m?Ot{_ ߯uVЧմZ m{\Q<Ҽ,<aƐxko m<:Kߏ퟉~.ϨO]N{k֭5ƙpaqܤR~1FjPSc1M<ԥSVX^^?'WR"5?4)ףPG9u񙚯)RqUS  Al4)< RYF.?h/'|W`=Xku=kχ7]?IN|{k>;F?ᮻC-[Z< /tnlo!K?hS㖙Z>"o>S~Ag7g/?Rx߳k_E_|9𯎯Sƚc귞߯GQ?/n=ߌ|[g_J4-~ψ[xúOt_:>vx~ EJ炭oW?XլEq._x]ݭA:TO hǂ>.~ڗ%/%GŽYG/ǚ7Ŀ*hz|U[G/<Ь[~}QmsL-,z㶹O|[Ŀ>"|Kcw@oC掽,Ӽq7L7~ϳèW+:_:;kt4{.$L/6',Ʈ+ V9MSNn2?ta .nN`j .Nh_EvQ@7տI,?~˟ӿ+ʿg%,BCnUXn?~W~?K|Yeև@|;¯%?Hi׬D$kt7w¿c]|5nao>OiͫjXjiUd ;cg_d ׈ AOkz[c[[P& To:iXjҫ:8X/OֆgژxԌSG[FTBUGNOVh֥ _X5e(ѩ<,aZpKQƞ՜~%xCw~͟|sx5~ ~.twi?~Ɵ_?uٛ=ߌjo?$> 8睡h7S|ς>$w[xKOI/X x^*KsÚ u+iEwNqӫ*1F. Дi:js*tUKZuaVVv`i҃Z0ZPR$*qONXHTЩB\\??gc o|w _|H2~?M?mK zx_:3V>(vq  };@l26' i~ep_M<1|U׵7*Oym'x3\/x < />9?¾ 񯋵j:G|-]zjtiו\\2r} Bj5YAe,ScԂjˈ+If 2OR%<u bqxb+xeS,J aچ%2:2Тefi/4ۢZ]%eg⾏~_O/|Jxցk_m_ .<5x)=xgL4Γ~O™to{ÿe}(^0^a?^_ᮙD[jz-uR=Ɨ]xNѮ|e.Hp$zy⟎-3ľ*uOH5߄<@ uZ񯀼=$vv\^0vw(öWz< QX(lQ\eEVm*KUԩUGUԌdOYb%d1b*}UJQ妧 ҕ,׷ ZxeZ~:QE? e '_ྯ|go{WO:Ծ4>Zh_>/ uh&{^}Kh~%<{sMG; ~/ִ SZ_xXIм?XϩƩ{;$6~^^\#Myo h-\׾"ֱh> gψ 5#U<v?jK:űfg/F8VF*WHayVsdR'&\Τi(ԩJ8T5S9{G/aJ V_,)Ɩ.`u1W NrBqq9ƞaN??x/R~ .sKԾf4ɼMc߈-,<+i6c?>-a^xßh3J?o_ t? ~,j߰V| ;ᇅ)I~ |}oㄹS!0|3'moŮ4:t>*x'Ꮘtf v/>\|O-z'G{5-kV.gkOi]|!N#eß~6_GڏFWƞ:ҿg[o i>/<ď '𯊖^b|iҮ4[?躾jZ|I_h~2k:z/t?/-#'"h]kVo-4MsP/խYʍjr_է,^k5vUbgձU* 5Lmf刨у ZաbJP,9V\<\0I(N#ROCWiGo ?Cg}g;~hmzn %uچڶZ/ jz^j|C__KNBOߏ43]7ᗂf_/~*/5?X?_3?[DO/|@VkӼ3$Du \G`FUYCƣH%EI.Tԡetj)F5N,zXPR%OϋN7}W-W*)b1,޽SޱMšijtzPn*~ |5/4x~ŭ>KFҵM2F~~,5MdXZj~7ɯK xKWn48Tt(4OhxW<3}7OԼ=j:fsDΝIFZ^Κ?sMR/,U*pQ^<,5 L *0QsXVYӫC1t23 rY6cJJ2GJnR u/)_~Ý_B1Y>_| K??n{_"{ˏ ϞϏ4?/kEYƻ4{??TSfQFX`G/j'}\O Ӵۈ/|BqxU{ xH4M3W_ZKt SԧK='J|Gj_dW'x%|3%N9=N5Δ#uOfC5;moÚLJmĞ'<1/o|a\||GAּ Se|IKcƑKkOEt[k[aƥ/dΛQx *kNH0Xo,cZ5aN:躸8-b*CCեV[ qڞk}8r(hso Jj.9%qXŻ?zY&xGKǎχ¿|'iGӮ ß:ާW㵣i ˟<-^+_C/̿+%Y?eO(7?>&>oF,/l|OP7fK~Hf kmU|-_|]WƏi>վ.Ŀ4jxL\֭!ZRi$'B\񟄴k',5<=HKRbGj#&2 8B˰x<]| XWj\S ӟ. aiRk6Z4,ve$楈IҞiT*ٌq߃/!k~?է+_e1|Mo WoU? mtٳ c'C>j.FQg~hoĞ{?xO |@;.u߲i[P<;Y_ V<% Z,mhb:LMV,KٯgNͳ,cJi<,VR9NիUTƬhӄ#jSS k/ ʖgq=0| O㽧>|/ޏA?oO_Ƌ%g[߉ߵ'z_B|#xM2|5׭h&O[wJ[׀~͟^j/~ oxW3žşx=kr]_ ew5h]zegsxYk-WuMO]u)5}gQ5 /'b% 39NT\>1r{zЎaW Vx|ieХQ~ ~/5/ho??_ZѵwCjxVg#_wg|KrPφvKc|t1~½{ŷ|A`?<'&Z-xƉZ~kxcח(?-~[_mW/| x/T;xRt/_ŷqG׊|_yYxw0E7޳%4QLv&'KVStc^:yҎ#?=ՠS~B_}8B0S% )\/xՠ0],,38F,&!PB2lOOoZ7/:f]#~7O]OSMx3< Co Ϟ.uoi>&nJxO1iƺχu烮4_x[>'/6^*TvT7IԜ qs)ӂEVb?&Il~_JG=|ROg3zUW?' WKbLQw?i[g?~?b9+7qqx+4/&g/9~5rWOHwogWkm%?MpG?6opE?O7g'XxW))$QN_ ze+ a?e/$[j?iߋwӃR ad_?4l A|]O'z?|s oOD'S|RSޕ owkO s ؿd2EdRPQӭ>2ȷ 4+ ge~(߀|7TgUմn, 6?j_W'er׊ҭJYJnOiV ʥܜUO )< v#TXHBAA£G$URU^J3_Ο_ڂ@_ ?M|M?Q|Nִ[x AASxCPxdM_$~Z%Eހ|)j4x꺖't/—6zv2C $Vnk`xnC$km]Wط{rN^WVSު־ )l4т񮯍Y=<^Fu S5S8t3E,U(x\+x|<08)Obq86qœQsf̫8QuG GK)gS*BsiNs +3_vĿ%ϟ.|54/x\{ao>j vO/K@Ú?uY# k_c}<E''|U -K5 ;Ll6llŰmkjuOO֬<5 }kڌ)n?*Iپ%Ҵ׵UZ5\1VS7T3,3PiFn6jUp%N?jj,W=LjTU*4h8ӗ5%`g(UBv)qx'$|L|%𧋴?wSm[: Ě>LW~n|I+mYWL[cclF\^16? $6Zv@qn^mB"On407^"2a_g\N/-|iouKMo'eciPO|Yygj݌Ko]MTԵ8|%-ޭ/弋SoL"IIzeRPsLDpts8*c#ըMaj*8](ax;OI:j;F8<$1*UUbj׃RKQƶ#߭|a-?:>;i<9/쏌f$6\̺}u-H5Z_go--_@\w[W<#h7߈ Qo-ޭc֙s\j% v߃Cү{V-g:>#|U~=kmsVokkxsU[Q=#ңTԢ$ofR'y G~Kf> q͡μjGpBYa|,ѦW:^i\\,f.0|Y*T'{HFp#VVgrAVent!< a*0<?h:/:sE:6m_"—s~VKkO[<7&֯E}ů uڿ[WZoÏ| \xn-O/?dq|0]oo-"{>TsAM> L?Sl־YxKڧ[nimn=WC4uk{?<ں_ݘZ5TփҰ'K] 'JKTk^g JÖ"ץԵZo O:mφC49m9q_88  C [fU$A UXHOV̲7)*YdcN*( g.0g8Uԫ^HӪZFtdT1ԩJ8ƔB1:.i/oV~3MF|6oڏ4M>*~10k{Fco}s↓MajE֎ݷƆ d=[&cuvx]oMbt}kx:oxgH'𖻫:VmamxbE?ܚWSMl౎Q]xyQ߉25mGź*xo]|G5OdžռGy:>dtk?L[W'y> x +C&hK| ")l1}Mx3ҵkֿ_D)ڦ:W?|P:^}|so >ws燵]]jC?k^=\~,|9=cU[@}[aFm6?P.>kg{ssvƭޟK`t?Ğ8h16n?SG~(Ծ(|LZÏ7u_5ģJm\x֙_Ú=] iVxOQ?/ Y\j_&Ӥ[7n1y2\ZN`do%WUށ]!pX ^F Tmʣ1RjB"NRue:uW[*)f,4PSӏ$i׫Y:6NRWQ,EjIz Q_}PQE[$w;y[//?_ڷI%sZwyW$ş_h_hWÿ*S֝ }?`|O|VW>oχ >"xƞ#G>xğ;⟁7<5iᏌ?>m|bSxN]GAEj0@ !|C_?>8|6> k6x_/ '?|u^Z~ o~0R 'LuFզҼ;>"D5+UJiƻnץ*>T*|U%NPk)WNH:8zuUlq[[ZܿZ7e+ *Y3G%F!JSVTFN8xc0\ƞr <]:KpYDiI5j4,<+Gq*-dZ$ O/L/ ugϊgٓ֋eM:NYuo xBeu_0m߁/m/\~>^؋Ş"xx qRj~%'o|V_4 xsX ƻ_߿E)R-Zѩ*TォR| )Sԓ$͝J:qg)P8wRg8MEQ )BN[J:1<3g-gcм}WZm-/NI? J x3I_%|H_~2X9Jg6J1`KXӌijש fxVN$ ᆯB^ԠN5剕J0J\83*5tx/7G~ې7>xF|[].Ə |^>,|;YxytMOi?^/|W$w>_7'ocK&t/xgYOz~+|I/Cݟ|mO7&ڮ QG<?UСΩ8,iQ%N'5R-KZiԅ|B$*J+C)THn9T+P,MgGp =ï?~xK:@E/`mu|XG_x#Du_3| vQRϗfCĉx Yx7E>'~_?U^8A?4ٳ/|y6a]C.^B'][Y|G'V5?<#Wz'Oo.| {_jw~)g i~vewo~/imNMO⟁</z|^־éi&m躗ngjm>ǩY_Uݬĺa֧R*WU qQo[6q#WSsRF!J71(aw3aFeKG3O|'Z: r5fļ}"XT~D|mwF|Wob,hx^~+h%ga>#^ŭįh~Oᯄ_~x> O/C:\t?|K|;/i?eu/_EO~' WHxzno/uXn//ioîOH5t#Hnf- lj?wd^xf/WE57M'nuBv}PA.iFss7|AoKgkV6P+"𶯫6|f^.im<;sgJN<8[AҤ*rRK,D'Yԩ'(ZNΜj S_ڹ~mISTcMJ*LDZ kU^~뚗G@4nA?7ٻe'?WkUh/D[xJ 4}<9I'>9G?iE<'ώv~ i~0WymMg_*6.?^ V x[|7KYxk_k=>rGXoa:x7ؚfhiu _Z~?4U K Ukʥ,E%C҅'S2ʲ\$RC?M8SJ1ڧ)&¯_ |Eg_%W|QS!~1k#Bs+i,<4?NO ;}uOo+O>o&/σ[?h5V^8=v~5^ ֯h+im7L> ֶ|OEtb+}aWW38yJUT=*RN|#[ʾ1.USTU*ÕTȐ֔7SId<.*uZq>~vZd_?"w^?~š^c㟇?~.|@VbR4=⟇?7?+Jeү]/_3㌿um[f~ڟ6~'A1Ze {%4xz◇-{_^IxK7i^~2g{߉!|5>.A/|q?>"xI։Yꚇ5__ ~>:5A>?xk^)GOYi΋M>],u{kS;X_mh͕jv^im}a<pE*I`h`j*]2biѫN)gAU)Be )T ҩRqSCsLE<4$1Ш4/iMWRM~1b~ '='>:Wrj_i>/_<1E }ti:-1 ⿏>\~К=Ox5_ړQ>Q{K/O?߳_mo?$t[kMYky_ _xGB#UQ|7x௉w0>/4;Suڤ+΍$^$4^ZWT}C^1K"ӫ9KZXzeVlMzXa#KKC >"[&eu)#҅(icr*`bS |5=[ğ>(i׌<y_&4-tO|-)ׇoUև>'▫cZh߃v P5z֟ v(u]e^<:(B(5JҷaK*6U'KԪVJ*0Q%R-:i,3*i^O*<$ԕ5aӦQYQ@R3Vv8URpNI8TQe90"9ͨ1nRJ1MI&۰$۲WoD>x ~| h~2KL߉4m_EԿu=;Vnwoq=N`%It:u!*u)PNqp'(N2JQdZM4IiVkFaETQEQE5ROg3zUW?' 埇;!;O_z_e>FicJߛ>/пU]?!ƿ_ѡ3g9!Cko8i_C_)gg?:?5pq3T~6IpW꿱?KI%ڏZwo)?NjW')$QN_>+__X~>7yG8[. >+HH((((((((((Iae\֝A^U<-gZuz[$w;y[//?)CN.5_?㟇Ə7Ҿ?|_;W 5/ |Kmm7>1t~W$?k"ªcpNI'ҫ/e^~ztj*JZ!Tr V=jT%()Jҩ *TSZSNtc(78IÚRe(}Zz.ڿROᶿ?%6>+7e}'zh;Ya='ƺl<s>񕶧 žִi _/㏉ma 7J-kHO?eW#7ns~rLh{)BXjTJUBJXЍ)E-S 3fXiBDŽggǚOxWR5Yx"h~~0> |M<3':< u(޵xW]i/|Vu7g3~,'P׼MZ?٢-|_;4=Cl?+u)м;7Zξ*7VfU/#o|᷈<'΍waEAV:.n! 7]߁N?ri/eO% [^ 3nSƥK횫C 8cNjKV5§Nu>;]b'jOARi2`|.qپ~6W|&>*kM+x4 ]`ȿu]ko ]{C|Mh4];F>?w/#I/?@};[|-_1Iu|Iѥ>$g7QxcB~ wJE޿O Xn(>)zF} 񧉴MP;[ԴSK:<84մ}gJkzZӛ˜>B/|5U'Ř|{O?7 ukcuS}k$΍+fçWj5ZiBtuq"Ptg8N6RO \Ԕ%UaUB4^.W -qx"X%)}s o0]YQOR^G^G㏊>מ|SexO)e_χ> uH,xϏMϊn|MKI'&P?aҼI:'gwï%Do'o' g=>W?75?SkxWWuY.k{Yj^|3vz>{¿/z +MAƻUu^K__[xetT?χQK>0  x`x_Ɩ>%<7kZخ'Ҽ#i6αiPjzccwxK]Bxhf8LL~&JI:'B8JYv*hj\g50 0[+%*4fGj|'ѡRs|eʭZxC\+O+S0x~xտc+t~~7W_UᯇN/Ï!OFv|׼]g?P6WRi~ ׈5/m ._ˣng .42E%}n5:~ xWtߊ 5 MCIt{_>KĚjMݮ3Zm嵕@7g߈~"|/ :AxJ84VZ~ iZXm!-\ W:<&a Z8l %F3hr!|V NgЧW4l=ZΚqLtpؼ6:.Ж^e?gګ ;|3[VGZߴ7oٻDS|&5$7G#]j|zc6? o>.qh<>_em;⿋?e|{7/|3^W|w3iJ| ex#d5h"?_ik{=IcпgUԢUJcRJ|sS|`AʇXrJ K4+πgxx_Z|R/~[x{FO;:v\qigj|=F<m<Č~ӫSgMW}ek?WUlc5QS9Ʀ6p.N86͡NaUQPM(U<Qו~GN<\9RqVizeFފ7ao·;^ۃ #x6k_4Vo_S^#ӼugY[? Nج|1!ďtƁ{W~+3Dl|kw ޭxڦ>^OO i:z|SZI/Yjzq? |1ռx2Ojrhkڗ6ri?[c-o`Ilez?'R>Q|\W>>ҵWS񶍯aA5j'T9gH~e1jH5 kV)?+}!??  >&}N5?!nmwdxЛ3XӬ5;) >xҶ'0Іl *Y^>'kҞN MbV:,JQaUP -ӫ8T><.ee_8:(_>-8AbӾx; w𧊿gC :Z<x~~[?'I9 |igCj?n|_~h'V%>;?yV>/> ѵ'vh+|1|@ /! xrS׾)~4ԓ޵h^:wx5MKoO}xCx23_G??gj/'%@Ek@5/Z6/E>aß|T? xZ:|8t:oň'촿x>xg[ujZ}z鏏ėO xp5wPAͺ |Gt+k,\9ln&9RQ!RVRiկW*QC2]x¾k_RCPK~&~I8/aXO5cVTR¤+N>NYPFrXu_Ji8TZgNUi9U) z/i׆u=&m<EstXA|M/<'Ym51KSg4?: f|<[\σvoÍE|'wٻK&WYß>W xD|k QnH9|?IO7ՋUqAI.jԆ")棌µ,E $&tq{F&'P)^QR:ʄj`)Ќ!NwĻ/x. A<?2|g<%Wm|`/OqThůmׇ\Gs /w\ N-hM+$??~|u7ïpmx&RYoů|Se5Εwo%<I;,߉w=xKBѼ-]Gφ|;X-Bдm2;=7HѴ6 m?L48a(්8PlWe\L'ʥӍ|=UNc'VqVMJ=yhХN,EwBrZHT`f*l.xF5biR˨B8RfeAa)a?>.~ݾoωf? D?d߉MmOZ_w|35/ٓ_%`[[Q𧋼3m4_ k~:-pQ?nᏌ:g~h?qD)߭\|0࿋oux<7|btmxX^kWx < />9?¾ 񯋵j:G|-]zjtiו\\I)Gib0wF4ҡ J]LUo˟|7?h+>i|o~e7ߋ60,vWRt_W:u^sźt/C7,^|[O#> |Y j~ |OW?^v>ug=^5 ~?uT_7ߋƣ~. ^u}Xϯzy1 ִ;Mw:}ַCy5_$x7_> S;UЬ?> OĘM6O h4O Jvmu8<@lG_w oK agw 8'Ojf9^c'Z=lxe,>61r>|Dzӿ#w|W+V~xŸ->$3_<{P~~ӧ|S/7JtsFk'ķ(stx.D m1x/ž'B_xO,uKCWr x^/<:Xx/v_`?K/tߴ_YZj~q}_<_ڟ]GYj6VSzv_R4lS2j%{jEJ1JURJERnuY_bД'Iq)SrN ѧJ\); kZxSx|O%헂_cKK_O%_mtV<>=h 5~~_k9E=OG̲xm{o|>Mֻu{ixŰ[x\eJ}] ż6ھH|AƼ}j[%4"NB4i,|GKWj}4q>KN1X|\e)u8[J <=:TkZiJL#eJ+B֜#8N8ЕI԰UF51pؚtRQF xGC_#x;O/ag; SҼGٟ_ //ï߷>+~'|?<)߅xsG|1Osƾ8|/A;Z>GV|#|wռ5}~#:7iO*_x?&Xi>T+?GtW>Vx9JL>rѫ -|NJ2˳+gxT*CG,x2ůt h_~u|Km_C>$?%e|5;÷_&*cc߉;cπfI< )|],kWǿ)Cյ}G C?\QGzÿ h:HEno x 㯊~8j?$P|=X<⟁?];ᶍ|1j'f>$υ7&NxF|M_׏%C'uo]]5=G/ďh<IOxB>- VK<;n@5 G) _je熵tm_Òzͣ{_״)5-9F}-6:vД?2u' 3QP^XKQ5~X!S _^#uL/q?3?/[|>'Mo^ g¾.mľ&Ѽ9c|,<{-/WRasfO|[߰w?ߌ,~x۳D/h>,˝{W!{?xz>k ^]?W~kg-&z7',״w:-t}3X,4v^t[5KEҬ^ x < />9?¾ 񯋵j:G|-]zjtiו\\Gx?CRg'|REuOjv?W |)jWĿ ._4+zfOM-|i{ Wh!x|SFDekeܬTtB1B&#ȒS8NV4N+ 1N8ꕤ%8:xHџTktn֫ v7F*74ԥUR|4yyR~^}?5/s? Eo |u߅|kߴ>ڇ{sGG muE%ߍ)x6?ׇWIUJV]>YX0AA<~?~%_>#|?N|m~*񿂦5S3xKzxr]/['YӤU'P1]:_4C]^i^.ρ/G\]+lnew'&Msi{?U\L1Nj<¤)chb'SR^^Xp҅ 6pt qJ^8JF>CRUTq mХEq_x~տu(_axS_!h4y ?溏Tl9RrrSNU4cRUZqJSvZ%fi6+hB +cx><7}SG_?h.ԿH~!:wvk{Keӳ*)OSRG m%NgfjҩNV%jM]]]ZtQHGO@o x|?{'~yv3NiZ-ܻgCtK}Uҵ .,|i!|ŷ7Œ-7`nv$w?gUZ%}MBwWОJf8.#*PɲՇ.iG _4)mZ2I\E S֔oRx\VvKVώ#+a<7_q-WȎmc$!cgX)X&,Qv?3 ) ?F$/؆_ ) ?j} R\M*Z%<X)n6#[o CT~6IpW꿱?KI%ڏZwo)?NjW')$QN_)|WOcMQcN/ˈ(Q?R ( ( ( ( ( ( ( ( ( (>oXn?~W~?K|Yeև^V$.N * >*w ?_JӾ!n? >_Y5;Da/~xşCڼ d8|!5g_5+ Zj:iÿ*S֝ ~Zg|1Vᯇj_PɤYdj?o;[;LO%֪o:xaOMRVPM{l65zxF`V,WrJѸڥMg*^J':^ýsQ ֵ߄)_/M l|t-Q~;#׿mxWuk!}86 5x<7_kZ Z6|g(ֿok G>;״?jq¾;e\jV?~ggmis^4RêT֭ߴҫe~ZԲXlU80QRGG<>"1Uc(N[dx:򬢹eC/ 'R+_ <%/ٯ=B Y4o  xx/ཱྀxZ>+{? j4 ,,<o F?<)>^^^3𞏫ZCWO妁߷wZ⫭ GF:I)#E΋{L$ /]ׇn>+MR@gytbgJ2R:v$x %M߳6wihZGӾXvח:e;5xm}wD5yfB&Ki7zEq> KihX:SL.R,!ѧ֔Tb8{|JBn麓Y%ZW>QL RTX X:#B!R6d%jitaM/M}xw^?ߴ.Foε~uGŋ GK]oSV>0LǤz[_fDN/ 'W=M/ߵ/ k=jd 5O^VRZ%q pf_Iqe\,iS4SPSW*xqXiJ᳊+%yթɨ-kr|Ӿ ZEBJOkj%|֗ię{/] ƞ| >_'q_: ~Z/?&vªq/2GAWxZ յK6` Y PI8'tJ~x ~| h~2KL߉4m_EԿu=;Vnwoq=N`% %J4V H+Tk#GҒV2(TKXW/iJgukNppJxJp֥ E*:PYu*zOprJY/?m_L+_1ko >aϊG% oO/ hOFOÞ6kK-Ff <\qkQ#+KR/e񿻨`V}j=MC8$|C?hڟ⦟O6 ߇mxOL~=x[}5Cxk__%Z|F?j|4{j(ie_.fKY|Sx7|F<_ Aʚ$V5|;y_ 7~_Nծ|/4OFĞ]_Hֵ*-cLk]F=7VRZE/MzUKJ5hX]Lʅڧ[YjkYR`'ԫFt},bT1󯋪ogV5_ Tk W8> qU#*r`#SRZ)UQ`)"~~ ?5Z)xB_mO_ cosUmu/ٻv-o^44f|x߲s]7kW}_S>&xQ +twNo^I Ǫ᜚VL_C͟C,j(jJu(%V{^UԳ̵妽<4 9o⟏|[c> kψ>5?oIGC=u ^#6׊"x~ּNëW\?߈^/şmxaWǟv wGOec-!UۭvNMJ/l_%37?t  *m#U:7W%u:MRu c+.nzBz338Ǜ s:ًIҔ>^&U)ƍG:؅SP(NӅ,?>cF(’O42쎴0B &-n*cq8DFeٳGow57w_V R]Mm3wv5)85<~1-}~x_O|τ?b ]oWk?M^m+?<#ƟOn[M?[  k׳뚟F?HTVtj<ңOs.(JiNF#jЩMC En!7V6: ޞu_Z01({JtR8ѥR)үOR| ^6ҵx?(o/|Fա!x? 5&=&=__)iை^=Ϗhux|y"vOR ?7x~? *g?_X_D_#GFTJWz2+s 0ZX)׭[0VjTa4#V5i>27i5>!߃>-~0~7=Ə'x zmc㧈 {*ƿ=m*4 ;7%_i%|M jO?kk]}'o ~~'i3q|8ZV~cė¾51i]QQ9:lNJ(b*Jt)ƌ)bq8?uC MJlK ZTn Ԫ&upuc{Y.z;,2ӻ93ViccF*j 7/šW47ZOԵWX?( /? G௉5SO2DYk'W?C_|.#X5|)B|Fo gcB'_|Fg;m?KWy|X!nOv|JмqxkYwB4:>EoR"uA9TbI{ ѭ5*jf0z t, ,5L6,M(b(8sR-5Ii(ҫ{,e9Fuqxlf>uJ߆l?ß|Z|]F)/e|i~C τ>|M7Aר'fiNÿZ5tN|3\ w}_Wco?>ϋfڛOGۼA⟉-Mx?Ǫ|k#D_kbxw^7V4UfMӊ8 WxtX\uE:TBoYF |+'KPi,Oߴ6 >ifi.M>:,%<cQ kKٷ:yfA*~aEJK6CiMQ G-*4MU*yդWK e=ZNr8u)ҝiU_e/|GGǏ|PQ_t;_/-k ZmwP'k~Ѻ.5π x>|KgiRG︿dqB~׺?~1/2QxCOcwY ơe!<7Ǘֿ>2j>&lGj3p*qUv'*3 XxRfOy%hR>&4·MO׉xffh+k/l|#aY#<4CZn͡!oe;43Z>>/s |KQ?uRo):WǑxgO!(AN|3{^SQ6ҽm$3>4߅ME+EUƍZ >J+msJy^IdTU`TaSNTT凝X'/c1ЂJ/^bE|w׿&Il~_JG=|ROg3zUW?' KbLQw?i[g?~?b9+7ƕ?~?b9+7ƕ6o&#ShS {e' _e/$[j?iߋv?o?8u_؟$wG;~p+})|V].GwӋ (OԂ((((((((((j$[ei߄_7WտI,?~˟ӿ+ʿg%,BCnW$?k?mNJ?hφ>|1K7 ;ֳ}^|-> .[M֪ K7Utӆ"ҭCӧ*[\T& #|#ɤ| t5_~ϰΗ??` i]#V_ڷ>6x<1[||;~&'J>"_?;3)O7Ku5珵߀>4<[|]OZo>1Ԗ׋UO|oC[SOU? Yk>'π~#^o᧋4cwQگķjG_JOYEeMZTؼ.#) jնo)*aTӫӪӟgPxg#͗<|`ux#@{>x:V^?:ƛ];+M'ҿuC|)־n(BO~_n>xC1?.ZEž35hE-QliK,P8Fee{(h(ic]瓖qWV)G  . rmJvS唡]ÖRSZNQSpV/AuO~>&> w7n5OxZ1x3L{>Z4>_^k~ӴK/%׋|+u-5 xKQ~*ߏڻl|?Պ!fxzπ{K_t:=w?4{K'?K)߄:/٫W|]Sƿد y%oM;L:<s l~:[VᶅgḾOe5 ikðAUQlmUFc**tBYY:nnoSFSʲg&8>yԣuj(҅E8eڛ΍ EF1#iQ~&G)M|)K?ihoCLm.o\GEG|)7^;#9^k<#|7[]Z`ZooxÚ%nwST=!:)lDeV|DyV,=< rO 'V6_NXRR "()N1I*g^ѤQEAEPEPEPEPEPEPEPEPEPEPEPÿI?`UV_S|h'~Il~_JG=}I6+~lBgWrӗC_/uqqxҿѣBgWrӗC_/uqqxҿSdmn6 ST~6IpW꿱?KI%ڏZwo)?NjW')$QN_þJ_|g d_?4lB( ((((((((((ڷI%sZwyW$ş_h_h꿵oK-߲ Io?п⯇Ud ;_Ud ;x*?⯉ ԭ4q$KOmowe/m/5:;x./ :kեJyUNTUN0|V"mɤC B&ViӜ8ZsF'7Ʌ'ψC B'WW+R*!z_m-x_M}KkǏacž cH/͉-͎u3Gq S4'.PX+.`p0"*RZu)ԥ9R 'N\*u#$ Pe %$$ӲHTF' u0!%*uN4e9њn5ap[iU4WKt/jٺ\xֿ`?Vbm?Mo쿰%jwu:ᤃX]GL4no@[֬lWqEm_WmZ9]C^txvT;^jI~4dz4i(6N7 ˙5z5+ NbiT§*F-Ԅ(fpp@ k/ >'*m~"DŽWї:o$ 3i6FW?mH9r9r9KcjNߵեV^9’$=T[MY7wkN +ڋ6OKڼWRnwLU?blD9yQ*7MGg$bk ? >(|a<8|<*U>x33Oi~R|[sAŨiQkqgCA,w7)tʭ][wA7hKR[†o%n@èV!}_dWkhej.Mn2?w *JWω~+xŸ 5~oJltVKkJ$?pi]vp2{ ɻ?iqҿ\SW josu~{ҿ\SW jostWJ:s"Mni__.|O^ +Ϗ79?~й?7@Ex4ï>?'uBDڛ{ҿ\SW jostWJ:s"Mni__.|O^ +Ϗ79?~й?7@Ex4ï>?'uBDڛ{ҿ\SW jostWJ:s"Mni__.|Ow[$w;y[//?ŭWoG_߳欫~ߴ/tm+¿>Z/0<;iGtMWUu[;hC)7y[//?)CN>?> ~>|rYơ>/_#_ !|8%ŏZyk~W$?k궩cDžNz)qąpU8CYa5^ jyГX^HS 7Fja1Q:e<>:jFT# I2hO>M~wGukO/;NşkxiV/=č~ ǮFZ}DŽ푛΋y65?!$&s?~!s㶏~-NW,/  υ`<#o9"g?|[φ?7Zx⟇?Y$xٰ|;Px#ƿ?>ymGYڋ~ ҭ| zUƍ'Ú~W?>kw~KhVEk^irPҾp8 j_Yo^ṥ8Bh:% ܼB0s`TtτY:u=歌TjƓ:\/'Fi_> C΅kw[x <#;ׄ<{7xtҦ-οC]æĞ~0ię$xU?gX⾕?dOx\5gH-mǫ[4è[Kź^Waj_]7_ᤥW%J:剫P8b] 'QêxSNiBUq8DC땫jg)Nu0ʲzbN51#/g>'WgU 㦁i~֮uxCÿiJ/t? "KhޫmoM%WnltiD?Kڋ=;o/7WWY*ʾ8:ͥh~=Q/Q\j6:o )$wʏV~ (T):<҅Jvnw>F}:،%TupFJuq3ӈxO٫ǝ3o`Ӿ|ZU.~:r;{7M2^^O# 2+Q~تX/جEJ4pz9_ZУ5RZa p9(6ݑx/I&9NY)JR' $WƲA^>+4M"^6v4&oǻoO7_I_s o>/i6>sz7V,<@/,sJ3n"8l5z*t7 [[/,iY~gqM5SO0_a*Cb01pT14uhrJ`=ԩiyjʳN9\/UaAG|}UK wUW~~ռxW?OxM;Ɠ<~'xro%oXMωt~Ao?Z>"x ەkO_|uxg/&gzO/Xi6G-kpm1O4 jĞsW}Hj\,D#|җ= 5HISsXM)`*2uQk^^a5K~^xJ'*ܕrbu3xhcp-3UG!R?U^(W xsxj}#r׾y_/z~º:yZ > ٷ6~< hZSifx^ï־Oo+д uG|}UK wUWg #?.gKQ͛/Vm|Z 3~ o4oi>(.Zt-:m~?l3Ɩ~5t][|~ 5k&oIl|+oHOixn,:VsxERK p*xn S(qy{Sr<ʌV:0eR2P*biaqkCKVNT(W?)oaʪg'!m k~y>"[궾>JM!O&x[I5AMH aF^\>' Hg'xCnOO( SP)BkQ¿-oڇÿ ~~oN^5_.JcǺމ۱z|M~L_$(pib*Ti R=i"ΰ<5JXGK3'`-zaW<lN/ NӧVV.QnvpRG+)J4G%JZΒ|_!R?T-3U^+\ѿfOn/c6vZW5_W^Mo[~4|#b='$~ڂ~l/_ qsncAN~ |M6go?J|?5Moz7N~cSՖ 8ޮ3W,ˉ.Wpkq55_ ^|D?tϋ >j~Ӿ!kÿ?xÏu/çBmZY4h{+hT6q&xM\6'.aU195G.G&S:(1x 5Jxz"k, (K)f1Iν*?QMkΞ!JoB?ॿ;*# [g>򪾚hh 7ॵ։/j/P*ojwg;Əڵ6I}?|s]?Pľ5"Gs? Cþ,+]Io{_|{.>x_Ug^3jgZյ;=CAqMLÊrarxɱysKEz+"8v'/1QW6|.*apṭO 9aul-OmZY<(*хL\Lغjt!):Mտ adOj8\4j-oxWWW:|-: .'\ItIN*/<+/B|K|J4m'ǿ-oAWō_t_ٗV+|M濠j ~-x N4Ociu.5j SQGw/ï>4nt[6\{x%_J熼}⋯h_%seGf.N_1x |jYUXB5e_/0X >?QRsZ.xjUM.jҧJ~N\ϒ)JH KVG~h>,/_|'xZXZU j[Iŏ\{_LЮ'5=2= Ohu%֙c?K|Yeև_)xM ]#xx{ڔ ]į ޯj^Imm:]YI=j0ZVNzqFҧZVxԧ8 IZi٦fAEq~?CV|u_Gz N?xWzǍ4 jr٦u|υx_|sa+|A_k_bu? [JO;G5kv7W_b,/u +ɳx~)mMMtr(tmr8`gEi77{&7gnvكN*IUTVUb7U?oGQE#0EgcU,($ :ODFSB.Sڌc)Imm &ݒz$oW5o{Kokaxƿxc +7oxvմi}VVw6H@I8I$zV!:^Tjz.ʽRZNdj4QV:pJSH6dM]hתz5Z+ew?|,/2]_TxS|FD߃[I__;o%[׈ukXe M8WM^$g FpQm4uy+ΜXΜN$N(N.3$h("ªcpNI'Ңr#)Q!)mF1SrQRmI6݁&ݒz$oW8oZ'M c\׋<ω񖇠k~:φnk:\jZs][K|/gwCѭEKzEk:s9S ө J8Nqe%(2N2IILm8IQVyzhNְd(G+4P~ yOаԵCx_ºM޹jcLѬ_Q6]бҴF,.ndg~ A|=RU;m+-KLNGuƵI1s{hm9Qs]5(sJ.kΒWiՎ*i87Tj8N1SqIZ.*ڊOG **b.jSo(B ( ( (:<{Ꮖ7ڷ_^4މ N_ |?R҆M"#Qlye~-IQS8k)*TWTRZJIZI7ewe{%}v4QE!>ao|IΩே|]}Q<3m*[u?Pկå]}L.&"ӵ۝n-a[@-4ٵ/xDCqwCcf[H:֑ӮjV^rSMՔb(ҍZ4]Fڦb(RskUF| $ړIsi6Es1c)JN1Ml(((Cm[:Z)?oUuL/ŋnߍ ϛ^TCko8i_W_c+?ி?/WWů&CV !#T~6IpW꿬O? [ &֟Aoz&u|8UO huτ ~x;Ǟ[ƱnG֧0 [^z|I%g a?L"?ۣ>nL?>6cwڛ~D|V|GJGź-oC/_ZkEZ7K2Ea poq_|fi^?|_t?{iVAk MCL>%;c};O l4,-1raR/ 'Bz NXj5eS ؜"*UӒxomlGahapYj}.\\<=(:XH8b׆*OQU~ /OǤ )cڵ|kU߆ ~&cH4MKO𵮅~`þ?- -W5^'>|Ch_t I~x+ck^Ӽ1g_O-%xB-Ϲ~Ϳ>#7~/_\3+]{?-F~~7j;s]OZv_." |cq .i([óK5?jړQ.D׾x?w)>$?\G>'']Nyg/_ß k'3VPw>)$5/.v>z$>[˄C ?b08l>q/,E&zΊW|B QPxpxU\m_N,>''p]co~ğ4DGmϯDگ$+pk"ҵS;_g!9]^/~!)ҵ;"-_DX|cj>2VF[]o&e(TThU *؇zQ^Sߴ0]?hkN,/^/2ƭ7TRYa67N?8)Ba”!/ؗ|#Ӿ~~/;گ8[}xcF%Y!Gm_Io?=&IԿ43Vk[~"o /Ŀe{?%u^s.aWMwewLiixY|-:~}Es,".xyO̩*b18Jwa֖)`*TS 'rȱGj3(R Fxx*L=9V4׶Qn_3|'oWnݩCOS_oh^ώ _ _ Ig9<{6M8\\9be^"Wp^7QCV1b׻//t^K,\ٯT%a9J3& 4#OOO"?oOwǿxk։s3㏅{^.?ſ4QxVO67|agoOGIaER0p(i*'R*8Jt(eUNlUOk*ZdVY'Vb㯈>9ĿdMxwڏ>ۃ[yxt߲ۘTg'c_ٿ7Wº͆e/F} ^joYSI- {o 58avۃGxY!5OW$ş_h_hSjXL5<-?':4b*Uaѩ(KZnYJIJZF7]lE|%Z_:4U*.)ƕ:PI n|;¯%?Hi?Ǐn>|xS8~=şwşK+  -߉4}oV𥏈Ud ; \SqZUqJ\҆&'\NU0E(Iq)A'F򸧬dtJN7Q$⏀g㯏<O%Uo?yzt_ <;?R:&xO@wdx?NΝ xS%Y>z9i- Iun3n_:վ1V~k]~A81xbx/ᯃlu AZ_>Կl5[~ϒQίxpV>n:ρ|I?L~M] Ɨ'x/k^.8i+ch3jxՃFp0:4a ؇O)`t1T,}YЖl,sSNy}Ԋ:teĕjѕE'VORmxj?<Ǎ~Oz|v ?b|cN#$u4#!թ:' ^i({UsS/vU#aU)YVUʴa^UN*Jk\Pj~FῈ ?^ W~25?>%/? _SW #ź͕8xei:ڷ|EKk(5'_~?:i:/? 嗅fm|4燼Au_hE?75|'xGG.Tpxiful Y`5L <ѭ 60J?u!R%NNj؉֭V8ػs:RΥ:ݹ*Y|gxѥ,5G tF>\Ҿ,2iҶeߵ2Q?jWc_ٿ_~xᏍ<_ xsHTX1x]_`|#h__/|H /XGįA5Wľ4|m8w࿃Ak ujuK?kZc_ ;B%Ԝa S<<l>cOT1V2W*׏P*l޲U湎cN59*ՃTp qxjgZ?>|@c~^8^_&?=I_ sn}FÞ$IJ]h^&O/oMO&{]~ e[ xMg_'MsVoYjmu eπ5pv"ªcpNI'Ҫ6+S1N/e sJJu_ZWj9UGW,D)œ <\)F0NxzxTR8K/J|(2'N>x;]?ww2O?zs|}xwO|7Zm?sꖞ +&/짤~ |yuS',wl6C/PӘAe41ot JpxN`EӮ[%Ȳ D8d.*Zu)bQ' AVphbfyZIT*g m^.zu<.7O~?w+*txG◃Wৎ}cO 32x7I+Auo;ouogI^{OTj1uSĿQ~ ~"_ ?3.e?>мOx<;q|AZ?%#H5:Vxᯌχ5ҼV__xoZ~ 2iؾߤ_65W*n.SrHgu)T(VQ̓P[1u"\rP:Cs*K•4t1tiҩS>X֩F5O1?k> ] '_ |=N+?{i5)|/s M)7,'l;q>|i\|W¯Xx\|UGm4 F9hZtc"K ;]Vh~ i=j|//xoD/~ ]iCg&gCuo<2 ?TTF<>"hέ: 'I,9eAMѧR*,NtGZtB)CƔ `V‹W/S/ƥC{Wڿi> :nx~?+:iKOY}Iou|\կ{n^i? e|$"c}%|@m_|G>M{Is|R#ExG?cm}C:q %LңZ32-R8|έ:qx*T0?k^| NJ#Ğ*Cj %['gֽ>|]ßw^O[oC֙ iguOxo*K_xSƥsVa[c M[O5x3|žƑdž дH4Ct-t'H,`Ol-!ZQJ), C{Z9vKpJx+,_UP<./֝,6F]GNxj~ XwR*"Y*[?b_hxǾM'uS%/|{^_ϥj~i(1U,L,UjPFNZhF:jjD*"Q[Y(*GP%8TPiphRg18F.g g>#xsW/>µ#|{_.-?fO~'x#?gGL ῌ.~ |.kr>2_ /twEC/X}q:v$x %M߳6wihZGӾXvחC%ԄoV*JjÔe?e ~RiFiSYGjrR$Pp)Pic~')K,FNuګʰsmTJ?ů;>!so߳yhOV>3C3|q/ ~*|$ψ>~՚7<9Rq2aǞ 7o~֣?xF~VĖ'y;Lد5 KkiV5t+D燼5gsxsAѼ?jyaiv:Uֻf^&֮ml oxTwQWuOPy8T\2}6ujjqʰb(TүF;N S KXEQ9Te~yTD'կIі*|غ2n~(=]|+GAu$|{I T3xÛ-ŚDh|8 xG:w9o|w{%>ST}S":ſ|wzU}&KY ^ ~Ѷ^֭<9F=[Q"?V<%h𮇣g>,tOwehZ6mhFi}0Y[iimp[H6+XaNt҄qJxt佚,EB*\ԩìMMOgPS A5&GĿ j%kC@jI xQ49-|M.|K[^]ޟsC.Q׼%w|9S[#0Bbu9pbJVQ[*hRad47kSJ~(~!As7h> 3H'qijcGg=oGW)<5/Ϗ4-#N+{hEϵN{Og᷀x߉쿭PcNG7oG7E/H._>Gijj)YTaJ5zw{*n1xzT%K`|ѝ7atiu~|> |-`,*~~ɼ7+ˏ7OǮk4k|א/'uό6ѯę$L|!z׀em_4?__u~ʿKv ~,>֤.j7g?5[GƐ3_/OC8Uکk䕲LEj14V*4RNV' y`BQ'3d>|6g<F7#BNGNS*x? o xDweGž4\y㏉:o? m?)W Cig׵?i~5քH"Jۥ,{ 7y2;Is%:)Sf2O~jڊI7.zN1JN(Q?Oac& rE58ag%f'0cK?wVN֯|)Uojm:_]C,/ŋnߍ ϛ^TCko8i_W_c+?ி?/WWů&CV !#T~6IpW꿱?KI%ڏZwo)?NjW')$QN_>+g 'Ɯ_vwmO`{Wi>4ӴC~%~$iWW&m&Inf9jno.++=6Nӭ-4 h,ll$ kkh#H`H8Q@9KW~=ҿ+uYaxQf.ru*×~g-- F/0 UT QTp.T)-?g߈ho֚>_ Ae_<k/Z4|?%+Z=K%hv_H$o~N{('7_oVzPktO鋤hxI~h<ܯ ox]k(>x?tkS6EȲ.SǂI(xzރ]CCu jxElQ]X%eYq1'zx_bq4c,>3Ҟ.Xn׎6Nj1qpXE<2F^i9ҡNx, uk[j(JqXcܫcNh*>J%ǀ#N<쯤ź]׋-~ ]IM9x:$iegh|Uů9johi__הּ]Mg>miLiibXRCͩWJpe¤Zf5X%,\SFSx'Z3N4''0R(EQU0u,/c4c?i?kOKok? M⏎đj ֵ?h_#^6{jw>y{mYK)nͼѧu׉)sk/|wa)|gנSBxƉ_σ~9RmVZfUΔ꺤6Y?>7Bϣ 5sp-Mo _Kწ6$:nKΥE{(Rr<:n5NR Sgy+/VcRS9#{Ry%hѓTT9{'KSr旳_1hߵís4_ C'hӴ4_/ֵ+s}Z3l5_ isGv.x'/[㟇_83VB>4H,~xX׾;ſ}=i^'Of2p'8|-za5q9qOGB\U:|!C G)I:Xi'R\J$#t:*O6W/NgR*>ql3|fч/KC? gM_|X|eῄ2ke:xV.[M/GJ~8cn ]e~2xO&eGG>#| ^_|#2ׄ>*xAu [_ go׾ ž\Kku(|Uh׼1?CK_I񖙧dg~|YN;߇oY~1𯃴=k^ѣ9𷊮s촟)??='χ_|A߇mžwĝ[Z^۟]мi⿃u34񆳦^uG6l:qy^X솆Gd 5tj)(a8 Ʈ;0# q-JxR9TeZ3Z5(ƽ*sJTJ0xZSNua\0V\Q_"NKqែ?| ;Oj_>*|B'>(uǂFcE~ω76x6}G><?n?j'졥[regŽ[?FXOGA>E/|'v߳! + =z@}"e>rp3f9lRx,//#gTcY. Y>*>w_-!E´jө< ~i_?coaf~|¯ڭ=:zPIo7u{cǨJSW$灴ZeoEU?|1JPө'ZWS<,|-ڢ?uK8?w4]fZFg<מH|d_O xsݷh_ I㟈x>?OƚCU]4=< gG~[+ҕW0Y- 'U,363Y%R_X4cC^rec*RWJ,ou(ׄqW pWQE;KI/?h>"gUx2Yaski5?^kn~ijj𽆙mdKy}. xlIo?п?i(_ ߰5{?$ş_h_h\ҶV ;4aG *P:ڷ+b+7)JRYk&r<*zsR1YԔJJ^F+ݿW$?kڿ ?3u^?'NJ?c/j ϶~"~ϟ Au6] /MB r_a%xD湧x 7յy|Q8x푼/źhz޹]U+B\\Bciά0ugF; cxKJU*8Щ_Za`9yObBE)bi^P<0fmZO3F&w|+9=GkxjK9Guo5==cPӴTukLi^"<|/Q4V~ K 1fWH|gӾ+xN~8C'?x߷n_ '⧌F>ZeI%5vo'$ ~'^^SsޓSG}m:XxZ\|_gK%ھ\_|[+|D |8еo>"Mc^ xV~(xy_Wagumy~/okike/SӬ;QiQt8)FiҤ4]*= ƌtKy[egSFX u)AbNoi۩R'̾>M# QC~|$?Ǟ?v<%\׵|ރ^>}9~ .k(~{Y6|SluKzx[^{K> }o =ouw*/[׆kXx{3žk|;y_ 7~_Nծ|/4OFĞ]_Hֵ*-cLk]F=7VRZE.w/g~$x@y7Mlǁl4hjV:]Jmb0u\]\Ds,I6 >[e Ɣi\^aS:ㅣ g( S8#ύ~ͩx{6}:?4+|IwMGm j^%iYj$핶xnH55}/Y-n .4+OVd5I_FbZR^"J>)|R'%kÞ Vo):gFK/kouox^ԴB ViX5$ ?oRaywR<.lUl-5p\^7ujY\eJSV"\4 qfepQLɨ~6iu@+ּYK'Zs߉gxᎣ1ϟ?f߅x?#cK#֯xzQB|XM궺kvQjPYmi-bU,t{BԣdK[t_LjV6MoF"J(0˧֥g QjUTzxzT^ RTI!/x:&tj6،6.gVxlʬeGO9:Sg|~! yNj4|,P~蚇O[][c1O۝#Z'3xx5ׇ*K^^2<xn>#x;a|e?7?Sg} u|&/OᏈxq?ޅgWKᮇmOغ-<{߰jz_4>x/M>gv>0F}[ ;Վmy{oS$@־[xl|>>hϗ_w|o~-wcWEjஜ_(gTjuWW )%7|TŸ^~k ?੺_nu>.?߆!~ c]7^#nxdx7Hgox\H?UtMy囹iijxWDӟK5;kȴm_]iCE/<)A⛝AYHZ_tI|Aź_hzG1]'Q|GiZ΃Z~Z>Ο:Z}o=[\,26Nxxy=NLLpXlCITpc ­:0U&Gj%NiGR#F|қ,M%UQF?cz߳R~ڗCV^L.~5kQWt~'&13Tq_AVMf4 {o!g~z?׉lO.!_5 X%߾%߃|_ &|: x_ÚOivvuXXAgecgVv,ֶ*Como $0A $QDj 5iRuaTouapXX_`jNѥ*qMN ӯ7Ryak+ϒu犤SMUKO*4'C,Xyx\|5$^xo2'?I|2_&׌Ҿ>~Wt_:~&Xx)e σtx?"|??S_j"ǚoٴ?,/|Eյ7~uo_xM?y |H5 wzΕx>y*k-st#UִC n/7eͥFW]E9¦+)~qJ}eN_JXyBqVx p]XJST+aq#՚^"Xu"'BCYqO h?:W+_VOW |Q?uP~-i~c{/ >Eq@_~ k; >1\;{;OM#ּ) |W߉_n|I'-_/-&m?|.uƋOrg%~2q*[|b߅ >/?~6|F_xS6^s4o1kzF=o[no峎Eյ58i}Z]>TRᆷ,}熥,qpbpю# #|>)6O[T#^;*qT3\7I*l &]F)OV1O#TQᮅhO_fgi~wFnj\b)'O~.E/w(If/6_2 |Ni7/O7:o?h$!ᜟ }~obxz%ףvX? x\-{/ |GxBwI}`2߰~ Qмa xj-' oV7]3Ş3Zw(.{/T6\2]nNJseVZRnQɳUWOG7XSV/ JPq [UTIVZ-9γ|I;iQ8ЛJtRyJY8:QE? e /gO֧o  o~R3Vv8URpNI8WUlmtΒx䄾3FUZJ+{[Ƃ\,0x1k(VXS e4RӡK CAңN0ц" Ecj'9O ?>m/ K[mWqt |a/Oأ>5]cL>+;{f% CWnSN7ǾO|KcCuZgIj.ڵt{vWgwk/_QG.RU\tR ʬfuؙ֔X, ti`uhO()aܜSaǹ6NeʌRZΤ4 (;?u^$տu_.'~nx->Y[i_| [~`K+mmZ۲IumVBMTխQ(Ч:ժthujV:pbh?J!_iy:|#{C<+cƚ5_9lGվx6ZƥcVvvچ5z$۳vZm$}mϖs䦠N5V<=79mSZ95Z:QF/)?oUCm[:Z1a?PX @e5O+7ƕ~5/?>o{|bS ) ?|Zk?nx?tkS6EȲ.SǂI(xzރ]CCu jxElQ]X%Qqcftj8N|q<Y9c}R0_N4NB!aˈ^yV[`玞HQĺ5rs-|/o |04.gg6o j_ V?')oTߌO>&-+P>j:ݯt{{A449 ~ KM.>s_x'xSo?-"M|HRu;m|}K_ l^/OŬ4<7?C#KG:1zPHU)b2>cR)Rylqf90tRu(ה=ʍ8 V 3Qե\7G0j9{XFYkWuiB6*pS[t7 wow>4xSW[߈?iO~о, g|=_q7ٯℷzwsA!?h.=^\ͩKxkw>|F4?J7~<|Q2hi7Ȏkiz`/'g|S׵^S|-oϯAYs,ڭ[[t)uImt+)߄|nF>kjC[k>|7_?XmIbub5M0ݩ_W\åy('Vq-{mot* W;c%ZO;eZ2s)f:~f1m‹NU%AsNG3@7 ^| eY|f~ ſ!LšƋZZK0xßNGF) ? ¾?Ww oy jf/imGo}{<|g_"+|"ƿu__5_|Ql|F.|kUowf$XSYO׾2xFU],>~!ZVσڵf_Nk˟o~%|5%o^;-cU?iY1\ ';T/OYY/|2wxsF𦕥Nϊu?~3?_ͭxWLJτ4;c?~|WM׼P%Γ|\-猵[xzv[~>xO2|5{VW<%> 2rgŸiFv_ѓ_ @!4-/ ~'՟ % Ox80x}Tcᳬ;C/˖64\xJej.s5|/'#o !xt?Ӿ x=^: g5~*iZk_)'R!aq6#e5%3ʸ0fuT]l d҅<=5VЫWa,NcGXXZ0o3d?Rxе jg?= |54]/^zտ/FoFM-ѻ Q _.4[E/OBͧIh/C##4%Qz7 KҾ|ys?_7Ze߇:|4O xᧇ|PMkºį,τ|',^!P~xoGï <ύ d|JǚG|[k?~,|b/ixI{ XZewq^35G^ 8FOckWcq2ըSGC q7G/qC ^tV ~xZu[G]ịcwboy [;xS|soԗxOx|5>$]__x?摬k 4?]+ڕ͵7Tkd:|[+1r\OZ؜'lQ⣂ex*tSc<0(ѝJJtqzPpapN M{9`,y))F*%#% ?zo[{g c|7W?K|Yeև_S^t:?bWÿ*S֝ }FxQgO~o~X? 5 |gcQuğ ah>5onO[ñj|;¯%?HiϏ ~yo: ~)|i_?jW?Y>&x:?Ox`cD__iZX.z)FukA()ʎ/,pXyK-1BtcN 5iT/4#BZtҌ'QΤN>ΓISJ% M9Fq)_~>+ ~.վ(87~G8Crx_<=RᵿؚA|  i*"+oOO~ſE^ ֒F??~d^<_Oٿ⮚]5]@:wLjuM)mMMtr(tmr8`g\/мIf<]qOZSU|[}+ϰ<Z۵5iWLT)f̥[W§~x,[8ƭRRYfUSSxF*3O \ueN1J :jөʤ^Uce/hii0xc_į*'Ro6U?xwUDž4/ɥ=a&=?ºܿ?㧉~|a_ǿ>.?jQg~xᯆ<1I>-xo>!Cϋ񿀵#]t|=mIR?vv}PA.iFss7|AoKgkV6P+"𶯫6|f^.im<;slW/4 3?p`E(:T.2V)vCR>5RO4N 1Y#8i)JXjէF""r;س^ }}Lh6s> 7K u 8E .|Q۟­7KZm9m~*C||Bڿa^Ҥw/ٟºGkP|Oy_^x3[ew N3S:Ͷkcg _? 5o7^|wh`|wxA-h_ںZ}PԬJk!289Ӆ 0:kݔaЏnX M\M9eSSjs*9?N&3RN?98AbtPVgxgƾоxK'û/>h_ h|I>#|I]oV?O⾨+g~8xMO MS|%Oj$-O'ƽcx^~? ֙yjz.!XwW>._G?ĽZ@3OYUK18 '$^Aǿ? < _-|OU?E 2د/tIA? gVleYY4f}Eʛ"N"y~xuj0YFU+wO:|=g1R))bY"s<l1txI_V?o>MK/ߎ%񖃠x@? |#⦋E/ٶD=OxRૻh7~u9Yf;X|`>3g7[KA غ/Oo o kxcHO YX/0h_W7$~*\x(18Ssܺ.4F6tIӎ?N5uYCXF"O׫TS9֩&9T8k$, -J>'¿Ο4_KLύ~Ҷw1o;K~l☖o>j07MKxhttٻBhۻAp[N_N_"מ|}ǩ?╟![ែ^' O/,ls궃YhK*pRN7T*\OQ+4hVφG8WRNFVZeQFYdb)Z({8RG M=6CD|K:Iu_=Gs?߈?ٻ5 xZG+~'x7k_ hIzyď/Ǿ>cX_A|<LzW^躷|G~֞ jSV>xMo=xk>_.<}OJbcڸx_ t;oxVo.;5/ڏ:ishoٓ?w/3O^ ~ixsO|%s<~6>#_hx|;#ԼI>_ KxCOaoڥG|,*ѺG?eN>k_h~g)h 񷎼k>x<;ce\z؟ < /7g||]G_'K- sJK߃>j/zi7-/ jցsaa8x |g<̩jTpN(*jBEo)Τ9`hsVnsx?ѕ\TJ57 ؜Cu^5fU~L]<.N^|2aS$ŽS?f|K ~|Ei]jMkKxW %}u׼U_Aߊ5+|;ZËF_ۺwj/ @i4^i0sk [z#h߶V9nQHfЩRJ\Bns0GokJn11,5\5(TVRt>"kKR)UԜa*VVG]Ko?t?<;mRevߴ<)GMտk76P|u=߃x63_5iv^⯅>xľ _>ٛ4C?h? xW'_x;ş>xSŚ&oW ӼIc\QYڜ_ѡ:Xxl>+ 40c|>9~ fVsc5%R,+Cѯ*tTq8z(b*Н?ЕE^:Z(J<'27~!nᯈ?f;x@>+]> SC~mY[u;sy=_?>!|1m=%uM;?~!7·?x>?_/~/GkwzƱi)O_Ө6T5+mr-6̾$gFj_nQJ#UK0U6Nb+9ޥI֩ĺ&\N/*|iSRɪSi~mQNNRԕZq~fO~9|5ĿxM˟/8uO|'A~V?f]ZMJO:åqKu/J5{Z|/CeR-_'> ^Ws*E^4>kh._x/VУn/k:T~)xi9b쨹bbU!)̸0NqmN>͈RxF3xDn pR8٥W S-Քfҭx:XHN燠__|4G_,>:ƏُǺ~7[9#x~1|o>Coğ~l>OxSOLC=/|9o>|OOk<=±Y?~̿| >~ú/>_ğZg~?uڷ_/5 Kjw? 2U^m<gxƹ? )W'"+_x3>[Mv /`|;F7qC{g4x^_]Z/]7KcM|EtS7٧⣫xH~$x<7!R' xk ĺ;ÿ~> c= 6=BVԛK߆tO:}{_K(Mޡyuy?sq,VcKR%:y}wd\8W t=jO5W-G*ԩTXBxRTf6Z*tk{YUQuPRn7 O!}Z6/.˅SM>;~1~jW_HomgW+*k _|߲R[|~?j?|Zk?n}ǵW|7Uߏk׉N .1_?+^YVwzvimOe}c{WVwwQ<Vv\\#<#4NȌAk|v-_+񝎵[ڍvizUƵjRizM5,k-i0GyxF|?o xYA3Z.E%JkxO:ρo| KWl9;p>$|GK}WWD ZP,te21~к~"d> g?|\DڥsÍC^.oy&Ƈ5ށirIް/g|+V~^+? G/c+3Y<+㯈G t_kڗmjs?| M]L+.&5PBn;h7>О:1k>3ߎU֙kzn}45ͮe<~ρ66 о3ÃMm@\?h p5S|-[u` ,N,F+J˗t}%d>ům.Ax{īIy̫F_e,һCZ-Qiʣ9NrxcAִ/ ğ]y5nY~!~6,"j7{K\|g9o;|]<1- Zŭu?’ZW⧂goO0s>){x4zguωwe/xÚׇCC噷T3Lg^{Q%_,La,ž3+B~𸜚'W _]cp'%St8*+KW^,4?yR2X*88۵T®W7 |0z/5?UOS_‹]5oy-NW_$E^ /4d=VDz{[O[_Կoj/^|,<){[(`OGa|Mx-h_7PIծG-K߈V|5b/MO|Po>%,O_;<3awc]04t]sN. hҵ_|QhI;~:3G)A=PŪ|%ɬk^^ z.^xCú,&FN'py>+S8qbrn(xx.ӆc)ZWN50l%b0 JrY)5¬u/˂>a_)yM,F6QV|M*u%_?7~|3{so|`o|ma?c_ǯWߋ[-O:g|V |A-ភxSwqο͖|j}6گ3BW|_N/2OƏfþ񕇪~ףQ[ψ g76_><ҾᏈk>)s?~"e]7^t]C:Nsķ2mnE ڟliku>_ZWǏ >1\j0+U |cÚNj4oiWu}FOA|+^8𿂼3/>|%"~uO6 $|7iڳpFkC]wo~j??2;u W\|=~9RxSG tx:''{࿏N.|A|2Ү|3iE^ iӥ|Yv~,ҵÚw3~ScniMFqnsndҠ#G;ƸPebha,28nmL6#-LF8J U:q'{_7[5ԞUU˒ ?Q'o=sF~:~_w|kw7el|'Cxo|'=F;|3G4_>'ǟwO?+~ o=O?< D?_jec_!g.4guu[/f-@S=;C8?៿ t?vj !Jo^+:#wS}7ύ_#x~?o^@0WD~{66cǾVW|Ioa*4*teHK&,W [ª*bYntͳDpPS*/p֫K+ͣA҄+xCRLLFNj:SGfXm.{=ĿcOx3__4oIMB^_-5} FŰY<<|x\/gkO|io /}K⟊w_~޿ -F|= kǾ w <$p3!,k-F/o âiixQ_Rj?v>'𧅾/'%#^|:kZ|H,5#Y~h~ { kֺW+khn7b8,vw0iZ]SGF g,5/hgTkS#LeWMSΥieQz*11FjU!i(_ ߰5{?$ş_h_h/my[//?j/?Xޟ_LQ>*w ?_JӾ! _;M񧏣ƙQW  G/OඵWO// S]Լ{x~_z7.uOD5x=.;¯%?HiM%x oo#1𿌼i>+Gv EFc[4R["_^SQU' 摅'oi NW`~X N/ںhT¤_fS X\L)(Utg?c*U%RUiSu% r?^/ k'g'T7ÝI3mto?ye|⏏>4Z-+G?l_y-&Qc'ac/(ͧ+TK_7>'Ҵ/9guo>v <_jzF~kk;7/p'v?}'> 7~޺1.՗hlo٧UK㖝[G]ƾ qıi$2^?0<-ik\Yֺ յ?JK=0j,d QʰtTGO幎Y 4ߵ< ,>M:q樱UXpP}XYRD#5V VaF y?U*bJq?#?͆ߊ5?e sj:τ6^#keҭ4i>h![5_xEҵ_Juچg> 0id_ 5~'x DiOa}n,쯓[LÚrij6^kzC[Ӵx~Rl $:fkw73xwzce⻍2/ j3hϫJouϢx÷:MYˣ8_&c8ZY.5<4TusrTUh}ù~O({KQ9ᣆtb*}k?fE>xSJ&T~I6:J%E7"? |I֓SZh -c$Cj(|#: ! ~M x_ Xv~G_xź^|*ԵK|Qoh2o|ak^н*\l18tRghխTRFL *POgnp"MS * r8-xӔ˹[N8bwZ?^|$~x>^I|}/l>=λh^1ƚv߉~)΁j:&K x XxE5 ־4/EAxcR|Q7e4R*xRX|vOR%48Zu9N:T{VԿg >#|0k!tsĖ>x REA0]j u_Se&^'ǟZ+:vuG!.\x@qYt`g)B3U|^\RR&SrR:rsu1n *R;ԭm:Y,֒ BHN#xByk:[ٛW|뙼 Bo 🃿d:5݇<]/X0|3߉w~m;@ʢy]K,ppPJãV>ʿu#YӊB_SF[qCAd9э5 >s*PWz3櫖Ur`0q [2o/ OHa}cGq'ᝧa `;V4z◇~0j> [/h&Ӽ/=?RxڟmZm.)i?|o|b4mG~7{zŷ>)FoPh_]T[MZ2?ѯx_ t;oxVo2tRp)CN8ZNzN)Ԩ)QujӌTJuE9R|x5JO?_N2զ|6'\ sMGĶv?u+/}^iZӪ&)_cUC⟄xĖ^ #lwxw^ м}|_/*ŏQ-gNa6{EuOc:PxlږnTzy3Y{Ʌ_J 4㈖X$'NPx(ǟ0T*e|=B5M4iRaiJN f>W *U3:O״v _i ηaڍQص]>{ψ+MSwį~E'HL>?Szï w+})-4 ž!Ƌ=.a]_^g/xsĞ<ƓᾭqK7Z/OᗃM'º\/G-m>I]mtZLTᢸ{^d'Mzsì6VRk蜫NLC8s(ս|} ˃(UXc(a Bt1qUZ8o>1]~ݰxQmGSX1}We cz_ek|MߌV_x]񏈴뺶Ꮘ7<Kch_Ƴ]O_b/Yq*~_P.xs/ Ʊmcz/7%{$0|Z|8^=|c {1\ZZkZ߁Ϗ_ \OơG9#ֺ,?hگ> Kl@ۧ}S- VKr sRpZʥj#J(Ek:jB)ʥINRI6m쒻$v4QY:g YsaZ}oh4IonaѼ/}7X/Y!Oм=ޭvXiZ}[Ȃ1.RQbݔbmJj)DGP]Utxȫ$l]NU0 :%5$ZM4M5tZ4֩ (>ao|IΩே|]}Q<3m*[u?Pկå]}L.&f4i4O]ȡѶV]aE;;7gdonMnN*IUTVUb7U?oGQEQE~PRn7 O!}]ͰKKra~,_tk _|߲R[}zJ71_uq Ƨ__AO\?S {e' _e/$[j?iߋv?o?8u_؟$wG;~'pRa1? nq\@z9KW~=Ҹs{],VKRqtl9ZRӵKk>{+"ິ$ )wDdb߳_C}t j(_uJVo'ӴOxKҭn5CRKm-mt)e{YncI?"7+x[0Z^.&Zͥr,0AGK=ps$q൵iOj߳:|mS\j2RÏ'WP9]CZǞ6u6Ei4w3mg?eE噝,?_fVNXdT#Өf/ )S8PxXr**t״^v;9㧇Rq.z\F*O(:x_hReR%Uޜ\_ٿׁU;R>I:!6|>cR֯tO:}kj/u]BN2,|#]~*|6 M#n;^x ҡXVk[+C xAtGh]?C~2~ҟO 3.x"mRRo ơ G|AkmtL}cC@ഹ{i$XI|HG|!Kge}v⏈|<>h΃~Mi_>*4Xi'oXçI o-BOd+ "*8wNd< u8cq+cY{$T6%cJ%VࣚV֚9Rn"RIx|48oTUӽWZ\;өRg O> ]]OOS=߅/7|G~$|W\M;k-ޅw\n5|6x j6jv?&x7]Ϭ5us?ҍ_~$/L7Mၣ#^-< k95{;0 |[3|)տ9}^[]'ʇx{īIy̫F_e,һCZ-Qiʣ9NrxcAִ/ ğ]y5nY~!~6,"j7{K\|g9o;|]<1- Zŭu?’ZW⧂goO0s>){x4zguωwe/xÚׇCC噷T3Lg^{Q%_,La,ž3+B~𸜚'W _]cp'%St8*+KW^,4?yR2X*88۵T®W7 |0z/5?UOS_‹]5oy-NW_$E^ /4d=VDz{[O[_Կoj/^|,<){[(`OGa|Mx-h_7PIծG-K߈V|5b/MO|Po>%,O_;<3awc]04t]sN. hҵ_|QhI;~:3G)A=PŪ|%ɬk^^ z.^xCú,&FN'py>+S8qbrn(xx.ӆc)ZWN50l%b0 JrY)5¬u/˂>a_)yM,F6QV|M*u%_?7~|3{so|`o|ma?c_ǯWߋ[-O:g|V |A-ភxSwqο͖|j}6گ3BW|_N/2OƏfþ񕇪~ףQ[ψ g76_><ҾᏈk>)s?~"e]7^t]C:Nsķ2mnE ڟliku>_ZWǏ >1\j0+U |cÚNj4oiWu}FOA|+^8𿂼3/>|%"~uO6 $|7iڳpFkC]wo~j??2;u W\|=~9RxSG tx:''{࿏N.|A|2Ү|3iE^ iӥ|Yv~,ҵÚw3~ScniMFqnsndҠ#G;ƸPebha,28nmL6#-LF8J U:q'{_7[5ԞUU˒ ?Q'o=sF~:~_w|kw7el|'Cxo|'=F;|3G4_>'ǟwO?+~ o=O?< D?_jec_!g.4guu[/f-@S=;C8?៿ t?vj !Jo^+:#wS}7ύ_#x~?o^@0WD~{66cǾVW|Ioa*4*teHK&,W [ª*bYntͳDpPS*/p֫K+ͣA҄+xCRLLFNj:SGfXm.{=ĿcOx3__4oIMB^_-5} FŰY<<|x\/gkO|io /}K⟊w_~޿ -F|= kǾ w <$p3!,k-F/o âiixQ_Rj?v>'𧅾/'%#^|:kZ|H,5#Y~h~ { kֺW+khn7b8,vw0iZ]SGF g,5/hgTkS#LeWMSΥieQz*11FjU!i(_ ߰5{?$ş_h_h/my[//?j/?Xޟ_LQ>*w ?_JӾ!~>=ßhKÞ97|4p3{㏋>5~.x_+(>|3>!xA[W>[hޭgeKk?OZw5uEg8bZjҫP1418Jrb)BMNsUJ :K=*qOX+k(Zs$n(I>7/x_w?k.犼#Gmx~ӼO/ž!48OV4tM_OOxKFtjh6ߚ ?g/*]sĻ6d4#~ᆰ5;"Ӿ^>\xsDj#!jWMXj01OȰeاraƭj ?%OVϪ"uIVPsO2% L5*i.X<1!*^*ʼ?ßGퟮˍW{t.Eg!>SL/~0R/瀿g?E 6fkey'gSfYAG9g_j/J2V4iLJu_{DmC/qZ_->5Z58<84-ǎ=S 'T<#ǃ\xB6\]6Ǿ-u1[x_DgQĈ VH#(`@YG̹\,]Njʱ\=ŠZhRKC /tpհӊTqc\fzXfINRO֯Vu:4E٣J?~<~Y3Jxƚ[YxǿxM֮|AqKWz|AzQWu/(¯\j!N;eğ/wҼ!~ݺ濥|,/7;_ׄ<3')xiEsN*thPicȹg$(U2eUNQN.*|&eoB"U:*gՖ"J_)Wzup4"=|e G')F;WҎKQi>/kz3ḿe~韴E~,X =Au+izׁRA㯅^P:n.?;;`taQi־'xED>/ì+k]z%gsCw ?_:x{ Ҥ|Eǥ:͵rGGcxsNCjWS.jZέ\i]t~-Υmo:.?kliz݌Z;[_X][@̊)T$ՋR*T<¬)mLpI$:Ss zU ^*h]TZiQu3 8PR'Vq8NUc'RC+B/,"+~){h\30S֣|.'-ա΅o쌺qkO+c˖ԝ: x]~8K7^\'Fn7 ॅ\9_qjzƯ~ߊr8|a}kj~*g4ɒ5~7E Lu WQxRx&7>NMWo_\~%爾eN,&{w“h+EZ|$ᖏidz6wsSEqn[eєhRbZqKҫujJS7Tx,M έUS8u^eZPF0Ƨ(SZt%YY~?gW߈$^^x+/e;Mߌ^5񏌼 Eo?S Þ)n|;ui~$Z+}¾`h>MWVy OjGYj\׻:ʔ9Z_RQp.*mWO >gRӎ*on9'N'N0^$eNF |B|`5 kHx]c70EgcU,($ :Oy\(/",ETiEԣ3{(ʜ#Sa3|FNU0,,3 N<–; K ?d__7h<{⟌~%|h>4~:tۿ~ |xuľ;G7O^N^֯[šWcgo_?g߂v^(%;ƽ|6׵->7Q~7Gg Lk4/6g?5>&wMľ!SgƍRѭ4}5 wEa>|dggQ|:]>C>|FVz_ VhRЮu=>SB\u}:ZU$Yӄ,B$ܯb.%RY2qj:<]z}オʨF9%FYe\}l5:lE,ҞcNNuppJ!<U|Y??xǾg5%71CS~:=yo^ ' xcĿ _CmQ]4v?h.~hg]sLo?࠺׾xᯆ N mvO'ی"ҥ 4I{(0fQ\9!B xifRGonNPXLFnIOƿ RoiG~SxWY{<:<~.K>"/%Wc:M)~*|lfGQ "+ks?5oh~%ՎNmǁ| h4R*o~ \iBm>N)Vsegveyr-6 bOt^%i[Guooi7;'43Y.Dz3@ԩŽ[sQQ*`iJKKlb)?&ksx?Z?W>VqkwQn-ދwF.x94)5?aRP7ʳYfYV(QT0?P(ӥC.Z'^*xK\1Ҩ4 ]Jm:؜Œ0ٖԥ떟ź ~ҟgh/? f]gmOZ߂/7~uu ]׿'4mSn?gojZZ7}x~▙7>q }@ # #Z hZ7+χtehZ[Gg6mfg 66VZZ[EG*+a0tMF8,U:i~ *9Riʄ1|ʔ^Ue,FP(pxuy^lK߳z/ )=j>z~ºOP?]7 /~>|7ס:[[Q MZ_}x^{]3пnٹCzo'~ݿN㟍W? Sǟ5/PO7OÞ0 ›W5x*.t+ [tO|ῂ1h?+i?xƲþ3mTjRwZαk#П:]֍ߏx_VU3B* Td(j>\%FoTkeu01G✥Y1i)NkaB 0kQ~hJ ^׾;xBQw;[߂IKoK=4W ]/i/>MTn_/#όO]3/=cn㏃5 |#狾QxڿŭE{M}WߎWľGxHd>k~Zg|1Vᯇj_PɤYdj?o;[;LO%,+}¾`h>MWVy OjGYj\ױk/%G)'q.12XPUSЧQz9xL Q -Ԝ% 40IFch& 㷋~%ï)V'S|e5g/Ys>#du`t?&Ӿ]xмcW(<ywmKm/~>6wſ t+W~3?N75]N}1j~̟[]^? xKSƩqx bm_]$Msþ ^xwYе Mޑq}\Oxm4>#Υ{T5KT'|. *JxPPωuT#!Ԑu>j8uscsץ4VpeR[NQ(fpp@ (2Brc7)JM&m$m&ݒz$oW!ǾO|KcCuZgIj.ڵt{vWgwk/_ZN9ө SNRJs87BqR$ԢiMM6Z4O?(|)Uoj?wVN֮fO90/G~5/?>o{|bS ) ?_ ϛ^TCko8i__AO\?S {e' _e/$[j?iߋv?o?8u_؟$wG;~'pRa1? nq\@z9KW~=Ҹs{],VKRqtl9ZRӵKk>{+"ິ$ )wDdb߳_C}t j(_uJVo'ӴOxKҭn5CRKm-mt)e{YncI?"7+x[0Z^.&Zͥr,0AGK=pdmoMF|4׼{_^6Iƺ֏O{83αj&}UmVrwɳiZyzХG>ڤT}ZS^iQqTTRp+eXz)9R*1MVpcROڵ*qr~qjƿ6i+_z'?xƾ <'].>0t/ [&hַ{n+'xÿ_k~ξ ./?|~6+m[Þ<|3ߎn!|?/,gGN'ƋG SOj&I/r5]{¿6:ڕĶ4S{9suj:Wx>9~_-/S))=UѴ ?)S\6o[iѼ/K˛[K֓r/OwF Py~cCNUʤ3.>ΌJkTܙsƅ4ppt!ʫsu% 9HM8ERҡ*ujK)N3%:|Luٿ_ o~!t>#_B|/wGfrZ߇uXgysk6a/#CMoe'cM]@|\!|[qk>:|H_ n?GmdGb5|40Z~X|)ˮ]|־ |W[Wo֤C.ڴ1xᖗ_ 5s[ǯ&k:߈AZ-|;_VҾ&EF'OP7B?cmԎB_Xُ 䓩?eFuhQJtXe'CN p-j_QN/3OoO5Tk43jД85:P攥i?1e9_?{_ok;^HKeU;ߎ?}hhWZ׆-oc]g|!5||=3|luy|E VzIQi{|&sA񅟌vOlf[kc7+/hXOtu[}?C>hkqǺ߄<7jڍ,Ax^xV.x̰9e>)]q աŹ&:X.)q^-WŹҤJNxq:~ʾ#NJaS18G>ýa'j? wO?xS&A/E7|]yĈ |9ewƗ~ DZ|J|>oA-K?<-_5/>x#l> ~7iB[>&O<}a״]uě~$#%+>4_N>1>7o6Oo~W0~wJz5|>nmWKf~]"3%F[ xwþ2?-bÞ?_|E4/Fo'㿄ht]?6nt7UǎÚW.3 xzLIz@xw] #/Kox{⼭~_So?:D63k? x=J?/KwM_M 7Lvzi%~4CTJ>~7xOxG|O[?ufm?u)|f Z/?O 𕎷$-ᶗ=6;{]Z)ںt=IxڏOwRgh$}KO? le?3cz?؟:?᷿i>O,C ?&_l.55/۷:>o6o \|sMm3IOm[/qxj:);>2HePZhݮY:O~#π,>V:t iڧ?|cFςc|I񮁨xOG x٭~ xSu Ʋ >K Z˨e b9mFcGQڜ9es5WO1S K1S1qY%NeUʭg .X,ħo폇 g{/ ~˿ |+w4|~&ľ׾xĚ?{;"?O Ú{ xi4=kAx\/gkO|io /}K⟊w_GD¾(<7L񇀼j>?|Q߶~47vX~Wq~#p 9LN~eSVL+),uTJy&e#*gxwK.S 2zps/>.k*j-Nl>"~Q F]d' W_?':;A,4ߌ5SXf4ڻUwŝ_|OԮ}/[k_4_D&lH+^Niֿ,+1Wq.gW6p(pW^X,)מNb}.=I$O7?lBm៎SJe[ƻ/~#׼)׆~ڿ aYo_>:ƍZDž4/Əi蟰n1֙χ_٭~~$cCgL _Hĺ'^'uAx}?| ߽HVxy|A>"Ѝe={+c-K αG/·dwM[ ?0ǖ:Nu |SR͖c/Ƌ٪5 x\;h_ Qa}S. C~}gmiDžhjgueZyNT˓B9c(Ֆ usεJ2]H&XLfs)ub13Tn^FEN5xTRr:u%hTRLfBZՏً[K{\ĸd,7'Y⏊xq⏁~^N~W>?4xDŽ|I>5|E#ƽ{G1~C|w#'tbLjNjt?Uxjo+Jw| u ONl 89aqQsJ<NNiC:U|= ɏ$V[Y[ %s/߉6t|uxJ"6jQ ľK_xSKge򟰗-g-t4_h ~+x^(Z$ּm)'McH|W@~k xƗ7}7X7n5]7Fox3>?桫x^ ~$w\}>0ֵ~'<}4xUҼQMwF<1^'H 6KOAÝ4[D/M_Z>޻W MB{h|o?Maժд sEaԳ\/`nhR,6 J8KFuբ۩OL'5.jS6 Zq^aRuUKOxa<5_λw?k^"Qc>🀣\soğ~ _xصO#>ҮwS5 Z:]ش Bl..8ZX^ii{LҺVjkIS50Sf+̪*n0Z,5<$]:XRxzS R Wt)ӗ5/߲M߁| K>@|ae~:/. a᫯xg&5⋯j~> ֵ߄)_/M l|t-Q~;#׿mxWuk!}86 5x<7_kZ Z6|g(ֿSD|)a.]S:dW~<-k54/7xs>&|>a*؊+J7Z\&_ĩ;yNWjEa*~ЫN1Mb#J+4hEC|*Q/~ h?~N ɣxOடc;~l@ ĚֱGτ_[SUwy]%9 ~)}{jxL^k 5<'~*/-h.ovRxKSuHO v wKYxwHc񾉨]~Okg-&z7',״w:-t}3X,4v^t[5KEҬ^ ox_ t;oxVol2Ę!R8Җ[Rn֬{<-,?ƿOo >=9@O[k]+MK_ xN/3Hk9|K'|MW>-޽k^"|մoxU?gX⾕?dOx\5gH-mǫ[4è[Kź^Wa讥ΓŠ_]gt (7/>mOtYgc𕶅lu/Yem -AuH+9d?2:ʲ j8#FMEz)gYB4!t'WgU 㦁i~֮uxCÿiJ/t? "KhޫmoM% {ǟ)@h;%ŏ~7o&IoM%~ͷEOte/}\7V&x˫x?KhTt0؜,mJt`B+4\/⡄0u, 8RGuxM\ScV|έVKTͨai 9~'18*0:t_66-#p~kN?f {Or[,4KG0迶ę'߆4xow/o?5-n?'|>f7㎥φM&^0Eǟt_A_<,B_>$xš Z}|Yeh|ku\jZxB|/I'Gj|;zƅh:76=[i{i40 xNHkM6^XumgO5X,KÞ twA%53O4mlQQЌ)< )t\G Qg7*w,v":jG^2X8VkVלZO0̱ǕU)p2ZQL>.<*n1Fpxa~I4]sa?ڗ?~0};CG|:76? ~]~_]Zoׇ|5?yKM;Ooo[i|mk<_C߰l?zd/ ?>xw=[]ռcKm V4~7:'o|?zW#%K7[GZ]u?O;kMOkK-Fӱ!^T`꨹FRT  Z%V7 ,d,hԵ\'iu7'1E˄}+OÛg.|!OZƟ|~x|UMc ^){<3BYx6_Ӽ;?cZ]'i?_>$gƏ~/x=5+]e<)CW-U4/隶WwQZ QuoE*,֩)F=dF>i;y?:DWH~"xoQ׼k߷W>oǚ]SjX]H5oxoŐ]\iσψ+ oS}>O|@/M*IhS4OO5Ĉt> [>7UKxgóǥ돆5x{C?xS~4^֕ax{ihz.eYm1[C1 "4]XPS).FW*¥IUj>!pĻMT}2ue[V^~jqpۈ0\CZ4hOA()Ӆ:=8%OHSᮁ@_ 5+<~w?ۏΈ~kf7$w|iM^ ƫi/!ϡk?'~^}?5/s? Eo |u߅|kߴ>ڇ{sGG muE%ߍ)x6?ׇWXfpp@ m>~ߴi{.jGþ~6K_x4~-k_x6X. o6겛ԖBapu1i{ji-tki.LeHgXjIʞ]Vq8yz^N\f+C]Sp\%7KaPB4,^3(u## m3Ws_?g[්g^ WmYZo;rs O-|e&u=;/>!x3—^!_ǎlSwdž0x+~1_|,]ڷOpkOƵj~%.o VG&E`Q% 3ib>w)TyU F*uUY)K ,KP! =*^SQ%6Qc ]Ia⒅)SJxX?~',>j |'Z||8~_=..u k|wu 6[˨74[^5Mnz(^"xV#Q%SZz7S79(s7%)5&d&qcT8)%9I;Y9$9O<ܫ?wVN֯|)UojuL/ŋnߍ ϛ^TCko8i_W_c+ட;/Sů>\7?W {e' _e/$[j?iߋv?o?8u_؟$wG;~(pRa1? nq\@z9KW~=Ҹs{],VKRqtl9ZRӵKk>{+"ິ$ )wDdb?oߧ|֤{J[ڕΝOCDլ<ZZjΗj־!UuեRX @w:|HՉX.S)N|ʦ_ Ty.e|E;F5#*.[\kc5aiJ\m9\oqwJ7w8>6|wgtg_֯'OӬy6w2mXml. Om_hߍ>!%wc M?Mh|C7—v7«/h}śkzEe zu x_5|S~Zo~Ai_@U v~%6 [z;Hk[F|7B5! n2} kԊ0\qؘfj%ZXzJ2|]PVVn(qq315q0aiҡRag:t)J3(Nfs+S^4>x_.c_w4'h?~:#o|{*Ftu8-㩢h.kio$ l~Xk_fud/?bxg!y0dś/.ddm:NjFX?0~:>i*;ɡǯMkÞ*yiXhk- ZOZuR{^Y{eo5h~gO|-no]l>];U$}7J|uioczmbX‹/_IZkz~wFS7.NS J0JQBtjetTT(Ҝ mF6X8V?2O µj1؏gNÃsjtz[~4ؼ?Ʒ /|C;7ff[>=╷iAjuοxO]^iOշKo/>9]xfZG|=[/%+~.լ|IƛO^ӟW>_]{}{N=/umB^ 'C4/ϪOO>&|%wך~χj^=~+j^o;_>[(ϋ2ot|Z+?xחQ~}_O,uxC⧅ SCg1X^8Q|L]{kW>0EehZ'.t h#š^][j7^>#~^>4x??g߅_G*[IVX#/.}Ti‹[oFQλ$[w^|gw+wxE|n>m^g/o|=ΟX5-FmFd!Zz?Ѿ~&/?~#|Oִ?/ #^|AioFzf{o>*冲i&m}!K0BYk<-ZYO&;?3N(l"&ªo^(:8zYCVq9t]o ԣ`ZbtaޫWWhuRJzhQq"8>~Ϳ1<-kzWw1~>{k~]O5KTv_?^k/;-Jj M{/E'@>Sߦ;vO|KG*|E?m-/ oψ) m|!C˛p߉!ZM4jе-"Ox?ou{gÏBj%~ >GGuޝ[k3Vj~ `KMm*Ow|)oqV]M|?K[^x55xݸs :g8 feKɱKP /ܭd 1Y# +iWU2:ƵLδiFe 1%c2ì$nh)\O4kߴoz_a/_K=#5+o/ht='ž:⏈?W~S[Ӽ;o ?|e|r/_z|;o ^w:vԾ |γk^I#▇g߅7kZ^H mko5~ NnG푨\OQiPkū߄|[\1Yc%]ş|WᏇ: %xkMx?hu_O|],&&mbu*qXڰV**YpHalNT>uʩbxQzs~U}VUciW=TPU'Zn>:  4hr_gދwMv_ῆ.7|mx%wR& !'ςgJ\CS/iJ11~ڥm}*&8MjMJ3e¥*kXNXµ:#% ?zo[{g c|7W?K|Yeև_5S^S'_OZw5vg_e|W`CQώVwڤ34|*f_=qm6}/57.g7y<6+м)CNh3WZsKt=ēSkF;:>Ij^y:}V΁} V/bixiq'BnksORq)b)OkJEJtSTqP΅:U"҇5'O9Ο4!VG_+௉? ζO_'ÿ:N5;0?ZË_O_>x E"|DӬ2|@X>}JψOCNa2ֿ>+3<j5S]g[Ӡ}wZXyFq`qq*x KJRn4`:mMB!b*bTpqӚtI  2 Z:q*M`Rƚ8RPhbaoٚwa_{ྯ_O=#O^]~I}sk9-;Z_΅=XtMt_$H'~ W~ ~ÿh~?ooڎ|M_x7ƺj}å_KOǟ]״ چ:ŭփs_CL&<Xk^#ZYkSU.R\3,<(rTCİڔ0ѣ' /w%b,m9Ƽ^ԞX%f&ՍGO>Z? .>x_L >+|}O_O|샬|r~~WTal()|z<1;O Ox-&Sij:? kZg/cS?~_Ƴ#6м!kqa 'ொ^ 5='–_tnQ5΍כj? x\-{/ |GxBwI}S& Y~?gW߈$^^x+/e;Mߌ^5񏌼 Eo?S Þ)n|;ui~$Z+GVӧOtxPVSjjxz/AQJUbR$kBiMVZ*P:3eɫpj0_hB,V"a>x MY|<~TuhQ{1;Aj ,5FxA?q};5]=EFmOS/>ӪӟgPxg#͗<|`ux#@{>x:V^?:ƛ]n\vxq9K-JTUJ*8W7 JTa%S*G8(*4"eجM5I/gK 'ԕ:Z4}O__ 0i?E{?K ?} $^ŭĿh\xk߇4WS {PΙ/xSHbKIC៊ 𷇯-txWLuXx^Om^6ŶݝM 7?|@5G2_t^?0&:9]U57x>ռxU~Gŷ=ԯFoIM V7~`K+MRoZ֛N>|;kW|;x;Iֵf'.GJҬa&u-;/>!x7—tTҮO,c,S\ṟ9++tϗTcZ}~xW7vFX|eV>0~% ]Wf~&78^!g^xI<{%l_KL>jG:w]Mx'kxshtQ\XQerP*RR<&ɥR)%R)5:rURa}Jh!D0WW~gN04(8Tt)JY*P7Z l%|O_*ǟÿ <i|ĭ/ jh~v>-x:i~#~#|>7oC|?H࢖>"-~+xĿ~IW/< 5/0~? Ʃ_|>𵎯^xut5j>,Z]cyjօM2Z6u fy|=׏kzJ 8bg)JscOU(ƶ?6qZ' bjIThSQT>%) qI䌠d8<1\Yn|0iJiҌ5huGQ_ī?_oú_uh Ɖ⿌w?c-?cߊ|>Z|Qym&? YҭO~_xǞ-_[4o&wH4o|X~oWϏU~rh% GM CSxEޭYW?M[ׅ|#58_4|)if=a.5+?R4{fXiu*RUٖ b%jG2^(l>u6jeN.֡K tAneUThC8L+x:TE8cOG N=1f;п (/y_x6]|{7{aqO?uo|So­tw}MOYgI^{OTj1uSĿQ~ ~"_ ?3.e?>мOx<;q|AZ_o_(5kwWԴxgBcD}[-<mu-&?؞εk!*Qukbq)³F.U}焩aVpu'F+2&p'O .tifV+%t5*U15Wj XRϗſN~h'MKti #r֭⶛Zo Y|/?c |cxj OM J׿cgM|7_3 ~&_x O~5T~sk\OhxVPk -o/4{S ékpk:jVvwn>uufNW}[S8irQJXFpԛJխ*=}:58N.ЄhO4pK҆gQe4a[ MӔgZԯG CW;xs5hk[uRx{Jgo,:-]zfkD߇k?/|u~?ëOT~1xO {/~2_~+c~)Ӽ+ÿg jW|Is"ҵj3xSZ>#Kw5h]zegsxYk-WuMO]u)5}gQ5 /'bU%8o[ܔ0_Y%<=j*gbpgS؟eNps,V64ocRHTZ=<թS`144-񿈾%|oڅowχc=x'ʉ2Ik?P}zg/Wzt3/|;& G[GSNcCn:aoujl_eo|o .[xF/t-wJ!VjܮQ=3 Tj)YW+1NaPJ7χ<5,<#'9上uoj*;x-ŏOX]\eӿ^uyjeΡ[Im'PNic5.>>֥iGV]}Q7:/:H͞X{dH.FY1qbGUGK Z6RR2|MJl;J[ !Z',e7|g<1Ǟ <O῎]V҅+x7~& husOk~Xx⍟ xƾ(s^xKMψ x+L4}K6~ o? ~ ~i45߂~i~|5N,_/~%|QD<)'EվCi_uO^ ;ƅM3 \E|#g'Ɵx{ Y_h>2ž4/o./]Oz-֛⟋^!PT 0%9%j~bv3.:qzk\?E)zʚO٨u)\eFQSy/ B&tV=q{F߄=CþӾ ߴmo[Nmc?%emi484fڎk^##~^WK>(㯋?.w /> ZԴEy&|OkvzTPXiVym_+ĺ|%%_S6^;~8|E]|j|Im'S?~ԅI{5yyBk_4z~6i3OÍg~'ď&O4x3:]wqykfOu+]kC}<&ee𘪸l~7V5J)8<>cFsN*+ hܤMT7USBe3PHb/hBTjRb'a_,<[ώǃ{oX~?|=]|.𮗥Ŀ?i+3mOwĭ^}Sxo 뗷^/zrxEf&v^\?¨hE/#{ -e# 3#oL gE$?B|+_/4NT'G%yl|)Oi/ E΃qx|nmi_OOß|_~owQ]^|ES1YoχE|Eįh^LNy㫝"_xBf,Nixj|/ɰg/Gd &58gapTQTpel55:xj"uZKFuԩZ*95\F^Tr-a+O>|~$57PZï|n#?'WbXGM8fss_o_i~^g>^Z?f]{Aw)Ak _~ֶڵtǟ.~&|[ASWmSW 77χ2_G;xQq[Ɵ~0l-35G^@*Yiob)xz\& )`pRRx NUʬ꺮(R?MΔJI^ oiR |_/)-?eu_[Cm |#}Ꮟ>+xYγucÚn3=oij[/| -}L"#-~>xV5KC$6B6TWe>"nGx0:Uü7[AU2n3U,eH*C_%ͱ2Ej*k,=)%>ZjaU~®J8B'̱ԤF"R GŸg$~4>6H.t{|Ek/Hz ֋o:퇅 <.t+__^SGU~/~4k\oS8G5ry}V^IUgNU)9U)_MB~$mGsoƿ$h?㙼5[m_|G#^^YMzCG3asN !x~?YCgz?iX$j/i?i:fkmhzՅ:Fm-jeSj:ng<֗7Mkwm4OHx?_ /|)C'~ԵyG_ _qgekw?tNt)hm`HYujӣN8)FJ4Y ejTgNIXC L=l%iVu[%8!N!K+SPtңaba^|.]k_x )n| ??e$!5OٟO<}:YWt'kz_|3j'v >)x xcJ}73u{ۛ4|<~nj𶑫' j6|(;״?jq¾;e\jV?~ggmis^4U)F,T}_ e8V⪪q b)aFTN0Ni\U nz1l'U^ڶUe':!|Q_: ._Jjz߂~|8_G|P'-w7/Iᯏ߇/`$f7ž :x]fku?.~>"-> x[qFh|M돁^.?k ]~К/%IOgO>=׃| e}xw?%#H5:Vxᯌχ5ҼV__xoZ~ 2iؾߤ_6[ᇁe':W5v-GSυo]{MCVcuu-2P;K'B`+2:80ePN8apT!0Zt!s LӍY^<i?,_ǀ1(L8V2xy0o?_ړ [aCi g~6I|n_5? ih?ٺF?oxTCúF/$?d? ?>Ku|Ja|dg9|3u/K5tق')mMMtr(tmr8`gRWpʜ6\ɮWN!ɪҥNPK?QAptU_SMQ18YaOʴqVNYa5T0)V`0f5j}Bi~+?1ெ/|{Ee]6 lt[͢^!>#|Ou+_)gQBo.A.ntM7o_ k~:-pQ?nᏌ:g~h?qD)߭\|0࿋oux<7|btmxX^kWKJ" V /URSDԭuR;#WtQqVv֒Cuo ~MR:spkx*8OoMNOBөJ_e$S l%QSTIRIn5ƥ5QկG XgBX?^C~?c?įA? e~v#мc(u?[}u"_Bs&4?lſ6ԟ ; F,_x~"g-Wm{>qx⧁MC/eᆯk?uø'> E^*bq8Rb0 Mf7SU#9a S XVZrrڅUGEG'Rl,a J4(!dЬ׳N??gχ9#C;xW<|;ibO~{ƯN__G|AƺxE4xk,kYu߉ןc@l ƟW"_-C|X.oۗ],E߆|!|@_RuUIdeF5e*RXFbѕ*zs^u8JJ sN!+9IPfJHƍeNl?'+-.=  %OٳM^5_] O>\žw{_í;Ծo?Y'AcaSLك_~Io7(uׅ 7 ߴs[|%iK𶷢||aeOCHEDhh8aRì:e9jLRc(qڜU5*T9P[mFYn! AdTUci)ʖ)a2(Byl'W|""xwď?|!-mY ji^ /i4|~v2i'>&mgS^\14^EmAuojQiwV꺝m])\ީG5Z摬iUPҴ:}ROl,nu;;{YR=7OѣԵI$/4+JK˶t3OYQm_+ J|nqFnJ82a^-Us{INRRêTWUbq*N(eNQax$KC NztMT+Ru~N_W?ĺd/گó|Q7/]ǩ|M.[?O⟋|g|>#Z:'Z–5;Zmԯ⿏:7|l~j i~|Y{O-_ |8txSை5 |9-c5thziEc 8jiuJ?kRR4')CG|G͉xF#驈IՒN 6XQFxN*N#c]EBbaK Pӡ /w?d _g> 0:6 xw- |U%폄l5=3~4=ǚfx Mдy?? 촟z&xOZ|'"| [~tO <`'nWM6>!gB>*/ Z?<__Iuφk*}"&԰WFGVRʎcĩ3*?VW8zrVY)ӊU}P`:pT(tUU4TJnRRM7GzP~>xkſ |7Rq82|ռ߂m׿:ĝ{>o'lj/3۟ x2Zc;g|Hp /|"d]਼3Z|kx??~"dtԿ?m-]> |AVH~!߁ ּSx}WJ'%:exIEoo Hq:Rх%R*#_&a-t,uNȱFb*aTk^'Z%<S25J:t_b1ٌqTpB_ _ů٧ľ/5/6&| 3Jxwniomh=U<-IFXSrCBê*jpЄYW{EӝiBuSR: qUb#hO7>,x sS_> ]|-|)c^ |ux\ӼQm|UgMC▱æi:ω4~ ^4} 78독 Q~(xKi.7㵏UÉ|= /6ZnX~QNEMṩQ=j*t]Lg5TԭEa(Rq S"U0'8VmʻSJէVJjEQbL$c߱k}o7ue-/|\kt߆?<3 |u/>;>,_"gG|GFwO_>jŏS[Ï~>+ešZO +ix[厘k_m,4?$MT*ʍw~We:FVVub[j2NrN%Q#*x{4R:1OF򡋆( eR( ( (?(|)Uoj?wVN֮fO90/G~5/?>o{|bS ) ?_ ϛ^TCko8i_?A_[O߸7øPS {e' _e/$[j?iߋv?o?8u_؟$wG;~(pRa1? nq\@z9KW~=Ҹs{],VKRqtl8W/#V'k/_GOjA/?0i\_9KW~=ҼZjuZKiuF +8<x뫙"/6yc=#\/ 9JTq*1IUI$mZ-*IUͶXMމ%ock/?7&O7POcJdՖ?EOCw[FuYκ梾!'9!􅷏{soggo4inngb^YWX5i$Kfk77ǯھol6Hlowᆽu_u-;ڿVSO65.|>_"?^".q/;u_^-mz%jo+?|!)|Cx'f&'%?|K𷎾_|.믆7h>5W_ x ^/_P*hU|;ͣ;u N>)ƞ+XӴk:SUZ _5+*ߝnoG~|0=_HxGS /%_<]ϊ_K|exV <|TҾ'l:GJ45RxRp!QΕ:|FЩS ڐi`.cW УS VNTjJEѢu*b;Viek/qOp֯:ާ\htW^-pwoG_5:<Ϩ7L2|*O',G<5o/xcNw'jikߌ1yGq*^}|qK%{{'KX|/cG%+zJwgFQ?U+ƾ6AwwxPm*ntO캝RZm>j |5 [OK|Yϋ[ZDڴK5: A0?/$?>]^R{  O{ÿm7LN{焴gEΕ|VԵ}rσ4>$|%c/|?w5M{_ľCogIsu]^K4}Il5ݩVYVSTqUaR&OTj^iƬXRc0xp0J:0)T0Np*ή/RZAZOǿe~ {/Ɵ ~5jZq_| 7q|a*ZF>gоxc&k? h LJ|1=QRIJJ Ѕ8Ɲ:tRiӄ)Ҍ)01RQIY\r7)JNSۓornsjryMQEAAEP_sz/ߍ5Yg7]vrR9(=0Dώi(_ ߰5{?$ş_h_h/my[//?PRu⯇Ud ;7_|Yo> Yk~1|u>MG_? mnZ`m+úީ.'úơih[@ !|C_7? |1ռx2Ojrhkڗ6ri?[c-o`Il9sIFsk7RGf,CtLN#84u-ITk,O ,&&8UЪV.t:tۊSWWj?k[߳?fMgÿD+4߳ďčW?|I~MW1k?g Z+>8ڏ hu]:Xuh0o ,nxCJ-^}ĝ+P'Ŀ.<1M3C8|bŻ|[X~ c?o]oljr4Si7Ӫ%UN._|8[X|]x?G쵉B.,k][EXjڟhx/1:2kS*pp=ZЎ-JRZ8J^ԡNJэ,ʎ7F8{ 8Z.7,7MPWO+b3|e%Fy.;`HSw#Kmu_~>3i9L ڮaⶩ}ULJtz?xs߳?5~ ௅8hV>m]koxS/ڗ?4/¾)ό,i%mGW ֞%Ιz~f4Aus{g` &<\kQTp2N>:pK̨BXeZ:Є1Kp O [X>+|>*tqOΨg3Xw[5J>JjB1IJe)]E')tO^ /s=[7> ZxGxs[дM 4'tmX47KRšݖmZ'^y|vU'J'w| |i1/ 7'#H,|6c`o}t~Ef4i4O]ȡѶV]aEtbIb+ʥ:{Y{xrua^RQESݜT՜d(Oϡ i)MrR]Y)Ju/QSQEsW'[ᇁe':W5v-GSυo]{MCVcuu-2P;K' Nug T:*N4ӧ9Ԝڌ!E9JrQbi$:*8f4i4O]ȡѶV]aEIMM4iZ44FP*F38N1' )FpN2jQiIM;QH} |07$TW ƾ.־Ũw뺟vijanŦX^^WgiqptάJ'RIƝ:t:Q!)NRj1Srm$gYEah"ӵ۝n-a[@-4ٵ/xDCZէ+{)V jA*uhԧVjR n2u$Ғqn*iI44.PTPNiQ\w/F/VҴx_`#_ |e|?jv72bz֓aM~&LI7ewn]Wi_KvPu!EME֝:aIKoi:Xz! J IƜ{+׏%C'uo]]5=G/ďh<IOxB>- VKhIIQsZV:5gIhB"IBѧ^Q";ogB+ G>;״?jq¾;e\jV?~ggmis^7M7e6ߢI&ވ,g;>JjUkSsU1Ѓ\ӥΤb(((+?%_:5oW⇋< k_jw۞*o~ OywVgVv6_;:I&i$md.i6mSVFBV7iѣ ի9Z4sQk)?oUCm[:Z1a?PX @e5_+3Ƶ^5/?>o{|bW ) ?}}?[g?p~Iw)?o?8u_؟$wG;~7g'XxW')$QN_+g 'Ɯ_|7Uߏk/?oci_ԜA]b @w:|HՉ⚷h<ܯ ox]k(>x?tkS6EȲ.SǂI(xzރ]CCu jxElQ]X%Y S,W{FJF&uF_ZJg ㄣZT)IV&-+P>j:ݯt{{A449 ~ KM.?j?~g 'x?F @UQLx~'M/։CaCo O5?P~G|XM/i TG/ڊN/xBվ IgDW+x_Z)xKrI7u;_ ?hO]^&kᇈ[߉^O 㯃&>JY[ iW/:SO\VSg<ck >|84U7<|.n*1g\i/0jat#:9ORW/*8BѝJu#Յ9GYJ(I8N'+ĩ$կfZ*RN3x%*qwr)sFĚ ߂>2>]kxoDž>+< %wK4߆:n ~N}1"?|?At ik:M/Hg~7|Cx/?}c=xTt/^ )_jJþ)kWh ?k9O|oǿ-~!|W⧂goO0s>){x4zguωwe/xÚׇC}|7㪘xdքrr6#[2U+^:3 [F.!C!Ωf4K 8C)SJ*hR:2v_V9!,Kmxɼ-^΂߈_.ԼmOn{h~؟ <#Ӭm߇ ~;x/Z1)/G݋jsjfS_o| O&C9>(O#_>!:-4?x@nu{^h1Bx;?ً7< Cž?|DͅōvjIvu:Tּ[/ךNJaxSJ|CeD|#i'L7B&ᯍzy//1i:y$ǂt=ƺ2iƙ<UWLV6~e̪%Vү Z8|&mAԪbp~aR>N&7BQ*qZtl\ejYЧKYΝ\,L75?U~~q,|'_?Xω5%e&úVl^8NJ4{oZυ.CWEm|~|5C᛽Rß ? q ֱw?Bs\[[MOi%ܖ֖;9Dq^Go>#5?hߌ׊ux{\OJ?k㿆>#Yjψ!t{^=u\:x]]|'j~%ۃ׏$'_~%i_>|0qCZ/W+|)Ɵk,Ѽqi^1m? Ox Χx~åbK'c0{Lc֗#k8L.8j9c n c{Jo*pb+R|aN pkƣQ!bg,=on NcR9}E~riď4W?V~3h~k. #mGF_7{wv!xCJ֗{KO?jO |h$.xgDW~"|σ?h/ZUφm5 _|cm;Út7CO>_NŚVsVӠ.ϼ1^Hg(V¬niupRsNrL|&LQ.q4":،]U(MX2Qa_ME?k^oRߴ_ٿ?cӴ9>#W@Go iQ쿲Wka?|U?n,YxWgVaQV"Rt :JxadܥVx\^.V૸S5ZQ:sn\Wÿ ?o_AizW>~5x LO ^|4Hu_=ԼLπ)_Hot gŏ^Zem#QO>1Яta ]CL4r\>mr:Y lf\جd0K&y %8w:O(ϡ1rBJ2R,*JNXJPR8ѯ75bT\MO{oE;Z[;xS|soԗxOx|5>$]__x?摬k 4?]+ڕ͵7T׋X잞҆VL:aêj2zե1Y~-Q)PaVsZJTjSQ8&yO>|qgƺ| |EÏ~g/+}úxGwM[լ)c-wG;)CNhl3rA6zαkq|Aui\趗~*&𾉪O.b6׈֯|=~QU8RJ:M.-()FX F-);7X,h,(7|9qJ|YxΛ<|E?h !! i=b[/x'_dEk/4|>S\QYQqJPkxRJu6`UªUxx򭊨{Z4e)h6yOJ)fq(:tU 5\2a+U'ّ5w#cX>4h;|&mnO m4/s?_~|\x{Y4?=t Mo "?? !xon?acZP_;~Ǐnw_+~xO{|yu/xC_-w(WiҌ)SbpqP'#rJZ5_Bp*ձu*Z>E՚Z0üEF4p5M9aj㥍Rjn0|V:+7'_o;a\|vcJ^9SN>!|S$?%/ZÏ #U ՇíHZ|?/? >0pi -%o,ڧi?ŏ;B]7ٴß"|0m-wA6iy 7ဿ_:?}{㷏/~ÿ~_=/Ğ$폈4?xHE؎񝭏uO>u?WKᮇmOغ-<{߰jz_4>x/M>gv>0F}[ ;Վmy{oɇNzd (MkXz8xjS:TcZ8TUk*T(*5"jxyYӔ*T5Fxi*4Na_SLD|-3X۟wy|.fh^;6kDo~SxU7/u7,mYn%tX>-dZ$ O/L/ ugϊgٓ֋eM:NYuo xBeu_0m߁/o۪>)|R'%kÞ Vo):gFK/kouox^ԴB Vb#FUT 8|^J0,%Yޤ Ybʞc[Uӆ֥,ak,&gf4✫ʝV׍8F5#^UTiB(WY'?iV ~\;]eܺ^S?'aŚs?AO-Ԯ/ݼ%TfwjQ77ZƇHh?f|D/_v |y?<'=G><~_º!zz>kVe궐>^]B+x_L״-J8D7Oˡ-ciyъV)BR2ŧNIWnT% Ҕ9$Kסҍ%bpqyeN\dN߷UG7XnRYa8[fWľ/2SH%x{S׾(i_~7\>EsKN%3AxV;Au:lτu ~? ?c[H/Ŀ|+> yVh OKǂ˿gx|s?ރgQ]39crdUs,=y/?(tN\T|%RPOlVh:po1,>2M]!R4uZo J`IPHӖ j?|Sᇎo>5j |Im~ΗjOi_ 4ώC[|dk[| |O{h~;:kq{]G? -Aj_ Qu{ 1{_xF?h/1iyFf~7)i//N[ OD燼5gsxsAѼ?jyaiv:Uֻf^&֮ml oxTwQWuOPy<%h𮇣g>,tOwehZ6mhFi}0Y[iimp[H3nUL>=HٵJTsXzR9f#+c {n y)T7N9l:QPj |*0aO PzST}S":ſ|wzU}&KY ^ ~Ѷ^֭<9F=[Q"?V_.uF𷁿dJ 3/a?xO׵ |ռ)k_P/|]g>"cW}|1[Hh S5!oj:#77%ӵeω|z6AOGř??/ÏKWO|?|7{?z?5h?'UҾ9Iᯉ|yi0t[D._|]~?-u_?ېxOgKO'_ O>.fmz=@|⿌i?OO[ɄIs #w2^xZB76p+7OZU$~Z7 W;]]_~GNe_:7gc4m;U}/tO7|7i7!enSgR5!ς=LԥQ` Y~aN.xѭˇk F) #G:w?dCka?'G_gig[_ xB?` Z3m_M)|'uu4j./.z+J՝jIӥ|WR,NU䘉RSSCR8HeFTt(PåN,U-)ы \RtpxT՝*5 ƄaN4iեKߌ<|![{;j^6 ~K⟉>~xOI}x/;z_>4Cv~GB+Hk^ ]9߀RxW|A5* Σ'LnV<핶xnH55}/Y-n .4+OVd5I_FbZR^"JcjrƟ<*B-XOa'N&X,!R)ԧ,4%!ШeGc#2:nL جueYVh? b<;izeoxNLO Z'[Z_:?5]ZDž/Q~$Z?O_s᜺)?+x_|[6~|>Nl"h߳Ǐ=S_%#[xTúu G>;״?jq¾;e\jV?~ggmis^5j8TG5R?5gZ:j=ҌSeNUTzINZz2F *hƥ(?>,\j59d Eʒx{SjZM[]sq~6~&xWI? b|o>xL|!}Q_ÿSGFi:Gß㏉7t׏~1>Ɵ3&U?ơ_& ߴo_?eKG??Kߋ~0huh~~ca ~-h.muڣ?~/E5)\w<jK;UۏiV/uyl4ώK6BGHfP#VRO aUJbjQ14+c1Tx\&U07T*TgM`KQtF1 (Ka偅Ojaᆣ !0C|Vqĺj:/?E/[n/_>?Kobv|Ex]մ |A \C&_|wJh|^e6^ ~xM~xUޑxh)MwS[{GH^soُ^&дoik~XV -v MB;x xLѼMN8TXOe rTjS,|( FQn-7-8Z4^Cm[:Z)?oUux6^kqj^imklMeK-73sL=>0x'?_ P}t 7z֦m-ee92?:]]ۇß)'ÏJxCV ׇSoZQ╟~|P?R·ն<񶋬ٴ+IKk9,,,dq5J80x*r%ZaE[1xiJy… C×QSج <=*tkׂ*1RxAE*)*'⯉߲1I׼m?< o14MK{y5K[Q{:uϽIfO:> ]w )G?׊h>_t0Ð >wkZ\iw$e>(|>7;a'mmg}<_uMG<9/*Vz>oƻoqA񍎩,ZROOsaqT*#NS KFգFʐG?B{ӧn=D]FsՅ\?2:sL߈5ٿO_ o~!t>#_B{/wGfZ߇uXgysk6a/# m7uߌWP?hۍ(_GBTq;k";Ⱦ~О&MO#^׼{M ſ>Ÿ_4Mg|{┳j>5moMү^tU&Ь~y?ח}pino |x]|Tbθ_ aa%4vJҿ/o~~_cG:#kk~KP\xi<9h̥WxaPŷ -9Tt)Vo ~:օ{!뿁>8|V-Ӿ:o=#/⥗MW~)k/-odž<]k^񎿧RK]w矉>;_?c~ƿ;~{R~xGi/+ |c/k+>W|g]>vgw>3I்xx_}?ź//(_>#j(aῇz|Oh~6k=.|#|x{ TWIvG?|oL'~4iƽ'D} Yxfo'׮o/xsZu|6i+pJ9dI6ESe~"SUq#xyLn;db·7_0Tbibxbץ*QK%GCv* ]XU{&b?aovE_٧{])w|KQkoAo|W i| k E υ'>|+e qH6OXxe@k&:{ ߴ!^ o-Ŀ z'l.,k?}#W5Ki:޵7~vkg/n~"|/=O=?g~+;k|L~ _j5/>!Š|3[o |NW4_> >?z%6_|յύ_f۽[U"Y~]"3%F[ xwþ2[j? |FfּSW_1sU?|G_+xI>.xZ{=;S-? ~y'>=+J+_~|j]3O~4sXf#Jo/~ \cxWu?|c\Dq-L+e<Q+bNk`j:5qyÐ͡ 8kfy.YKQ)JrׯR9Ֆg7N~6xz5srÿ)kQi~^G45O[GgFo"΋ 'H|G_oh_c⯄߲gnm ~j<1߉17Nx=S+\_3kK߳>mW<|iď4W?V~3h~k. #mGF_7{wv!xCJ֗{KO?jO |h$.xgDW~"|σ?h/ZUφm5 _|cm;Út7CO>_NŚVsVӠ.~=/sLc0>ۉ7-p1~-̕ZTquu:*x },M 6EG Սbſi)U|"a\N1kk}FzʪrSC?|MxoS?h`&fO<-L0eTcFEN, d%axURLVc-tΔy}B(?X %#T? ~"SGUg| 9b چ/>6?~8~Ͽ>xWu/|lS%/W<<Y3cg־xHt=SzOt+mjP.o4γL 0/-Uq_?}Ryz1ugOj+M_}DsO?7EAsگ-n??xio|CQiI S{cv/J>i>,,?E<[ ûu*w ?_JӾ!s|=T|x.Q淮y5կڞ |YܗWBºLu}mW"'>W$?k^X%VQSTSt䓄˱eE$ӺK~ҿ'~>qG_h^1Gl_[_(h >"lo~5_߂.  ׵]_xE/6)K"~8Oe idH?>:xei_?j7VYB2/mq?:|im^"cOŝ!|g7Tޣź] tட+PA?o[ǂ<;4.| 'ZIJ~-SG3?~~$о7/__КV4Dk|𷌼Mx \] ©G>UӄiJ+9e{56ƞ2\Ta~ҝ:мEG]Vf<-pT!*XxLsj5s~ˣ~+GB%5[b_? t"W?xk|T4Rvs)tOÙIi|IEƿ_J?؛ÿmGᯏS-jW6WOY}rqoa=3SEwx^x|;}P]_Hռ!e/5+?_׿SºN2;V/薒x_Եٚ+<4pRRhU Z4MFT,|T:co4r<5\+B6&jVO<3 au5:nBx+l ?`o>3~ Ɲh5㿊ڵb=OK񽗂<K>N^''] hᏆ4~!> 3 ־%&?kovߴwtE׏1]|- KBu26e떺ݬVԱ Ta,:qJlpRX:8ܘz9ѡN5*1U\M)Ӗ6 ĸGUG冫RhE&|+bࢺ <=o>λح~j5zօi ~,5jA 2<A8 :fhZ^huhfVpX^kci}Q[YZ1oQI* h8zYLedR'旸dN?aRJ9Tc 8F)iSRJDu8ƗҌ~J|;oX>c7?i/+Ŀ~8KZ?Z7_ Q?.f=|,5]1CYxH5ψ݆hPi_Wlcow_<'xIKn/xCݿ4/|Q4׿C[OI0Cc ^a,EY}\7,V raȩ*KNZ8$*ӥ1.cOM#мi}ty/kJ?~ռ!|eEaV=O߄7:VGOxDX*t7D>=ѿf_?en~$xgᦩ=G>7]C7מ  X"*FB8&1F*4ygt1UfZypL-,V R(8-jt~Oo fll㋌T)b!RgeQf9gXL~`a*ʖ~4gAWU#.mزĘ|-D Aگ¿XC-k ORҢҴ?Ux$ς LqNּ+W¿> >_L?9yc=^4g|Iχ~״'.q?kV>whZ>M^OxZT,<5Kj[.nmWIimx6m1ԯ ѨS:t(j 8'Nk Iԧxʯ ү8)2PN%UTgagZ첖"M{xOcr8Ԝf:0i7u)σ/-7/en/ ߀7x6?6|cjᎣ|89eo^Ws_J= cƩ4};mgxsgş Ϗ8t?>,<οcxF`|'ex|/HYUK18 '$D JbhT^qGFsgs&5FNI΍(Ӌq}^h]ԅ*PJУќp\#үM_H4c|;}~>-+©ih:sF=>c< 6jf٧𿆭C&dڿ7xVI u+^G^1Ծ7kO_ x'jK۫}q{|W_m3U|i?Ƈ/_aԴo M]K7Yӵkvc,* \];߁uxEx^?a]/3,5+ZW ;=X.\x]Yj:εx4ƚ! ƹT)asZp`:8#X^|Go{gD|;! O~(|[@ x>c?7@MohwX #Skk8mKn3?̟ o =uqGL@G/6_~fK+/@C[ [Pkk}֫ V/00t팧2/NQ  Nj>ӕ:ϖ- RhΣakƝ>i.\=aMG]Fm:mJ#9UWo 9sDW嶇o&xn)?~-?SWMxw|:|nOZq~~.t6:|2oKYT*&ksW C6&˺9:6 ˹X0 3ȯ#_%37?t  *m#U:7W%u:MRu ch+AƝl)rF/rJ!ljTNXJ\j90֞9ԭ<ԩSø[Ja8^$ET檡+hPSS&K`*$|6?xkC|^ W+_t? |/_m?_ ~_Q_|aŶzx_/xR[{A?i=?- ~ i U/6xsm~ Ե-SԼ;It>qk&.gY_? K?'w4>>='E_%eM[mتaEC8P 4sGReZ#)ԩ*yuRsyn'8NxLU+Ӵ+, 0VpN}Tyh1u*OOmk!| Y xcpݮ)l<_+uX> i\gQxY~|F?|,_| o~$koF1O/ \[Z~̟>"N>xZ❧4_x]g:-3Ǿc}y8eO `OZ?/(l,5~ǝZm UӅZP:O ZiS*H,l%(IKBcRlOVS;r0mNz|.ԩSB1D-|\S,<%5?o쬚/"񯇾 uíW][ S㯎|=> |@f;~U.KM]iZ/V_H/X׺|K~&џ&14վ|Q?߆z9Ꮜ:-~u 7z߇?h>M_ti*0BbJ+qW2pWjrߩqq' Y:ꕫ*թN' O gZp<V8jM5(|1;Y,|+6S-}?FF4o[DOt}#D܇Fiyvv6ŽEnWnY/I.C?wVN֯|)Uojm:_]C b.|w_c+?ி?/WU@e5O+7ƕoφxCW 'pw#T~6IpW꿱?KI%ڏZwo)?NjWk,xbVe|EJO?#Ƈa|q]G4_O`k^]j3Iqq&/MF_J_b^M*M߂Z ${=(w(I6fE&Q.ڷ?NS!φ:_vˢ^1τ/>![N~ f/Rjk4{Z|E/WVON<_k%sXx\~3~VgEz}1m ?%+M>_&k47/f+p5Ni^2dM3G_Xlq,>*e^iQ?Ղ tN8 (SE[se:xW*/0 da9#jC[qk>(H_ n?GmdGb5|40Z| ?'G7)OEĢs&朡ԧcMS8B4ͼi(S-c[Jٖc^"LqPx:pu1(O1V)R'|^n$zwώi t:ΛHKeU;ߊZ?}hhWZ׆-oc]gWO߳7uy~ԬyK neB C>JUWpe)~?_?~ k = ?!%2G6ϋl.}v@[~Or/ܦ'?ʸƮ|K&g<'tw c1G8i/7敱\¼)<]㱕E,F'YXs:ubti,v'QXMz=CD~ڏ=ft~*SA/E7x㯃"t/ ]2i+G|kM _-K?-_5/>~̞=୔?' #v0>&O<}a״]uě~$#%+AXa$1[G(+,?$/kk-񿎲Ff??z?^x/kb>z 7>'x+Nsǟmf{??o/ jƯ߳mޭ |,??.}Gt-h_g<;Xk‚MIb涏PVXiI?_ןS=VG9'f|;b'0c1rxCqTJNS<?mIf3zUʻT~,d,eLE5Vu9Iÿ)kQi~^G45O[GgFo"΋ 'H|G_oh_c⯄߲gnm ~j<1߉17Nx=S+\_3kK߳>mW<‚MIb涏PVXiI?_+Ş;X<.|b=%G?ȲLΚγ 02QSmY"ZPV〜p*ʊ'TXxg^)3j\^cfRkՅyajS4CE?_~!4|#Z#; |S[/~\Cc?t3<{?6K៊<˺7|)XSwXo61_'P/+B>s $<'?KCoO5‚MIb涱xX 8 x*Xl7 X9΄F\/ɨc1؏J]1aNe_xzmTĨ}RbTgU#|.+JTIE6?Nj6WQTV)|# ]xS~6Hb_?ݧ|/ 믊7`qk/eOk[T hKO+xK⦥ QFa #Lί;/z͎GBm׎k ѺM C'j~$?+x{N]5t/|*𭧇u5ljwg6_5*+|(]kOj/5RGbQվڍq׷Z>xMs[|;Oɧh 3{K|R5_4Q-A[ OABҧyn.5O5o j?skx3/'19a],uhhb'Rk CVJ$Xkb+՛miY:Q'ru159b*jTVU9GSn#9_!i_^{ 0ռ-wx/@`7:K4iv%oge | G_7T>xC{٢߳.Ho#r<08`R~?K|Yeև_5Rq"\cr))7ymڵ[B;B9I)CN[u';h^:earI>xZkogB4B{T+;^(f֬?$W$?k&<{Ꮖ7ڷ_^4މ N_ |?R҆M"#Qlye~-^'_~'ٴ=c⿍AEmioG ?>xS >|)n|EF派 M^|EN.`:^wa4ŽW:EEir!vۆYBY9VxPu*ΥUG,xO88ݮ_|#{û ~Ϗ4>/kE?>0n|"~kO)oSm;3Gj>u&;|C}~;խ5-|->ZEy|3'@ ~ [R |*~hŝqt}:WMӬfԧ[; +g#W:^tRjoTexbptW*<3rЩ: QTK'djժJh1c *\*81:~Z5?x<۲f3|J/ƣ.xCE?[i^.5 otoxe% ^?!b-R+ .xw4!f|Ko-_ <}/? '|DH׾it h6wpF|.ui?7gMOxO? ?^CŏcdžK k>'G?5 hKo{^Zi:}`G@*qC R8\DQTQUAJJXuNU~3ڷN1<ά!JcRCZ`xl<<›~t)Ӧbh4)RRT38洰X˨}^8Z9R*ZU|i|N3W?ßOEZ;֟e_~6,Z 1=*īh< y #~]ᶰa Q?/|ϋ|>t߳f7?o|m_>'ۧ}S~?OAԭcM>ov|Eį?|WkPk߁+_x~}t/mMeBW:$ߴe7<;? uϋ?Ѽ%Pn  {6~5]CWz5[ß:ϋ>?bxc ķmEF:??Wz?=n AtT"xN0\F}^ptkIT -KNGkztߎj 0imֵlWx}ĺ e>$7/|Lxցk_4] _ .|7x)<=gL4ΓJYUK18 '$^?ko@?/]i©}zt/"> m|Ohi?V /C֟i\xXʝQVXHug:nQ `wz. K)ʵikpz8,6G6&S:r՘VJp̥*tjU+R o>z'+/#=o?h^uҵxm@OaB4=-,m[<0h߰>#| qؑuu~]"l6|"vo7Zy|C^,Mgw u߉w>3]]qKO{ Djrvz2=ɗ_Q]3:oxoEk=sgK?@/ ԣ!K'Q}x+EORl pX5 ]J4E:؜6K FJ[7F 0jF49S[s֕iV#|1}M{B6{O~Ȟ_|%~F_x|?BWG3ui=P]hᆷ^k$5_4C]^i^.ρ/G\]+lnew'&Msi{?`YUK18 '$\}rJ*<:F }1-ըkF.UjNN#ay"N7R,. rhʲ!iɋͥy!W ^5*+a/ ^_|Kx#]AD|W@x>'x?<) ÿSK'Wf_7߄ i-t<'2 z/5mk ϋ,|4^׿,|YO𕯆$xĶv7L/O⟁</z|^־éi&m躗ngjm>ǩY_Uݬĭ׏%s|.Ewe N ĺ'ME?٣ϨXE5zeiRw̽9bVoS ~҄Yf;R;IQaJ)NtVq15UxR)f9{0P˽VTž&q؈R< p?P|~ E>,~~Z|GC[Ax;AB!A~x-R?⯉[)twֻRSij5ߎEe^zVXӫM%ؼZRøU4}[,2BI}o>:e iN㟄(âLaxOw uakc2xtC]Xk8|:"g?ƈ[o}Kr| My?X<k:|A ~%dW3x+_ [e߷(z =8%$%p^iptc*pԔ„qZRJISRI&:VaR*gN+Ƃ)?׼ L][ž0/~/v#xsW/>µ#|{_.-?fO~'xSŸ|= Gg']vY /c*x_P0ǖkWǀ%_cڂCK-[變\ZI.j"CbVYe7Z|gtq.ThNXIӕ8TFtc0XZԥ&`srDܣQ*|' cv+xmw37j4?-x⟌|/]zxzx)!h|7uL|a\M$3㯂<*bt sƯ?'5o v|{oxŗЉQ [t4ŏtFد"['b"py/x_ t;oxVoeIV?~l]?!ߵw\^5aM4o]ꮓ]'&~Ik7M7gk5j뭛]?_7Mg'W P~mh!g/ ~:ƑK2BԵ=7ߴ'?ki>% oB5)"Ե:(I2gP5qO4h94k9tg_L[$o~ <]VKⰱ-wQHM-,#䢾-% ?gm򴛊iE&}m/u?L'į;I_o3r-_Wm5OڇYQGź=ƽHS@a5j gԿ|b~#Y-%?hA/1n#j_P[ %̭qw_7/.o' Eao&UYidZZ[ikw>]0b(UAfYN6aK 86Ya{pëIWiܭJcXW:7Z)ƢpMr=WO~_?Tϗ$WǾH3(=G &^ .qel8eU/_og?|? k|/i鷟|?!u{O|L^jW73YmWnFhEO?#KAi&_EtxU\7jJpVyMߚ ɯ+KIU_8t^}p2oE,OU?U1?L4?|'Dg W7 .qel b Yrk? Z?e ?r ş5ǾH3*͗애iK,.`?WvPys\OMK F <+PNxjq˰R F.k6\qe\>J)Vjӝ9?➓+z7򾟬W2??O5d?j|+?=>@O-53 !M_ßCi'G+?=|wa?0W2??O5d?j/oP珯9 ~Q_?L? ?9D? {6 k!%A:+#W+O?*O ~[^"ZgZY_76CXx)ῆ/~*'I}~гK$ n˫x y[H,zG8h-p%Fd%X e_U:Cxzpmoݎ*Is{K:t>kBI!<4oZspdrԿV ǞQ< %ںx'?KkIi41d.kCq)n/^s~(wT)9$6rJ7ޝMQkNME<+&[{/Cۿh-߳7Š r+kO);N azWxBP֯kbw0E%H|7GT𶱫Vy_Zf㟋|iA\kW&m _fMu{kd7/$/>w ?_JӾ!p<?_ߎ/ߵ6+ de|UO٘x%j5|9x[:'4-7⼺^kz"-y>|C߆5OԴOm>[?|w)ǥ~ x>>S\gveΫioiQ\4/59?#j4RS 87.:5db)RNEKNISHV tVr崥B2MNRS?~о4~>#-7់>*|!4K/|By3??g]k >7x;?i/5>0s|C㇈Ik7xC=1cS'|}O➉<7V75i~7|Sk K{g?)ѯ|]]8xNdha槟eGNNI^'9b0JTb1v#t\6>Ε:q \aN1N:G T#:7Oْ/MI/wWĸ|!Xm[^1Z>k*xWIg_w*%OS<«Hٗ^qڗY;}{m-PŪ->;+] w,vM1<9_ K{g?)ѯ|]\YSFTԍ8cnPR0btX)b\ᄄ',_>61ҏF5cq)Uj,5Խ7 E4x7V R*U kZxSx|O%헂_cKK_O%_mtV<>=h |#Y'n׆!W/ ^ҿYxsDW:t/iCZ Muf⎄@jK4/59?#kҾ1BO 8xO'ԭ?hHou7@4Of2H-Wh4v[RwRYVxӥ^"#*25 Ӕa1fҌhb(Qa1Uᇌ#\C*TBY"JaY=k׉5}??گW~ Ei| ?pc xK/<_"ү[b*xKYtX|Mg-[=Osķ^&J B#_ڼ}2xOcOO۳Ɵ4_C?|0J%φ;׼7xwþּ'`<i_~GR^6h_ks<FiA`j.oT!nWN3)ѫ^V'ZLEZpTXVO.4$$V*AX:a#N+V(xFx_Ú~$/[|re?ƞ4[m?OIkڷ¯~ZxK +5%e)_׾.x荣?эфV:uRSPtԫ:tq?iN0 Ez\5T3K F1 tㄞ0P Bsi[O>?<5:'G=~_NRj߀/P i^x&O:玼]9[|1{:NxOa>"OK⿁~'u UGbxGÚC5n4ψ61k_vGR^6h_ks<FE\[c*ҥ:NUc(E: 2>j˩~y+W%VWgiŸ֨YE7B81AuWJ.V_'9|>O65߁;~/{M{ cxWfF|v5x=Eth <[-M&Ht ?>%kO > w|c?Vz_? 4ĚG5o?>;Oc4zm6^;{M#B?ឡ7Y⿷mFO>So?e w7g|h$~ xg43q#6^ ~j=^~ |}/Oo wGdxោ|_g'T._?w<5?~,0~о-Xx3 KoRо=k/,7/Z wō#SOk+Z<]qiGcF= :qxZ\3f{sL9ĺvOBI!mE:垟uooK7>?)ѯ|]^~"ְՓj>*mFK pЩN1!s\Xb*幎?J`nx<EEUb+BK2bXڮiю _ʂSP__Vc3ZΧͣ~g~!1_>~.K>"/%Wc:M)~*|lfGQ "+k\?h8__+]O_u_h 7 >Y[[-?jo%'qk?o{X}}?K)ѯ|]G4/59?#kxΕ$،ʽJn2(ig9^wVך)NUB*ΕJ%3.Uj} *8-"cMR&ORW18l9%_o~.x1i 2@?|#W|1~LJ~?ٟIu'~x|ҵ [\?.នBg?ۇz炾ࡾ_]kC~kLz-?–=uO~"}RA㛛i.ĿoGR^6h_ks<FgqUo%,U,} Ԍ:?0s9՝jQca_-B8 N8(gNnFf]/RЕJ4KKYЫ)IԩN^?|~ E>,~~Z|GC[Ax;A5Ze^bj}jWq4(ՅLF'+J5S*<; -\Kju(tXuKoGOg/^<3aO|-o. ~~%4ҵ?uN|[^<9K*PY׊3i:g? ~v4ygߵ}֛s#؃'0i$e~)o8kk>%E查"3]gJ>}{DE4(dtZ%^%oK%/i?_&Σs/|qq`%1cO;-k`mωKO jՎ,~O ?+}kC>2|V_ C_n{_>x ~S|<{u?G^-E$q˟5TDM_wTDPQhP K{guJr< ҜU&FkpR(u)VUO`px^^Jr R&]_/EA(Xʭ,|G[1SR\†' zz+۪i<~/d/t\%$)Tq7/mRt }E|y K{g?)ѯ|]Yx?<(7?dR:~gê?imM0_᩿hZ})K/C/?%[OοD,N>:i:. O OcLyUJtkM5-BPZY.@ѣʋIJM)TP*q) Վ.mn,Rҍ9.i꒒VTz뿖_c+ட;/Rj:O/<9xO E|q9+'χ6RT'dGk-;MӴ[> J?s ) ?~c[q*rI7ɝN vөqk^}&m.|%dڋve~#~<E~ɿ,h^%u[/m^'𬺤~[źDmx;Ym>5:ܵ]_g6_fm?ߊ_N_ K i.47w~=Þ7ցWmo(%Lj|9^iVt[+OS'ׯŏQ_Q_>Kolѓ<[g^8WxV=x|ޏwcm{PtYZ]goQJa-!J _`0T=zУV9p&GFNs&F**琓j1pr.JYSt*yů'W;yWM㨷4?xNFS56|>l_5։9u *Vm6Lo$~Vas/%tZxCO[5g}cSut? >j:h:YO!㉼!uF6o֟?g/_-nZOï:x-KL_aoM> %oo0>McG/n<5ƳVBЬ5-1<7ؾg:<7OL5sǾ%G4b0$B,}LJRr}_:)ciԭN?AuheUeN\,b8T]*.Ӭxײ9bХRt]H Wm|aۿ |_\<-o໯Wuͯ&v V u߇Jo%h>OOw?jIeysZvP-kΓ;k.E5 _1~j_4'm+w>ͧtnjix15M{cG!7>,y#_[M-uoxEI|gq_^/ "ta/]KWoo^xOSE'(;Sn^TOᵷ_&Ե HMyx?I^{g|)/߄%z/߅!6G#wkzÿ '߇pjgIN+-ЧN3IOOF9x<(OZKB m`+Ÿ2US w-C/11>@ax\_]#tox _ S[6hvj7]_EBIMC|kԴOL4km#";3-Cxso-OH/S-~_[CJo4x_mz6X:.+ !VhO_~)mL|'w |>kƟw /;{>q.گi/:~ڦ[?sRjQ)J|ڜУy&j5)c)GN*U%T|_- B*,2uuTh:6P#S*1gV4Gׅ-F"N ZSo'-o)ς7Q9x_yO^5}X\|3ďį Ֆz?#\?_#ѡ|Mm{IOꚕgxŸ|χ< :hO0?f_cற""j_‹ _sH֚ޫφz.x]O x]eMb4uMqWNR$(JjoR!ퟰ M)9N!^J2GR԰ JO`]*j=b)RbOo'-o)ςs7ZG^>]eC+׼[? s^G4 ?^9i:w/kcķ^2|5mY{ Jx) 韵/~+j:'o<}j_4-C|gUvx?ĺ}s]'WUeҵx=JK(ƽJΆ'^ibN>YRɇ7:*JJiƽhKVuXӧU5!B3N&R瘌JQl.[RSU* o'-o)ς~k~0'I<Myǎ?f k+cK__xRtkY5vQƤ% wT?b6,&̰_S6{tg(*rG8BSz*ۍU/6S2rXL4'*Ct$Wz& ?|񍽆jpk?k psZO?GG6ip$,mn38kiO|?w8 gG$Ϥ|mo~$x7^Kj+o]=5㟂ˏY|; _ ͭXY˧EGQڻ>O~+~/kߵ ?4Eៃ6gx6.{_ ~&i5o߉Z_#j^4<>5%P=bs8e+QIV7FN xZ5汒pji%R5)Q*.jvGVUuNiapbiF'8=O&wSGmmc^ ]xC:jT6+g֚R;T"kWT4EԼA^6/ğ7 /}sưx[EO|qm+>#|Eh:Z^5}O^%5^@+}X|I|Pw?_3>'o!k< aznusN8x*3,mu9Ά;/H֪”i0s7G9 D [J௖g~k_ ߳ g⾧ωڧ7⹾xVׇx6ž~$zWgF嬚%wr~|o߃7< ?_H?g}n; aJ?U{-tIhkO>tk]7 >G:5ӧ5I0zt)1NjW0aU}N} PxKW ԍ.$ƢM"yqiUSS?Qfp~ҟ+|6r4ÍF?|5s|`+m @q~1xs0ǿ>O?W=/5<'^|IדXtnG?k_ٞmcox2gό>3w%kx&|Oe xpsX?r?x.o QlM(t0\jtG_00ʢ TK9o]SKuV lb碽֨Bqt'Nn:IRKέ(ѝn4]|5tQ3W B(o<7ྷ<]x7/ږOQGF/i6Z|'oKk_7MRϬ?F'Z$*g_O_|2~ 9o|)?o_Ͼ'!U|ekg&~!j|o o:|?Gg}C ֺM yk@AGq!+Lo^2׍kĄ|7CxZMM+][: BK%VZMN! ݭObj:b#N1K^'Ԅ*)8<hЕx1tCSO/h+ b Ό1k?`c8ָu_U&a_Sм9U𞫪h嵿/Xty#w٨>/ٿCg4'GM|-~-35Gi+XJ|O+׋>&zeHyKiԫ^j*15! ׌bpTBcⱘc =)f4ps5=8(S)gu'ybΨ׍zKO ^OO$rKd4)oMc ŝ%~1? _RI%q]%Z}ŷ#?O-sqc3¯ ' KTϋӤu|OHc 萶xտaٵٴO.WOji?X7LcAßVSY~h [oº8])o~_x>4|;xBEU!^t*{΢4iXqTՕL7}8tkU)JTN/7 'V]kZIR~t *'F,L?.UaU#jOu?g.ZVqq7BY!DΫ6zi>ut K_?WʖӾnJxR VK盧90]JVT^7:F50,Qؿo'-o)ς_L?$߄";M?ZŇ~R 7xxŸxS^ /ه[R[ 7U_Ok_ jkx4K_)S߳'gğXL[7(xᦹeKisxO|y i\>b5]X<_ގ+,V%Sjf Fs -:!*Pj-R\trTc*IөVBBI#J5FjƇ:PjT?Kk^; wOC?j[__j>Ǐ,^UԼ xzc 1Vwvo9 D [JU/:f=<@|O|;o?׼/@]>҇Ÿ:Ӽ_x\=/x^,1;^'w[;x{$u7~2Mz/ 2֙X>?dFA|`r+㔿~%o4$?j/ڏS%hE]E|YNm&7>1e> k/ jgxVž5~';7-_|Z|6Rt_9_^lX>(;7>xZ+YᯊkZ xǞЂ<?gWGRwQS8ЂrKRT\aRs, "pT+ʔ`i:WzXҶ !F1iPP U#GN ZSo'-o)ς<5a<;ixÿ5DIo3^%ѼSNYР./Z ?6e-_jnul_lM7>-K_~ju R>_IO|>]ca|;\Sm[*wܨ/$)KFnWJ5êQuqo ֔K/qR"Tc5UG4eVqTR^4',jUhʴ#\+jT~kzx;]WoԴ -Co㗌4 >\🋾&k.}m,֚-TѵK)l.f߳Woio~~ ggZM'MZB+o b__ | |6pww? _A#;K?k|?}ۺϢ鮟ekk._Ki>%~π49haO,)E!j*=Gᾏ 3X!Ox:/~*3$RG(=q +¿_;f_iS[>x__4vyxk1]keڍ9Gu+Ga3(l _?G/'˻_> |@ot>:kxWM*|{~ nmgx+Wm:F~)j|/xWzI?|:o xMA9Io 5ݞKyKTQXU޶Ћ(bs^8)ap;_iK*aqG`!ZPX*᩸QuyOŬ3o||}w|mfmSEg'mb|uszc떚7o4K-FÚwÙ?@?ߴ> >)|-|K#m|=i|/W ??־=xʾ)𷉴߇1ilm ~Щ<|Nj4hךFwt{2^;.sYо*j߷~"|@z;~+5o Xx\N y%׊5/ IokvTQV8U:nu}eeӕ*sxL^x^4mt:mNf3N'X ץB8ZY}uFq9M.x+kW[|O 0^ 92X'}-6mϗZ;t?<_5hh*Cmo˹X0 3ȯUxZտhgOhoeBo?i?|( GeQ6N?=^<5?%o=YF-NuZ*9SĨe2UY}|×^ebk۟"5 R4S ou$SQϞ2 u=IXOߵoEֽXv2ɦsvæA{[ϭkRڦ;K4KS38kiO|^$~IxcBl|y'f+GxQy?ٓ0yoxg 7H4}jI ?8kObkݼ ||Qw㟊|K?kX5ͥՇ~ҟi.vg^ wF!EUR|Qu>1T"^ӗ,+RWRSD~߳f? Ծ# yG)|3iZCfaZ\ŧ+Y=_mb?{_3[o(38kiO|P[( ?gO_ <=νj2,:(%`q}}u;e:e歬jw6^e{Z?w_մ-+_O7kek|O~rh;-W I##|Uhpm9%?4[ox_.|3SiOXW|7x#K:}gMzcvkrAiMB{yzquA^5[^07e9s^X?bݣ|)#X4 zT3Go? _xf^6Sx?:_o{hͶ/?  5WIΉᯅ ~!H:ֶ :4NJ4h)ϋCkw~i->]O<-hZok C:.g7T|Q5oxX>$xS j>Ҽ?(?hOjgR8l]Z0ZTšos#y֌SOcqF'[ ig6qu&3jZ8~XsЍ*qEB9>U6`? &xേ#'u[!x'ĺ& i=Ɖ?!g/WNtcx^Z^Xܼo|W_HomgW+:>xo]w5K| _ h?gAKš֏xO=ͩS]XXM ,#5-t~qqxֿ*T3hЩhz*|E:%x{?&u*WZViՌmq-JirժIy/|~!)](: ޮ4ma|Dz6AWh?VxG>+~M~-W44K-GWo5]xuѼx/U?<?J(g:Z]+sofOw?aV|<x$_ +ֿĞ'E!j:'|]|gUxx4 ~'U\qhvM"YcѣꚒ{%Rx\%fA挥m)-q?ٯ8%'qFRqm4U?<?JOxCc:(u=aL\Mklowh/"wF+tU> ExΊ(h:ў0[ _/oᯃHU?<?J(u=aL7&6]|+ ?*߇m~?4~Ѽ|@Ċ'AQu=aLq74j;_x$_+d6.a UB OF'/X6!'6,!\OՕ#g:sFkN<2\aⲔTϖ_n9Vk2^ľ&{N I|8B\_꽥df]oÿ7^3"wF+tQSu?aL^69_,;"wFHןJfO_⿄PՓ~,!χUx5|Qjj]\mz-NH,)sm/29$$* SegR2IM(GE>ӡӢ_{(>;]XТ{b_bD?*"~>TDPQUc0P ɟ*۝j*Y_/z"QRQI(/f\ԩ:k+N/g97.H7|i:[?dc ]>5|.O5xn! [@?b+R+{{#D#,>g߅~< Ao6eU i-\ꚁ|=؛N,R/MF}#Rg:EK{NOin0Ys5s*r^3*\ME>6ZWFSQ^єVm$Ivgÿ7EΓ"yFHQE3=n \O[g?W_͇EY/34_ÿ7EΊ)7O/Ol?^69_,/EY~4"yFHQE%h:AV[KJ~73l;/RbU> ExΗ"x> ~?_袩}ƞza?q8̯j:3W+mWhmCo~`Sѵ m[Gb08ﴭVSnEŎim{k$W0E*^>Ѽx/QB3-o-\Ѽx/U?<?J(h:ў0WofOwaV|<x$_ (>Ѽx/QU?K+w\6%ofOw^_"yFHW/O9?ğ j$>f V|io|1[q 0jZ1]EΊ%J*%f9.2s#Z./Uŭ.~ ٧>GFQx9(9gFIM5z9rY 3e?Mf\>7Wox.đAoek/@jkonc=ҷx17__k?|SH]|$Y 6Z| ?V럲ubQYj4)ME-/5VvM)JW>+I~!6~V/x7*'ݗ Mm{EY~4"yFHQE/{%a?'}?6:̯/g7EҾtK?? $xY[5cxuUӬ=u/xukӭ-41uw($T?7͵'Fd[+s$ )Y^ֿYNJx&)M(,ҔyK,ҒRI)$J:+4 ¾M oK;xmhEeh.ŶvpiaigmP[Q Ǐ"iEr5})N~dӜ)K|W);R );ۻm1^5cƹbRQʸ5$I%I'JmU?<?J?&={E|Ck1]>j*Դ&Au6dW~cwu=ag[EOKG^d[8" \ 5bx5oEs |V<o?"gY:*E~ ί.k-kNXjz^eѼx/U?<?J(}ƞza?Yl;'Rl?*χo?ċAg7EҊ(_Fo^Xx>lKOͳ+KyuOuO{5xSM4]i,.iEksuzՄw/~guLזIbUM%_M+-uЭ>*|Fh njcfډ?~5in1Vo٢(O <6ގq.kpXlx6` ļMaF*xj4kOHʣ9jc3gq KF4eduJUjTwPRuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/TypeSystemViewer.jpg0000644000175000017500000032730011665471334031005 0ustar drazzibdrazzibJFIFCC" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?M1|̿ I_| k%|AmG 5FOxٵGU5gV߇4 gя/0<ɼFUI`JS Ҵ[Y&eZ4k-COm;"cPѰI捂`%khM[+Gt'Pk-L]fúMWxƞ<'uo[G톽i?J> !03gnC!V/\fiU*>1>3ĿH#s_կ m`{Fe/x>h4+öww2^=ơ6{am5]Jcvx%?7 ]uBH˩Z\ܵk;q{i%ak+_Ep/Zʥz0m>yy,Gs,VKK7ZXӫaaK0eVδVx[<&Zxf5 WB* < 晖;`sfqu0aar pQ9'V4!s%5. ,]F% ѿ|oo\k0t)X<16jy͙; iEy`eg{ 7Uwֻh_MƱ ok65gH fIG2άjy 8aթbZu)XZ,x\f EHak1)cp}R X)¹M|/&e^XUL:Gbp)QZ+^sJ'3]Y _K>M.G/-ﮬmⳳXK۶rڋ4h$!Y!2t_72 k c]=Vڷs%SMyj,i ķ)EJ"rywmnyø̿gͰңW.X JZX*:Xj{Ak >&J4F1?vxkg"4o7_j>>߆blGut|9xEW$*;CsCj.\BfGXOߴ/nuk,Zi2*:ޏ72gE4eu&[дXu/N+>my7;8ΰ~: y' ¾]Uz~&ab+SV 1Np>qFgB/.fX.<a*54^N1neZ?vxkg"4o7_4lgQw^n|_ V~Kg<5Dw7g|.#FuF?fWoOo俦}/ _K>QJ1 `ǯ4L5>'ٸ>H__º_K}5 K?xow!O5_2c?ٸOOOcAXޟ_u}Ϧxow!O5G/ .Y>ƫ_,tyc7 @?ƨ% ??|֏,tf?=?>KQcz]/yO>% ??|7Dg'|֏'ǧc1oOO:_|7Dg'|,DU/?Z<X_,}F?1u]>k|,DTCjeOG?Z?p ޟ?.]}W̾XhOGnc~y{V7ts^>]}Q K?Xh,z/z}> _{}5 K?xow!O5_2c?ٸOOOcAXޟ_u}ϦO wpy>08q<{}Z)HI& ??w{Ÿ!.hC&7Wd OOgOy#]gm#)H'& ??w{Ÿ!.hC&7Wd OOgOy#]gm#)H'& ??w{Ÿ!.hC&7Wd OOgOy#]gm#6FO1eԫ;游!Ieu?/?o֟4Xb偏r9ӜgW29]C,(s5s%]0u1j5UPsPR}^KK0㱴;IkEPpSRQ3se/:8ί?LӨ3h0x3zl$1⿍7VL}kZ]arZG$K/P &_ڋ0IЀ` =3־_ŻOږKi:<wpfw1$־$=rY%+o!B~țsA#s_xNjScgj4r)EK"4bm-{_D~͙m9t#?1e8gRB쯥NC_+^_ď¼OgÏ^/e[5<ojP\7ouKo>}V[߄woh؆tw3B39cI# =CPWe,smſH'KgHI' [[c_L/|AYAg%iM?U?Χq4g¯WVַ=In,mlS_WLN6.9G q'f gÔWyr5s ?'>bFn%hIkv"o|q|OY0ISg9' 'n/T ӣO,6exi*SGxIB;;ֿj4#ڏTхׇ9_<|M[]Nk}2I}yV }x?a~/~W_eCSe<"Xʅ,* Ʈie񴡆֩EaΪTxkR}s Õ_78C#Zdžu+5~-?t wN>Pu}x{jJ>;ipXM<3<9-4$ŝؕqxY0_fxǁrW"̜ryNeTS^ԩbb*U*˒r9|Gm{U?u g]kZ|z}3dAgedW YI¦{H|c;i?iZiWeIeN9%ޙ-x$𯝢K Zxy{JUo[3P`7 _dᗂ[Kg ^D4u-|o{$C->?G>o=q)|Of\I/3 -χqؘF97pxN#V,ZTkjEцFk-!x9oar 8r3 嘜~*PK'd:VtSj:zO?>6?~ڍ7+.B0~xS|#=[Pzs!6z6?MS?|KuiZo~ Tds2.ۗAG4rv^y=tw ᧅ9߅O~"q~gXn)px8JwMK0RxRb#FxgboorN>5yD<Sʫ|ʎ'b+Sꑩ_Riэ:3N\"7n B|X_"IKSJvXjK4ŐƄ W=W˧xÍ#G>iͿ_e;KO.oNӤkؖ5f85nb{i|Maj,`~=H[v|dK}Algy.4 iqJ-; }Y^PY뚕ٺ5T-1m51$ ygx-s/x<* |&p%M/ſt=F񅝅oBnW𶹧^izlWPiz1@u/__ſXi&y/Tŷ_;9ij}ᝯyN{͝h8#>'t?kA QOĺc" }= ܝ|Ÿ|MwEMyxXY/4Z?9z"eVsn#/, KP?NFxPѵ]{'u/4Mf-V i ]if(ZKFw$\K%,O9 Ff|X,Oԯ*+pc‡\%c&e- IJE4rN8N.g}lJq+:ˇ\_cj֞[Ey thO ai?<|EgegsjZ1x,v-Dk1yl;_g|Co_^=[o+]2Fmm|?]\MisZ%T./`֡ѿs ~(>Xς(dD8*_H.9Xς V]8;\wxwb)|-[L`S.yq5c9P:|?V"y8L *x _ 1t6# S+ѬQ8TWςu[Cc~~O7S>(QKSm \Zt[[]J{Ү/<%k[i|#i|鮵;9-#E:Xk1Jk\ڀw*M+Q|ѡٯyy]X3,na}"x61_K|1קtq0W̌l$C m]G,IP+&*<%<oRx,sg:ҧ,XZRӕz1~xL'oX/IH-[YC-ᕍ4ӡ%F6.85?W:B\ŕγskj*.4¶}a[-vǨi7o|ѡٯ+W^SC豗g?WAp.e[%Q0,_{-0y~aƏ7]/VoG?vQV42ޣaA?/=?a>z|&5 yǦs haO˯EfY;kaA?/=?V42ޣ&Gn^pǗLzi>Ə7]/VoG?vQV42ޣaA?/=?a>z|&5 yǦs haO˯EfY;kaA?/=?V42ޣ&Gn^pǗLzi>Ə7]/VoG?vQV42ޣaA?/=?a>z|&5 yǦs haO˯EfY;kaA?/=?V42ޣ&Gn^pǗLzi>Ə7]/VoG?vQV42ޣaA?/=?a>z|&5 yǦs haO˯EfY;kaA?/=?V42ޣ&Gn^pǗLzi>Ə7]/>v'<Ó0rjFrߕL?G+?d'e?N= 3f>?=qB Kዏ4?Y|0]Wz=mOG#S9?~ÞggG9 F|? ?f{ay%5  |h5&?/9mOG#S9?~ÞggG9 F|? ?f{}xKkS? %OWd#S9?M<+5yџHٟ+7ĀQ ~/Ox_/Lƍ?__Ocrӟ/M<+457O9 F|? ?f{ÞggGL77?~3 _4}?IN|?+[57O_?+7ĀQyџHٟ0G<r/ |h5&?/9mOG#S9?~ÞggG9 F|? ?f{}xKkS? %OWd#S9?}YzX?nbY C[׼ogwj~7\k uke]3u]gd{K/x  Եo#/jSվ5NDڌ~?^轺2]4敭tM JcM?JWdS7p{4"xeq/IQp|i<. *,4nFxf)^YaBpRϸ_3Re>XsJ:iѭQ嚣(ԩ1)E՟z>x_CѼO} ,0,~޽0KOi}o*ů'd:|Ҵ-CJe.|K{MJMKyYRHXmV$?` |_~3\I'MB'A|Cw[/ x^-έ;IzmHo/oLE٪%.# J]H FkU@YUZ0^)xy Rf9\;⧅_.#8X,qhG6MXj_q1xУc^MeU*2O1N$n X?\.Mhy&# k:pKW?u?iOG'/ߴ y~$\^@? X^y+$wRGeeggu5oQpLF_p֢!G8k&ox?E_ٲU!g|d`r0 f9NDV?[L񅖹c :wza%~[s|96IB27D~9O|FooNo^ xQ/oqotTs^S. WT0Ibq8VN%i*V?5o cL߀x6ȸCx'45œM T\Ni]T9FluZ~ O Sr1R_> ӿ?g|(Ztc{\+l/UeH,t[[GGm߃mKxVt mx-1?â[᫙ _Rծ-Km{oGJb~؟Qr Zޙt$g_<ױh^|\5( ॓A)WxP6I3ϠYQx?_ axѓ5Bp3δ0偩x8L>ߧ#>}+RkW#9g6ac)N8?z<5l_O O#R<cT]9/>$ip0 V'|2@`7mbWwNnB/½?ឯOִ$N𵯅-<7Qjzǀk^>'I,O5Z?m,U$]K@υ^>t(F&*UtyT#?VU~7.S˖sةf->qC oͿ÷|)#\xR)5o>/ňGO p_G{ '㍝~9ďxWV<+~OW?~Ͷl&5 j)wNմ^I3h3{ s}hPx4^: m&<)m~3P_[x]ч&"/&Ə/ xg.[~z{ @VSi~,|#exnZ5~ }]>|fs=Ha,4WQrʛ8PyV#MJӭrIҜ\iqub1~"ci]vw$ix_~x<Z?|u]J ] }>;Btw7?~=~|(|3̿ 8|k Nj>+x&㿄|u|YxU֫xYesohVp~n?1^4*U!VSG:n8M*J\Q^ N"*jp~x: TR7MQ V4ISԯFrbJTUф1gVk? ? 5=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€?;^|;r"A]7 <:^907ܢtitY7^>$7g_[2w 7㍗Ÿ |@|;/ğ<5xw t5roDuOJvM{j&_Yj7^\1o )c&ogkk8ew)mqxPi[KK kkʈn?~ طBW]|7Uߏkw <~^'u%VYyK>. bճw^YB4'8JaIɻ:Ҳ?(᣼iFcgQ^yۯÞx</%iEM%6>52j6+SGOjF4F׸/J?oz^%⦳ksLί#᷃|qsM=OЯOZEl,M>[x5kT[{"P)U{JW~JU:QFTJ2k{)J*U)Q[*>*W9hRj'QItAV$*sg_VŵuͿk☼ "VY "-L⽋IR?m;+_ٯ|CKyJ|W$lQo<`|C?;X/_quu'bk} jX< .,EL?₋aGh4>oZ?@~Ox_JmyV+gH|Ie:%~%ҽ>N[ %/gfNQUy){F[{nD8{%&8?kW?)XXn]yϵdoz'ŢxQƏox.O OX꺏>k/|1ec :+yq[ˣ=ԛUntlo%݅k=z?3zƚ;| $[x%eߏl"=-|ise&MK0k}Nmm/o -i-Xx]cEmu%xBM>%^-hid6k*W\G uԩsXҲjԟu?1KxTJ}߽%N2MZ*T! NiqyS8rTpU)!׃^2>-o|:~/Ӯ:]tվ(钀R֖ΐڏZ_ XΧ2oοxSGj[:&k^|ɫ]Tll4_Kz/vX2hiܶx!Uo?:>*%uq.w:]MajU79|0> 5~_x?NxK_JyV H|7ek:/"%Ҳ>w?a;ߎ:Ut s_M˻am_gk}X۽?g.&>oZ?@~Ox_JmyV+gH|Ie:%~%ҽ>ԩ8{\#un^jpRNWZR԰i1DWNLS+tS;KKX»9Fέ(ckQZz?G֯?g>G__[V4֫?5%^Kx5娾Bvku]3FѼGxvRO޳avIO{M]lmR;NAm짞m. Ngt/_S]BGIm4`WMR=Vo?ca.ǨIgMcT[*bn7??cVY|@kE:s_z·ͥ?M"]NK69T\/-%<#p(ן,j8UcJ ^P_a8JpUq(`bJrb|TSW`eRsou'V4W; O3? nʊ?᣼iFcgQ_4Ro?^A_Bhјku?TQ O3? nʊkOSb?+(S O3? nʊ?᣼iFcgQ_4Qp {,G ~^~O?᣼iFcgQG4w?l5*+F=?OeOGQB-o[l EѬ/5]_W~]i^]Zޙ 2^^]KRM43 41џڟM{Uk T/Ҭ4Z|m}࿁7`ޥ7[WF?? dԴO[R%=Oh9' US{z#M^wDJ'QΑ%a '$s}Jx;2FU5v7$TюnÞ׼CmhkjiVjZ^+H)k&}5躗t"W|+^Iu=2I5 S̿?'~ߏ/o|3?LJ{Q?7^|xSx &MVNnF5MgBԼIߎ(>Q5Og-?|y7'pJ /r0II=wI_V^?i_ #(|[O ^=RUtPZ+{lŅŕjohјku?TW]{]K~xCQxƟy9fO~!l,j|'%Xڣ6PVrg:VTaJjTS1KgʥZr4Px5%ӌ)SSuթRFujscMJeN}41;Ɵf?O0b/e?.j^!vxQ{^ǺguN/=S,(^]|]u}-z @u 6k5*mg|3ZΑuXxGKC@w5]n9~?cZSTzi[.OouŸ֧K (½j5iRScJ)u.ENK<7iuD_k 4Htpu8m<3o?;Ixcğ-,{o_K?Í-3ċOxWèj^'w]?Z1 *n86V *9])aܰSb )VRxXTok&[S&tmIc 9 O3? nʊ?᣼iFcgQ_4T{\7z_WP#;Ɵf?OGx[Bk"J_5>ֵbZy3=c[xoKE?Lev*g:p&I5JI99֫BbZ8)9Dt 3ķTV)R=zw)PTQF*Iohјku?TQ O3? nʊtڛ:o__|.!VWG~>WkV_4 a6ZnV>^nsW$w|Io%+= [?ˬ~> |(ѓĶzƿeh4go 8-3,"Z\WBTq ۛˠ*#R53jr:rJtWttΎ*# ]RҧokInNtZsa2zp.7A)FN5p#*ySZƥox.ټ18QRj|Is<$9hc\jE y/xž)׎/x3o]V [ qa;–a9֫:qoqiM1#$ONt1tRRp/cJN-f52uʡ99Lօln%FUEVGx[hјku?TWkt_x? xZдxC57u(|9? {XIY|Ww iqCľ"ӾUp򦪬pMKҤ#NrWj$a0RR x? 5D*|& ?4 +F4O |o tO=BPԯ}dYi𙧞_/|5o |_xÿ_9KM?o>h4 _uO{MZMoß>![xB~-F?Û7\G bA|-uҟumO7Ú滦x[d7z,>Ͼk_4zׁ/>i<#K]|?c?|eоm@S.o<'_Mb.IW%Ia0,D9]*)hԯFg<:]SN!Gx[hјku?TW'oF_ZKo'o|:w᷏fxH>&x{0-ᖫox*[Ohmbs:RR(a=MN"uG o'O Wѧ,E(U*>ۛj_5쪹/g=}FxJҖ5F._5 O3? nʊ?᣼iFcgQ]ϋ%~~5[|B|]Y׎5s}g'<7/ Z )x[3OԵLx ~/EvaR | w355"Co~*^1j_ĺyxkV jzV)9u}[ۥnnBV^q]oFoW/*+>4҂)|oN),Y'gOS|Wi#40]5ukkB{k=ͺxo0Z4-6na2([{Y|eYⷒ9 eO?j_Oǟ 5/GV??O|r]g>jvq:p>gǣkV辳R^ST,#?ǩZ_*k>4 >x74ڭ4 .uX\巃VE%?Ԫ~ʝ:W ܎:a VԪS*U9pNn#V <3Aߵ˪V`|.ZqJ7]eE8UQ?uO^,q`?'_(7> kO%·Ph_u#Zwt?xHueh~x-#IuhmomN~'&^~_g `խk_4{Yۍ ^ѴOgOW ?.)+1`_+x<`0; / Kӭ?'kCA?tX?k孇u ġ5bo x)'Yj,t?x{2agmǺFi}j?xT |Umw\j~2߶hj+Cm???i~=2|@͗6:}/L=^'}:ŵ6>վ|+oavEo[/ԗ O4{,CnyrN+a8=J)q8n/ (:[ K*rҕ7,} >/GOR1R?8* q)Q9j7lGֱ8/7Vѫ7ǟx/~L>_>A+_ -KSᯆI_~[_ږ;>4]g8ׄzι{W⧉/"/?:?|I࿎'l$i,~ 5|$v[x'L׼3\φuOk6i_[x7wx_| \*o/xc~$ޙx_4MS.|U׾$Q\t˝MxixwQOxKW6][UO xwS-/Yϋu@t2=Uеiu]#R4>O”Z5ꪔN+UvhQXlEa'jsbaTjQӇ"% ZžCɿb&+.W(~QNIC_ ߴ&j(l-+σ>ŧ~˿>{xR;ZsGZyjVvxC,&~-M&~Uo/>-'Ku|h|f>#>,]qWY_K`jj"^5wzO@?NK~8˨O? jGGz,?%5 YO>%B?7ψ~"j>υ<-W YZwĭ}o}iHҙ4_wO?k|A}?ߴn>14"O<xG-|miu VlOtK-2(| A|KMÏþ U/^XZ o >&exc G-|]fҭ5{~ïCM1k#^#׵M\h''? ODž4} ÿhqi ޝyo[tR0RU:oհM⧙eT48,u8]\ԝ\=?y>TUpR9& )9VXޝle*R)K(,(((ڟM{Uk~l|EYIxKMkT}7]_N柳մzu6{ycؿh _xȣo4?6Z}(ԯNECcF([e')OҚI%]YWxNSr)U:éʔT+еm-In|_ l1ɬj?f߲&⿆PF_%-m'1}QL;Ko6x ?Q^}#fynkZn:o#xoj;<a%"~ k|E6j7湩e<='6 7/(7[F>zz+xHh6 ZZ]&OjO:| kW> 񭏏'c5|'%0–tҬNj7|5ߍ~ ?ß-a|0Լ#xƞ _Α[>T׆Wx=CV /t_IeL4I%NWO1˱ӨʳG,1xrjNipON:,F Z\#ST״FTjԔjSJ^oٛ lnÿ|<׿fIn^k ^<E?* gƗ-1~$xRoÑg-W>!fW¿{N.`>'s:Mg /5MwPl{m?u-!g<VOg㾧㯅?9|~|=?kAHj~15/Zό x3[S%_6úf ? Z|9ӿic[xOnoi^,sTph*_/ɮ.Z|4sG"*q^*2hztj aUh´qXVSԕZT8LLѭKR<6_Rί)9O OOM'~0x_Һs| ۫ey< Zw HYjUcvJW0)uByWx|cUڋ_~-$|>-[NjVBj#,>`ԥ ,p|ʰ2K u/MTUxZЩO>YS=|v"7΃naN?~&hOzUφ._g'Iw῀_LdY>^ԕAϧjwIorZN[ ~ ÿ'xc?ו<Rͺů 46>~g%_mxwRswK^(#bgW's = OvZxkunOZ_$5xJ}ŞeXd/uMs^ԯ½6FZR:rԋ? .]x4'$+EYB=IBMbJ<Δ,|\.*nJ9fiĵ8KJ}./ПSG./ПS\/G⇋cK7>.|Zv IS'>%>?k1<=}k9mo>-x0_z~&VVW)3Vk|[tOڇĞ:}4[x0i1|:xL¿P_n/jYUO 9P'B<(JcR<%9FyR RNg1 g[Ngfm-_4XXxZyyxF>)BO%|g YZ׋h:7 e[O 5 W}Io$m+J.~[Zk?(=?i2n):=C/EDSk'+OU- ]VU4 Ժ\hNiBjtS)Np:jvOe؉`ƃ:u! _R*JÄ~zz80Ti㎡I/f+ ϊdO?>xswO?z΃3|sf߈;<_cN[(&wj |}qZ[Դ 溿_^x?mw~_e?x~vN|Zz_|c@w_xWL'm:][Gq Sp5C, 08$sSQ ӡRTΦUTAoG¥?aBqVU%YoktcK/WQ8)_4aRWWe|MҩWJpIa: y_^3~a oi5_11|QoKKzK_4[=Gf'.MWTl7J5n Ā˦'t%!-Mz./ПSR?\|o_?x~ښoϷjg/'>-n6k[_4ۿڿ/ynǑxZO{ a+xh^.3+ፌyvx4[#^mkZw9:|;oirUdBER/+XД(KF.Uj8uiaSTLmz4qKb3zXhG#^?~2x_i4}#F'/A㗍Ï l1|Jޑ?u?V m.fODZW' ΫsD^O7_;ie~ ;>%AO𿃿hkx|K#uh]CPANhڧԖ Jvbz،ڞ>T(֝sITQT-jU*Fx\|F_ yMx^W? &x_@M.!Ҽ%xS?/[j% <;|[gNjoZ_g:& "{ OP{i_Xγ¯_XT|G+{'D?͎m'Ht>&ohY zƘ<#qxWτA?xti?wt[_'oYgu33GV—#ؿ_ )g}'w7PŪr9yİւR̟9Ŀ{eߴ^4>. x]uIh~ X3ռ1zoo |Ki}Kſ"xg⟏;&c_'w,|g.Bh.!//i/$^־?MNxA⇵%j,U5s{3ǍS;_w+m&/f~uiE/мed 9OL<-A~.sxSO!o?֖?d/OY>мaLҼR2x&O?MQdM.</Ѿ.~_fϋ=w> iddOn5 ͭxg7Wψ3>68W߄ev^G^^Y%oxO^!ԾiO_ +S>%_a~]' iLzOu-zmWEa?a5J1P Ny|r|J'5>C>>x➃x?뺮Kut[bZjZ֥mD(RtraqtSTN4]*R0Efk98Υ6NnyhIźucN7 :Sz]Fm~QW༺87Zs퓦qu=7_FaI"YiZMګ,t;[+X⶷$+LI?;/C%_[<-wm@h:}ǵ)vRRJFڕ+pfUt\egvz4>6>#I]_ UW['ۭ#OOmmfc"巵Q\E+y/-#@ TyRmZ_c3/6~c߉ƫWi)Ciޣ/zlz6uo;K}%.uE5O?oz^%⦳ksLί#᷃|qsM=OЯOZEl,M>[x5kT[{"P J'ӥzJjVN5jMJ:Sʜg*tR?`S9ʴ-\hq7˱2pxLN_U_TSZ.^ Tχ&|ExCOh>_zwL<5oQ|ZֵI=χеD1jq~|<]]|@b☼r_C· xq#<]U()Ѝ?SWRCxiV}k?"~o|ywRhC4EĿ>ag./%c#E|1xG뗿N~~*x/3Ӫ`_xĞ ~OxvF8G_X!Ok t{:g^fh~+mg׈>w.Uω/Ư_Ŀx:߄9 _ xO [>?A?|Dx.,̟-iXL]G巆Kk_66u7W2߄zĭ>ƫº-dž/_R?o%xo÷CSZ㫭._h-ֵqVĐ78xR]>+k Blj\Sb2ӯJ4ia18lZWxH1!f8N7ΫS'(g}Sྯ5[(ҫ>SGi^CuoCm?(:߃uτ(Piٷ-&ִȭ 4x_CGEߍl4ZIdƗ_}5:x.8qJT rT)+{zs¼&-vŽgO XjYd0ԣJTgNܕ(ౘ<FG8?~?u':~.Y|+qz#c ~͞/~,x[ֹwZxS>)hK]Ӿh#x;@} $f.| c-.L:/*j'|GWTC_D'S\֔i:]_TS5 7ԩ”Ybq5^MʭH֧i֣Ɯiӧx`ғ1ӋJ-8񋯄WmAUVPY9p(((ڟM{Ukw>sCev?d|-bZ_/GLLJz|bw^?f?i5x>"5?s\x2wǞxsWǞ9=[]v/wg\/|ec֐S](>Q5Og-?|y7j?{Kk2EݧxDw{=;wX_!'] Ex?G}. i{s{oxYlYJsBN}:|HU!g4^<%_xxW:~5 O~#H3 8ST*TU`O.+ݕxО*_>u:#G('t_-Mk߈Yx|]&kk6_m|uXN j]ω-4d4_ iV߮iogqZzWoxcJlCYΈ4φ6)h~C~kxֵ +wzc|O5xRӓ_ {KR2VY])ӝZWZ`%Z FpR=.HgW(`̗-ULEW/U-Ѓxѫ4o<,ӿh}BǏEw I9b~9.ƻ}{|NsA8a5C+ş a⸴O x熵xgS+ Sz-Εi5Jq:VNQiӌEQiM4fvy*hUa:uUBuc8TVJsgmCl3_o&Kg T{aI}>]ֿfq^o I/,S>Nش/|L[ڬ{ho٧:A1F ->gf[!~5fLS[CrO*_ٷXf&O{+_\}_}nIwkw%~/L$~!xǾ/?>.?kO ~ξ iKC4b ]i^lVxWWN:뒖&jRxz5`Og,ھ߳Z˒SR:rZƪ/Ù-|I;QV40agFGtUvLо4lo6'];Km?7 |$[> xDĻxgmf5_|G-ޭ?e/[g?~~3Z|UA>>qi?~/6%uZMgKt!JoUJ;>-Ĭlt}'K+*e7 KxjufJuu[ SUqYe(¥ Te*sRKS7Eg>Sߤї-i>:zxzqe#Ŷ?7|MmK=ÉMtgxOxwH |*/Fjwo HoŸ_x?S2kA]Ƶ]{\<|/>oWI4-w~+5Z{-Nm㟎j/x #4~|EmúF 3 @|E#ux-|k<㥄_ u?AG»>_|@ǃ/ǟ<%jkugMORQx'f?h'a}|n&é:qc y<enX\uuq%hEQCXYEUtm8|D7סR$S߇? GgWEm> />)o5smt~|ž7|Cx&MYm9l>Gûkm:[&i>;|{I<['fL+3V'>!G}cz>׷ .-)~>5-7_ei ~|38|Aqg5MiZxt]'sƷiUuZ7IUV%~QS5!9S#W {";Ά/C}j . ?:?~нgC^E>oKKzK_7~/{a~Ԟ7_=?WOk_Ŀּ3xÚ%Tg\*xtgy?i%ѭ>? =) w k{S^Eϊ>'X񖆞6>&#ĶxN𖡣6u qz:\apK0xFWl!SB+ *qxT<2x_ Z/4*QTet<=(ή'W*|Z~)4?u{߷|aO V^?w6Zo>NOXXK$~5 Zx{/|R0&ո? AE?|A_ '4T_~"~Ϛ5^ zw]Cg7Ťzk k/~(| -f=M:|^ķ|C}jW-iTƝ|K_OqOu~%s-]=V?^Vz|}a|;2 CoM2O)ԡNV:YPT'e<ʔg,Q:ªT\U>qT)o Уt-X1biS+(iE*ZKf9$Krƿ|Bci>-?gO:O;"kagx?ſMQ~l4_ {c@~%_ڃ➳E ke_{wž X+s_tmIG=.ExǾ2K7A~w?_2i |gz~*~gO>"/xfkMѾmbƳJ׃oMWZ嶙o+_7hmf-ZƑZ4xzZh_SZ"6qjWZhK <08+[ay)8XtRZO*уS J&8iӜ?jc",^*hΌЫ+Ҝa}>"sN,MLUxRZu?3vkj_O,C/sx_kd>hk?O~ K{VVdF.Gv:>>ص% h_Ƅ.f Ay㿍NJ`G!q }5_ ikڷO%tx['H&d5^~4xG➭⿆> 煬߅eFLjA=WPL4?~k3xKY7,hI|?A߂<Ӭ!i"jc7X%K^BxU{N?gψ?oهZ^ko٩x P|y~Ɩ+>xvG|uƁ(u=+QO}yui_'>.<φ#i,4h?uWkg^O_ 4Oy0ci'!cּOZ> |~g>k~:m~:'-K¿1W |7mg[/;GQ&<c'PM}VHԅz2WRd2 4uG46kNuS^ &6ጬ<9U*jjfx\Z:5*BjS!*xl%|^*X154o?5C^_zj"^->6>QVi~ >[xƿŏk)N2G+ oNf(NEW&:EKMw +~f 1dž|kD|u`f>6}fa >%x'Pѓ\_Aó[:rS^5eRGu(U˸UJr)ԩ{ ½Z+BJOEATsznx(ԜXzRC]'xs <%_>7USU֔ZҾ xSय़uU<*_<-NcڧOf :k[;FEh:I|)$בx⟉ е:7>|Eh?ك>2/|i7?ks5+/({]^^ShW>tUT JZ|\F~2L5qmE[GC/ߏ3_/A>7> eleٟ~44V"6/t~.{gdkK/7mt^1\{Nuki|m-}|&Vm>/Oj-^ k/6:i-Yo@SM$K%]VI+`qzj7RSq^ZPt: ^TYQ*nX|5|&_ú26cg:*pT9R**Rro *؏bq_/o֭Wto>.ߊ_@1H|=|]W[|?_ 5}#YĶ,w!|;hφk>6Iw>"NxgA ڟm~ Ҿo?:>*%uq.w:]MajU79|0> |3_zҾY||OٲxI{:֥o Zt~)!/Koxc#+S~p,|+l~ gׇ?hfOz-_/n _zx5էskkt;~W}O*:_k ec6/ĿoG]ޟBoτZ7ďd8Ҿ/xH<]WM?,~$xAMD-tOph<6n]Yťi %ʩ]<`ԌQ\*˰J4YVR3kbq:LEHԯBU\F"&*%*JuVPۍ٦ &M\a#`2h~!˿O_$ _, zO_O/¿ua'q3㖏iS JiFJ 2NfO 8Upp'ZtruܫVO7R_u!U9֣D*hWbEW((((ؿh _xȣo4?6ZgSɱ~ѿA/ qG.hl"dGg/|ec֐S](>Q5Og-?|y7"5?s\x2wǞxsWǞ9=[]v/wgYte†}eetu[~hKc_>|Dɣx$F,֣KaKLOOuTڌߴt>G~>/>Ꮔ|yOx7|_"]j׺|3cbՌRƩS*4 )FMU1xk;yF8Ra(QXDx8c?6JtZx*3 EUhR槊e<+UUa9Z3#5i Kž~3|BW?k񧊼jsx#>1OZ!fhߴĺ0+y-弶Ѡ/;5I}BǏEw {EmI|^u*ՕJr^|Ei:RJӯ^}URItQG_[o~ gg//S퇃u'wZ%"ڧ|m{|&'V^$ORk:?bпg~"E1mjCOVѿfƺwe4~Yl՛Ɵ1Mn=)~?fbOH??i3Mr?A;9oQ%ݯyc3f~'\<5:7C-Wt/zMwּAx>Q,u[2/Wrxk^КWN:뒖&jRxz5`Og,ھ߳Z˒SR:rZƪ/Ù-|I;QV40agFGtUvLо4lo6'];Km?7 |$[> xDĻxgmf5_|G-ޭ?e/[g?~~3Z|UA>>qi?~/6%uZMgKt!JoUJ;>-Ĭlt}'K+*e7 KxjufJuu[ SUqYe(¥ Te*sRKS7Eg>Sߤї-i>:zxzqe#Ŷ?7|MmK=ÉMtgxOxwH |*/Fjwo HoŸ_x?S2kA]Ƶ]{\<|/>oWI4-w~+5Z{-Nm㟎j/x #4~|EmúF 3 @|E#ux-|k<㥄_ u?AG»>_|@ǃ/ǟ<%jkugMORQx'f?h'a}|n&é:qc y<enX\uuq%hEQCXYEUtm8|D7סR$S߇? GgWEm> />)o5smt~|ž7|Cx&MYm$ԤWbFWҾŧX Ii/‘xDMf0y*>9l>Gûkm:[&Wo6e> ~ze?UXo}|`sZ?xSԵ"EZ^%o[9i,(h~4xSZM.? \x_ a ?eok?MN({^xRࢾ45< ^65==\׎j>N'E~Kx7w 6#//^oz/4:f/p/o~F[?H1 nuCZ<1#R5+_i7 T&:gʕhʿ𯄿 ;O<+L|pڿ?O↩wm;?ch4_./|xH{k~_<|/z]YkگK⧸_FbZ־ ZyC^!imܴ6ڂwx m[oƚ߂}_g4ς le7?)~>5-7_ei ~|38|Aqg5MiZxt]'tTДi}eBOԧ|ujTht*9hƝGA2\+|iSMF5)֣SNoXlUJUTWG5S*KG> ?:?~нgC^Es^j . ?:?~нgC^E>oKKzK_}BǏEw ѿ^Nxut?@Z˽oi?νU|0??jO Zc/r +'uy5΋/_^ _7o#hvnjhgn~1?k_E]j]?/)moAxெ62jZ iگPnzCUi"ᾄNTRO}W+*F+ RF:9宍H,Ca!_5%'Pxuچ):kM!i?ğ^۶ߵM43?h(?<᏶|⏴Z3@~˨j|m_ǯ/{_y/⏍~Whi|B-{zt_ExX|B??h_փq*W@>MWŶֿ 5 __i4j |1w? ~4G 3>9m~%[7|6w<>Ei4{]"jP?lJ~L̿&>/\G[n> ^!G I5+XKд*xcNT>?nç8{Ms?9񖇮kگA =z⇋>|0>֙gq?KQ!}}x'4%8ƽ*.j:Ί cqF=< dJ8z3 W=u_iթJC1Np(S+a14pتN\(a׀[:e|+~w?ox|x_5'Osxķ>տ+miUj&_o>|=U;%;[/xCmMCv޿rk>Y⏆M%u_*@W?ghyޡߊSψGo>[|Xvu'ƾu{GUֹmxw[/YG|1ִ7^%:ֶ7|kIejz} b]GS?OJl؞rK}U&>=97G=4Sim~#m>Y]:,𾟧x$Cy|;5妺|IIon׾5_ڏ}3ß<+/oƏSռW><𵕞 _X ڟiƟG fo k?q炼/G-G)Hߴ/_X-[ZvO^Sj5O~"?픷IH/4OgaoW wş?4 ^8ԬXu??z5ljYKKӼ[H?-GS|;|]sW!/w5M*>h%;5ׅ/S{t =Ǟ~k oIHxsX5;VOߎh_ R.?~>E} YfN2|@|95I6xWƬLq4a%bUgQjḇ(Zt\({ k >$QQ#s/WW__I|*< |OςuF}q k +kQ_;>/|?׀43Q7<3]N' ş{";Άr?kto|"E~>#X|d_o6;kWh_JxuK7^)¢bY5ZR7c7ez]oFoW/*(6{~Q_`&fW0c۟9__-k~u2Gh>_zwL<5oQ|ZֵI=χеD1jqyw=z՗Ú&u_xuQCx)ޛlZؐ~ %<d}!:,؞k孇u ġ5bo x)'Yj,t?x{2agmǺFi}j?xT |Umw\j~2߶hj+Cm???i~=2|@͗6:}/L=^'}:ŵ6>վ|+oavEo[/ԗ O4{,CnypN+a8=J)q8n/ (:[ K*rҕ7,} >/꣌FNiJ_xԅ J#Xa|h]ϋEkD~? ~&~f|/%) _H/?iq|F`-KLju.k=g\s Sė~wƝW{>$_oxö4Y?Jx]Ok~.x~:5C_l;Gσw|Iyx7ᗂ1?]L<_u&c>*tkO\K]:eΦSXZU<4~ |9x;Ku~4+>5_cQ xRL/mE4=v]SIt.O*(ѡNgRZڞscj:poY_Тp^np>|L5|owWUh^&'~w!w?~Ѯ.i}.,=&_m?u?XO?J#x#~c|_iZ|YngKnx~k n?|"x-|3/=6j >~hڧgoiO.l-%*o4=37 >z½x#2zO>#qi/5AeY~ڭ[åؤ  -`p烖QPU%K_xnQF*^?xB7 HХ^Mxi`q+8<ի C_I|_o|IO^OW^> "o kb/.o,/%ߎ_|K^վXρZP}x ZxR-s(˩hzƱsu[L9۫:}Bn8R_ k(3xBx"ZhGulj?ilg_|L%N}ĺgx᷃m<hַ^c<-]'ZwB,5K˫[&X½J-J4n\n*ʝ 3ZX㱔i04ҧCޜeJDlo ,YMδ1\NcjG J\(ʵHO 1ƿ<_&{¾6oO~%`&9Oú^?W'ujH׾|DMdC1oE]Oƿ¯z#m)=Cz~x|U oǯֻg,;I|?~h_}Cg~!Cjzoi- a/`柠[˥ir-jK,m+zv;Οk-w? I!9x&o>|5J-khmV? h~ ~D|);Lz ќ)aaBTG<5Iʴ"EZB9e~OyJ 0ouԔ%fc:xY a\ xSjԔ*~x{g#G&(߉^}_ZwkSYSa'Ïx BNj> |rxSW>!m5mO5 g~9ů~߱W1bѾxZEZ+a9~~ #_xM* ADֵREމ>mћ?I֍7|~4 'lMhGӾ^4c߉ (~=x_K?Ɵ#$|<-|t ]>(i:{5-4 u،5㯀j=SmsnsE߳~xwMo?loKߊ'mDïx^(>|xWCWz~WS6<3,^g̫/bONu`ggtiΎ^.\ߛ "PJ/(_[X,(%} xXiFT|QOi$=~|i:|Z=z|^8?moTMQN? xoz3º?]o^aaGྗGY|"a|jwBLE~ [1Sb4kXZ{44 J *1Ȼ/šFuέ_>6)MgS z?1[w7iz}ց[Ož"Y w>|<g3ό-4xkM-:W[k/[Kѯo7无|gOw[u'|ow?~;韲ߌ.| <]+||?h>|wxUVZkھKROhovюB8\1j\RT!T8>CMxGÿ7|Qǟl|K/>i__^s^!kO<sgm$^i<Azi?~5xCai?xWƶ?*ğ׈s=kRDO4hz׆x]}2Sg)VUibSքo]CJ2fN:ҩCE~Uo9u6~2i|OO ԟGkgj9]Ğ_Yx_#xÞ⿌(R=mkZoSּmsOBʭ:~t)=6o(ɹTXLu 1RʭYCc:Nqӧ_iF5ӄ0jo`2j^4K'FHOӯ>>mmjO#1}ixpZY4/x7*8Q?k xúGlW 5TӼwxkG~R%Z5KxJ}INoS^y?xĺjv>>"iZ/>Xx#w=п'!/4|Mּmc|,t<+6yѧJT)Ua׷gR<+Q Gsb] <640LTQxƼ eǕtҫ% ҄Оףhqug8Ÿ9]?x?Wď-h>#VyKx޹skx6?-~7o3x{{HbNu*aʵ<& c -Ff:k][\~UfG:쥨oᗌ5=K]$] ͞1e[k. kO.wo㖝b↉G>8/5rSDž~ >\&!Ǻu/mup\e?f/OyQ]^}V_w?_ #j >l|^gƚM^?xrMzv%5/v|7~9xO#^'ǿ3ռGey^!77Wί{B*/T|Khm1 ugUbg,v2u#Z27fRWI5WLML6 GB1RQ.Pmx{]Ծ&xOimu=O+5ޥK5m{UCx}|T;Hּ7_kZk^0o>(x> 6mP]NS|Gj|I{g@-K^>+S>%_a~]' iLzOu-zmWEߍho͟׎ Cj׾+.֭,=%>i,5H2lD(֣ 4)XNRN8 YЫ֝JJN3a^aXhε*cXl*s<~. C0NZXFFtF>{";Άh߇/|xYY]M#_~$ru~gx~[6GC#h~ |ANIxK$֏ xf?-[Ʊo#>s|F, /;Ěh{߅P궞]z~|H+a]] b~=];Jǀt?|V"u? oKϊl%xn_ /h#\|^SjS>|?-J/jn T--0_~| xk!džQ+Ŀ h^- |-uıN7ȴ |Fτ4Kx_&O@~-|aڷKˡXG[Y@}7Gtx:K)UMSᦏxßhmG( x?.]gƑDox3_K-J?Sh~Z 3 1w>iHOc/:*>xY<~!^,Exo|)X7ڭ:^'Oax8yIՊq{(ԩC%(b'%>"5_GYV<5>~$_'RXUsz[|?hx>uPxg>xğ^3|<|V& &5McSe?<7e_VjdoGa9rCB{UM<=:U?fl>".n$*W熞Zʯ">+þ \4~п 5U㿅|+ᗋme/þO x:j ixŵOy |2c:(ig|s?K4o \+JmZy|H}hD.-bu ؔx[}-g3c/x⭧5#|GkG'kcºkkÞ>wU5C. xn5~ҷ |@|gL}\ľ%g[kH?>T4zox1+ߵ¯,_w}o|EjߎYψB?|0Zi,0.'?ڛLj=ckgc ׼=Ow_g g^'}&_|EuxG]ݵ|<4CVރk??hOxU#_l/_gOo&e ?qat=w???d߉p|Rm>=Ӽ9uOy''ă(bqNxyО2Tu(T+dts,n]U{=O%Z8Y6ps)pZ1o5t{ XS2sUz׷Up\F90O^״π: Mt/?Ɖ7hn|4^Zĺڞk< aoM}{]ǚ-Uuroڎ{mSie/8GP|u|Y}?NHvkMtR ^|/2_W|1tUsG5 /go |V߅! RMoWW\ivVVoZ}GD|iz'/?;Y4φ:~Vf~"W 3i@+a:ޙ/~x(#;__xcGPt*Zl8ε:qS0x!9  Ef?R7 C>Vֿe-c]׼gڧS~)e-b5|w|.>1.?ލqozv?>!{F=<Ke_ ڮGC.~iv?uT=Ƶ୏īxL')&3;Mnj~(Ytm/hw'ڎᇃk? W?~/|A?Gt/[y ወo6z5U>L#Q⦧ xʕscܝxЬy3{ZiQy#4Ս\K UbXq VrSYJ'R'T4SUUU m:ͺl '?nձ]b_֩?xs2iO]UK7Ixm7i7tnĞt]gAᏁ~"]XxcQG߈^6/~_#a'ˆ9ß~2.*KQommxc|7 KXTW2Ɵ?Oh?l ٢"x7#L?_#G H|clژb% >m!Ǐ;]^6z􄩿eZ.PXIcJO W-%8ERqT -<,j |b ^1ܣZk;8rNukfNe(IWr1 Ei5q6BQN+[~2²~1~:?f ύ+u+?h XY}Y}TK7 ?it5/ڢ'{&ov~7CߴYik}_g~͡|@ >)LlAKEU|JoNX'ZZ47 /ISN/ދ\Q\N\UIוzujUJf5/zݭ1XI.ZR ?6{~QG[Qʊh|3;<[w|ac X=' 5bַ_ m@h:k3)AOkYL?B߈½+3iyb_-s?jO<3쨯Su)Og8OՏ=9IKn+r7Wj3<%iG24,̚挵gf?(ie}{ž [O;zt~$h 4im;FYhKjO~~_m+>y#|wPxI<)\t fX|I 6[b;5-Q5p\Oj/ ?mC>/W믱xٟ~i_fUmժnO/n-紻&9fXVIJř 3&G(ҫAJ0jp˭e%)Ffxo򕗼lc)PtRJ8RTS9>Iҏ+*|ӟ4\_*=O ž$)o<9X>#tx.]5mW=S\_}ۗi%y5 #(~՞24߶s*}?oKoWx[ž Qâ4 h!Lj|Yjp-A-cNgٯ?_>*'t|,t'V}+Bݥׄi]$qMjw'Ү-uo2[Zw#u#. `%Gbپ.7&~0Ė^NW_+۟S^T|qm6䕰YNBIIОY:0|ӡjDV/W Җ&ԣON5|'_*YkUغ(*S|xqGefKg> :x|DnJ_ gB>,< sz= wbſ|B?koω>,m&o|6 _>}{}/^=7~#5h/<9XjZ߂jԾ:< {x֍.y:O ZIvQ,缸L#FR EpmJ%N9&*/,S¥*q#SSu)աjIbVeN*K깆bѥYMկe4U'*~/'< J~ xm>xob -"?,|{Oú-r/l8NG^D@fo]ľ&1i7xA~<_#O|-4zE{&xB[Eċ 3Jm'|]3EnxĖzd:ϊl49VL/o,ZG\eٟ^?| ; _.3zb15jWc[INXAxš ^ +7Kon6n-< J8}^LTS3_O)<&/,bqs\O%j :th*zyͫ¬a^e:q<¶ aZ/7ڗ6nTsxź~C}kU~='S:7Gcnm{POwH,i9 b>kU.{i mg[kwm?Gu0kV|jZÏΩxƧ{uO z? Ku?Pq<^:x[ķZ,5Kn'ş~@T),_ WFJth9ԧYHjUq0SGT攖4֤ckc/oRש_i*PJөK'uO:|@^Aw_o5 ^'4]'q>6nkt ~'Пm0?ڇD>XWE~+3Ѿ0l[^G|/!/|M~)?ƍzKY~ | =3)m1I_h Lć᎑xxxKS^P Xo6hIW ?>?gt;Iw4_4xJG:N? n \Wյ:S5MGS+ۙ҅hQ(Jy~+ XW+q,ۢ5,,Jzuhb(:JeN=Hjr>pPS9m<^Xk/^Tqus~Ǎ_32N/SOxÏ5U^;ž,:=C4/ x3~?zԞ#fw/>|,_ .gxVڮ-=藺D/ԵoxT,Vi^j:{q{%Ω{,> o6 [ƭkEԛ:W >+I]|fs:p^h{J)ɶs rʓx0t^ ㅊj,F70NʾXEJ^j8e|DU)S*). *'-k.Th}[ NV6W2\Z[hRF (, d[$hƋq"(TDPQ@UUPNNRq\rn1Ti|Jt(SSՅpV#u-ӞIgl_oC\gQ-k?i_ ?]xX0j_ ߁? &Ӧ{F4$m,Ev|6!W^+~ Pq4g}^p X aP·/~Uo/Qc >f?m(ey0'QZOH"~ k|E6j7湩e<='6=SGΑcڋZ%}[MʾdK GS㻿+϶dlo4sSOxMzOm_xwo=wĿ_c2ژJ8|M\]:_V 5)OCTؾUyv:xbjԡ :ty!Y׋Q rr{H3i [ork_?ࢿ/xK?/umO឵"A?Ǐ&]~ם2^ԒMҨXNXaR^žIʅ95J(E4SN>S*rvygJU 2䒗!u <0A۝~ >9+]h/ "X|,K'4_5&u?njzKyn44_ x|{n|`<槬|Y>0] 7_ σN/|=ҬѾ&kz7zkww"}g[?Dh^2RiNIփؼV:xv6j[\B-[~RR޿sÞvxwzo 2Z|)zM.,oj/_ k- _F0ng4xvFO:>.|J=^/ӵ|4?¥o^ҴЮto:Eƹ7+BRzӞG!/ER9~Jt]HSrIBJ N"5n4J+U,USj:F:k'9 Q)]aIi*?>'#J:׊~"~_5v?ق]g߳Ah7OOOxs cχ>׼7]_kZ5 x]֤ > h~_o>xUu8R|agv<Sxj]$^/| ~x mMzˠQQ T**eqP¤]ҡONU:QW :TS"L}IU|MSlN)g(CrAFTqP.Xg/O^/ƞ!||a]auφ*kK|7k ww<7h_*2?&7Mg_ڮ_umT4}c}5𿅴OƟj%|=$6m?<]x;?a~0|&{ï;>G59_.//NĶ|S?ګڅO_.?hH1|wKAžc4J~Z.2Oᶆ<5~dnchǟe5< n f?ĭ7.Z|pNo |J ~η-Ə~Ƿm\JTO5!%E:ja7Ս?hTM)RB)*j8=.(t1T9Ք*QQPZE8TNqp?#O^3?lOO~ƾ Ӡ>+/[C~vOi'#- ~{V_A9eK8Oxk^~׺{φ7 5G:gm_VLO|#E5Zg "NJQ8cT:VXbTOM•jQʄ'NTsZJjsw)'&7R#%=?5^&-?j=ggf*- +><ƾ2|{_^5ָ@׆dYִ>_,.'Oyg#~23m׵?Y<'Eo|-ioɢhҬ/]&OKҊQJ3QBz V^ ʃRΒ+Uugú~ŠJ5Ta:J0*K `0^t0XZ8jF n*k^3Ǻ+Q?j:?[/5oNq_S?4ĿuY/| 3hi}z*Qnῇ/,~F_?ώW>?־4zkɰkNf)a 9X'j(yQSN*:p N>j/42pJ)bUPLq(J9Szu6ࣉܘ\kX ~_3_IƯ^F߳?ozW?>Ml~' ^$-y/qJt3M§>?g oڦ7gl~O Ow!3ZLo׼Z_U)TUNT!|)౹u:s5 aERp$aMB2RV7Nwc*7^/i^u5Ϛs~ @о xcw|A-]x+Eu>rWZ$? '⟊ε qTѝ*ʗ%8B1zoB WTu/4|.6$ L;P7S?q/o xþe:)>i·ֿE>x{0fj )Fo?}oQ3^Bң~hN:(*pJtEt8N3a(:IBanX:h9לVNrs9~jέzJ5jׯZOWggw~?^~-HKx?f i|pߴQң? ,8F-6a:w1!h fm?[F/k6ߵvq/~?lx+ Y~~5?|>uzQ\kZl/ENQxI^)'Lv\ՍƄeNjUSWƩ9J>Y!RЛ9bԣ]5Yv2\ɫ:i&_ OԚZmluu9s |m7W $fqʉ yI#Oo<7-x{ok7w0O-x,[yi`V2)/]J8h4 su8dVjnݵd! J% x^1T]wwNrh$OSOyRmZ_c3/6~c߉ƫWi)Ciޣ/zlz6uo;K}%.uE5O2:Ư|80|/ |Io5G} | 'CɨxxxúdmxF4? \[jm?g= [KMg:_GoS{U&_E."Y떚|j֨DR>. _1uL^9]m|/]|k[ԅ)PQxL5h]SxsNxZWm?: K;4ܚU'BSjק)WT˳=?vOaŬebzUFe^Pk~a|#IuhmomN~'&^~_g `խk_4{Yۍ ^ѴOg`?h/<C3?8xO_huO/ছ_~>gy!ៅiC/ڟM5r:|_PֱoG< _G]3K _*|]oLa ,gZĿW?ۺڼGf]P?goZċoDLG.l?)zc q;-1bWQʍJRL>69v޹/s~|$/|cV:k|e.~%T)o^/|E|P<'lV)|;7NW:~Ϟ;O㏁?e+ YMO0O5$i| k;ufPxjxrFgɉ% m),?mOvWWlcOO~3 *cWDOT S]˦j?> k "|Y|L4X~?%{Etm&/:DLu +24kaygkukSx_/sW߅~& K_ |<#hl<)Ct3Z,Y=}ZZ-6lВ% UЎSFu*9b_r&IOQ4_ p~V#(IpJcrs_4Z4:h,-)9mN?ioNxx[`.|i[k[6YY|[o'ŞKv0_xTOioynڟ^?ڳZ&eX|/- q6m^O x:?t]#F>8>-NCſoZ?@~Ox_JmyV+gH|Ie:%~%ҽ>Q8SO)B34Qd9{r9UʱٕII~b!NU&[TNXZ#J1̪QSUcjNM{΅<冔C,r{E^8jW__Y}τ_Fh߇>&?/eo1%9i:9cSxCLѼEwhsվ(~W|W⟆~8??l6}/ O^ %ú׍3~~+>7\M(6{߳ /~$| ;S2W$;5 oVּj״KxXO=u/U<d):xcSZ%^ؠ5pR!ΤOGNI2 m9IrP NgA.RxUhL"'y<$^MT F5AVsW^9&K»)SMSJWVES/7:/ ~:Qm_ <xZ_Nϊ<[)_ *kg|$vGڹOڃ=#WIYK~/RӼ/׆li[d^&t+Ut/59MV,Gl齫pE93aeRt麱d9UK B< 8zҚc3,^U*|.i)ըdiT:TbӫZJ[4HM?3|1;w_`x>"5?s\x2wǞxsWǞ9=[]v/wg_IWúwaWm٨iۚ槳۾<ßھ<z##>*#>_`--g{kJr|q5O{oyA?Ǐ&]~A?Ǐ&]~j۟nv/.AEW)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE se sMJ(??e/Sjo Q_7Q??s?,8ƙ'|.rm@h:kn~ صA_?NJ_d#$ǼY6jQE#Q@}5^ K7vr:n< 2I:͕F-Kk=ͺxo0Z4-6na2([{Y|eYⷒ9 eH ּGxB?ïs/~ rǺ 3j6t]rh|I~qx-~xg+ς& ߉4hOoƍK)oe;-6_xW:߂>J^-$ XT|Iw}=Aֶ):}[Y:{vS/[-]wrzTkek߆Du]xbDW4  Eǎ<y>~Vs]xGƗw~/Đ.z;D|_߳#j¿;_Veݯ_FT4kKx5iFmZ ԥzSeYB De:0rVlDj8sJnx >쪺RSSX=9bjStʽ1~ i|K&^PŸ x_QR>H||n$6~:_ |\ |w~_'_? Aoh>4Oi~~7&+i3ti^!=%OSO_?OCOUM4|O\MύGJn xWn M7:ڝ ^+፿?`7Đ|{9> XǨʷ)'>MxUtmy%?lp~IPRa$,ULQTsUxKEL֖)үRL,SFitV⼆u3Ӫn7<&gGSFux4s~$h_C~?4_xOֽ|A񽗌oOWG+jVYYWO 3j~# 'izn h7n|ia/J{]6icRĖExnBm^hvxhƵJ5\iYDy^]:*y JeCŪPKG ^)*G RL>CʣRx+Lj%!N2pR =XO )Ƭ%'k^/xgƿ9 xzÏ6xW^S |[u/þ)V|nOsgn4-zF> hZ~'wƟƋ?>'HO< l;% l2ʔ)T\=lu*VXXcXbلƎ>3tVxyɪTO q8RpmC:gHe/?'gþ5eޕoY&|Ciw?o^U5nk:оXχy}٫AIo*%?/ x  ?h@~4|I>x|@xwl﮵hLU׎k6?/m ĝ6o(쬼/}~6^Q_|08 '_![_fWƚ^^|]fH>#xG_]_/ď &?/ xDWgɾ.m.Cu_<,~j݇yPXZ\G آ;[37g4[6;$7otψ1]gNU^8d{_Gs#Ik_@U^/3N#2}G2iVܡ;%8h2k߆W/[mwa7Ao>.46uO¾7Y#7z9Gl齫[7ğ~^4mcw}{ xwοS~7g//? / Zj~- k~_Xj?o&f%>;g`#M[2~QУNLVsGIq8dUZp&^3,2>LF/UF ~1{\%WR2^mҭNI'ZgZ0GB-B:jSNfcew|E6j7湩e<='6Q5Og-?|y7ӜZ;I+l_nO!fOý!>X&&Cmоk:~ 7K>ԴZCm:IjofTlY|9?wƚWO -i^x^/<3Jծ:W]r kv6 5_Ao3PLmoN_k5;h~5Z>}ɯ'ˏ~J>}ozw'OpGġ-5{ĶZ=Sme}~݇kvzij-+5 "I?C_RAJyT0hץͪpXxPL6_FIUU0gZԽ\2m\v"2y:3Fq*td ZxEhթ FѧMTeygn>2x|EkhTGƟ~2- ÐSmo|?|D'S-CbICǯj~7'N[qtxs|K{RxᆇTݧ+o\|5q>2o _կ .,Kx3Y#qͥc8@Ӧ?1s-Kxz H׮'4% '׌n>Gu濢[G컪M a;]SC_?.wj:W#n`ɰ?f6UhթTuTjtsFtZZq)KsjT_B9ʌy'c<{::toa>oRիK^5,,1:J5g?u?x{[*~2i? [υ|Fo:4?=_G^W~O!KV@tok?f 泮I>|??/<'i^swU|Weok7ZbȮ?l>,_|S7'yzqgmf,)PR,:P&UYg9?OOΫAEtz;_3Y<,/CN'şᶑO1|o-~;լxRO޷saP }s]h( nj<MT]ڞ m?|B-:uCOo_$+|$כ'A#JDO|B|Q j컪új&A鷢\J -CphzxgO PqUxdZu8zR4T(ԩNX-pjsGT2SΥO_ѨBT% RZg/2?^ %H=>3(׼qhk&ޭFҢa1' *]Ggu '/G\1Ϋ;?|c:/|? k:Z>?`&'ou_} '"߁z~n|+okR¾m%<7ı]A}CkL|i--:ÍO&߁5/o\Iw?xSF廹P$mVGf3O+䒝'#Qa] \tq+RRxOiPuc,(xjoZ' y)Tl Og<԰U[W(]:\?'g_lyLëY?cM[E|7Wnj%o xk-4|:D*=ė$ԤGԭ8 >!~?9Zxg?g ;➑W <}럳(%W^9nSgo?^O /l$d|5˗x??o<'',|Y'5! yY\ڬ3Ng᫏J}Úv,,7XZS8nqĪ uzT_a#S,pu0qO^8ԟ,Vpu^UVo ]Juk{(aib1Q4UiZK+a6ȟ =7StיƜgSԩOO^h&]JLO (ի:uU0cL]N.A~ӚX,Zr~4ϴKr"ػյ_oG_uO> wxmë~*|;>^VhM弆LoeY"# ?ۛghrfQcհU<6.%VWVqT QIRJ>HnK *J.:*ҍj5\i/dT)F*I^Q4a/IχZ]F$~<gj/[ɆMF@gF4K_Q^}#fynkZn:o#xoj;<a%?3|1;w_`x>"5?s\x2wǞxsWǞ9=[]v/wg_5e_5:u)(M٨=~ECE'M}$ۙyA?Ǐ&]~A?Ǐ&]~j۟nv/.AEW)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE se s}xN?Oڟfi~_~/q?i_d?rZ{ 5bַ_  }:?(ke{/.kϥ˟xK_[il${46TH[Ix-|x6yhķSxYȢymeW3gKH,os O>}ǵW\Eѧ6Nӛ+% Wwn%JUq-UûzsGi%mz߶o F?/>.?| EW;ox) ,oM[CW4n/ok?4/ZoS&D~SCo/ͨ9uzxWC&-;,}.>hk7~$5x/kuž2<Ιzׂ?i:ugt{t)/I'3l-^-%We~x g/ge2?[?xU7ZkrƿwïLѬiګWGN߳mZ|-~ዝOYmj 2VЮ=kRE gUܟG|m_41_~w1 0k]??~"ADjrZ~+bi;: ׆/tO|&t Mд 9#KbHZmW ҞVK o^Mxğk΋q |">/G w# F'˻_-/jХZTZ4XzҍUN(PgF(s=yB*5* JcYSN=ڎ-*3M⽕WRXtb#Vx7Z^u2 i|K&^PŸ x_QR>H||n$6~:_ |\ |w~_'_? Aoh>4Oi~~7&+i3ti^!=%$~ SOòG~'~!gO7PӾ+|U?-s7>7~N?7n#k5G_j~V5<]~ȿN]{v宍-;MԼ={pt.?Ew|mTXxľ% c_SK–+LJ^>N|qÈfuCc8Ek  X6o4Vm? <l^tۓ iľ#:[6֑j7jU8Ueu%FP΅ʍ(Jq)}eF0%_ ~;^=O7ïGg-WƟ|x>뿴5|HtψГxo>iea j* >(~Ҷ/G]~ֿ_k?>hNzoL<3bZ|?zI5χƇh'mT?^ 7Ն|>1_W7! x>OxE4{}/_3Kxc|xi.WEv=5ÿd7w~ h?g΋'<[ /%~6<w3$>$uki^njڤSTR8,u82bxHt7mk?GX;g`#M_Q~65IWúwaWm٨iۚ槳۾<ßھ<z##>*O ~;oFFO5= tG&w`xVKUq9ik;kZWۖ_ !;cum/ ~' ~' o_sMԽ%(:B((((((((((((((((((7|xN)E/&){|wSLZ+==BU<@33Íik[ 6NWz?*tPx.S%> 0=iP+l(IŨ|=}&P_]}QK>ЗξuyHil4j[^m~ѧnws D (g" Xc*A|7Uߏk1NmН7YI_VJa +6VKZR WIw|-VJ$?6kO|<e[EN߁5񆫭|gwo|k붾?x$,Ț- ^s~<~ڞ h:9~߳o 7 4kͧMxY4GZFKOkWҭĖv:~YizCxvN_> 7a|ǿ x_5;?zdzw aSeifj徱h5i:5j Jrҍ7N#1 aSܞm5t Jpe׀#T-BV:x,.k"?㎃᧋_Y'߱?WK?i"D6C7oDž4-_Cd~Ͽ<9O|/ |(B/!x׃REV(qM z/^}qj/p2^q|wCuk 'ƹ{hZuΧukÖMox7ٞ-цguk[Hs7; |`mtKȼM5?iifDū?Qׅ߱fi|5s.5iS{ᾥm?i6Mo;#b|=k ӢG𶢷:~"R5q)ǯ[]>t_TOR I/tO0)uKKR,jbmj_]z8eFqԅLd5iԥAST烆,DXjjM]ƭ:^x߳I麒vj"_ٮ/W-Ƨg<=Oukc^ͭEƟG㿉~x[A~*|I?J-CZi/ڻ'$W_lִ]KƢt_ Ms<%wk:<1뚮w 4#A3м?mK^ᧂEWTuF跖zo]o\ֵKvpîj]_w]6VvZu¯~>4oxb ; .7>hVii7"}@3]m_Ð麄paeN)YSedg[3Fu.b+Q^)NjR`>MQF4`p5gJ\\/'(4S N\:.԰ԼuQxYw'Q_h/|M? ~Es_]/gx'gǃ?h;?,~ǥOk߈|QZE\ ~{,~~~h|-WWռ缴5oLMIU+wF 蟨mlj>;D|_/ G?~Mx?S?Cş h M wGe_k^#Y$?eGa?ŖWa3 Soğuk~7AM3?O6=GCO=l«oM#)gKk:8c_xe~0񭎫xv ;}|[ޟmvc궚ݾwrҝ8>w)UNz~Rԧxtx_&>NtUNSztpP lV9Rs{j2ÿzrK~Қ׈>"|oÿزÚI'i0M6+mh@м ,M⯄<)wZγwiI\xHt7yw_ًom$~k>{]|G>xzTt_x7Xhx?w^1B77!WK]%hxPx2_[8eB?XB֮~̿0-e\`;V uBsx< VFZԩB\D^T$&+ӿժUFhV(1Baqغ֬{%^RO ~;oFFO5= tG&w`xVKW~7Xu_~gtk]_|zqkj,tkO˼l_iY~q V7?bx>"5?s\x2wǞxsWǞ9=[]v/wgYq ξ֡YG )aAMMtgRi{ҋ䒒RiUKөIʼ'R'g%4%wXz6^AOigI_5OigI_5j۟nv/.AEW)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE se qQ>ɼ~_^??O3o߄^?s?,8ƙ'|.rm@h:k?k>KIu~ڬZgExOC|}cm8[ o yy+/Y|ăС_ŸNjrĦT$Is/tϸNqaSSwxMO$j)-]#.i^9#𷊼[j߳& 6/c+E .n?. OѰ|<Ď?k{&,M(Ul ԕ)qH<ܜٴe\FԖ#AE0(JqMŧfm4=F;X}`y>mR??3?3 1}jo _Piww~ w[\O.{gr)vyk:}KVHҧQ.t&4^bVW}s|S= KŸ| ~"kHLj_4RNx< [mmM6|֕ רt$UJ刞m4qyz咞Zc+&w,*.֨ђFԌ_NmxW 1XΜiTj2lkpXg/^|kZs/_/~53aZt<☾xG|>EN;/mo?xT7)f>_yo|D¯WMNXo~ʓM{}WR5}b-WXtknT:uk_3UU2G.(y:X\6هY6j5$):S#.ea*-axЖYV<5*Xnw`B"ĪաRpE◁4^7~˟|A_Ş%𿍿ixY>ΗwL<)Vy?Mi:[=C◉~,xcKkY|'I+W-^6UKiء|R[iFƱr?&쎟Cuk _mhwǁm[? xrIN4X,cRBa,(9sMP2EZ`QJ]˪b#S0h}z6WagJZՎ0:X+PV*?[x:6o^Z95>ox7ٞ-цguk[Hs7; |`mtKȼM5?iifDū?Qׅ߱fi|5s.5iw)[kzO~ m[ߌ]շ~i~-czt^(4v>VCZ[F.1uy|_ǯNwa|SWK?4b'8?š洦I--J]xi}w[6xQxRRA 'KXS B믎է^Q9W3l.M9f:.jXzFeZX kBY^(_DŽ?j? iv9Y6usZ5/}u-ޡw4ڏ?Os'X|XРоxVemZ? Msq/t 59J :p G*x첬s<g[3Fu> b+Q~Rn3tjac?i"YK qԧV.UTcjXyTnڋī?jEm{h1c + e|c?[? <`<aA.9c~=* [^D䵲/WCo75cG]G?gM>o¿௅=홯|Mue~"jM⯁^#V5LJ_xoD|Zw_*oxs$_ƽ>;D|_W/x.6:čG\jK_jvZ l-G~i{O j-.uIn u)OPU ,g F9f9si?5*4#;ƶa\^90G EhJ}O1P:Uiн:غFuKoh߇Q%>?~Mx?S?Cş h M wGe_k^#Y$?eGa?ŖWa3 SoēH &~煿g 2_8|K}Ķ iڌm>/ٗY|x<[*b-&S$^g%Gy^-~*xcOjO|Sk2~_i滧x^RuVTnnJ*iJ XzFrѩ*SC8IƝuaVl[o-lLj–"((r-jR0p d8zT*Xj2?j2c/-Jh?n߇^ W¾9Ѿ xgb?fXt >q*CŸ|u7ztͯQ~4H?g*A MFM?g?|h+n{}/~ N&vZG;^O6Vn{G~xXi]C>Ҽ_s.-qqy+_zߏ7ί}FG鷺ޝaSZܳZZ^v}F 'Ld{$mޤ){tUj*q,U),,eAU|6*iҥjVT({EJ*)B.X3~7T>bҩ[#tUjJK~ο u_3k: ^!6>o5-_< wZeDԯ__4UQJqukk;k *֜"w,7)n2N-U] I%nVO֟{?u_O֟{?uOWpڗQ\HQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE&ϟo)7(?e/?Sj _7=@Uci_d?_ؓW?E~U᧿Ɏ]? $|!.mHZw/k}T+7y5_h <?7džCkL?m|ek;s>nZ|5bHAO)2<$K"g|36&AO dYrz2ܧ{ a{*XUhTJp'pMX|ky_u*`SR^$*R\6+F5VV=5)JcxN y_كP·h>kf7|: نFAWOӿ* "Mfat_ž)xPYFFElmn2"+[yI.i5WS_z[3㭅qVVY,NXbx#q*UwJ[Vi~_}t4Oӿ'<|3cL> ~WNj?H<ݽQa?/yݿ\ >w[?&w/Y]0ZaTR2u|' ׻ݕqҖ278MNZRQMߗ1VjI鮝]=E~0bOH@?'$c x/><јg?X$LQ_?ؓ1??|oII`K%3,/ E M?#lo/$_ /^;јc>xě go?M?w Z?gV𯿶=!9%g5ퟱey󏍿<Q߃O1STa?FNw^a5׍-Y-d'Xki u?YO؞O(%?` yi o,C1 1$Z?ߎΔ#cś$Zqҍ$wDJ_ š_dM}zc_ҟƟ?hG?~g}/)KwP_KQ5~x J5O(-Ouz4dkFluo[QK:_#1H|)waWm٨iۚ槳۾<ßھ<z##>*k?ୟ'ݿ n ǟ|meؓG׏7]2YԼG[-3NVh:n';GFGj[?%~3\$gHC{]\\=*$ e_XMivi]Yjڴ7x)x)GՓӍRI%q_I+5u$[^ $9>5'q\Mxrone;֒>~' l> Z?`:Wĸ/|'.&zRYx; ?Ʒz,ѭot>y7V.$mdԵC=5ms?O.}|vZu#࿋IKi1L֖nxxB\c—wkj1Oi+/tWo?;~?W<јg?X$LK_o?~_~_+K%3,?OIyV~W?߱$?~ ! W.KϏf{;kwk/:w3O>;|Nĝ6 ;BN^# }9Ky#_\<<+ȸ&͸{;e\]=q>m߉qa>40+1x\nWMbp)RNrN7q7ffOM fV5J+*X5*PJ&$6 ]\ xm(ث|1_sm(ĺ|}~]m/Eoo qo?tQP qo?}~n?UPTvIQTQABt_*{>w?WO*]qẕ~y?w?_.]W'_>y?w?_.q⨢ק]?>w?7O*(]>_eup?U/o?EC-'.[m]?(_m/Go?E5]>_>y?w?_.l]>_>y?w?_.]>_>y?w?_.Xat}~]TQ./m/Go?E ]>_>y?w?_.~Psm(sm(Os袀]>_O]wq⨢]>_/o?tQQת]>_>y?w?_.t0m>y?w?_.(]>_Os袅t1ԫ\2!,A#QEyؿ#_DOuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/StatusBar.jpg0000644000175000017500000001714711665471334027412 0ustar drazzibdrazzibJFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222!D" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?olZK:Ak/$ '75֢nfLn r"nNYBD5Gnl_zx-;/L}ʤ k7Ofɣ\K +?yך}W9Lxɕ]oT#wBU>vjjvHGҘϪ+*DfvM"| e h00{h['uG#zmQBKk{tw2TpVt܉]Y3vA7t?QG&F'#zmQBKho]0\Io򓜟דon~&O*5I翹(ԻnI$ >01?{h['uG#zmQBKjݧt$77Cf&ͩ[y>ZweE`H,[~Q޻G`'9?{'?{h['uZ6͖gkl}Pi6g88SŴ'S[ſ̗6'v `޻G`'9?{'?{h['u[ۦ EpgBȡ K 28nL,OF<Ė)9y<'ο%(܅@`'<S(Ҷ].-rp G&BAgom)İvҤ>@Kn{NkktftU-n;A.UcԌ g#\WKwR_L֡Ѯo. \2ĢX7HUBO'3I/Qmp][ҟo?ov4ث=TՏ7M?w'L΅ΌC2n@e%XpAB ^ѵF{vdDvV;vFITg;wc$Xː8u"{S#yᵂV(GI;M6I{b: :*H;tLO?tw2Tn kԲ/vbG-Ԓ$PGgdsުrv@tQmG[qV&$ IVVt+QmG[qVJ%yR;hdnJ6`08#֤ğwRT}Z}\޳: n??玣ۏ""NᾸC2K 28nA)D^3!dr)*Æ >>.ooYGEQm\֟r[JKv ڣc$H)⫑ &joYGEQmXw0G<"DԌnASIQ·iF[qQg_ڵ&~1nqd~bOIyp3lZ@][XvD={玣ۏ"9t_Hm98MGΙ.. u2M^H=j{\U!%Wmmⷷ$qǥΪGW[ՠuh-kYcEΜeJz2\jQij.[Pq+<ߒ>VңK|w9.٘zMsφ5kYd$qdq ocM3N90YT>B !Ƨc]1WLb*i #`I$?_aC(Ӌ~,?(:[H!'Ӯ$Bl裓YV$a*i??«ie٭k~1fbK0$O'* _EռMcZ`Lk>yrxۋ - ԯ`m83vdnXrx9iXP ? E=OU[Օ0DmVAn7I&&oyr]B ە+mEm"\H#p$Ƀi??8Qp9-ڇECG3?T0 nw*VԵ+DiZ%QqlP^2AF’2ҧ8"8QXP .0pڌzBjǮ}c!J r8F"}t4mca+nL19eQ]_aC(Ӌ~,?(LTKX&if%e.w_-3T*hxJn?D77_w,|"$v[vz庶T|dè4M aӱXEm5 ief8rN\ }.-Tk~lי5=8.3GZaޗ>wKi4isplxUUCv^N/i??‹W@~#T96y:? ~yu[{2̛ΒVwR\66:8QXP .7tQz֬>R$j p@Wֆ˴_?cvƧm(-rw:VVqgP'ެnE=l?,5ԅoťiq%UE^'TL`SbMrկkd݆ٯZubXJ GJref?i Z6qc=j7tf).]cyd-8̅n+ŸRnE=l?,4nE=l?,4ƪN0!Iu?G{8a TD|.<<}3~{mo[ZhȺ%iZ kLB l94f->+_:MrIޭK?05.2xkWW6:ɊDA^I-ƱgDFy1Ԑ㾘YhUH+9m-Q5yE+ 'OIb&Ib&]ssvm/ K7|c: )p P3WUUX /#* ?g|>AXaXa.ثdc GMԮ \0fi0 3^?oij{^ ,Ă#Q2A$~G$~S+/e;1%8D ͖'[)22U=S%hwUyk)ٵf37 vd8zIb&Ib&,szïصbLIk[9Y"B,ɨJX䵵[uf {rsg$~G$~IO)nhxO{{i9B'-#qTp-B8J=4i^t 34883F[]u-@o&n4mշVi[mkO%km.K5<Obvt͓h3_Ki^0'6oAxǕ=u < i"Յ b#ץPI늳HT8'F1P X.'93bdFemz5f9# areRS̠&Or\ڟU;c|ٟDžvKĊ.ǰZkŌK4]ZSFsP6ON׬ұZqNf}"3#\ɌH̘THySZz@cʞE3nl\-w}.%)cɱ(Πu)%_SH6f9\1bL%K撾jtBHz4MAy,ԣ~$\SqZ1@'582E)pVha#'TN*9FC"zwTq֨;/򧻐"o38pCXZfc&-g${n*&hocH! e*|͙%%sl ]45Tj̉ݭũ{$9DV,XddD9& &)&107 C&4:L%Dba%3BĈkو 13$@#'zwTq֨;/򧻜x X 0/12,\J`0㕽^d !^ԯ""Ybuy.LdflWn[[z9:'r"br_ygf3(Ϧ & >Q=1Ӹu q%4 Uϖ[A:;W-WfaD.OU컎Z~˸=gߗnC~\#v_X:筧=tP5PԑMW#\5lmfZ܉ڭj`Uv3et0sVg 6+î6Lnn{6fve656%K.OU컎Z~˸:<џ/Odz=ǭPw= ^1Owj*{u']Qrz?eszxO ~SϷqTHySZz@cʞiEq\Owއx{;={zߔzwTq֨;/򧻚wQrz?eu']7?dw?wAxǕ=u <\OwEqz<7/GO>ǭPw= ^1Owj*{u']Qrz?eszxO ~SϷqTHySZz@cʞiEq\Owއx{;={zߔzwTq֨;/򧻚Qoz_Vӎ߆sco'n֨;/򧻎AxǕ=~-kcgsDzxnWWO>íPw= ^1Owj*{V5[[d.W}Zz@cʞ:wTsO-k㨷᯿?w]]^w?wAxǕ=u <[[Qoo_|;;=p^Yj*{THyS?᯿߆60]vw<{'uuzߔ:wTq֨;/򧻚Qoo_Eտ }laxO {)g۸u Y-6#HHED{5_>WٯQv)HXcexe)qt6ؕpDVI~9JK9 .k yX ]4Iw.eB%8lN?Z bLK] k^9ljRp;!d(e{uݞڞWe^N>b܉eHag?K ;|s҃i^~`/-J(.M|ʴYQqj Nwe+ #Wp)#*SZyf͎+:gs>z?^}!N`R[-*L592C S_qb6([)'8Ae (r>}KoWe f,, &( v 77-inJBDHKpS-=&7~;G/]YO觗Q{-;F'lzϨx#ӷSE[=,ځ&|Z陾׋0 \ݢDưd Cyc RnҊْC<*|b1~DC~GQb H1$Ä?8m.-lWVoyKj@KHWun>}:1\ݭ8߫Ze R8̀f\y:2wW:mh!G|;c焚$l?IV$/+(qCl%HQQetf* ⑝_>3AEdDbԪU.KQC԰eT\/?e}I>.=#R1rZ3]!Tp $+fZGLg\)O?/n"iCâ"|)[ +AݕU z 4fhT+yfuHi؂ ,'-jz)xH^Jmk1öD(JL R=0<>+X"z?v:ǭ @jժVŘ͢0kbr4Bmdu썲k=x5e;~.[SeɒȽ^R-Id<ɭ:h WnZ:B v7uյź!^>m;e=I~!>X=49'v>ZBem {h+@q( 5٨t#o NmkBYi\b/QIٸF5 ףg[ɬ%%XFKq]vܤm`ĩ7Ȭ+ށm1]5̪:5#Չ,vp*IJiMHˉ3<*bȎ_}zX^z/Oc_HGH1%Ą8TrZ긊Rx#[%KoYDHjw,ax[0wW0eQHCD,q V\[dj1K}>٣~U^**meH^5L "ىԉ*vGiZu oٔ'5L3Lo.dGl/$#Ǥv{B?|:WXJ 7 >PхЫWc2| X  &֠a7Z|n̍^ˎsp)#6I7b}R߳\v)-?̟H1%Ą8Oc_HGoG4{^;af^ئ_TeK~s';e=I~!>=#Sė~[??ײrm{z2c7b}R߳\v)-?̟H1%Ą8Oc_HGoG4{^ɶGe˻ݏ݊eK~qئ_T2}#Sė;e=I~!>7zh#{'&wٗ.v>.=#Wē7z}hQ#f^o6}vx2O71O71$xp+bI~qqs׫Bw;2[C>w;УG̼O}FXZ~?wZ~?w2#Wē?e}I>.7z}hQ#f^khz>g,Nz?sz?s~+bI~qq$xp=z(/5=SgsQ'byVbyV̿H1$Ä?8_cO8C랽_G{ٗO(<ޫO<ޫO_~}\zG쯱'!^ =xmTeئZJ[~Ε;W~}\zG쯱'!:߯Wgc] p;,^2gS/[˙^+bI~qq$xp;o*?OmQz?;і/b}R߳\v)-?̯H1$Ä?8_cO8CyWg/WCh:{Lo.ezG쯱'!Ǥ~}\o[ʾ{?|zA^>gteئ_TeK~s+?e}I>.=#WēzUAw{?,^2gS/[˙^+bI~qq$xp_ub)-?b}R߳\_cO8CH1$Ä?8޷}~'t6}Lo.;W~}\zG쯱'!G?ǫEFX2񧓑lUMh߯2)b88)bJr"fr)=1%3DDG7Bu]"Z$P5dE!CLrcNEtcC,X0h<p`ĎBY hN%:7gOpHTEk(‘6<-s(pG^RډQ16A/3h$?HD=V$ZSk$bF%CdJ@-h;,6F E6澢r, Iȋq(}FXĐ:jrsK,)(39NP\tQ<񪩗X1 HLDđ&&&Xl1 8kN eg[#"7:=Dq.ljJ2;$SpYKAlfV^3{bucn%MVIu&-',X2ѓpv.X-HI?G#EUk%nx2C\3r#Z?ɵ _BVZ`rΰe& c ElIf"U԰ew pF"]  eǴ\y^5f3|+>05Mb?Zku'sdT Dg/xGeEѤFU#倐GJ^hv' TF+̔+Ujӵ LkHVs8&yYe13΄`B\Ң3)G918:V&,&sCMU@晙|tde䜤bfqѶgW5Ymĉ{u-Ce¬Q>cIK !4&F f@Gd~Tj( Hլ3893 ѹGv^gfKEH%`\z#G8"$v`7I3Nj. GɟڔgqG NlX j"6DbSw'{/ Z &ڀb#̧h 2:G׆Y\5њSBɸ2RG$c%a4U1bV++M$eiN2K>*<.^LJh'aEK"l96L"M_s1#K*RcroY:/O-5MkWYV6ۢ¸>bHAH͊+ZTY Lf&ա0-i1xĖؚ6bRDu9O ?lUc ŨVL9j42:F6gxrؒblnw݊kܕ5&k~ۺI ;<10(g%S$歷> Iȋq(}FXĐ:jrsK4bXc% 7FצJ,=hI 5RKcWY ]Jf--E1LjE2)u*zY}Ȳ ΏQ4KR=)o&FR[EשuLؽ]X ceխrCII 0+@td<6&3˄V Fie&'5xcfoZ[@ r-ȍh&- |i[mi+:7,0 TLA%ؒ(D߁ae0j ɋ :EjAT ʏ8,>kI$6gW}a5.j M#ע~雮gK~Ա5_Kˤ e)]xu:e9vBtjrvMÅfށR76(ʁ24 l.pD퀑5 a BpR c`I@l;BB83PH,iQ M`N>4p z n1̯*Oq=gDMUz ̵YzGwKzhu1A!Jyp4JİkjU@jO Jd8ZB[be샢7wwolXV~5@ `t+i HKVȲzaR'@0PoTh_d3 fJ9*-yUco+-2HgmF36({0} W,1Mmoƥ*Y XH4!"b9ԙ#\+ѩcBôV$7-$B@$f298{*W~9C gx-^  AnJrSt3WVՌɩl`0xdH=#h|{Ϣm m$̑td#lD]sZf'w$h QZ't$XL,d5u ԡ?A%A72,/391e(|@BrbI Ixb蠗j{q8JP@.IߒvRٝN7:gJ(h.u*e$tt1,4 L9Wf%R6z)9lG+OVgM"(ü ICwR@cB(g}LF.-ȤKh!ia$- FC$\ ԀZW"gY3>50iX66^&Ʌ(:a2k.)ڰʗY G ' zָ3d.DWۅ(Y մbievWbrB⎐C P S^1:|cp~9~]m m/wSBX2se$eŸhO4ۯda @STYKfH ̦vCK/}1J$39:ibW9ԚBjz!qVӯXC;Ya3 C31rC9(8o+d쀎ǂQQDQ*2 Cφ3Y(J, XU;X&"[k eb1II!{0/ 'Lr, a&.a24.>};!E1JO!%gKX^b1 Xkc͛ ZbR(HNKbHvXX*~Zk6_ \$3q3#31erӤ_N,o2p03ˢ0OK#ydd(X@9H#9r"q혬}=kUhSwgb]u`X HFڈXv/;i¼I dZ|:_w y?/uI;^ɫ[%Zw /S k k-1nJ`+ H҅[gr1.d̻ |ǟ*LkQ ,-JqủB#VrU"3O0.2*EaDIL-O9&gϊeM}0uUedrf$3W:}V%)˾)J}S:=$w -0$R!3\YT| ϣ!IӅ:-wn]Qe64[rLGCEl T:*>8A53Q U =ϑ& Y3y2})ElYuNqc-l usOKO prĹ.|f*p)f8d]amd8@ c8>C-ݒtq\ =@Ȍع-]irsK3y$v'ӖLr|y +uLĐL5T2ũ7fuTZfjnW2a\a ԰YfWհZB`d Qš SdvܦeshhV]Ȳe[5^BDUb)bس1Nm qRغ!ݚHM[ٜ-DH6$\yb,-IG9gιs{.[-Ф]FGN.2A۴7 h^>lёP-Tii#0( KH*e;/#RGX%g©"9,lt/3m3fxUcj6jrWbܚH b-UuS#SDaK$)-KlCv+KS`d$qDrl[ ZVb\ Q^!jPlΑcs&yS,p90!΂7a68XehI҉8\ɭR& ;ދ氄_k 'Q"~h"iҊ5q)>gL)3kNL֯\Ȭ+mPρf\9\[>&Σbk) ra1Z۰unbm.VjP5߆\}b3\S;(UNWAGS>,&A# 播ubt1^nd d9Y,_V'rέ*͊+m׽SHoV&nC/\K:>kz&^i#URE#qdʟ/ݕNAcwC(N= dJQz͈j@-Fޒ⢕$gŎBCz#~9u@L'$G2տA5cV&?J{$nluS,lhڛGmQ 17,Ȗ՛ײRQQ' o2EuL)@5SRI%Zd}z.eG5c 1Vk5.:q4B4dR28} Cq9^3e{a)-V`nm:Z1^ βl .)m*"#'Sٗ3+`Y%CSc$S^7p(~~ccx&'yik^@B⍡.UΎlkmE: T`H.fLJNY1DMpRRtc ^ܬ9;΅mHxo3^X[XrȤ X,1l265ŮbGKbv- DCPv)ke R9LyEl*bi"ݜL*:eiB+#;ҷ\]J12-CXvG: ZE1ּ`&5͈2 kHcY4w5VnwIuډ=X)%c|K $#>8i˘K5,lJ`ΩV|)&ÑB*2Y|l&ldxm2duYe]uԶ4]&ŐK"ɜ3(% F<$J"n؜&ZB7V eɊy]~qr̐? > aU#hcdemj@Tt4SpahV(=T2[1XCV͙B\,G:nRUed㹐o at/+LDŽ@:k}s 6"Z2f+vPHm`0WhzL` ΁BGr5.ov Cb :q˥Z Xx%RvZP@UܦQTkk  d\dDR:&xCk_9,˦IyDpCyq< C;\Wd GtiA*\[s}`dd-aH^.eҾȆ2$=yFl]{e jHCɎw&yToҖ6H1[HߚZ?>(hIuvS7aYdҖ/4i^vF#m wipBޡVYJc3mem+UclCemTlL7[Ysl-&0۲sԱG40n]]SHm*aήuf˩Xksۤ3Klnx d8YQJH0Ưӣ(锭:[%3So7nB]It@y"Q{Q('Hܺ-ucvjuřԐU}7Y$.b R"ASD5+G F m1Θ]ԮZRYX;181fQjAfhH PVlzTf6YJc8af}}*ǎQ$XDd$)j>A鸄Xl(dWi]"ȀwYI}t)(L̋Kנ)tu_ЀV2%.+P[ScSve1nLy-/]e]J]m]mkmmi[nkJҴ+ZW)(esPLRITPBlȷ7ҋ+^&~Zmvl^u"jXg@,0Pb|Vp0 ı"VZ*QۈqTbI 2XpJX`T$`Fw tP6KhJol`kL=m6cTTs#(HuډܛrXƜcZ^tQCβT(!FO$ksR~[F&K"/`e*}f($k@:H:6% Է:5ͅZ*3X.,dŒ+Z[JuiKiJֵiJRkRZ95QR+Ԥ\sl;,hvYd5dS ,2C(\V#`,2YlcՎr#%jAҲtyÕ:ᝎI?% 5cZ"[WȺ#T0l)#kԞW#U9SDg(c͋\l_uA7mRIc1nd9X-R?iKWy.davƷUvwll,Y#cdfk^Pԕ*TTnI2ӧϚ5Nj%}6Hl'6fy 4=H{cbKƛ p}K+Z"4Y*[k\İz[ׁ?eiYPr>ngl2 mu)j3lruO*YKzA169MS8$ WـAsEK,j:2ޙJӬ"[5<,z6pw^98Lb@uc ]$SXzdjf`rŀ![TFP⤈ z^2IPHJRQ 5i;ۓtdٱm Dt*,+bf*LWQ'QKPףٶ D:-y}/W=9_&ù7<}hn Q9zj]^żŗE75s`A* fΪ7sciR+ G`buJmsc;Vss<1wdZ r;I~Ա}~MaʁfB/45!V)0 jd&M_)9"vI0EC/"WCZ-vX0#/xf Mh})[W0elSى:Ŋ1:4zgR~豗ieZ30ClɏeTE`fA/DO)&ˉQ(mĘ:&K]hS+H˗2Qb3[`JӬ[h \b Se:n q4C]K-V MpbpBs7b:(R䏣 n%=~46"n0.jy&)`U(ЅƩ!td >צHXJJd}%8{ D~J\vJEEg\jƋ8ѥnMh|rTԕd R$$. aiK3"u(ge2#$Q1.)2ڙUG뫇HCoH;)7`4o8QAfl5Gµ(ϖY@]QL:KnugG%6IR8ah6uVY{S:vL P[_ g8yIJ:.d{oO(൥$,°0LHnضl>lŸa ANIx%Ć^q{MwIjڮ@wE 8~?[c 0Ft1.,ĒK^޷kKᝦDZFSذWI5L>ĠcF=jW{г l@ޭEQ{kW56C$#x<ٻ*}|(HlZb33&᱀]܈f #̏JgBAFꘑC)^ɳ9+V9u͛y(-&kR3 SK*o\b"*1U֑=LtBGwD~3XLc9.h黬>$(ʺQ$yu,Lm *i$‰C5 ?i2YF1Nk^BVEh,Du>) 7N1/jvp|Y2]`%8ڒB,ڧyUR(\è>C5Ff1$23SQM2)aS™-̒6wwr|(l84Y5n)9wu~ܙaè&uR q,dx`b23*&ZpۓR=)sb\1 8ṫ$pyCd2Lf$+HTP# k9 .'5BfvglO$+ӿk w߫L.؟HW'iSV'\+ΏX?]oru֔<^AM`v;#m#x_诀,{:>=* G<:ͫY0L4bFOLIibfff" B^Fk `;JLM lM͸|%nmKjyoVTVif#cEteҔ)JҔ(X)A9Qs33?\=(WҘ[wIvTp|xs1fU& ԽG9pd䭆֥ܵ/lsY8^q+U>Qpr(nIVJ2#uqW'dl(y<ᖱ@ I8c/qLb;C"mD IGm2ʿeSĒE IܴAbrqzØx vXX٘!] 2n4:V% i+,j䘙̦k01=fdwjbRX.7R3089z꫌YB„XIKfKj)4(v2C*_,l /ȓf?L]mٺvsJPV)E t=F.ggUĊ"p; /Zz10 ;߉xz޽1m5#r#D\R "GDKR:'P\a&NAz`P0㇣MnO!r:] l6b+&GQ4T5+ w,s)0DkfxFnq{``@l7gv&_"NT^ &/l:%+5ϽMT,Ŵ `- z>ՖkQDNsFfF5Ṯ HaBN`&"d?gD1b8h3T`npcH[%\e!92[k UQ0^ ʬ7}9LeTu/\J]H7VŊQO4lb-=Ehi"E PSm\I ď(nI!o7o{&W8Oz F8T4JcH6ˢ&Ie4|D^N&温l*M .j-L6Ԗ v=pCg0k$)uQWN% V,ۙn#|,F*W>9m,."-G%hk(l0; 8U̽xLÑXK9nw'K ܗSfwk&t[Tz? 374s93_ ^e-VgQ7ɘDڬO^y$'ـA~z^Jf:TG#9K~Yڻ DJ:"fA6Ϲ8M7{7.[,S>M/lI7_9mO$ [[J.-;(bsb6<uB± +,gu ׭߁]sұ,GрgLg<\9Î8888p8Î8888p8Î8888q6't;զ  lO$+ӿk w߫L.߳lYM1Pdb-U\ȭ; j\5صxJ"8>f@RT*\xhڑf݌g]<6/G7ȱUe.5SnDNmvP X\$ؿ6K8 /jثLIMe{_FY`BC9LFu{=hde+ið٩dX(6w)./:3y*)C3z֪29gၪx<'rd uBM[A;5}vNjY$X9OFj ZcVsHUΎ7='ͷR"V9:ڧTm5)>tYrfKU8l#-&LFd nZycXaj}MpŞCrۯɫyOlcX/y W-L֚/@i7 :%nmdjnkW?La-qDy]{m>kK[?~z[hlI_NJAG~OhB"5i8 ?)?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/v⶜tK{OGz[RLumE65UcvJ6MQQYTtm_%X{Ofm/Sٝqʺ\)mQ)+.@-?\/i"4]N[WT4i`]7zHN.?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/?kSٛr:g2x6~ͳt7m6/%X{Ofm/Sٜ۰m6/T7U-P.kUNFHĎLs9OFYLe3ӗDyLy&xuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/CustomizeColors.jpg0000644000175000017500000007007311665471334030643 0ustar drazzibdrazzibJFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?xCsowpcbXaT]Ex{SH2 xҰ|]/>qY<H^=ʐ˶R;H퍳H~X1e ~bNvӍW*7+X72y O"6(VALɣϞp~5]νg=I$30/dױsZ.iq>iWK',xI}=F(Tpqk_Yw^gW>]sky b66ymVe$]oDHmF1l%y-T;#N){:]E#||M^~gRv]?3+xt;PioO/̏u(X 0s5m Jm_^ҭlմO:HX*)d`A1ޛI4OYVy9J>$wo_Tih$z',+?J> Zau}.Z>L^G}i<.{i<.)@=x tu}Voq}.xu zj`57tƖo.O^}Z{YX}7K ?㖝Gթt؏o.R}Zig%)4fmr3~nG'>׭VGG&c:2KbYv$`1P}F"cXѕܩXR:; )}Z]~0P:Y `X2[`=c ,V mt0y0CԀO5Z}Vfkn m^0+B(0 n>fmj =Ye`yn "06.5+c9[ %zQ鶢%-8xicF#3:qYGiYn[$[W'Ш!c#8(0 n>/-<?Qyo`6y{lso+5i—թnk3e d/w`,NzӍͬf(͕' &ݮ~nXlLj㠬֤}Z{yv{Eiii C|řbI='gH2H^xxs,KBr9,OZcjnS)1ꓦ(w7+m̃#* t8g;; >?n͹qE!|UhU旨,VNꚙ 1*xɬӖ]Ey 3&w$7+iˎrX! t86q5[kTV4`gUzҸ M-έIM y31h$뺏/l6fK HTe,v63O$Jm87gFhp屝q855GONyq`.7eh̯rXU .gqéޥo7n"L z|6A: /_:N7HjVlt'Ğ#g,E33US٤G$"nG6 c{cozuY^q\#A2}'0\Ku)NQ=xՔAEiN,mbp6_ZًkQ\ZD rmOW89n54mλ1u) dmjAcc%or#81HCX # 𖯢jqi;cG%8_J֒Iy,6Aƙ44gFkAR<1!'=P)>c4=Фph|DP yd$/ Ka<ϲ%kv[ rv'+ /&%=/w=C?w}Nswe=AE{?+ /&%yoĿU?o䃔_>MwxY[stך,I=*TIXtH { #>k[r Q?" HPnT #?W_LKQ ɉ~'uZ_-A-س @튙.^Q/5K_*KcCJH9 z׬¼b_*tjF鶩#ȈE26/VǃGAy/t2UWrSPIz>g~) 8u/-NV>_»m/m/Ÿ֥^'V>_¤]/Pci ci .f_ύo 2|nWg6/Q6/RԻG4MNξ;ci ci }j]Wsuߦ>}.?WS6/Q6/SԻ]`iq~8X^g=.?ٮKm_Km_Rw9cy>߳K?߅ ?߅ >.WsY]ϬM|g~(g~(Ի]oϴoַ6@?G6@?G֥^w34e-#͒4ĭmsp2FpAh@Q'Rw [k/ifx|geDni>.q'i 生ɣgeDni>.qDJ!yj?i>_IԻ abyiToʪL ( 32O7G֥>rq*xG~UCgeDnt1W Գd }j]n]B y>o eU'1^sGm۷cv_l_le:nFfZEQmt)keQ4@2#?nrampA"F;WU6/Q6/T^=iw2t}3Tӵ;;Hllo3HA T,ː0'z''9ۻfvtici ci ܢլ -;}'XXM^mKFϙO5|RRӿ:m/¸_0[dvA_*=AKQK5\_n%֍4y$&gbrI%rI<);Qg*K"+ŭsIymձA9q[x’' k5K;t r#$\:UZ,$."xOĭ 3Jꍥ<rYy8~"q.I rwՌҶاCjc3&rvh$vb5.>xI$t6mg'kuM #r0N# Mn3-c[WRk ><1*٬gF%oPI5MCSϕ5 p5 :LmT!͞.I Rk};MG"Fk_8i8 N?F}cY#GNWoI Dc9vB͉2 "('mKT6|V~#Hf7e._d\ p\jksjZ0llHۉ$`Gs*\aCy%X,Pja5h2k9nuYooX#n@c,"JӵOH,t۫no7öC0hP]Ah?>g>,ӵ7%&UYǕ|y{-A彴%gxri@eDf"0v9Pp1y(#c};Gx]NLu91mZRǩ2r͇ʯ5Աq8B݌ b u6hw6[}AFxڼQ7&"{)eXf)CstP=oZw55-PlK,mr ױ N:cZ@Q@Q@UԬt}BmKV5-qG8U|I:$вaHdgGPciykj6w0۾vK FA5yK=F[MSS2E\Z-OwP{*q ]U::U{BXy,_O=@Exr:[Q5Cy{#Ȼgd l2es9R\%[\ҭoȤ$rU`A*p>aV{U.կu~=:=},DI*I py2]wQPt|lc2Ihڇ6*=ve~~Fl7m(i"A1൸aGt_s c0 +l/e&n<-ptPC$a; X'o4Ě)^DDvH( p\mK/Ķq[Kk )/01݆;d1` MMk,j\۬-HW͘2[p(LhyHKUT I!ү=G5칵]V($-Q %;|`@#>\kW=$ťDQc $ۡ+# XdP"0ee# :)FvMvH,,dSZv6@#wCg8$z[-i%b|g 'PjڬzNJZGa$fhrݰ1"Zo 7.!/mΕe[Kwufu \.rn.a_6I\MB~W^$&ݜm$횅&q$>N8L#Woɼ%s,2vK|٢ߕKm.v09&V7i3%-r[qBJ [rP2 Ƥ#w(K[{LqN$h lPgkcA@Sum.;RMI5KtxcmC$3l\NԋIE[K-RGz *z(_?Gڏ?/>Q|Ej?" Q=G}ϞG|S业8}݉k)T%BI%@MZ ( ( ( 0[G8#5\z.~sD "H*eƙrO.OXة֯[D'e/}+# ïŏU'TޕrZ35 KqxT Ood?qTYA4n;ye+YݻGH063)W)TzC\W7C_Jƈi#*]\O@=({PZ{ Knd"pG̎Q>~hjIg1۲:hk/ZN툩02wm` OkS=|]ͽ#ܡ%UbEbc'#xNh.guXY.4UQFIˠaO[ Y3]Xn)'qkio9[APM.R ,6ylOq],Q»G{rTjHh@ ‚9gL OIofLR=܌$r# O\Ms9s"nȲa6GqkN:cZ\eQ@Q@Q@Q@Q@Q@Q@Q@Q@ V#IdPA$(2E <Mv2E <Mv2E <Mv2E <Mv2E <Mv2E d1Ɍ \ G 4((+>/mf?hn~sD 눺_+=!k ϲKϽa~oTӠ':FǷҲN:cZT-6H =8鎽jQEQE}]/NLK0Cog4+jp21zv ~(Zb~ק؛N㞀9Nlm> wG"t#x  ժ)MO+L4Wɯ$i>ȂgfޮπI‚04:c<'}F{-/#3dy $6CԜMӵk[b%21y8qWkȴX777:Kxm[91;ݎc!FJr96~SY9qw+E!VNOY?xfۅ/_i~}vuktlHK`N:e8?_/ѰT]oO^_y\䐹P9P:rO8'LԴ]clg_6)#$ew##8X=ӯ/bzzE̒Glq⻫v *I>ͥ떗I%#<`̑0]Wi+}?/ojkB+,ye:y;蚅ŽƝۿ$WQjpѮ4K*pTHyi:&kYpxu|7,6iʼV;731<Ÿ/'fOK[h2z_^hJ/(.K)!3^-; #gk[^_ D2XMbV̿',ޗrs>z־T&D䎥wcr0=OdƼJ KOЮJƝMYR Ar]kRWOMX.'"VA䟩H$; ƥ7tԴKvӿE-OPX#N+= ( ( 0[G8#5\z.~sD "H*eƧr?2Oh(dִʳ#-6{bo/In ]_6hRpˇ] I*Mk'$$#n9ea8./ EXRaBS :;rKPݰ8 I$Gwwmw5KQے5 8f3[x.KY+ @ u6+Y,LjdhX/M> DI#Ran`ArF9A aMR3[uɸMߍ "<$\53j#|ܶ P}'i6jc`ߓcFˍK#q Hc=>ȤC uLٔ:RM="[O}RpTJdv$׊&c \ۭXb9c?v8 3^O=W͒hCqER>]VGQ <jQ-:}0IEyFE $l-sK;~jԋ[ӧH2dUvd`FQF px co-pM{=시8@O!Wך]蔮yk?%(ze~o"O)f57׎e~o"O)f57׎MrgSoӎ֯;s7?1M>N:cZ@Q@Q@Q@Q@R;omH.ϛQ]Kk(`R]_._ϥs0*nMMnIɸ$zSMvBpI$V0`cPFGjJ(((?k>/mf=G 9@޸5\zH 9A J+Ġcu7nZǤ?TI~;sӟJ=Xʹ*W4FOyTr}N \x 'OE j]vU@$xgI-mF#ԭq=4Z?J1{r;yƷGa9 ʹfh|v\nU! ii6},k. ;<$#®AX3Ta=hZ_%Qhh#7D eLdT} k+M>8[}u_쭦շٍX2'8Nc^EqvM{]^MhF#])ȁcc"h*ʷCh o˷eD%FFtew)v@* dyG._֍nMg-ٞ2Hg3W(%|>s>s2@D\)局~aNO8$S?/h%|꽽p&-%6,sus>?(!'T+Q4Y|XSS>`Зܿ~s>\ϼz_Ir_yTmp |^,$[ TGaٍN+O_o}} dyXk?+ѫZUVK.h5mrdyG._Z:iyT߲8/8.2A,kYiZ;l~s>\ϼOJ5IQBO}^ e/H%|>s>v]OQ8P2N砪k<<+M3Z#~ qdzkeljW9~s>\ϼI~"^im9WF2}4o7S ys @tp9'e>$n_udyG._)mu-BL|kM~G(G4{{-MA6#0U\a #kz[f'ĸu9}} dy\Y]ݮH "Rc1x#nr1Wim6$1@&^5gv55%%|>s>yX;.Frpdzp5N[ӯ.4hػgȔE/$ =C?/k̾/mf?hn~sD 눺_+m: XApl{}+#,׉XgJ?ַ-ʳjԋh:8k;XP6ήNܒ7lI.|/m<7]z/"@e*AH!}F0w↾exL8'YKw#c$ VLj5)'ϷX\[d4$A _v܌Ȏ{Ϥ\j[Om;;<_!%xa\ ݍ 8;#zޥ[ȘnV+C:!<@ /Po|#Y4MGmǘTy*UX0 ccG$3gD!8$6.v獒3wHrð'ڍD%Dq }¢*c\bBυH}cUO2 DC $.~gkŧŷ}#we&41,*f?1.H6팳46cR)c|Ā16gfܰ%YB"W[h_?2'CCvWqv4wؚ84Ǽ 1L"6+{lC+Lm,]ߴgI[Դn߳mcb:WN0˷$Ȋ4'ݦ;.t)yܜ`Wx yeV v;uXeTԮefXE(WH!q'}q7C̺5,p8$~_J46FF;xB E 89k?%(ze~o"O)f57׎e~o"O)f57׎6wx#)Z`qLuZVL:ծ)Y"HTfYnz)#Y1☎[kAǧ1׭tw 5dk,`{ʯo}ow=0IKID3lr ]O7~!1G}Qd$Gw W$r W-zkj|ii64m&Q*:T[25I iU)'P̍ev72PɤxOWV'NmylC4ߧos>7^| X4k]oM@+UK(1)A"CH<7>/Ɩ^ŨӝH Ț'0)XJPE֗g t;9mfxFא1缢-H7lh|l:B޾ieEoȯ4/ϟEoD2,|[iVwo驪I{>ƏEoȯ4VD,̥ tt]躼^7=ʑ]Xy@OndSeombmnVo )eK:4Z[.Dl?w/;P͕f<)Ft?.Jńp- _h_F?CԿO9d.kã?^ {Rk[i4~i#2Nc*p\垨t-QЎN+shU' ;pF՘[$MוmEoȯ5I) k8*p+z4܏c*8YU][[CͿԣO&[i$HU3AڡcNzjxzX-ƿۻ 3PiAaGQ]'`q3^^F oC47_?xkv]?@Ek5U3]ծq4/S^ͬ$O ^8VGA_^%쫮N3*`fj'EL~5(8'i/]wK9Vvf12`lfRS <_oJ(%xFUn\S>zP`u5^P̍ev72WyƷGa9 ʹfh|v\nU! ii6},k. ;<$#®AX3 za=hZ_%Qhh#7D eLdT} k+M>8[}u_쭦շٍX2'8Nc@}oi7yv<>vXrpTi[\Gwe5:*%E,* \r洹6绸5l^/XX 6 jUtVXtieY4y5%T#8T0xLz%pm8%n pyF>?hRt"-3hxZgOQoz6Ir22;+}s}q{c$D۰8XLmu7_Gcw'syv8QZbj}gt߲l?qz (+FwR]蔠 b,(\+1݂_KF[]#$/PeHcO4-`h8i(JJvU e;Bl4uɱG6sa 9b=m WQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@x?- ׼W_z s]q_?xkvZǤ?TI~;sӟJt$HVGX?ïu7\MM7ydPƥGmaUT I]tj)=J]O3IZĨq l-=l"$kʰ EsK+Y׼;w:Em"_[\tvK!eu7ăp˰}ˈusYjngaٲY}H`0Tq\<5X6w> DsDN  dR\j/^\sus K<"&gh*)$[Gr$m^-~<=xO[Gr$m^-~<=x@nb,T\2pt^jou¸;s7?1M>N:cZ@/[(ղsTPKe= ?l:\jou[/W5Etڶ_oV{Q@/[(ղsUʑ!dY$(: E\njou[/W']J?z"Pjou[/W']J?z"Pjou[/W']J?z76sܶ ,Q @[(ղrڀݼ]s ELiEǨղڶ_oOȻ?EǨղڶ_oOȻ?EǨղڶ_oOȻ?EǨղڶ_oOȻ?"㺷[YYjٔ]ZHvR2&@&wxNu/:O.'gNPKN=+-<]Iwlu(ݼwU^3n\ ,|>O__"^:v.|Ϻo[(.01ƌ#2ďd44~Uh-ԑ u[2 "('_CF3Vh,瑜! $k2x Sd84c}qiDžWkiT؍nN[Xvw1jqI$^wmce+)C0xJvvoxqp"$O@M\ӿGK>?cٿvn ko%x!`_.xv֌$-&ƗqIK馴x[gI<["纀B$u=VᠷRGT.M֛qn4zg=} jP=; #?dKW36ӷ|oqn/WRK,+ T<@p;s'+֦:wt{y!<nLg#oy@ɿ"Q(٥.cxUfq xe-mY蒒f220:N:cZT-6H =8鎽jQEQEQEQE[OS]m?G%OP]aeqyr]m,vvc7PPYJg<9k9E֡L$Y $wO̓Z߈x(*]rN Œ@$.`b~2O[m*-dZо]hviW.ednBgU*8KY^&-g@z{IG-&F W/'j8jҼG_Ao]hi vרZ܍*^~V|t86u+M.Oar T9+LEo.^I\ mB   6-akoƒʗE F}2e݁y0h( ʕ0@5? [pO>KdkLH0r[7uojw&5'>+#fwdA@`DyiH#ex*NTc#f;z.-g?cI8#m9Ee׵T{XMp~mu=R.u Cd rxcwZ,1C&Ʌ2'ޠB:wuI ?#YZ(((((?k>/mf;RvfX$s.2܎@Ej8?sko p:] qxo4~8 @z4"66yZI-[- = dăQ~,6²aTll7A ?ioOߙ^-'"#̃cggXlmk$2 ǻ}ҝ61<.]z ,z gϳfϗa.WLƥGa U" 2>FuU;~ p0,hϧH$В~vǏQly\#ٷg|(oÒ OI$A$M&YDmQN7M> (,gm f*dې3SQly\#ٷg|({_ZrMuqiuR&cwE_9FTcңJڴOqjΙsck-HTneCd>ݟ>͛>^v˟҄}>}6|o?W]Z߇-fK>{X4wBV jj KGC%\JX2TwHp(v|6mL5H?=W圬qAۡ8oiא]oxo4рx*aǜ?zN:cZT-6H =8鎽jQEQEQEQEy/gsӟׁy'%!G%!G,[_ jmΘ6}?sls w9漓ZZG5tٶL>sӟׁ ]6mϻtus^I -s}Q -s}Qw #WºOm Jsg[b{KCAkKCAkS3~ŪwIU:vA'͜ȉ_g??@B) :4jY` 1,LjI>JmahdLrW8??~ŪwIT4-ɷ,M&B W_ \T_ \TfMj倂|mP xև%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/G%׃_ \T_ \Td/^axH GƹoKCAkj/; !Kuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/Main2.jpg0000644000175000017500000071316011665471334026446 0ustar drazzibdrazzibJFIFCC-" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?M1|̿ I_| k%|AmG 5FOxٵGU5gV߇4 gя/0<ɼFUI`JS ५G)MH?$rN GCc] Iì[tH_/vm?ZvIkiZGHEC7?V-I,,'Q+jaiPi8:QLOqc uzn#Yɿ2N&8g̱qv?0eBJ8F5*J_`TjI7N*i/ES`]3n; 3󐀜W$I5xp0{610p0I XJ:okz$Gͭݤ/.'M7CmծDW>'\+G2|cۋ9tՓCk~v_'+($/2~1™_qP.Cf\aܓ1j8lU'CO 8˳^m˨ViVu50qǺG O |f8l%Zk:%b~% ѿ<5Dw7acL6mcz.-nEҦ0}Gr'[Z&hEױ][\[\}_|N h oxuWLXcMNX^fk q.-UtaB_TCf(qʖIV һx|0:BubcFn7Ju#$<5Dw7g|.#Fu?|t ƛۭm.{f ],- Z;MiEquawqkmuau $/q$aO𾻮V=&iڢ]Jl5飕TX4+q WY[|1{\e O F?:[yx|6 ^28̿ exb1~',)pX68:T^WbZ6*G5Ңeղխ_NtԩV)]Y _K>t?\A|t٤ 47ڞL!Dy :6vLΑsɬs2+ <30i_%aYMwO,HR*xx> cr&V S$jZ9ûVSD,Z8V:RUX9S,=j9}] _K>?vxkg"4o7_<3_Oj._htVwwqZ]Xٳ()+,2*-ˏD@<)o#RF8.QHZ=34+ ʫ̰3[qfj|7atq8b(c!JSRSJ/zyNyR S| SX[TѧagK^ZN B:a ;uR. ,]F% ѿ|o+7JG $ٵwGT7vlwa61p'mZx߅=h׺?4;Vе:+oMBW{S{n[݋ŵ窢4'ׇ+#\043N5c_(e1S2#"~F MhTˣ5qbpjvV뉨f2I`*'a1cSi4erN_\䧋pe zݿ<5Dw7g|.#Fu z:>#n4cqodZ-E=7RZŨI5 ff{"Dg0jfZ솉 βn+q[ƧL`˓yQϱ}Xt#X̡g.Qt'&5', U7⫩{*g|;Vt'K9jueBt+BJ-7#k֦. ,]F% ѿ|x;,T~2%O'tvҠtYRmAo wol,̎]7<oZk/Z3kDZU&UQ{&q$0!P oO xwIl`i+R'/Z8C&JjtQpU͔^!a#O0xf2\xdOby?/.?<5Dw7g|.#Fu=)Ciu=\Nqs12+ 24R|WįmŨl@u o$9.Pw>^)fy V{18p燭,]l,*kB R!bZVWspee W4pyl*VQ.zhӅ* r^ҭ)rAN2s]Y _K>_z'j}4)4ii|֖yese{yeoyn^ 6Iu+-yjkswp!!->[hj\Z]Ziqu0M{k/ይW*X\y^$'8\~;>ur`3lNYʳ*؜.WbTpX S)F?AS+U Xg qL/S'aqؼfҡhURTy//]Y _K>ʹo/5ɛ#^/M[mOLum*RMJ-m2֐}L P] Khz֙D ç?AӼ_jExB]Ȯ$Hl/c'ɂ+{;s,v{UQ˳:nGGaJJO6`cW¼GBiM,ɳ ]L^t<0⼚.x:8[8QT_Jc1OQGutkC^®Y#蝾Q KB]FtYub!}6]KLuOfkEK`H `[5b {)g]\X--9Y_MKHy%Utn浚; ?rgXxqyDl  b N< zУ,BVJ(RW_?+|:1o4cbx,%ζ*p$FExow!O5G/ .Y>ƫO xRӮuox^i-J]y$ZݞqK%ճ[Zjw :_75 h\ãeAiW;Tyq{-AmծQ o^9|lrdR֧~mf>ҵ־ rXYk,#1(cQԭ:xٶ2x Ukbjasz2XhU,fbe0VsT:Jog/ .Y>ƨ% ??|e_ jWڎxBԴ)մ-^KJa6\I=`b(1n mx@};tgOl>}[[_"o>Xe}cOU7K1ꪴ:yjjcV!T\ڑpkrI.p> nts*Vsx}r ݔ~=1/ .Y>ƨ% ??||axvHJg56@L.wqȶ{i$\"4;YQ'u!qaxz=G- ;]^T>k_:{{/K;k 2=eYO_.kTRWb*ƫO ohclW'ҍgl`5KᡫO״I>6tݗvOxow!O5G/ .Y>ƫ/7CD\KC7IRNB]4(Xy$fPں/ Xxzƍh&Vꚦk2C.ou)6}6$ZKj^՚)RA4uPp0U_ 8^I.y> rs04 BX50Y##`9KNnZ5c11_J+V5:҄?xow!O5G/ .Y>ƫ9.i?%ZO KqCKn#ha"Tx-ѮR-7އw\n~+’+쫈me_$L{J V3ƷLֱwbXH,*¸~"pbHt(K1O/IV!*հ29j/ecNf5xT+Cj^>]}W~[Gڏ/$)m^!BE}gq3$m^MzeY^hu_H/4Oq#If-:iqχUㄝ Z8;01L.C2+1TpEogNFR`x?'C&Nx {  Ix쎔Ĥf8hsRN@xow!O5G/ .Y>ƫI5="+)u->;+o-$KM-dMJK%䪖LBbp,8]mҮy|/'nQgMFU.}n'F^iZXU羳YǨi+uMߨX㸴\W6^kEZ! SbӫpؼƔ>.eK R[3ypUWWVu,. fzӂui!,dEVRqr>& ??w{Ÿ!.hC&7WdykOOgOy#V^6^S/&wiX׵ SH xwK{'|sxo =v7Ecb..HOM/y%g_p73 T@>?>)_h]h$%QqH !EP m/?5sF_Os߿lky3|%C*ɪj.qM|^K9a8BYNhJJ49T?f xO¹Vw|O,n>i`\. F1i(ƾ])N8/i):^n W8ymi15;0?hث(" #Þ}S~%ׯkx@-oW ?KO8G/x*=#Zώ#Uz&7ڌ^G+ãĮWGI}?JOj>% ]M yc(YXdB92~xͼ ~q$ laG"!'tO-BƎ ~6^-Yqak2ꔲg(1kKjQoZUa(ЧӖxc٥UZi4pZfJCGzS{*ʷ=Oً$~qH"OoBA A #W?|Ϣ麮;RiZUs|8!|Sƛ[K}^h|`oBVƩǡxS}?Jկ: 'x>>;xw xL𦫨hZΕ؋;l_\@.ln'̶#~rQ7 s2?J/L_-W׾OO>a}=5O ^]W[3LN.\%(<<)sEUa3lj7W 쾳RT)SץBq>3԰qؚ1L Z:/TpK[/ĺ4+էΔT RNU":|ߎ_gdΑo>hzbɩ{RM0^ZXx}?째Q{y. Wd?ڕcx%7Sb8+IU.~Ǟ9Ҽ="7%O j_MoXūϢZ3KgC'b+x'hx'~#SO  c,_{ò.Ժ/|sP? Zյ2`wg3ǀ\G8_ 3\x>20o5 ]CQP 5?ׂ|uAixZ|JYj|1/.x+W;Qz{xNW_jZ'4!.>|hkc\?>~P 44m Fo^b f/n?<'qɛ/ψ-|;'k.6i[#-GO7??H+5*?[n:|<|{dF8R7n5渎μ^><k\=hKl77hC O  FFBt*b1kdOc1eY _K Nxz,JQc*sZnn厎n}e{iut&n|&RÚ,s[L$?:3ox'~-KV$χu '}3V4b9l4˫wm#e,: y[ _n[?Ae*29Y UVm ȣ~s9;~/Og30># 'yuƶSfYf*"5iԧ#.* !Vu+Rˆc2Q=>35 /kxr+dXL]8\Vc6L3\ das*x>:u)TOwm#>7!ֵ .Im%6sb[um"6u(8W~$/:mjG[use-SK,XV[ A 3jh-c"s ~(>Xςsbk1+b$pYyaVg81rWJP 8j5p_chK lq lFOC2X "sR>zr aVܿ/-<}y>,jI麇u4y5.oiκƏeo!kEk-2nCLs_IGq]g9ԯ56׾ Mk(4-V_ 9YZlPϟV?475cC?߳_> N[:>/¦y_7x\>PP^ y|\%S)?༻NYU\沦S),xr{o3>/5)oWk& 귩e*j .YF{]&M [ߪt)Կe GJx:hZ.}eb՗Pkx@f ?#xus|ѡٯ+WWa\#qNUCم/l:([Ӽ=Z;_T~sxx7,յB|n %n5%.wCdw| xS:$l|/isTϭVwm6~.em/X 3%iK6mP+Q|ѡٯx(f~c#of n5M0+L.e*ܟ-1YvZIPQG?o?Hl%6 8Iqs:Uqx51UʕgST¿e,5h:o~|D/<XF{/Aƽa5¾ YLztڵݤ:Zuݵ8oo5Cl'-ZΡOx>H ]sFմ 9`{/'}>jGKfOScC?߳_> ?Ti7?c ]gF6fgYa)1ȉ,Nh%x 6g9vc-43,ge:uf3/ l_WTdѣ+*L> O.<b80x-T+acE8aCnF|D3Z?`iӖ1R䦪P#:?ʨUv~&XǪ|':+iڍQ*MRPl5(%[e/ $ ;^_=gW'Ck-+ O O:/Oe+W^c,5*oT?6(k~:|C|D2xE|EXb_ZpV/FY=qauEZ m]XiTx>k__ZB`-}~2Qi_jm# xG}FGY"##*e{cC?߳_> zΝj߱ZYǟ٢{[^RX'GXNUp' xNYLfa.>z_[e8lel.cKT)ԩyw,EZy5gƼ-ٿQQp+R hc(̱UHRV*1ƜR]I(]x>WK(g|0a0+.lKQWO>!i^1ωl([_A CKӯY[ +{ԵKkZMҷ_oD//ÿ6"ռ'GR>.cծ/vhcM<-:?ؚgbuYdejTT1aR br=LKOO9!+օl6ERts2+T=RWX~Is^}oE5ԋ%͉_OX๳h&HS'gkǿ-B۶Z~Aq,p[i7+s4&Fm80\M :>VIA~I?^fc{?>+ W9F낪>gxXxj FӼK}pjN,ء0:ݼL-,,涴ߋ|3g|;ihϢ^Cpko5OǦ_ "no7\2f@?sV42ޣaA?/=ga \A7LX5^LLj5c|. *ugR1x N+BX>1s6Þ0`zGIP^1,e<~U,0Wk(T)ц2VS_ 5 7|<>R|409gO7 C51akek A8S*:j{wŗ mZxWwz}48|9u>4-[6}^j3^ދF%2:߀)2LxRy()7DŧY\MqEqE-սW7Ý?h/eG9 F~f_{վQr5qH~qy(a?8?Wn_`2 C3,S =ZXXbbVk!e,FsQ*19ajeKaq4W05%VeV5\Ռ__|1}i~H"/BxKSk{[HF麜h^sl\^Rӹ7+ZM1%~5[ jľtx&Q𮒞]_ML2O=ʋOh4mh[چ3Ý?h/eG9 F~f_{CY֯b02W'/he+-"XpLl1ڕ֡ ]N*HNexUccqe`c11S,–5<%cô՝ qMΖ/^!־xf~* ogo|M̓New{jpE`-nK qwa~*7<#}KMeı%q+G[2-އ[j4ﴵ>V42ޣaA?/=rvO=@*Jyَ\N&y'3T\F'BuNN2qF7K [FRG˛ f͆ 7&m_QJדKͨL.:օLp\;?/ 1't6_|$k^Ɖ+]}Z^Ysȫe-s̿;X_zȲNE`j_HK/`8Ryt2, Ĵ`bh`3,Ggٌ<چ6K1GJ6~ٶWxIG0Waxk9.xpU,VB<2=:ԨMUi?K4=WMV> OZ»_ YǪ/t nPFZQ\шMfGC/i;u/ ]Z-!x[]7S[-J7X>SWtgq;s̿;X_zvC\)fISQkUL,M,:#0b)b%IaGJxzݘ~ C 6"IӝhdI^: )SO:(TSJ*5$?ZCML/K;D://X*.LS!Uf{z> ,%iakXiɪi)n}7es {2au G+/|}c>.7=8w*߱결! AißEN*agS Vj~gq'C q3!07(43mF2HSbp<61P ǯo ꍠxbh-'HgwjVr?/m p =NJ;t._I7]>>oX 'Y䯩_x~ݭ.uT/,t6  a37#QInR"sqxm,ij]\åii[q4ZF9=9 F|? ?f{׭l>gaqoq}wa" 6uӵkMOӞu .i|I65ÞggG9 F|? ?f{c/;K-q|e!U@#9`HOSf>?=$%PE&)&ѓ[sH+ŴR9qF7oߣN ᯤ1o3UxK U R\\zSi+UUz^#qAX lhC.s5jX1ç!WJ0*9R*7~vf-e4zm߈5 ;A1qeݕ/ZCxtK'оR|U干4{^siXѮԭ47^a5cvP^nU?s@~(<Yχ$b |-Au^1|0xxG13x\TƎ#0˫q{<>;N"X||pg*&|uZcJkN̨զOZ*VxoZZu0ѩ >}KTzM3~ |=f|=k[Zh/ ?R.. _j$^yuBw&x[gI?%qjw~Ոү/Zwyg)ÞggG9 F|? ?f{0X\ I[PX^"p_̱ن6>SRL2Ac`)cO#4g )ϖUNhҝ8O pp-\-\vaG ^ S /R7 W·v dl CSWjO_jh=|2ֵxOƚ ӵ{A%i7;s?v0?1tqK|*#qyOy&KG3j.Ib1!9G<iO1*|VQӎ*.#S뒪ah~971Y/UCUFL2ipɝ+¦FXTUiVTѮiok4L׉p ;zxjl<*r> 㜂|cb㈩ypl0(µ1|b~,?M4k}gߵDjթZèCg w^[Grw1*'C~I߇_~* G<JZ!KMே$6ǻv+\]Y]]Y&[=31zc<=) Y-cO¿$? x;ojM['.g_ ?o>#} eb-wW4;U?]XU:&adLMH”e[>Ãz 84p8͗өN1|JS\wMoA>~VIkϭOhuok0hXͫɦXb"}A[D{~x7+ƿ<+/M-"O_5ZJ:ƵծuxEѬt%~M'Þ | O&?.~%~Ѿ7]ԯk6;?j>6q߇^<}WQͼ\ho#"p8,.m*R^ԭ[%J럂Kr?_|&H|7(/%Y^_*ts̫2ou¬U*bbpth12>>ߴ|R~߷O5k:?H],Zs Ү&$L?hMEtk㮗. 2xO8€I_!yZ_F. ~ k |wOV4ox]7~OxA爵OhZW jzdž[ZM]ִ_~ZBdž 7'h(|=iW:_ً.ۙn-%_t1S/> ?"8ƖKWadue9n&x=zXX֞&j(lUJM2}2uʾ^%\9x+x\38ʭ UOB&XHiJ FP_ ]Sy5WC~˟>|5q6s@x:ޥgwۼ@|}c-H>"bX1jWRi?_leoBe|1>xw>|{h3xfGf~ߵ|1?ZމÿWZԾ|BﭯQg4?h Z08eQ}*|\\* ]TÃx/N)R*U|4f*pk]%fFr1kWw,[r:ѧ*RpO> b~|Mxw_ |1o'7]/cƹOU:?π?o|$ֵ}Qtٝ7/ڷxUGoj-*hckTK^4ST)1 6Fsm,'t *_[3*jSX8Sê*Ct{Z?n?E{Ke?~:a/Ӟ3+|-Ư9,iL^.+žֹx?]PoN*tq2Nstf+3VJGK,?iQ*ʭ*Ȱ% 1KWWsı/$퍆XCU7BR_?ಟ3׀>RYm>#O '6|ue5oj?<jNmGƿ ,[^.i^nOOl>7-o>|#-'Txo|?|GcD֟g ~jm;Kw~?;'?Ru|<w7>;:Q/x#]KxB<M::.hߊ񦉤kz~a6"M'ak> SΈ?_U:׉[٧d ?I<ga?x.x^޽g*GVաGܪ[WJ=:F[QaV秃.;\PGܜg u9kNj*êTjԥU=)~n~_?টS/ïٷ᷍1|:'ψ)/3:Ǟ,״7Sl   i'5N[gN}j5*,]xЖ2Tpr`ibgZ:Jt,3U~ϗJs81i~!? o_C߅:h|Gk0V"o s'cFe괟)wuxᶛukm6|>epЭ/m-U`@ޯX:ӵ?ZއAc?Oc~~~%'O*~8D|&_xw]K>;> JּC3P/HҼxKVҼwGWV?ѿF sxi#k\ţ>`SPUEJQa'JiԕUJ~c%BH)Ύ \fj\>S*j3peg*㾩RsyÃF~ϖ^&mXӒ5aB'^?W?_~3?}/} n&W|/^új~*a[YihZM{iB8oz/=?¾RGiy-|l+ٵ? !"ܾUXx~Fj"iV`ͫx->`kbɪzN"8,\w0J1xSSqq5Ihde ZK/Xicpa'O)JqPΤaZ4]:rHRW4g5hl7E~~ EAx_YAᇈ>'>4>YxL>o nuh_iz@n5<><x_ڣlK| E|/mV}B]kHѾxK;FO=lg¿? |]؏gnO3}"㷎&~~7$|A6>l(#mI.|K\@XIb󅂄eBk[F.Q|2֦ :U~a|5\Ѽ>-կ,Fxl*\HކXUNl _0ntqUsHQ9cJTr&xB+*wC-^_.hC__^"/u{ >xX^a,|#7Ig4[Z}߱ ?h]ĺox+]PeҼGO/ki7qsF;J+i4B^)Xh]音O<`:|g楪i9^ҼQƺy{qxR⥑tNHoOү7/OྭOo!?@k?ErÍN<,x_6ld_|!Χ>6.! 7LYMP^ӥ}[(WZӜqUZΕSQ䜰#F5s_S8F>ڞZyOb'lRa sZ:JX*u2ө|@#I3ˍnإg= ~EK )?c\~֟?eO-!u |A$uo _ǁFH`o?C&|edPG"O“p c_/ÿ_ᗁgس0*Ԭi~:|`ӡ;o+_xg~'xKI%|GJAD:?@ٵh,2Lpx,Db\07 f#BWT(G_a)ڶ.i5M`1R1CuwxgmbsxeR *Օ,5G5z.ou?x|1ٿ^<,#^PxOD?}?6>Wrk~uREo|3kZn?姅?|)xWm |j1C|Z~ ZX%~DzNk/3;x Qx5O C6QU㏌ "Z_YҾ4|BOm'~ï`xNoX濠]iOjҬC6l'b1*ge*`+eURW ^9Ӕ1SьqңVJƍEOԖG0y]ZJqK؜F:{JO ^TgU_ ?ۣߪ׉[jG)1]HcXԹTU,UAbA9pA𬝓vwWvvGmm~v9)H*sp&r΢W5e{?ۣߪ׌n?1n?1=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GU[E?l 9C}bZS=?¿ /_F|{>oqg=t4. MI# UQm`V3]6l-kݱn7;>W ޽>?x?z.?_/v:>7YN[OZӭm<'GG~о3Zoq>/|G_-m~" 6 hZFVu[y쮴O=gCG⍩ʬf4NwIF51'dݑ'MT-iŽ/ug$-62*PPo^ ? aho^ ? akWH~>*IK-cῌy?ŏ5Pg^;o}+F(l1gαx԰Z}]/?դQex?iH=\eqj^>xVW'+[/>)hw:EέWulKoj^`8bL1ԧ.|VѦ,Lb(1aj*N8x|Lh톡nWU)a[Cu\>~5'UӤ0Zw%o^ ? aho^ ? ak?hy9koZhO_/~ߴO~.GѴ߅4 [y㆗x-[EVSn]*c<9(jGw*x[%wiHkvKQվ(Nmh k~tOG~ xC^!< W8 R.eV8׈PV 0ϲ8{8V faS7b0uJ*qӣ)%c)eUR )SʼOF\&1o^ ? aho^ ? ak V^|7u۷e<+߄_> |[Wz&/=K?|-? oa}B -KB׾,]+oVZx;?f گj??ߍZ%<@<Zj:D­M'N2q~롖e9&oZtKt8*)ÚeZtO *qq*e(T>"*uʭ Ig7VTUZJGN?ӷ#ziW\ G#ziW\ _h~_M6^C>zJi_y^ L7e=Ou/P? %n]_~Gno6>hm7OC2ʳ Z+JԨC5S•/+7R %8쥋`qTʎ[NaU«OSCo^ ? aho^ ? ako?h|=?@~>־|׼ΟeƱO7s{[xhu F%?k??nϋ|c_>|bU?_# faox E񿃴?žվ$x{[yCs~ӯRgQaU4̰1xfЯ˕SQXz#SoJudU .))qToSդRt&Ε*޽>?޽>??Mc/ig K| HooAK?k&4< axG\޲Ed5%~ |GU}o?_?^jo |%ygσ]y_Y|Wti-F^ơi~/u>!ƕ¬E9Ӌ'ӝ1IJNrUiԩ*iԍ< N*5yjM88)3}lM{,M.<58ZqujB:]o{|4+{|4+[⿆> ?/s/7k}??gmr -4J46(׵]vݩj}7O#~+~ :'ǘ</MgAu]=~Sҿ4-xIqzn[ʧNSbr1xQνzkRJ9Jx|FJ.[W1! UciJS5NR>u,9d*xSu{|4+{|4+Mk I{(N?*s /Ok4w S>4z|@?éAJ_Լ5[!O#u_l>%??޽>??3E`xQ»?5E@߆~0x\y} ;-tKo Υ~)j> >;[(~-BM]k1-+KU0x-/oh'4N(IAm;,4#]a:FWC8Zp:O Sngq,]KYA7R:*a*FIisN"ʩRE~XJQgJ&%ZQ;{|4+{|4+7N?i_|A7S:Zxu=n&}M'կ6?h_:o_~Kx[?|mX+z?#Ŷ.g-Noz߃j5bZMVau4c)U+(5p uYuef_GLn3ƝXZ9G\k*4sͥS9F1/iwcrq/<> mfFSs_֣Ὲ'F|KO3GjR[|0]_ϻ:.C'&L|A ,žj5_ׄmx:[?hO "goi|ya__>~~,E+?)Ψf-vO|#e]x~'Usiot048N' 2ڧ'CtqO[J\ :sNvmF >.*bVk)J%ӟ#ziW\ G#ziW\ _/m|`4I|WO࿁^!|OmC5 麎X'_=nAu|"sx{eC[Qi^ |cUzXh*[fKmmGJ5 # x3@;FLEHҡVS<%9ENWdyM R'TWJh>ֲ:cJ\\pM8Q WNQcK%q"$Sԧ8ԅl$3#ziW\ G#ziW\ _ ~׾8h?ٺZMr^1 ewox#]sIxx?TxӴxK6_'VϋW4 m7 [j'Cl~xP:Ziz܍Z+i]\4iaPBi5:*dwtTP&KW 1UcOԥ(8֧tݜV*:r r:,A{|4+{|4+ǽS yi0ko;yWAyMxÞ1C/KK?x'ϏKY5:SJI xP1%Ԧn/?I㦧|Y~~7/ƳuĞ3ABg }o7;#_׵Zfk¾>t-sWPͧ7ZTӖ"QQjQT,MʶoZkO UӧK dJr)Ӆ x^ыeؼZG VJ*rTo^ ? aho^ ? ak PgygM7h~v+[<]{E~Ǟ(~*|,<[^ ދ ½5h)0xmZú:X5_ OҼ\妧(JsN$IԌjRUqSJrK]QѯZ#ziW\ G#ziW\ _?/D~ʟ|+J&OKOYFmx~+E'vlm!޽z>!)`guMVKz M?j kAß֩Q.%>#:׌#U~(x>-kw>6Ek)[땳ԼtZ刜aO/^xJUWէ)ti\KaUJe(\TRRaR}O_.sz|vQ2:|4SJj׿OºZ?׿OºZ[5;/Ii/?cYXoG>_S|}7w~*Ga{?{<_G>|g^~8"jzK| xhn}rQ  _z:xIz#Ҟ-.H.qe5eYSk'hG$Q jJ3ìN0%:*0~*1S2a*S ק*"o^ ? aho^ ? akƯׁc:KXմe~'/V|3BKhv'Mn>,־X{K^fGu{;M&?g?('φ^mwMg>)ѿK*.>3|o |3kG_E|Wuyg/_?$U#Yb)ӄp*5H|b+naC09FEJyՍq V"<,+y#,<- du% B$7φu07φu08B~>g?Ÿ |$A_oψP|;I'gsoex+4vMh@GiV7¿ۣ⏍^SGD>.ƿi@חo Nk,^ǾҴVo|=J;gOO8pbuN ;0`e%㏆gM/?7mg|<:ok>->şɼ+>7?Mן|- ^|i'4O|KX/GC{k$gBҮ(eψm~ Mti/x^|Qi4|?i2iQk6/hmuH)|} *AJ18p|>aGB9rZ8PNZg({6)/YWx({0OU+Yv-Bt:~ΜgRTj1T?o?8u_Ϗ%xL= [O>{<+xHBBҵkZ\[?diG}ƒ,ngQߏ7R_;7WƵMKfÖOKi:74~>%]z_+A֚.5MwR78q_QEJ9 U5Up˅ZrR ũF4ux0C7|s3R?f]TRtҜէ+ƥ9JN2i`7Rt_;y#ޅxkψm=CW~1FҬm[CJú$=4"o=?KOQ|7 ZҴ? x6 _7=S:'FzljW\мmNu<;o } _:&p/~UgNJz4*ӣN )S4!N)B4qF*F_:_3u*7:6'Z8ՖH1XTf%WZc 'cW|;/+?u N'nÚgm/Ʒ'>k~{-cOQ qgǾ"-Լ;+oE}J,"VԚ/g7G3~?frre9JW*՝J4u zH%$RJ\J38xl:Е7<:xyFp!L"0xCi?$kO?\u^+_<] ׺m禦OR|[]+i)k &qc%ŮwCurGe? Gu_O<{oxv?ּ]#($!%ַ^#|]q[[%~i[{3~?frĿt?M39Rc^?y M7K RpMӯ]Upp =ۖ59P9J΅L,eaAŧFx|;t(JET`Og GF&%Ӽ_~=O[cj/ҵJ]wH>7I4mcMԼ?]ic8x fo*?+$q_6v 5:ĭG?,,𭶅6EPU㻭6bM^Ė_tG?>?ho[Vn|SDx7O}:|7x]y&úd1siZUe8x fo*?29bBjԡ˳Ec8x fo*?4~ >z/7A.-n4wM 94rX <Rٕ~ſ3tacO~RF=*|H~|G>]xsGϊdXmCG|Svm,Z}!׵o 4{ȶ/wǃMcOÚ}%K/}Oџgw_ᔿ|s_i1>{kn{q yk7<گb]1_G_BԅSUh֭^^e SN*RSK*iцX.q=9Fa:F \UbKNH$&&䟶B1BgO t #ᵬ:7? GxMK_d}cBed wl|skm6?oK _O_:4͝#I?>#Y[|&Teo~.D_ ^j6t M.t][|eEιML5ι6wi|E|xJïewX+R@& ۏ~oVc3Sx7!Zfς<y1aC+aOԼឣk?vCi~5޶ƏF}ZRhe،,qPNedp?V%a04iF749JPf0F'8_VR9UZUN7͈7~Q|2OI>_Sƞ3OzϋZĭC]/x>4k>;ŧxZMݙ>-4Bꍷ=έM#E5z&Ꮙ/=/x=/[}:ҵm/>$4BK{*XDq|_SWt|G4xK xW/xᎉWMuMj{ xoV4c_KmHԯx}_4o 6Oþ=m<5[wDÓx_<|WK 𧊴OW::?o5wS&wkjZ^~Lߵ>%;xH(|OP7|6oc::#֧"1ɦ\GkXľ2Ԯ/^7z_ŸxNOx᷄Y? |1š!xZ<XloIi6:΋sjKm|I-{]R}<[.mo'AO4ms⏄>$^Z t_⎫i6W.Ҥ*JN,n&Y7*x,aWNoYS.%mJ#)RZVT'Xwʔpta(⧁0RFJPqS:Pq<> MOP~ZwIG\xW1k>8~&x'ěAmѼ3z|9/LЯ.btWu?i? "Uŭ\>.kҾ |a6I ➟g/fknjGi?|,E>+S<[ eZ+{=xSǾ Ս柫~+ލwj>io6i~?~- [῀|[WXF㟅5O^i>k(>|tnb7$+y'f!?mRQR:թAޝ %<l=IҶp 8:GAKtaTfUle\]B*:cxN|;n}7EO]˥Ƕ ޻OO R׵BY<:#Qo5KwuӼoijXh$l&I议_fgg?-<+'e9M㟏 K:>4Y6t9)ڷQ߈'FW;Z&|&Q⭇/kςŤxX߇/u_ xSX-8o1lu>rgSupبVu(c Ա_[ϱNhs~17yRQ~\T^apX kZ7.bp'OY~7Ʒ0ԼU x^GGOBK=?_<}+ 6gmB{-`d· Ay"ό.> n>/&\E7h Xx>.?^?xSL_Gm8z n1hOu'Ժ5h_|:}W"}xOO?:ьj_ <⟆M 7tVzOx]Myoi~͟ZMw⧍<#>F^ o?9?KMǃZZ%͟<3m n] G%XNg7῅z'<o|kW¾kk¿y5ZoOA*oxNQÞ,St C?|dmg 4½Þ񾝡M4[Mph:}n!> @uX]~3c};u,Oo^2 xnٓw#uHP}?go<1>Y|rK8$o)4j> > ~,i}Zo K-V_iσ*B"=y"4tueQԵv<MKi~:QB&5bRWTUUIC&Q"rT5iN~ʅ|4*UagFNj8Ϭ`k~1^\XL*:c/iz7> ޕZ?ecx%;i&< )h"oJ?tOOlS. ~ǯ>, {ǟ@oE_>.c–:xRQsĺNJk:[EGKz/MUj? :NZx_\>> x/vO_6?i:\Sw7 ccDhmvVkc~t5ğ@tSdCT6_WZ)baYbƽ U[5/Q(gVY"kV_i ֧Ssꮜ^IѦ\gGeaMrV&pTR+|KA~)sP՛ _x?]|mƞtu? x᷈#{j7^7lt۩u(\^1c42D4:צhzߌu O;NMo^5]i5dм3RZxWXO+w~*|![YIuJ<;'j.է*M5 j:s q]z8E %Qe<צL.=9+N,LX*SxpL_3%F5biC1QXƔ:KkVx_[|gx_>A}vCaegūNL}>5?`AbKN2/'?>oFcKo7)b x O ,O[ۏnď4V⟇_-wx'Lvw?~%yHҿgx&k|h|-Şt+ hB_?go➣oNյIxnL XǦU+qԧ){\TUZgIY'9^# R9.gsqRJ9Q,.Q,>0P9%GxI1(EU)/̏_J6f&__ 5Zů/k,"/J_Aú^("M +/^z`QD?5 }U૟OK^_Iu<&Q j<9{; &OߎOX0Zk:{n KXu73Ş(uo|EĖ,o|aOk3橩V6Wo\XҠO^xw:Q ~'Þ(n|kw_t{B^M ;~(k>_|4um+*s-;HZWO7w ῀tKR3xRfCmv :j MNXQ&oT2-,c'R agNn4 N!U)85:UiWXYҜ%q};*mFOiE_x k\𧌼4|y}ޙ-ׅ>+[G_]q'Ŷ[5 +kh`Oe rB߉<exoį񅽭ᇌ<"k>xkQ9'ajo|~>xgZQ׈.,GnWzoÿ^;~3#͉ws]qx՗*b*3.U^i^9MI-&QJ׫N*TeNRl>Y s?cOٟ⮫CY½2o?EW'7~u? ǧ> ״ Pt[h杪hZ4w7pO/#). Ëڂ6FĿĂP&> 6N~g|FG_Q}sP wY}>KM>MGGK{U:ZԎ'"z$sUhKqXS̨{_3%{¶+3*ga+KkASVN* ixXa1XJ4Rpt!1ZtF*&'+'yMkoxBռ9I_d+ZN6MG{<;ijA{;g+QKoX?iO'G]#?Gӭߠiz~\i3=|?jhO@䚘NtcNrƄ"'a1xhEEU,EJԜ]OlTuyS{Ib(b>{sbe+l×񏄏K/E!|>GG>|(gmXcmG>;⦇ok: $QK\mß+^ƝKĿ~0x_~R'}YiZ.wezv8h..;9!O@??&&Jiʤ"+g٫ᗅ<'M7H?xGtQgƏk cQ|S\е[xŚ\~.Ɖckh1hvWG"z$-#^N*U$X9e҅j`+F%iF4I.i6.9J뺋tq3Nj8D}koG(,5`_m ~#|@Ua[͡ kGV-#XtX4UjwW/?I⟊q>>׎mQ+/i.Q×C]aj~_ < a'^~oLįΥ^jno'ח72K3'[)w f ǮxoykqSq`~v u=BI-店W{{m;M4+7ƕ<\XJla0j֍0q^ F*p%Nf9ʤ,gnT^R|Ҽbqew+׭ZNS9KS~?޾6JqXxkĿه QS|q=^ !u/Cx߃.|\}՝ܞ |C{⸢Ԭt&Vt+~?޾6JqXx_¾x@WV<=o N-Bi/:iwOgiڅZYC,JȌE~Q?҃:PkP[xi{*QKNSs']ZX~(xZ|Oԇ,s.<]->uG4;lK/?^Oo|svWVt:-ĹY:Nx Ǟa}oudOuK?ÿ'7s~֚ǿڣOwx֫[M_ O.:G3Dg/ڧ_UO [<-k-?ğ3xǷPꗗ:FsS᾽EAx_G|Y_ q-c~xC'~6u<ψ>]?^5Jݴ~Y=oNJ-?{ ~x\ x'<+;x ާ#C|E'<{675: }ݍw'-i9;➍{?Ǎ7M7:O/Ɨ^hZVqKkƏsu6. Pt2xn][Fu10:pQQ}j|$*9z|)Qq,u<^udΔipuQ*/NqbyXa~aW~/4QS d~|c`BSSh5Mcុm_ Zt]o:|"G~ >m_&GP |_~ W?/ xK?:_dmsHJ^iEJ(2[;߃-<ƙg3 {N?Pk7޽F??O^xCjVPkL؏ı|>> 3ᧂ~74 uK=gG>,cM埇:h-K?zg?sFbIRk W9Sr`3ϖ2vueّGQONtjG  Y,MF. {ZUJ+:W9UQQU(QU)K{(-za4P~+Cܿd3Yi\RM>%&<3vo-kM)|?_׭|h|{㖷V1CZgľJѯa]tHl|EWԿOmI~F$6/xO&1|}-!񭷌G,"ғ?FtQ?ٟc~E/?j)<#㥿iワxY?\dkCͿ}D1%ƜM<.]NqXz9qX[Wp+)VY&YѭV8*CB3̿2ʅe psӡJ2.F3d+a*1_X*GR+y?[!~Ο ͦ?QGN3?k W~jWOGWQ#<h^!}+nM_ßռm73i^-3yei_>+$k|/ ZY5GcJY|HK~γ~ҟ8AtO߲ek_<1U9ojW^_| j>ot}+Q)biV^+IBlk+ҋUϩj`iEF=He4*_^iR9#N*0^QӡB_爭nEԧ(K,&8'̿;h|O*'&V v߳=sEki7q:r4qD>}ե\^\Y.5|??.'OO?g_ j?t>>ho F׼Fx[Vt ^ƺw^Εnjjz][Q#>;'#7_xhx6OVJ( .>'[xJy43O`V8@nkc4G7._74^7Gk߈ B5?^F Ze텤BLTЗ+O(9:XFAaB. SYz֞SʲIuңZjn<+%)akǗ:wʫtpF8NXLV.q8_ُ [U|:gH|UvK_Iw_O4O~П Q/+ƾ67zfK>5x WŔ5^o~)Ql?2տg mh _WIō;Ϋ_xN,<7;~5'kKִ_.O~Zxk BVWM~ O\xڟ|sᾆ<3-^|W{~'\ӯ&@΃ iƏxwB5:x uS]|h[G^.'?|A|yhQGxž.&?KEâح_ _5yӭA& /`y4dԳ,]jFc a^Օ5TH„1*K ϰDpQB#R58!O?j?~3zx?jo7mF9|03/߉π>3xSm/N6=SϚꟿ#8-THRXO@Ydti~-P:ό|oρ'ß:y{$־%kω)CƺOkxzV4..5|_\Te| yVjJ Y%I{W-c%AX=xx^)f}B0ѡ''SZxnaVU~F.Y%G .[ UU'RxQET((Iae\֝A^U<-gZuz[$w;y[//?)CN?e{?F|#g M㶏eמ_>'4;m!jw 6-~'q{+U{xm?F}zi> ~Ο~xQGa8>Ğֵ(B?No-5|{#e|P3RKMcE|3K=Se._ ~Ϟ9o~xKgH>yh6|h&|V/m֞$ׁ; z|Qrc,#(%xc11ź|yf.ԝ9<ZKN .#E,=<:Z,v橨TܮJ)'UTgxl/??w xºb WѮ']Y;N? j|/wnt{je$>|~Q^٩6^8; w¶:W>|S&x,'mx^IxKG Z$zeӈVTZӭR:+#Z4(W*)(M*'Oj)9^?.TܪFq%yG<8ԓ"JJU_|?񾑢>+PƧi?hچkH^gQ|u=?7MΙk[xo~ߴ _û{~|~S|d>%Uо3~/zOd+–.??V{i6:f}M~-xb4O:&^->X?Te CZCgF[ڨS[7ǙNu*'קG N1xEVSCRu-)bqt3yCJ>ҽ\~:݃P q~|Bu xX Q_?=7߈rQ|r&4/kP厣Oajkm\]'9\5|o>h_ a/i8$i|?WįW |/{*N\|b|I;oX_Uҍz Ty8G٩<֔` EUHӎ6k/R_msu|4~ ix΃io_x/ux?Ix5X?VMJыPu_9JJ\*SS-WF*QxJxWJx*T ou(3NS*8覴WֿY7߅kо<iJ_]~g>7~m?y߄c7? ˡiZ-?^yWz&i^5ai񮅩[ >#|<ͽ热tˍgY[zm֗xGQޝ]/h?VQZʼԵN0ʛsh0[Y)JST]9ӥ;J4S m:U 13RQkQW s?_DE ? +| Sρ[xMxWT x'!Ʒuia[_ZkWe_nwYZ~#gxs_m?h#ᖟ~&ѵY4>1WkkZZu|Iյm'7pѧ'J8< 8xӲi.u)Jy<58VJjy =IU^8էYS[32Ղ|0X^O4:$1_gUЭh.O|=#=|>!px߅u-[R]kV\O Mj:fWz|>!R/2W~2nMK(sqF|3 O>/~)U%|3ƻͣWVnᤒΌ1rQQyfUSqC )G/kN{HW sR ɬ=5N1Wچ JJqc:Вp,]Y1  ^¹b76~>7r4mCZ:(]t-V?N?ڵ,?e?kZsGR~_ m:|5l? 7j,N QS\|)߇B>8C&X^}F/n}KgًO.<[Kl?xZ#Ğ ht- /Ӽaı֮-+j:Z(S'W.eJH{Jp8},?;)K^sX15jը*>꒫y1a*Y8QmNo5_[[? >5a=:O~ϚXt;?"YTRQm7ˏ>jO~&x^źŏ3SuǍ>+izDk_?5/!__ f;_tS7C4f|Iڟ<5g%ƧWԭ )W$/şj+ОN*R({*j* [ ;&]p½[Յ<4*uBSRj-ZZ|k _|߲R[~JH [x?<;gYӿno٣ԼY[~ ]C|u{2]4jQ[YAݿி?/W]%.hYd%+=Uֶzٟxpkyd@-Gg֎ZҟW 3T~x'i'Քw*xGG[e{i?;@oC$[~?Ѯh?vi^5/h:ǁ|ehw78گ7FޟO^*7towogy:F#|e,ZO4~'mrᧈu}CX4on^dӯ#Y&D<;e?~|LT]N-Y<=?> GmIW^%PЭu)/-t[ojwevz?4K h𦷬x͹| Ox/|%#-v>x֐0AG`?!z3T,ʍes\,[0ZMR]RXcYE,2`a*ja|c?3xWmC=7;/k6>$ZO­/x+ßOG~'|9_6 W:=oރohSnGii^ QH<56ufi%vĿl'.=ό ]NVMcLYnRlp?SB5(a`䱘N&cR,jBSY/uxVCR̨U:nxWb)8d)҆YKWC,jy+Kǰ|G,|5:឵ Юi$Gh=5Uv]!: 6PxO7t_߄)LYkuڷŸ|)?| ~TĩWWMGM[o#(wZ76_Yb{ x7T[[CoX/>)ֵm+Ě'wl9/I%d(Nύv?Ğ"%>&@+ ZӼM?-?Bu3ƶZUX\_N4^]['<&.ˍV9y y%)ԭJRӣXyʞ'T-|3Iw~Ϛou_?DaGgq':/tSZK m{u?"]ZFV7Eqzj~"/m ]LEƏ_|V>%4GgO~ů>ľ ƭ{ T7|!j.Ku>[Zj ?h߭u(Pb1JTu2u'J*u-1p:4զC7iЫʴ0zue{FiJxFJ\q9e.ztfuiӫ7 NQ_1W|;7?]GG5wÿx4uпG3_}|>ri:?᫾Ɵ.8~#%au_ٟNQ_1W|;7?]G^i8ޛ&}?Tgc+֝/ {I=f&FmYctWBsI'7IGFq:0 7O Zjn0m'tNq^袊;(j$[ei߄_7WտI,?~˟ӿ+ʿg%,BCnW$?k~W$?k굯z#*^ (5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?(|)Uoj?wVN֮fO90/G~5/?>o{|bS ) \\^5 J71_t~qqxֿ~-5g'pw#T~96Jq~bK-ߵ:ߏ7R_;SRIe֝_}8?)|WOO7yG8[. >,~_~I^ < T_pu7|Skz\FG/:Y Y=Կ3>:tO-M 6w|_&NEMVm\a.u /~2V^( ~|1ŏ?nt_Oi?V)Bgn{i#4ÓDu{⯉|w Z{^:=& Ϳ^gimgX,: /]w/q/|`DҴ?ZxN_?KœW^C^6AeݯQ?Ax/g/u(5xzO/ u (>xbòϡڂxݼS Ŷ~0湧~H~f.?GcQxE~K}-~eo[/s6_Ml1ớ蚷u{]S; kxozZ=![0kJk=6o t5n1p/eW+pժ:%p :0~QZ\#pӏ~+>iCS#,UhJ9{4Ie:x4lDЫG~73^&> /ß#_ |)COw]ƧVC&;U G[izVU9V{mcXX;ő|2M/: g-6.ᣦ]G+-n mo74MmV[/ xW%41iζ3+`b7W(:ipJ%%U8էƷPUjf"O0j*{O펁x\|a>NxG6hWյ#1妍ቼ75oℑu1{k]⶯E֛;xrxsS>:_ !|[[KHO-<9\~=lSOB4'um|^vA[[x;[FU "Z/1O6f+Vn.54<7D2IҴ={R>%Z׵R孇u-wCfVzs M7N[N\GN8N%µVfI*?ACF*ճ,ahJYӫ%|Yˇ%Y5j*שR4.V8ѝ,U/ D0u*aҎ*1(Ppx΋KQ .|A&vMO?9_z燼9\liZumH5EIXjbĞ|[='ēx{?o:F귞Ş5I%Ε[X[i!X7O&t8,cƩW^$oxw [Qnu_-MoSFqLJloj4]O% G^-?7uhzKˍ?l{+[[Er\dL7kU*ὕj`:y+TTi!QVQkaNaeYt,J;RULL%¦ :}lL[kaf¾;X|K~7xs\oĿ:g|>yğ?jxSM.,|Wi:?v6ڟ5KgE<%wig 6{]|I̲qqqKZ7R(bjbɪְ|<*ҫ*iWTJУ58MZ9f3 ج&VXe^Jttg%]GЫ^/Gý_&&0xoX|EÞd|E>Axw_O_]gĩwC4_Rj?_G!qJ5o&tO_oQ=5/> GV? WǍuC(Ҽ[x'ơuh{B_կ|= W'۬:^L6֓.Y7ljUwWo#s'(abׯGU9[re4TڱYNU'3ʰxY :%)uk -;iZ*^EWßTQE|V$.N * WIae\֝A^U<-gZu|U@ !|C_U@ !|C_7'E~P"VQ>o(|N5h {~-4ix6=SG%mxF5sIEOsӃ]RTvB%5*ҧU1Ua9Ѧu%3U*4h:Ӎ*PR^ *T(uBJӄ%]l៌tx'|)mch{x;5 j>$ _CG]y|ix~ĞUo/ÿgOĚ5?/ Y,9мc~ ?TCRѓ@sjK m<>'䛝*ju1`S|2RbcZp*R79$<9jϞ<0ե̹hІ&2jxZiK6T8U9)?诏~)Trƿ?f?,k G񗄴CÃ[oz|kQ<56KZ޻i5^x4/ xQH~|acxW5im>i~ cW}RN]?#_>x?8? '73hXҩ:0x %uV ** 5/*uN)(EԊ;N.reu(Ŧfz`Q_gcgM[~X|jb|/.:궞?ewRִMr[W7WFMvo뚗oBbS[E>"OW%ԓxd}&īsu++ދ)TS ՜eRN3[.KFb>BVEPtjSO Sԩ JpTVc^IMSs 5qӜpt|ҩE'7Wnj=~ ♵ =GQ< ?SkiM֯sxJR .}P:mՔ{>3}4=JV{m.~D?m|*g ma,Sl_4k:S"ʽ*tNRt*2*FJs)ӔUźr2*5jSUZJNZu#V:e(ƭVnQ_5xV>+5}^]Rwŏ|6|]">oU??x}OF_x[:'|15$>'Ѽ8uiEΓ5~!^+x(xC᮱#+uDmnw^-<)/7iͦ]"Ԧ%[E5' Zn_xm/k5W JZnJj3W:c=PZ*TVM)Ԗ>.H**KVph[V?gl~9>f//||E|+/ok_?j^>񯆭|+n/~P~ 4O>5VO¿ž޵w+C #EJA::U?gHІyS00TT0uZ5'6Hѭ}SE~{|5~>/U?ǿߌ_ 9{Rr|W]nIOG?+}?e->9񶇠j4Ƶ{; V /^/u 8uxާo>{ IڮX-҅gnZVΡsKӷB)ԄӥWBn-N L\H9Sb8JJfɩ4Oݜ鶕H(JpjB5)QF9t'Ÿ7EV@QEQEQEQEQEQEQEQEQE~PRn7 O!}]ͰKKra~,_tk _|߲R[k5~5/?>o{|bS ) ?}}?[g?p~Iww*?o?8u_؟$wG;~7Mg'_n~/MJOA|/? nq\@}!EWQEQEQEQEQEQEQEQEQEQE[$w;y[//?_ڷI%sZwyW$ş_h_hWÿ*S֝ }PӿhW-g ~1ּ?M'g|cw㿈c>_׊~jwkMŚ͆7,x^k6z bm;|G_xV~,t}bOzSXxi79{Ÿf^ x_#-+x|7K_K7u]oI~R "WL\:9f4VԞ*8ŘFjnu$9{yԭqt!?6ٟCc:u[o?-Z\(U|su TR/Jv"t6]oƺ,-|}j:'v>?~^(ϯ|lԛY||;[+Ǟ6s+~_>)uN<}o6qNP_XfY6oqpgN5 ]sBNcOw~ 9m?">6t#POk<.?`Zm{<~wN:o ϢEOٷ}^%~G4|jJƟ_<+>׾_gn]~35 3V>VYIt7S$PY=YRujO-pogJ^ҬkӭNb)ԧ>֥zmG3*񦢕:\QV#_ 'BUCgĺ|/<}]G=kVUΗ|Rl%gMCX>i .ZƚEл ÿxO xGK?|4>^ş|}_x_|A.;Κj&J)RNt*SJsANg<*nԱBRQ`UV tU֭RINQzJSl'Na$uFE(QRWSEod?Nnψ7~Ϻ-G +|1Sޭs/.ny[.|@ x: mCZ3ǚ45ob/k+kYknt_(gNn40%RJV EVYR&7*EYJ#:YMú>4bciFЍzMTaG_*xzj(PL5 tJ0&~ӿ~/cP>O+-<|"_^ο o~^>#:xS'|qy?G^#qVu-`?nŦw@.l#Mo֑<uIEE:5B#2ī[5˩xKdܰtiǙ%9SWle|EzTOF*N3p&3oZ<~*SSrH2 4(߲=f嵮_ߴƣ"Y7?~05ekjM'VvKWRPh/L~ >o?G_5φ_n%~+9mOc~ 궾>OZ ?G/x{:S^tE7BAQsT_Zwv/J u\kCӧ ]Yl/fWӖ]k5k9՞]0ЕIJ7^UBjxy/ooA<ix jQOSf?_FσGc0ypڏúRCsb ߆f?׎._w:5įG]9i:u!BkiJ.FT' fTګ jʥ},԰8 9e C'%TKҬU:5~,?^fx./~ SNWmOx[Uo l#V+ZӼ7~<7?xg:~']+ WV9!RPʅ++ЄD%4WȺƻOvφ|u_ G_xߍ~*_~iw~ ]f ;ǚχ3xAf[ -J-kKMsZ߇uqZxsJ8%ƃy.⸵> c]Z 4_+Fu'Y#|nkUNcc4I;Sc0rIJ79p8Υb)zxx:x-FZ32V2tmY^Sx;Ud_ -~=^6:u|g|P!|;oxc]?Okt?|-m~6mC"@D4O ,\:G5;gGח5iχb{saq |rܳh^%iq(7(96Sq +z,eu}15B)ҡNujU TەIFOkRI]On_ٗ5j>gA1)im;,|74/Ś^+կ_Z =Z^gC.~9JѼ| 5?S]ĉ4Mv?I;>>7$#ѣj9G\EJ.qjPԠR99FW ^өB-EOIRSZWM:apBi[PWRQo~|o;ឹ6f}rC5[MOhY^+ψ|9=VuDҵWӯ4KO%j/^G]6¿> x53w[> Լ[RZ, Ο|yyawK*ZʟW簌hb2nk{( $ʕ *~ZPҍ9#ʤ:j]W:\PRr'--}}h/{c>1ҴXhz?>3(i>*It_x;]h<)}j$|Gcwc~G%[ľ/O^wE%-S.xsڏ<=ZsO[ߏxdjԍYP9Ƽ==*EG Mxb*KTj2:~8ך)SxTqa,Ey^hE֨M9OQ_s>x@oįෂa'-@WÞ&^E?- ^hu>0dt m-': h>h<>8τF(Qҭ[Rnpօg6zrOjO+{a?.>/ڿ>Nc|1^ǂW;ώ|= gIy[\eh:Vmx +N^_k%|/t;_O}|Wτsx†᷇h}E׼;.hz<ڥRi,D(xz$jѭUtᔽ9NpteV:? 񨝜%GV2iT}+~~o@i;Mo~\|D%xᗎ>7߄Xu/Z_ŢSᗈdگV/y[~ Z蚏q\uQ?|4[¾sHi~ _|gφ?B.qTu;m+^ծ-|=M \R]eR:2/`qr7:hN2QJu)9F% AVsRVp"8LG:zsDFI(诉|;u+? >#i~+<E|/S@4?|I |yD6ßJ<]E 2x;r/5} ĦgI:BIѭ =hAF^:#V rJsY?*YT\*sGVV8ϛIh,k+O6("S\],7/j"g|'P5x:Fx]oPkxχ~;]dMa7࿀vޛ^_M֚u >Ox3x/Zд$^lũ<7+XCJhbq8|%ѨڧybqXzRĹ,=7ZHE7RT_XН68W88՗NVK'+}E|ɣ~?$uO~-?ź',tgzi$=2ܛTԫQRNZfiӥì^Iх:FTg&Wh9SjDߜ)ީRUaNs ^*8c:ҚU)_+j~(_߄<A3xWxNg4:Փ^3C9mxOǚg<}ZL͖\lj?m/%𿄼Oz׋d_e`^g42O|Bm#Z_O A׵ iSQZIFNLE %:j-Φ/J5XBb(N5Qu+RjSi5(:N*N aSnKJZVmڕJ>YN)QET((((?oUCm[:Z1a?PX @e5O+7ƕ~5/?>o{|bS ) ?|Zk?n|N~*ÿ*S֝ ~r>|#I/߈w׿>7x෇=|&V Rumj%>ggk^&q4[+s}qF.y.22)MBˡy>[Vg( JRvsIJ~rƒwڲqߴP䨤/_ !^k>M_;x' sOx[__<  ?iυѾ4|:?>Ԭ,i Bz-ׂ'x yb_/]_=j(YifixoK> x>Y> !xsELk'Ǘz7ll#O{bWCI!|NY+u;HK__xV?߄wS<=Be7oav6V$9PxoPF/[_^%9]9"WVxº^ugiq]*UNU!Nq5[0Ru1˩URZƪXNjB8nu*NJ6 9iF4# %8Sbk`0Օ _+ƥȭcqC)f_hچxf?u|g}k;O>ӵϋ~!񞹧YoB5\؋|!!iO 1Ѿ >oU'+.[𗃼^:-߀gDռ=~?L?n<6quzgkF\-j^S~Q'<+=gƾѼA>XEqwPO?|G6O¯|W>Ҽ9߉zO]ƚN|59o4ӵ FM |Q<y>IjvL]l^%֩,%ErXFq*Kƺ0Ì":UfNPʤoFn0?UU(YnUueEԥ9.7B x[xozĽVVծ?1|rᾼ?Ŀwi:2EcoJլ=itdquWg z}3ߋogm;B]b_#獾%juO?=SY8HVx:ڍ؛DOͮw]~_/O]KV ě xS,?h>3i x2/t~[GR^7rk05 êhOC?4mEπ~!XxWt[io5 [m~x^nG Z񯇭oOh6x{[{ tdj^p% N\*aV7 IJ)񜲌F6"[C.*^ʽVSJʧ5ɎѓRN2ԣVJ^&~!6?-uG'?F<>n5q񆙬;+[Ro>1>]GJ5jF:~ߴng|:q|WGƿ ٧oQ/8GSxv,[wW~l<9ao_xR-'XW~ h.|O}YCߊm{B|COc^ OxX/,EGKXx&#Þ"м_ Şլ5 xG|AsKL4MbCK4EseeqմIaI +GU)qj:xl%e*q}𥇯9G<)U"V) I[ 'ӯ5gn>$'/՜?j/+-eF m4vZǎ.K5 ԛ:6?7 JO٪_~߲ƯKnόZx3> }h߅G|VWgFlFC%?%_:5oW⇋< k_jw۞*o~ OywVgVv6_;:uփsuE7K_xzo"o>WcV֯tbE#iީ^*7Vuܭɉcԥ&AӎUU',>[gUg*Ӝ',]LN&5)oAbxΌ*Ɨq58uz(A7J' Xzuh`18Z?e?a4|#ƭZO?iόzOQ?ƑN|QO:|1?_ជt Iχ_>,ֵ=S+k_׬}oߵψh_hC~ߴ֥/.eƉdhHm~/jڗ«[7|џ>>6%I7V>+5}^]Rwŏ|6|]">oU??x}OF_x[:'|15$>'X(:J88)9.]%J^#^,OfP V>>g^$crڹF2:4)+bb*}o[nnΡ_h5~!{ oמ/YxvWxso~=Ҵ{u{kú3|)?|$?| OiKꟳυ?j o/z9\_A_/_ ~k:iφ~"xY[g<*|cjJU4-;O|i u|9{fp>_ M][iZξ~x&Tv'~)lu#σ>%t?|axGW{־ŏ9> ?RNW'/v~&}:=WzZ+MuBZqh D^GC։3COǨ>&? |mSƛ/=?I?Z qiZhn4}Ua}~_KmK'Ge`.ɡEݧt/IZ ڏvfu:=[m;?/ KMcZпe]IdqE~|ym឵k_x |=l|yۻwM꫉S99Tujprc)M:ty*%|q`1z2RRтTyRs5,YJjps~ʤ=:ԡR~߲w?~'h#mg~w9?IC -x\&V]OW4|c⛟S?`3_<)0&OzaJ\u¿4/k^o~xg:i&{g}σm;^ßo<@ZO~~]M=?~u߈ gfJmr R|]im"]ú炵xox2x#9xM[z.{?1S '^.ᯈwzN3ÍŚ/ĽnB64tP̣8Ul-L^rxԩ `(s,)USVtTVRENbNo5ƨBP.8xp~# |ߊ(B'ﴯO/{E'6zk"C'ī/෎x|MZx{\mlo_߲ߏ>|G; ]<#u/-lj_t&Y;O @mw~ ߊ.%SZ ,XԴ_~?#Og~!Z^?oXEM_ x7T:ohg -ͬi~'ռ]-'jz_A>+j? iF:%WJ?i ]O'~?ŭK#Ƌ7">W_ ᖡ/ĚƟ_?<}8|3{;n,k:-uᏄy>'gukd YP2*IU(c?rL Tjv*BYNTo4jY27Ni^(0{UV%z.#B8Xu9Sq3Oeg/<*ǺN8O+O (i g?x=ֹ?}/M7 iOß $tO[^yOTѼGw_w~h^0x_=_C𿆼]᧋?+_ xu/i^'^e,lu#quVZm\w7LIxOfA ?u߇:~#]ZYx3j|\Z2h|? I|CmR]eh/c3,2sI}cOU :V5ץSVUJLF1+P(R`%҄te͸ӧx*8iˣN]xs7v:־>_Dk֬t s1}S S+}?i~rkm/>#G ,>*x¾>*.t&/_uoxf|t>)!PWoZ-Ish1>~ď <]KU>3|?xEq\4#~~j5.kwt][:׀n-I5ٿ 5{MWA~!hx?/7~!|:^?7ڮ_%g-쵝TmW/Xo.sFB]F&'x%iap8'YTbiw,VwNMoLlq^ VԡO v7N)5TKV5p*I|K=_!a>O> {"s|||E?5 M_M?A>IQ|G{7[ş |B3omS[j|]_/ Vmk6<31Ao}YkޢlR|7m3ľ,7|ui~O;nZ wDžY\h?ϊ|'ýuFh:Ҫ֡_䧃yJm:Qcg^WN8|v#+ɱ(]:u̗S Oܞ/- ,YP:nS_ɱYtUiV8Ua D]o3⮭0|=B,^(^]rTHgzZ߉nD:OҧNҭzzqF֝jS*RjSZg(iݛ/vb*rqR\UmYΝHxI"(((Cm[:Z)?oUuL/ŋnߍ ϛ^TCko8i_W_c+?ி?/WWů&CV qҧ&OZU_I/~ӿ~6IpW꿱?KI%ڏZw~QVRc8]'Ɯ_HQE~QEQEQEQEQEQEQEQEQEQE|V$.N * WIae\֝A^U<-gZu|U@ !|C_zy |n~>? ~;|5?.|a)[ğM_x~9MwB΃'1Qះ^85_xzHl[ot%8Ն# NSoX|Ve g,&+i*%EՁrTʣ+ȩ.Uʨ9I * ~$|_|K/g_߅K?|G=+uNžUl~ӿi'E/|iw3εTm߃|E'X%tR=½#Ş"?YM}G>o=[7|cR_9x;Hwj>-f _17t3S xJ<Ki&kFNFt LxiSxa'%V X:&3.X%W FI:tj^JjBp}kRz9iƃe\%\-4U+R%\,7? b/x_ M?Qk\JvY~&_ >!Zc9w_|ERmƥ7tx~ >:w@K7O/=@xXnjtem6>"h>6_ usPaV5> [$ϯxZտRˤxG>9j ?l1|&]ύo -'_X^7_|;? xK%TQ_#KԯoxGZYmgK>Hm~/jڗ«[7|џ>>6%I5UqQelE,\FTlfeѣ|NJ.=I<]_iĪ53 JReisqjѨqWgJn5E<4Oy<,fğj(/M2l=~jWh?Y:-:5?9O?:U4o_k~5xK a_|a\0Q6xn}U,MK5 UaRJylAޮ&L)WŹi_*˲ʲE&~ο 4^G~X|, ߋ~П|+|GA|C^IԴgR߄mkKO>,aOoxPį~+玼}xetxmSG>ZƧ ui|8e=ƕ%֗KimxݏxQ%xXtU6#BA:梶.[CV1Uqo*rה*Q_~RSVTTRT8tOkU>x GAԂq*إ^}Tp~&Tps Tg/~3g cǟ3|Q#K&gm^-]o}|I|'[|Ik)Ewh65omͬ|/gA/mX𵧌ntxk^}kF,ukin 8yxv:ߍ 4k?'xS ' ^gHŸ |3_~(xsᭇm,|{a4YENXX|"-u?-~H>;/?Sӯt)Qÿy4Z=T9xjk*Ia]l$\}'(JRG/cʜUMqXuLXj|g:-^\0*/KIi t{è|_x?ᯃ-|n|[yx5xW5#¾8#ϻ yeDUn>ƾe>*{S ߆мAkQ~]GEt[Ok>L'#Ao⯆>]c+t f//4_:Yl>$Ck5]JI^bigOQ5yBDɛ,$:uq4iUӭVY~/K~iAsR^>2'*S S´x ?~ýGEη|#/ h?mgUeo+F=x|'[T ÚvbGś\5XF?`ƽ4~ O.) ~5ſ>ิ h_5M >$u}^\/~|Qx'[>f¯6?iu'g= ǚ 񯈯lxcxᇇc%ai,缶1=ҩδjz*QNZax^8p({*L=m^.J8v~Wx+g;⟌ _?~j>9ƥXuIOh^'OT?c^)Qi n50~%xu x[\/P;1C|~2t_g_RE_x 5MW#EuCž#9{g%mcC<ʵj~)}jXEjJ֫[½JեR*Q|L+Z-'SV**ӌgBX*8FR*xETcV#?s?1Z^hghýwZo>úΛ|B-|AxF|X< X\|l"@şkUR^? coznku@æ̺_{xCÒCl-e%x]t5P?mR~xž R#LׂϊZ=|T#Tц⿈ӿMK|m.r]CEng/Fh ^ aoxɼs~6j4;W+^/Ӥ|U:4XzjXjyr(^m6N^{o]I{x¶-T7OC94|%k|Ig5?^kD[+-ħK<[/ Js~?0|lx<XOËvkğ t׼qNg3xBYt_;V#Yh5q(XGV[FRS F}Jqs 1X֓PRU(+KqN5k5i=xJYn.G2IEЬ?3o/7+xr>/~?7|G[/?5ᯃaWXeρoƿo ޓO?:f[ᇈm!xCxSmM|} l? oum#5]W6 _\v?Wx +N^_k%|/t;_O}|Wτsx†᷇h}E׼;.hz<ڧx%|;槫xwLk~/x'+ q%?|Géxƚ֧}*-Ÿ E$|'gT*y}HTxb:tYf9^XdN?[Wu!RLU,e|Lg[6SIUy)RI(S0XO2,!j+nQQUNFP._g Bڟ|{koدc j ??gώWZ.4 ?S?.o_Iٯ<; si_SB֠oo>wG" >$|.owoZ,x> G~*|lg֧ C}E[~ Z蚏q\uQ?|4[¾sHi~ _|gφ?B.qTu;m+^ծ-|=M#_h1i9|_Vxid>WMRֵK_ |/6} F^5"\žcVIX~q*kpT궒8֥Xz(Wi͹Uw7ר*h~ &Ϊ})BW5EZ23 _?ozNJO^ [>>+U?Yxo; iSWxS=⅗yY?kSm?_7'X@8iٛľ:Ӿ=|nx\sEρ0oͺdzGf~/.]ˮX~ڿ<":||G]gYn =gIҼ%y:ߋ=}-DmtωMź|[|hេa%\V/xOwkk]Rh<7Kc8 !Ya.QriTbR3[V?{C_qu.gJwuq>KJo𪔦fEjU/jBjziS/>4[lj~ ~zmkß 4]xVk0#JG<_!x?i~k[@ ?hY>4kq;Wּ#zFHޣwfu K훏|y1oIK^}v/|+xš<M'kψ'xQ"/^! ]~V.~?>xċO>#~qwΟľ3~xŞ CֿYo >qxoty;[ CK<9ZQJJnW KVwUp}bS9VRЩi=(ӡ|q"˔)^t% 8l U: =0Tğ.f~_-3k5|[m_2I`4Eѿl wLҼAK1z1>ӬuDo2Úl9mm^P.8'#R3xjs)E<]\_KSYJISap:Uƥ 4pRJtS]\wK T+8Uuq 3ޭc$?kw?W|T>~MմW?ŏ +{ No>1j|*lM WGx?ɤλEw,cw#M-S:tKOn#Y𞫥G,4OLmOټ=Wu>&o*OiL&Zx ~мyxC>"խ Luo]i u˝;.g Tpu?040qnm:aV&E֝*8:jJIέlMYM_\RS¨uZUqXiIi^l^iTT)h†8/(Ii~/%xCּ['+~ |m>xwᗂ|suo*(2x_ݮkOТR\_$kV|>U֟کKCF<];YNXRz5zu`{֡ERQECH`?|'_kW>ۿ uvc6/.ɅSM>;~1~jW_HomgW+*k _|߲R[~J dݟ?S {e' _e/$[j?iߋv?o?8u_؟$wG;~(p;)|V}.GcMQcN/ˈ(Q?R ( ( ( ( ( ( ( ( ( (>oXn?~W~?K|Yeև^V$.N * >*w ?_JӾ! '^1]|? [x> %{Vi㟂 |B֢!^S~)C6OӼ9gǟ!!F] ];In#_? <4 |xMu<3j{X}cR"eï͜ |rS_>!x%t=Bwc?/xºIuBz5gzK SեaSRJF?ils2Ju a8p 5Y*NѭU%VR)ƍZ~ Mox^*е_]U5ZO?~SX| ;W~iFmZBgGD-2M=t]/ ~Sᮙ'j 3Ŗ.X^? |:| ͦo7V4ސ5cR3CPRɷJx:F>D*s k((΍IӖ9QPr|*֚,V˳7w'ShKZV)?{_d?b&W3xcuQ_E ~JmۿOoe߅ldR>;x/6Im_[Pҵ&>T?:> | ߈Gs y\b*'^W|EJj58՝z:)rUV(Ԅju)9BZU)N+ste+sB 8J2E F^wEn??;&ϭM׵? |6m/iVq|!i<5c8񏁼MCAiWiasBJ<+Vռ)Q̟߳o_zG~7е/.5ڣŞ(" :OMG2tt@d|3]\|?Ht~QYNs4N>TQ0459NSRJUZ~Ҥ9JJj>ӟ-J&eF0SNHERTqxeOtiS?=_`RO]G h7|AM)m$q?xźV(sxv j1kZ4> x#:ǃdߴ?רkI/| EKOoj?c啇y=oGfS#k~?;?=ҧw~n~!^eƗ]ɩEEg*'Bn,U(N*-bmY%8K R\єUKIIr0O=,"1`x3n$/?i~m–_ rOdž;Kg|mA^~2g jG5Z~95k#K|-ƿo?Ou?J2ThS7Edn|*;SW,UN2ҧW:9' R3|)?|$?| OiKꟳυ?j o/z9\_A_/_ ~k:iφ~"xYG:S X[x 2]j<1=n|?GoK_~)Z:Z@-ay+믉^xӧ ඩ_M{x^$YҴ-4O>F?~_ٷŞ:f}:nj$xSš?'4U]sDZu>wx;Pm_TӡmVon|sO+ڹXq)X)SeX74W9VqjT_ SR ӣKN,4mSY̰krϳKsHΔ1_XDt?`3_<)0&OzaJ\u¿4/k^o~xg:i&{g}σm;^ßo<@ZO뿳}7?>I;+oK|I3> ^m!Zȿ *K-㹼i:2-ījw<-+G^~W[]F ib &gQTX,,-:ta9?}E8 A,.; tlc)Sc1ԝ,~*)[[ï~!kDŽnmK.3i|{]Sh-/W_ĺxk\y0ߵGox[.||x>g -ͬi~'ռ]-'jz_A>+j? iF:%EC݊ Jz^Wc%MIԔc'VGSjl\=jU{I,MjR^~z*{igx^楥xEeu(>(|f7xW?~=uͪ|/__tCOn9 nψ#zn M5$EeԧG ' eeMLTiR,SF4%JbHU:X,x8^%N8x`XÙߟVoj_OZVGA7xCmU+? |cWwk.o4s{sh<M;O~gF&x[ϊz8kjqTWXk_ҟ /|}5V:GV~9?w)|>|Q4?@ƹ5ãT~nu1ZY*U^EZyPp]VMABU)Ƣ:!lqѫ )Pa(J5! a΂ F/*Xf^ &MY6|8d Ut]+ e /Ï^*OGÞ0eޱM]ojlQYR:/Y7[ ehSڥ2$VYJeR0-]Vu*h:kNrrNQ%'N8Ģ)QE~PRn7 O!}]ͰKKra~,_tk _|߲R[~JJ71_uqqxҿ~-5g';c;+,S {e' _e/$[j?iߋv?o?8u_'ߋZ_k>w7kvh=YIh_iW:W>|K_u=3^awWzVe{j[^F Q$iGӃO/3cMQcN/ˈuBDڛҿ\S#uBDڛҿ\SW jostJ:s"Mn=i__.|O +Ϗ79+?~й?7G4ï>?'uBDڛҿ\SW jostJ:s"Mn=i__.|O +Ϗ79+?~й?7G4ï>?'uBDڛҿ\SW jostJ:s"Mn3j$[ei߄_7T-hxG>w^5e][n|+[i^~"?xᆉ#O<;jGmg Lq?7P_OZw5u_OZw5uZ=oSKQTQYQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@>ۿ u|SH`?|'_kWf3l'_au?#71_uqqxҿүƿg/W]!\^4_Mp'aCGɽl֯Kă_|2F>)xG1x.m;ğ=x~PхɧE4S}{; {e' _f_Mk:~|\u}Vv:nIdF!RkXeWb3_9T_IXhr"uOQGxjZ%Q8NsvQm#^MN*rn-#NSRyRԤJ:ݻ%!R?T-3U]/+đ|%ǎ<^O[# 4+|:n|!K=OIeQ7dQ/|WhEl 4hMߏv_n> >|^m,>+|#灭;Oo|9>i-Xx_X6fDpjUr,n&_Ym|40Ө82j>aWUG"ab፨biѪ劕9<{Su(եf8sc,^#Rה<)oaʪ?u9x7 .5w)'MyNJ 7ş<5lk|Ewm6m+ڟ(J/^9M?5|; _?o~+k~.tm+Ee[t)ci<9W7<9e~< Թe,>XFf/7.zj18<'꒦xRLTeEk,'*új1Ƕ#C ⽌q8O:U*pf4]4# [g>B?ॿ;*Q⯄kDյ6G >ǯ|8 j_N; ߅uu-þ.||Ao i3n,lxе߇^/<+í|߉!W+i ~xH""kV$%/ |8>2ÚɂY IP`7Uy ΂*Cʔ]:ЅybxB?ॿ;*G`xSx[Oυ>1 gOW< ;'57]QS2j*X ,35>gFp*S9Ԍڧ>]e0:_YR:8RXڲJҡ4iKXW1ौV|)oaʪ?7 |>%|+G~!\Η_%m7>_[yZKžgAih|Q]6-_Ե_Zt~Gh:g,!/kv%o*-|=|??k]G?ռL-W>)ސ(&G4;aXt 5p7^.#%kz%u]$xZu/+ aYЭSupFZJH^n9rJN6*rqJ֝UBVQhœRrrIԣΩׂnT1^?5)oaʪ|e|:ῌ|k9?uh~){|!aS^+?|#%tO6N3[ƟPx;S5O>/[~/'_*Gkuk ]ᯏuŷb?i^7 _HPTӎ08zӞE`xkJ.f8NeZ,:˰x:؜^ SNiU*\jू&VSi}{* J7:%B?ॿ;*# [g>kW%~~̟__l> xmMj Ľ9mƛٶ· i'>?ZF;mF O&{oOH>>_x? |@7>[|m~KB_k03o:[ŚƧ-[>q\f,BY\#_2jjA^xxEayygG - M|gOi:2FSN3sKu0kԎ:t =yC# [g>B?ॿ;*U[F~ |lui<;>$x:> |O/o>*GH^ҵ^,2KDlj<]Vtۣx5g|,>|)|B<?<cC,"߃5=;ſ >$^#OڵiWbel8L&+#byn28lN]bsEW fj]KMBu:Qbj1t(9&<3wo k+mn@Z~? /|%kE?ڏǚ|3iY&A}B]~}Vψ%Ҽ=ggNմ?_jvzo>⚙rb2V  =lDp8LN_b[/xPUgUգ ():*5tBS>uI_ Ȟ8ռq|!h&[j3j6wn|u'Zu\O=Ƹmmmm<'U6^xWz^t;hO ,>.[9⯋;迳/ĭ+W^@<Zi4/î?x\x/ࡿPگpOW#M=_ |j>__ |i ڷm[NPK8m4; x^(оKù8)]֝S+Sb հ`yv>jʾ_`f:|~ R\T*\cN%U5Z%jRN|YKo_ gOR7lve>|,'ϋ*J\OjzdzKۭ3K Rě/Ļ |F .)<s_^_ۏ Լ?Qu}'Q{v4 f(a<+x?V?K|Yeև_7Z\\.ZpPIåۿ%۵쬍h_ii˒j<&'zt|VJ՟|;¯%?Hi~";¯%?HiuM.|?|_|=>*k爯,-<'Ddτ⿊Mot'o1u/F|c^% TIk[gc^4T*<-8:(εGjt(BSR*x|-SKJX^j'RQ:Μ%RF8ҥ*JB'^NZ4)ԭ8B_U_0Nyo}Gž :fǺ׈<=~,!xo_ YƫcO0?x%GƚIu[~6~;|$o񏋮u-4 x>!̶sɩ.IҦ'S >W[ ,%(ۚ&5 R*(pSMÖC KZ\˖ bh*1jJXMӒN^O/.kjC/ƻxK@D? <85>>~&u^>oj>4ev]MK?=|@ ku~g:׀>%xcXmF/xZ|k!Ltυ2ex[9گ- FQ,3CEіsNԿ$B5tyNhp9R:ikuP:ETQ/W|6ϋ^ $-+Ş W to|= ^iڵ hz֖ƙ}w?we/_ ^W.Jw5 1ᇀs /#W,l`i_c}:,u* {G\UkP!bPRΜbZt]HS*iQk7RZii~|>|4վ:uƯ߶'/iSZߧ|5-kN>yߋz%}x;\to$_MghPK|1 x-|,f/>Z<s$]x+R]I&Ahi0}/:YJ7^ҲR5KU:PY[Z*T:]2a6xď|<_C+Mkv {f; o&ׇ_9i2FجE:Tù;/oOV ѿYƜ)+J>~_ypؼfvW~ζSog:XjRj PQ^ soGY8Ӓ\ʵ\%J6Ta%8r&_FbOJ*|}GE|ǥ~5¶>(hkw^1մ i_n~[}SWi:7o3!𬋬>+g/iGž,k>&_&x^>j~~!B~|9yiZ瀵_v>67_MHIщO>NGN3y%W J\up)ig<"oGSN syB\ӔpLw('JIUNY+UQ_!i_쥭[N,G~x㖫 6o Q{|b|%uI#mt]AI}4=JV{m.~D?m|*g ma,Sl_4_rOw,lE|#卯+b،3zJc<Ѳ2唧Ҝ(aS{9C bghbTҔܢ|#} :<]%?h |&έᅃc oC?oWx#߉S^}"o~Vo.x>9xAԾwUQm{J%: }^ NB: *]}7_moD3zT5omf { jxkNu B uԣtԝJpD'91rI̓Ɯ5}GG[k'Tj~QE!Q@Q@Q@Q@Q@Q@Q@>ۿ u|SH`?|'_kWf3l'_au?#71_uqqxҿүƿg/W]!\^4_Mp'aCGɽl֯X~M>/x+-o?k#%Ӟ_Eu G%> i57Mg'_n~/Nz?Ipƭ E~ZR^u)u)FKm[lDNa4EJQn8Èa$Ÿ(oLo7N%|3Mv&> qžѾ" 1xW591u+a Lw<2c6kNa$f7Jn/#f?gEF|n}l#?7U!7._ tY[އg_j ףVonzd#Q-ԾAk_~״-6Xҭuփcw}K}X{v$i>Yf[ch~^|^N23*jʦ8&3 E*TS%'0ᰳu)*(l&\ zxzPtqQ UՖ#._هƞI>|Sdž#i3kv FMo)!?O_hk] x[ 4mBk]AM5OUo|3ǃ3'=Zcr]|f? k߉- 캇W]#OޥR x`J|}0;Su|-ZA|[kkOO|#Zо"4+xVTּxbľ,U[|J[r~$|G.o^>gůV~xC_Wg4okÚ֛x⎯7EԴ .5VOR]Kez,-GAa':TVSjM T+Ryg4j0b0/֬:j_c1 eKO(QS?m4bOE_Y&Ok+ГhgK/ 젓xKᯆ&$YѮ&_/Au GmwqkÏ |[Q2n5?wφ.\E+Gx7|A\Qu](fC2j0~?' ]މ|2ٳ/hR|I~ O⏆|OOwϊ_>-jO/xg⭮:}RH.#jx񇅾+]ះ~ |?g|_X >j>o>!EOGމx}~3h_k]k:|}sH. }< B`p|;_3QY]*xM1n8jx|MJ1F'c9. \l5:9t3:5)=x1pKAf,ھ+ ZjX|NO=(){>4ǫN?>h?k '$۟^_HWl EjH'TwfB+gߑW#7$k۠:kĿ?>n<{`ڗ|5;º_:CSkZw&+ T0zsa&imZܾg7^Ox]ϋgڧ,i >%K"-W^-#.m^MW%̚ݦZ߁&ែ |ޯxUx[^4 ZMueiwͼ;Ek']<5 G GF s]jXgRVcRrJi)S<>5a UjԄ`_Vs+e:،]X(cqWW3>&I'j] _{ا~ # _KKxkǭ[NBKi߆ol<^#3.0jh>j?xrxm xZ\+>6 o\g|K 5$lPxVO< ~"^"%v9/|7-#<>q¹s)xEl'&jn2*cůwL^^%UXї_8KrgMhFƟ ?gO~/DŸ-|!~g |7_]~?i > m4o.]xCοϏOj=O? Oc3?u |N>8{Gm-5 Sž]t5OsM_ _~E<@(sl O? 1 QYAv/ĺY\C/*TTZC+)9)pF<%L%L<*UZ健 8kFIFyJRjT/_'o쫨\w?zk0OO;hww[񟌗y߆4Ķ?8kMzy*y|_Ψd?-pv],r,+"Qf1JR0l|=iХ(aQs\UjO 5:TpPتU*JzOʭ.7_|s_~񷁼34=}(b:e506ϴO /g%,BCnu R? \_b^Ŷ ֦ ZA$%8jp,-VnFCk[RIo?пx ԰jxZRNtiTURP*zܳtFoʻ2:؊J15]jYuiT\S*tuw>*w ?_JӾ!5~wÞ*ÿ:ׇ ,ௌnw]|GWOíNv_ iYԦW$?koNLDJpĸ¬UJM֣ԣ;ҫKRT&TTy14(UaNx*s9N{ZS:l>#U`:~T+aj0ש~!io5e⏋?|:վ"S&#/ռA{k>'{=)n~%:Sÿ)|q{EhX&.S\FuNujOb#RI:XiuV]^ NYN#F\6 O Ma+O s{5d57qR8zE|!g:୷Ÿ^.~x>9|@u`AO ?wx:\n⮷]M[ 5Ļc|g׾6jMW>>𭎕|9׏e:ɧj>f7xw$#m_ǞjEdyuT*W9a]HsMN9F^Ο_7DUeRI4ln+8(/c,7ŸJ3E ٹ!EӧR1G;?| _6⟈_ujV'x[ž җ\L|s6={?|;։7Zgno|]"_ e #>5_ U%xOt/ƞŸ k/37Qj?|pjx+~QWfQf:P曊(,):'7J/iV5֧RP|NSkRIN6ՕxQJ.ok(ӫNJաV*3]g>r឵_xK>)|j~߳[[xWΟA4F-ksvfaM"]{ߍ^'<#M%ekϋZό~fuχW>>k//{Ǿ F gMY5oiMѧ:QQ)ҥNT湠C3qCjXYYbrVY}*ҫK:*kVV(ʽLڥog)Uq V0UhJ(cErc+gpw/# }g>Ϛo_ uxKķ,mk~.M=xW<;yas>qyɨ&x^?;ψ?a Mko_,~;>"ԵoQexLsigGi7Qk^/eTTRe':wN*U*NK:U0x&Zؚ2I㥈WtR<5(ER Ni)Vy#*U*7Pe\V(ž:PF 1:~,~?;(#7~[oW?i3Yߵ7;Wazm?V<') B]/F|_7O+V;O⊖ փS xl6hJXDqښJ0O᫃CRnRkU}j<%/UgO_!&>?~:X.|]a|ޤ~ k7/|Sѧj~ { S~'í߆fo?_Q8x=Ɵ~,~xx/麯4}k^þ,ĝCCGz(߮OqZWWRV狖>u+s5S14u% R5#NRWe%FTZ)S te|NG0g\IF5%uRU>>~՞67ox@3 |1/==wF2/x.T񕾧w|I]P/3)^UCkY|>BNo"~+*{&Þ+x]O 뚼6lXԴE*uU4&q\U|bNϙKz^ϚjeNhKN4pr(ѩR6X갯RPkOuC_SĞi~{6e~'Zgs].S_;+߅~![./Zha}Jk4k.|@ x: mCZ3ǚ45ob/k+kYknt_(VrsqnU1]o1fxa(E| b N7UU+I$=_[Vb5aWo΍_Xkr?oŸׂh/}k>'%? t$A'ZZ;cxK+Sn+&ƻ?|;i|Q~ dopikᖙ࿃Ϗ-4_g /i)|yz>NM׺{xC_5]?%+ԃO<'ɔep48*xj؞jO:u qMƬh֍L+B)WK.48<xO8ռsoROGþ3mm|]^!Þ=D-K}o:}xQe_gjZSC$!kzG{߂? .i t_|T|HnE"|HJ_B'to>GmR\f*ҔV/X8䖟 4vJtc!AXo"v*ycaʵ.D7iB:V:ºЍ2(QEQEQEQEQEQEQECH`?|'_kW>ۿ uvc6/.ɅSM>;~1~jW_HomgW+*k _|߲R[~J dݟx?Jo)?NjW')$QN_ {e' _e/$[j?iߋGӃR ad<wӋ?nٿNtO!Ɨw:vx>}ĺč*P$4m_6i-֬0M\}eegiuamZYĐZZZmmmi B1"G*(O>}ǵW>72brܟ.>l6]O<4\7URTҽr8A奿CaA*!VJ1\ʎڊ%Z' G<+??>|t+~7~7Z&O?%kRGx$MN<=g>!xWB|"x^Ǟ;UĞYOt?f?jRQ? w.1tOi3/ݼs |a-keگGΓwjf|hVS #ݸ~j|9|8Z?5oxu>6)ծ5~)Y[u+~z-[ch͛J"k䶳l 3\&2S:QO N&# }e~޽zSeS-úrӣ]f9. Xѫ':T)a2krS\% N+[٬{|,i׍Gi_ؿĿ| ;Z|x!xKezo˾=~)7g/BA[ė_4x4?¬L>wpBx[τXҬg/]o*> h>O7+75/.UmxAtǩ|btEJ|<7π~>K}JA47k]AM1k_Ka$?5jj7!|5C^>3!i>6OoO>5-WCm Q[+-m#ɍ|) |mgΈQ<-[ֽxK7bomN¾'/m_k0X\Ie-ѹ4;!Bxz7?p{^ Ʈ'22Zi15hsR_(a(%)8gU: #4Ti[$cNgRI*ӌTG2n7>3ퟣxo0Ih~9G_xLi#3xό7_ l?]4x>*ҥ>1 eW: |-!V;LO dhGo~+Լ ㏁<_vP|:O:~+!mx:ZS]kaw7:ngrX쮞W5)|+_>24,U¯>)ҼG{- />vk46U֑w0Xfc.#%O"xTG78:*FtkFץSNuJF Jxά!Xv+_ٯin/3GρiMKOZ'3^.^6|=luhq?9&]B;OϨGǖ}c'_24 ~_<¿ ,x};|ߨk|)H:'ÈWnuXԴ~>*q|şoZSAƶͧ~)S_Gu힜%h Ru3(x-Y1zxS`4oO4?4_ZkmZxcW +xd/XwQF KXԣW<= 5 9Y˩ٖ"V*n-ԧ8֝*kQc#FtJi´*{,E Ej3jթ0jh(33kc[Gm!Ѽ,Ux{UǧAPӾ/j6zluP[X\|ञ6 Po\hbc/> ^u$kAJv_ǛxőCT\?n5tG}_\bp0u+c0nKSS uj*xʴ(ɩb({MkaV5e^)U* (¤ܕ\n ޮ'Sb(ҟ~(tzFx4mg\zv;|[HۼRǘ:i?1 cx[ 9zօ%PrJS+[1磚,UgװO<*ae1NJ)>jϬj1jR5Tj~28yR"8yբR^uĻ?m+F|, >|uOv$ӭ5 ''d(־4F޿+ |mmGE~V3oW?n94iCo5 5OFމ>qQףkb+R҄׳Nl],*2aNL]jt! 96,d'J"Vue}p:)Sj1t]OJ bm/?%ϋ:&/x'5Zg3hLj<%l5 .Pkпj<54~=T~^$-kx~.kᎳx/O~7x7A8F⏂^?5-ѯ  Cټ|Jͪxk^K{c^%֡goyqd#C֛HM_hZƗ- ޥjzvu}F=r*z]TjFjpWT-GF~vr$?rNz*2dBXI;7SVUQPuUj|}Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@>ۿ u|SH`?|'_kWf3l'_au?#71_uqqxҿүƿg/W]!\^4_Mp'aCGɽl֯bK-ߵ;?ߟ7R?:ORIe֝_}8?)|WOS7yG8[. =s?oci\_9KW~=ҿ+ ^%8?6{egYڍm=]YD]Z]ΒAsms L;"21oٯo!>χOxv:֥osj7'6)ծ5~)Y[u+~z-[ch͛J"k䶳2"rΖMGT3',oUFUל(P<,9q:k/;pҩ 8Fx.Zr'xDtkWnCTcZ|kddO_'|io㛏 M⯅^ ů_mu/& cxt7MR? AW]۾1~к~"d> g?|\DڥsÍC^.oy&Ƈ5ށirIް'~8N|+oZ/ xugIj_Վu{x ፑ\YE[ص=g?~ib(=V?^J,FSsyÒTe*O-"xlzK T/k-xj7N(U֝EN t~ΟA.'Ə |JK{)ś|L#ӿ>+.&5PBn;h7>О:1k>3ߎU֙kzn}45ͮe<~ρ66 о3ÃMm@\?h p5S|-[u` ,N,F+J˗t}%d>ům.Ax{īIy̫F_e,һCZ-Qiʣ9Nr&hF+ρ k/ߵ?x߄>?<>1W^3ƿ/WGѾSXtkK_ xPcxs ?p?_WGO*?mco7?y/[/EM5;H#C|]a {]όx+}^o^=On 60mψں>xoޡZ}~K_¿<;~~!㝑O<{|(|I⟍7nI,>xBh'')~ ּ=c"y*8h<)R_)Nyfq|_W̱ S69o#1,X9T˫ҡ<[էR-|EUg8%*XyF+GSZj'<ӝy ~.~M{_|3P|U >,<=Os})xC_G&V?x{?|AuK_iĭVE~w5/JC_+K_^5oْ7MOM}߄/KY42wD#Ծ!>%𾭧mL~>1x'(xx'⯁C_~Sú_.ιXz׋t]X_4O iZl~(m4$iu([|b>|5]/?e=m7V/ |3K~$u)[? </_hҴi9U|Gk8~ѿ8~ |G\|!OßC/> {t%kw/ONKcO_ïIO~2JҾ<|4aW9__WLS>7ƞ"ſOz_Qsa)sgrOls|6uguheYrƖk/ W Qe\bZ4i13P&H*N*jt3 9{ޞ"rӝ Uto?+:W?|mW4>~6_[/sPU|P%|5f?^M. !C{Exci?x[~&U׾ d&W?We2>i/xV~?<9-JV4_iV\giď4W?V~3h~k. #mGF_7{wv!xCJ֗{KO?jO |h$.xgDW~"|σ?h/ZUφm5 _|cm;Út7CO>_NŚVsVӠ.<<;L cq>d;ʱ\1gY&+-N# |y[3^"+ hs:|i*f8ꔪbԩQ,"J3ɾKFpF3."_g;MQ_'e4Ox+ğoٷt h w7o6e|Qgi\xFxj5?u.z_|K_O@ Wg'xw^_H.j4?]_x'Fknaf/Vz |IX|:- Ƴ–~)~j;xSK?%7ڏVe [ve>}Ưe?D~ 7w/ ~wOG\t?X=ALf|EM+T|+>$YΰJᬇ\E攳-VaxJpkۨ饈PjrL>åhp8ZK F|?Mf|L*OԺOA gGAOB׋%ZօH5[ 1ź7px_W?R`kT|; ȥO4\?I> "H|Df{$ ?o_AizW>~5x LO ^|4Hu_=ԼLπ)_Hot gŏ^Zem#QO>1Яta ]CLN!f g,x?~5Ln2fY}z>r*w ?_JӾ!mW_ſ $mt-&M*WZ5|ѼI.➩xh}E|tԼ!^U|so|53;]gW7zZY^_ 'u֛nuK{8[_nt-_m2HwmV7/>52{oƉK+YSTkξS0ղzQ|TQTUajS7*1*l<c(ao&J5M? ~ x:?|8>">3gk"ax:źo+0G퇷B?m#wn1R|t~ t_~5oº6 ;:]k^o?_~/c5G/ѱnP蚮?OTeS,cGrYM<:){9Mjbqu0ձ5jKYfR.LBcT%QQ0H*GK2NjؚtqJ >7~5߂[[{  ɟZW0xVS·V;n|Eƞ.6Z~&Ԯn5'֣:~[_ O_uZG?-uxZ{*oWTѴjZս, P__-?exZ-#HJa.ϯ^kIižim5o橭X:>G*lnjEfÃŃCݨŦUF>>[2uaW3_,28RyOq0Zycҭ׍ ƤV51t8F˕n\2I,A< *QQCԤb+GGw7<_{ 9C?mSg'~t(m?}Gu|DKu_i'7xu:wo|9?|Ak_ڌ_g?'k>|=q_<5ᯉׅ,;ߋ7a(MVNA|Lе ?5jx{I%˞еMn;I_JiWWX_wzehZХ'Ī >_Q&rOԭRtjCW__5]lVˈJucŋ*Ob=()TPU<t0T z?‡u>¿ٓ;J2&𥾫oK>=|R~7#Ӽ}IO 3th'ol_?4O|TǭǗ_Q ĚMFFgmu/J!aزR3dErGo^6u cRvqgp%>+i7[he͠7xgRቭ}_隦GwYдxNeJjueW\''J#_'msBwqx|axU2úp*K,:3Qr^SZNԫu$[qyLN?U|'G{Akg>.?s_:Z] ߲n|K~ %Ori>3ll*dP0lPV*YIRUIߋ7a(MQ l?&:t˦FI9g9=ܧbͥPbkJN%Qƕ:tFc׫jC̫qKgQ+RNFҩ)sUjNsYBߋ7a(MQ l?&/Wq?\!9/ѱnP蚣ߋ7a(MQornRLWBߋ7a(MQ l?&ܷ9?7)&+q}!E| l?&6?X~Teb[딿8g>o6?X~T,?e?_-O_Ɋo3HQ_7,?e?}wDX'/7Ϥ(}wD_F CjWp}rbW_F Cj_~/c5GV+~y>K1_Cs +_~/c5G/ѱnP蚣+?r<\!9/ѱnP蚣ߋ7a(MQornRLWBߋ7a(MQ l?&ܷ9?7)&+q}!E| l?&6?X~Teb[딿8g>o6?X~T,?e?_-O_Ɋo3Rn7 t/UE|r>!I?oK? ?V23'uF-$ml _Rim^[YoX.m,GV+-Makӄ씪7ݺM}6ͦGx@e5O+7ƕ3^a᧌|P>|`]σ>&~ÿ ~IƝ->FS+:ி;Q+9|XUMԄVR ;FR[R)էRfjBp>%ԍ\os{ R:SxM)Ba8FJJo)?NjW')$QN_ {e' _e/$[j?iߋӃR adwӋx6^kqj^imklMeK-73sL=>0x'?_ P}t 7z֦m-ee92?:]]ۇß)'ÏJxCV ׇSoZQ╟~|P?R·ն<񶋬ٴ+IKk9,,,dq5J80x*r%ZaE[1xiJy… C×QSج <=*tkׂ*1RxAE*)*'⯉߲1I׼m?< o14MK{y5K[Q{:uϽIfDҾ^-+m[~&xRU/j> ê|5:ω<%RUU'/|9B֮. *u_.ȿ?iOzb|<6o\7P׆|Kh> >wkZ\iw$ @> Uk_׊x/#ÿ &XJ|Lt 7귄bʅ*Iʔz4lWthkaSN/:Z?k ŸCJ|Gf_<;ď '~%е[ Ʊ&Aw}RmN_uG^o1>.~?Q6+ąFI04vDv#X7K|)fl|5jޛ_xM>MskYO5#/t/1[P??g T _q:hK iJҿ/o~~_cG:#kk~KPb#*ys*ї#K47nZr*S'u Cw'|pM|/[|9t߈zG_K/1R4_[u x+E?=KBּ1kO𤖺?>|w ~>-㯍?fw׌#6g//_Ww/__-w!/V|=umJ7׺o}{<|g_"+|"ƿu__5_|Ql|F5&}ރᥟ?~/ ?fO |Vq;imx'Ğ>k.:M?uk {'i |C Sx<[Ꮙ <WO ]Xl~!F? k/ėg\ӬuKkźo.yx'4W6_??G6lߴ·Ls|~j-1joh ik>׮2s6Kx'CѼkxSxǵON"zsØJ9.p9/1˱t-kֱS0L69xgX.ixk&p0Kp#cjWêxJuSKijգ_JIF|'_ D_{=Ɵ<{g~0Ww Sz@կj_|C@g뺷$i:a|>|KO3|m3ek~ͷz%Dx/ EӼg+K⌷~>$|ea~3?_ͭxWLJτ4;c?~|WM׼P%Γ|\-猵[xzv[~>xO2|5{VW<%> 2rgŸiFv_ѓ_ @!4-/ ~'ϫ_ 三a<=OfѼ-|]7_Fڏ=O⌾3%nGBv> /t>~ԞH4]^>Ή D/˟~_ j~ w4|o6|3:4GA歧A]k={<_`}Q\n[c[*,-HQq6t0T?e,XlS #~*R*E,8UNc %j'Ur䧂b/:\xCߎM|C" Py ~ѵ_ QďxI]9#O ⟃&OSuOD?᷿i>O$ڇX M? ?b]v$>x_YK~?fN?hgB]ڼ)HxG+W_NHT`DsW2ퟢxO?C?h};ৌ#.~:|MͦxX"jv}x[,a9g;ʨƍ,*YfɸK$V ;[|))l4l>Q<6=~x'DTʋa#:Rht9TS:Z8N.)?ٿV?|K^/ş > m0xSP׵ M_Bѧl-xyutO4z%'%x{*wּ+|J^o|=> r\Aor; _|mᗈ~p~$|:^ kKg_yx7źg/iy|2񶑨zW0Յ\ig=?ƙNy5|a8^[R8y0"bϰyr2 ohe +zLdpҭ8P?a'N(ƵZ^.3(*a<=ZSBNxK$_ڟ_h?_񆱪k?Wj.O o׏mk0_ |$W픚|㝿ω)o>?7jK 9X6>VTa)Qf_< Kx9YTHE:-<~jmU,SppZxTn+Jq2 LkQZHCGJ ^<-gZux#% ?zo[{g CKO7OW$?kʿ3~W$?kʽ,g7Nr/iп a,f ~*oZ ^(x.ck}Ҽ;Oj~',VӍ=Gº~s;MJ;ynntYt ڭNoÏ:'^-W~>[*ÿ#{j_d_oR/jo;^V{/oZivʏ^+Ҿ|gG~ΏM}u>=+Yk_ۖM[mj[3^X ^ETmQɥsVq85)PJ*.psԞU>uuty/.ZOݔ*4j1p2Fel`O -~r|Cx@-Wí,hZ._ͪȲ1ݕǞx Ꮉ}~xпi'⾙xoq·Ƌ{`Mmf- ޯ~\}=Գz.W-;isK,ZMN^J*zjGxE6~%y*x5W I*%*W~GxS:f>aZy6:} mfY}u3b+M>-%aY¨#W#] ]_x]{@iu* ϋl/4iu( E%4iP}C7? ~ont {<9cQTEkw+D7bM&1ꚍzTrwz ᯇ_M5V~ Q|;6֗$qL~ }fi%Ii5kF4N(ɩ'=FIIFVSèҜUITRlSsN jJ^ *rMB:5*|ښNUƝJTcUF⻯%·=*].4m!D"u]bJ4OVӴuJGe嵼eO %hxE&{|&5:ERk|d7SOikm9"@>#j:W<q=C6֚.j0ڶ&˩6mҳyiHZ4ߪU#ΛRNlSi7u EN(0x*Q&=Xg(٧͈<cKXrԫg5S~!07++`}U`x )hݵiY7QE (((((((((((((+gR[}zI?ڃJemW_Homg~j5>/?mOk3Cҧ&OZU_I/~ӿ~6IpW꿱?KI%ڏZw~5_8cX~=?4ls{]q~)/]JX>QZέOh8 ZkZ&[Z*:SYio Ɠyό4 DnWu R^꺅jeo-YǠGQ'ߎ2Tm?GKv񟏾O}CfӾMwVWzo_Ѽ i>!31~к~"d> g?|\DڥsÍC^.oy&Ƈ5ށirIް C >~*y|Ѽ)W\@Ҿ4|Ui&P~O$uOAZ#CW^#jC[qk>(H_ n?GmdGb5|40Zy׉)sk/|wa)|gנSBxƉ_σ~9RmVZfUΔ꺤6Y?>7Bϣ 5sp-Mo _Kწ6$:nԯ+._W<}r8OVVYw [pӕGIPri?샭h_?>ok;γC>8m*Y|D|o▹r|vxcZ/Zֵ[$~y#S1o|k7#ng+=G}~i~6¿low:k!|R~oxzUkm>A6~|s? y[~57[B=ᯰx⍿<e7⏆wxm__?LJ}O~ߴad|Sh ,dY'᳼OJ+-q9u$[^tֿn\[藿I<Hk_ڛ |KYwxfƻcG5 `h]O~$:c]^-|wkc~0<)j!>Гgvt?gS փ{SmT {GxKOYƽwØyX|\uX?Mc:]s;ž=O|Wq*Qt#y] 9nS]`:9jaK:asL<$0VSY6kY_[|RSSXl+NVTJ5&>o 2g'4ߌ<⿏_'/Z t7RZ=/]տ&exI5x aZ|'gٛm-[\mյ_/%xgޯ.9__eK'|;+UFomk:<=|'y|,5_|SEn/躇.to|b!-aWƫ>O5h84Wφ? 񧈼qoxgS<^}\?%KyrVSX%+>۸LFW8\9 pl?Fg唰P:w-z+cYahx*Am&x&N?أ Gj_S>)Һυ36M;^9o&|Ec7Ɵm>H?#@o~g6m:7~!e/w/|wo?+4i~7{sƏA tOxN'x\3e\fW>&Ӽ9K9ៅ)Yj:5m: bKYg 4?|O߈zh.thoO-]LO{>wRgh$}KO? dV?3"zb% Lx&> Cϰ\i  'a𷿴4_ [ 7zv'qD?M/Cj?ZWt-o:G'o?Fl~7߅:C5C/?x^#_|\/|KG͇43:^/|(~[_ ><{9/׏|A-2>x'H#-5?>1xF{KkᗍGCG1 \^Η'ס^}˔gu%|CC/pY\xc#ni†! :uF5qIF0T o:0sǺXϿ?':;A,4ߌ5SXf4ڻUwŝ_|OԮ}/[k_4_D&lH+o&|OO |9ρR_hOKG>#_ҵL6 J<2Xj_ΨRF8)iWj)bJʣq\*U(bcZWԪB?Pׯ`jIo?п?i(_ ߰5{?$ş_h_h> _~?}|U@ !|C_U@ !|C_Uc?]s2s y_B"~Ѷ'Ǚ?2S/ _xltWע?*]/}=n a~[êWrkfK,-m>.oT! v 7?wo; _67_GZZii:x:G/E}7owO?4|Mai-  I{͵SNQ="Xx{_m??t{o9A|Vuπ|goFxR]Ο߈~w]OKcC >Ko5to/C/È/S $~+ҤiiRQ^g5ǰ~1aK̕ZxTwPl>?G)ȩTy9I`5qWiө2?k9Vi77Zi J<Ҷ#(FI+K/;!$h_ )φn-&hڮm|K/n;"|}:zm:k&]_ei~;1xC5-k[ZmSƾ$ռ=quXסAyxGc+{*a\+/9C஬'/zEiZxkv=1frIcA''1Hҷx\D'ZQ)FN-sΚs]8ZSF֫RNQnԅ*U诚?gOkH<=?h -|8Ήq|GѼ#y'e¯O;7·ַogsy\O}5,g)?7(hVu_~mGq|s߇*ž"7H惪j^O ң֭.m5T:VqeTqx] ɩ+I*Xi5,]L=59$԰u1~҅'W% ;3V1Ӟ[7 ʬ)F8h֩Z*~_Ξ;^6_wO|6Ö_ ~/Y~ͷa7ok2Dz񯂼iZ#Q/Tsg?hϟ~xkϊ^ |YxÚi_? uO^"w/ Zo-msutSRƱUl4ZvpF ֩6)XR h8JƜ\i҅.sьd'㭽giDwOYZLf>{+ciL>U 5Oh*<&o |`?h|6s/>~ʋpGuu lJOux T+ ]|_||@ucH|7*X>~\&M+7Qe֍kZoO;J5[2wY)KV*U1aFrf s)̥%žVcN淆<=*GS>wʣi3r3SbZ^Ƣ ?T_o~G'ڛFcs]sO _|<|o?XVius¦Lu;H&[/Sǿx/٢*_߅1C~og/|iJԵ/W:a;=_yυM^ մ})ShS;MPRLF]b[RFhӫV_9x=c b$fPO q|5>zЖ? EOJ2-4*w=CNj?Naڏ7㍝\0B|7fvo dAu6Vγ wHǎ|&EAྷx)*_ْ?~Ƿaగ}O{P|-ڇǺ;_ua 'MFM>.fgk'\(ϖR)֊tے*δ0ujb`hXN7Q~KK7<!Ԝ#NR_WM{ ۏ <5&6 Zmk?>x+ž<|>4ؼg k|O,vyogxß |~~~>G=SxWntc_g~|sL񦟨oO|MމK < W똬 JUX`\NGu44JTh7RH!RqTу =Joݟ=jxf J)8)JN F&OkE|??$d~%~2i} oQIկ[Ʋxuz. Ěz厝d!-kj:eHVxsHƔe_اWsE7x<,ПuFNʶR硍ԯR+\N֭t,>yCz~aJG(,((((((+gR[~JI?ڃJemW_HomgW+|^"ß'%׆g/?O7Mg'_n~/ɽl֯bK-ߵk)Kp2{> ɻ?iq)/]JS!φ:_v[x_/I&+Qk+=JNm-i쯬o`'t k$xgdx9?3~.־|=|%~3ֵ+{[QNx?tkS6EȲ.SǂI(xzރ]CCu jxElQ]X%Qqcftj8N|q<Y9c}R0_N4NB!aˈ^yV[`玞HQĺ5rs~6+m[Þ<|3ߎwD+|qc?>0q?4_T=?\xWB7xo'}sj΃h5xnĺ= [kczI&zH|;ߵo~ҟix+՝iw^:o2u<1qx{S3t+^7 a^_jZ8OG{:1Zju"Z;O1TJkam pT^Eu2t|M[jNxGG鬺XiS#6>t7 wow>4xSW[߈?iO~о, g|=_q7ٯℷzwsA!?h.=^\ͩKxkw>|F4?J7~<|Q2hi7Ȏkiz`/'g|S׵^S|-oϯAYs,ڭ[[t)uImt+)߄|nF>kjC[k>|7_?XmIbub5M0ݩ_W\åy('Vq-{mot*+1'29J ?3qjE*9~ Zо/x7|=w;ߴwÝgM|qۥT-sEwXǂ_Դ+k1 Ik3G٫cٛ:soGqQa>[էtRgV=f\W7 |0z/5?UOS_‹]5oy-NW_$E^ /4d=VDz{[O[_Կoj/^|,<){[(`OGa|Mx-h_7PIծG-K߈VSZB5 f{Ovr[J sPO1[?|I|5/_Ox3Ŗ5x[:/LV}߆K㋿OZ~l8ּ%M߃z s]+^:i|c>ٵ/|9a#'\3GL\/Of.gc19fsVLT(c z^cƦ42/Ԏ |N'_hԩNqJY%V*tijХZ~Uo 2g'4ߌ<⿏_'/Z t7RZ=/]տ&exI5x aZ|'gٛm-[\mյ_/%xgޯ.9__eK'|;+ |Qvu]{S|9_4"Ǎ*W+ҼzN\~м}{$} ѵxIOTݗ}/Ꮕ>8L'OOl~hVgCŏ!G~,Y}wIѼi =guxrLF/[W[,e[pr=*zxIfyF 2̩ bթW ~ʕ1**krĺ[[j,MXP*\; `ŸU_ȥoATżoDm!?,će&%>*Am&x&N?أ Gj_S>)Һυ36M;^9o&|Ecګ~. FŧϺA?~0=|:.Ifo*>h.ᴳ,>(xZSoK\w᮫~+|wl__k߳K)4_߅Z7|M|=;KbK?a/'ǟwO?+~ o=O?< D?_jec_!g.4guE_Oož1>h'F^=O?|}!Լ[o i^+=M ʹEn_jſ ~4)i ࿊z/[C M˧rT297`8=S<.+/# ]xS~6Hb_?ݧ|/ 믊7`qk/eOk[T hKO+xK⦥ QFa #Lί;/ߋt-j4_'74A|[akO|Gw6W6 ZYkz΍z|~m⧊X,'pk?M +|U[Tae#O=Uq .*0dhQw5C0R2hTZ*QBpJUiJ<1~XBtSPO?':;A,4ߌ5SXf4ڻUwŝ_|OԮ}/[k_4_D&lH+^Ni־G8xY^iĹ\1ࣕ^y`R^xz4^&:zOW?xI.Ҥu;m^Hk {L>=]x[>,'υ )IdwaFQi.[[únZkswiw4W,$Q5.r!8vO+}gUȥ}Uᾳ,!xTN^y˔S)}Na@y;d?wox Z/wE'خ<&uyţ%dmg5+!g7Vp7Enf4$࣍⣍b9beR* Rۜj)¥H\G'qiM Ky&:i-E8AY,^k&W5ڒkS'IqVf? #k}ima{mE*N7,>o $oy䡷ukʊO աƒVKG,rjthANoj|>3W֣Zzu$)*'UԒtԩB5#^#'|znKe:߉gg`o isY?>#xSM+;ƾ":|e- S!#@~|f>]G\?S?>#|%?g պׇe+~'/'<=/Eޥj~!xŗ |KK|/./n;ڇ2Bx&9.iN?1Ğ;? [i>|D#xׂ!QK&k^#޵7krRIΥj# +Ԕb1Sϳl?+ԩtm:ú[JITu%$sc.;.M\qN_C8խ߳c?yc/o׿>=|.+ g;/ wmH|&ş0վ,_KĿ|'h%c]M"yρ?J:gwߊ?e/ǯ/5/~,?;>"xQ&VkZ^x>}BS_Xh/c(~q]8j/(Fqq< RRJ>իWS$ڕiUЭRDJq|թ9UaFyԣB? MƟh?_'oo3Oe<^2|]4=WOm-Ƴ&=~e[ Swcߵ"<~|;xg<<'P'1(f5OF"uic>YGoo[ %*cԾq5l]w_#[x\DFq{^Ku^6,ߴ/SAkg=!*Dž4Xf9ou O6Xjxyuu뮿u5oWRH? 7.hJ'ɳw\a^7I{jӏp"%.5N2/NrMғn.7J9vmҢES˳ ET RW5O Sǿ?|{i|']~NX\յOǾ4о^*&M u-kD?jt>'^<'u?a{;}>o)h&KOӯuXj meD0EyEE΄p*9Ju<>sTyV^ ͠jO)bRUeW o{Ggc"af&,~Ib=b)aR[or ǭvg/~~#|19!\\j -῎bs 6_ >$Mh!JT.]~!8?p_k_׌SNѼ=^On.49/I]SCk|N-jFڛ)r6rfx\\TUU&yMSQN2)aFt$B ~KSWr,^1?! ;Fn:gm.QEG_X7 ,= m¶x/ğu? ]x?~&Þ2gc|D_4SxSG+x1ExKE?d*?Wt*rLIJ)*r& "Wa_ V'VNT ץ(YF,~kEYO殽^&2N4S?Oz~Ӿ^ax5_hG) ,/"sZ$/n,- N,u"| GJg}Kj i|9}3߇eռ izz͟,,WJWUU?{_f]fyr⩬5c^ Q'G B8/_i+:krhMJU!*®"5) {1mlqq =x'x,}v3{|8[mZ'4K g :_O^k&'-iF_χOxv:֥osj7'6)ծ5~)Y[u+~z-[ch͛J"k䶳2"rΖMGT3',oUFUל(P<,9q:k/;pҩ 8Fx.Zr'xDtkWnCTcZ|kddY|RK{⮇~$%6|TZ߅xNx+ǛZ7|;xfÞ!}oB5ơh]?C~2~ҟO 3.x"mRRo ơ G|AkmtL}cC@ഹ{i$XIC'A| zoO^NJ!A h4??foLNCw'񶍦[o}}iZϪub]N lqXj4\ࡋb!mI m:ЕZx 4<%\/ҏ<;מag+.&5PBn;h7>О:1k>3ߎU֙kzn}45ͮe<~ρ66 о3ÃMm@\?h p5S|-[u` ,N,FW/{J>տ9}^[]'ʃVVYw [pӕGIPri?3߀i~_m?eO jW~)G+%Oڂo?lY.}~$]Ŀ ķG>x?ߋ־q?i|O{5_'> <N~m↡_? ό?!x[|[mCtV?Q|!G4z_qt?Ox? '7EVEߍ xkW5|+?S_'~9=<?3Ǻ‹ gĞ)y'fIB~"x^῀qk!?"qX3j  3l5FW>(rXVis2XƤ| 0JTR # +}jugc0x.>J;XSx*QG3c0YSͱV?`];a).gHDŽ>h '%C> xoWz|;< <x{Km56P_e7Pϋ?,?dM[ _?7MM-|`ek' 6v:YzeeVgߴ!^ o-Ŀ z'l.,k?}#W5Ki:޵7~vnk>VxFM;~{kf.sqZ^fM>O|U๿k=kE=nj_'e^x V׋&|ᧉE|@ռC\~ףQ[ψ g76_><ҾᏈk>)s?~"e]7^t]C:Nsķ2mnE ڟliku>_ZWǏ >1\j0+U |cÚNj4oiWu}FOA|+^8𿂼3.hg>Q˸ Fjx-3 %aor= trb2_Sq>qxGz|7'ǏĚ]ciZ?ՎYST^jN/YkxV=O|Yo7!;dQoN4fѼ-|]7_Fڏ=O⌾3%nGBv> /t>~ԞH4]^>Ή D/˟~_ j~ w4|o6|3:4GA歧A]f+0߀qzx73kp;JYS| 2l4u*< X\V ,yl7߆(f9gn.xZ،m,WZb8FTYvMF/ 8~$>x_YK~?fN?hgB]ڼ)HxG+W_NHT`DsW2ퟢxO?C?h};ৌ#.~:|MͦxX"jv}x[,~18U<`*Y;9I}?lj. ~]EgOiiC[k^Ҽ]\[CwM|fsczxcJ|W%Z0[{aV KeGCZ2m!i)QND(֢SOI9ѫѬzuhTJ##% ?zo[{g c|7W?K|Yeև^=OzoO_c(|;¯%?Hi~f;¯%?HizXao錜_x?4)~ kzN3Xþ7{Xi^5u{>6յ=oKA>yG^Gi_OOKw~|K~e/'x => k—^'|v ǧz]]<|/ |7ѵV~0<0_"|$ע|/]?" յh4JK|:mk>1K-l5V Wb>¾,>!<]|<~{F?<:{fŭRNӧExzr>s57:jr' z ¥,l6k%ZcJ N5}F*oГ> jN7Ƽіpy .TAe؜-oC5*?S?fO$|,Wg>i6ƿ$l̚W~ \JEhڳm3O?Brl5=#C4K?K|Oim_zu]z5+mDѴ8/ ..43MU/x /xW' Zشׄ#@h0|+H|QM)|I 2ھ Y|Zqן١5bK<>Bj?~3 ï?}o)Ŀ!|1ִ'CU^-ld: 𝶅ȵ^IRX^-壌PԫKhU+Tᤨ)ʍFaC^'燎; NWAkS~(k?[:6ƚyӴ/Z]6j3Pͣ]?ahO7+bxQOKR7ᆏ>'CHOG|?r -4_C iWZ Zn&k'S>|9nWK>0VoΡɥx][šUŷ5vN]Ń"W%[u-k? tσxsï:?M6Io{Okz^G<7]z.{oZJZ?.񣂆 %|QSZ5*0Ͳlƞ+:Q)FrBrIu+RR#F| F)KŒxrO8ܓ/o?POo7+G|&|-OxŸ ß M|O?< 4> O1?7_~ǿ>-~кg}w?(5Oͯa-C_%> 񎫬äZzg?|3o j:$67f~-~ߌ?y~  >O8R xYuu/ QEaPc4n-8aE>- AOh~ ~-k^o5^mG;. '_OɇLWէJ"RNnU&F|h9aӕ(xO\wi5o~m6G>-Ϗ>j..hZKSj7O;/ y j2k^Ugϋ<'[?~CW_ xPkK9hk6֝[`mq{wo G {k뷃QjtNp94q1%9jխVu?,KZCbZdž<-MOPcH_ٳt'|S|+O5_ _ < wb)o)xCVmw"K~O:Ϸ0w0_Q? T~Rhlf9*‚XAE#=:skV jM}bOwmьit8JqU<ԕ~U:8Bz8meT,V`*5aG)QaۦBjKl^ u~{mo}ot뚾 6Tƾ+O~if_MT/G6K/"Q)f2{+7q 麟u:I5:mΏVG%HҼGu6òֳn?o /^S7>`6n ^&?E>o|=!DyɻD WSf] yԔc'j3,-#NjSǟk9I/Ҵ[OD#tM'zK#흉/OtE?fU(^>x |2|mckrx 5-kCؾx|Mş>&kx/t kᏂ |8>G h?<G,^-v4x'/5Ҧ:x"࿀_|!X❇x@cu͗ ]'BVkSx5(eXRDe.N N*9_#Q(Sg)qY3C Nʕ(m:W1Nt0xo ~i/ǿ ~͞'3xk 0|;gn΋ 4DŽk}GB|rC J a|u,񟊼 S|'C'5 P)I6G{io. ⇏tk_ 3XH?|4M7G~𥯊|;VnX_i{]"ߡnE CK?g|7jOυN<>$G~:8?n֟e$VӴ[> |T\7D֭Ÿ]R'­P](]E_ 9k{hs}w; =o|$I =Û|>x"J!Rap U8){8&7fs!`<x&О"iS:ѥ,+?mU,N]{Jtap\/U)Yɳ UUQWVƖ2q[1*|i?-^ E_ !>x_^)|(𖵤kN4k+MOw=dI@?`/_ǽ_O@xk ]KI/>||~)|ug ƎW;w>xdW_ u7>e6ǞYBzm;ž>x> EѴ SY4?~!~ hvݯ_>3 <m x2񅞃j:Nm2`jjKwcE-*i_ś^^s6vkhU>x['_ῃm-oY:iO~4 VյMRz-j^-IJgPXj֫8e+bܥѥVcFyB ._J[*5%^T91QT(Q} w:t+ϙ,e<8j*pj>h+~џ5ſRg)_^&:Mi⿈I6M'hj :AһDnOoY|7xw*¾7cmMMIvmiqL|N|u46i &+r_&Md|1g}ZM?|OP5 Lr,2'H/_|]kgh֕ yX:8e7ɳ  ,2#Hs/UGIDz;xTy> kz;MF-6|1ŵj~ Ю.ko ˦æ\ZOdKLa' :xu =. f);N5pna<hW`p_W7GJpW.I'<$pNu!Xמickҝ9F6Eթ( )Iq??n7.uO[ ^/;[o|Miz|&*Wl:ޏk#zt{{X‹ڳƿ>!?m[ ?%5mO7|Oi/ |$tK |f(M'?:~ctu?&( |6kybǕ~Lϋh۫ _|%_|+s_~+ _|NQkscym/iE5/n6KROeym hK XڸH(jpo.qf%1rRbUeANhaܽki^/ J!~6u6A/j?f;Wlj2x:/^!𮡢xY/?+s+j >|+[xƚßE-&.m.Qy#Lmn5mR{yY.mKP'Wi=RTQRT* TI~S:ExJ5`ctK OR*gN<4ΜuTEM8+a֜iT+[Zѣ,DB?ڃJemWOHwn>J~U>#[/lCko8i__w :?/F5g?ҧ&OZU_I/~ӿ~6IpW꿱?KI%ڏZw~7_8cX~=?4ls{]q~)/]JX>QZέOh8 ZkZ&[Z*:SYio Ɠyό4 DnWu R^꺅jeo-Yεσ?~2"ƾ;¿n |Q⯆Z?DOW&/ÿ7~>=w uE;Ÿ7x /OSީ|M[W: |8)c#TSSeFj\U Ӯ4fªѫ|D5h2=s+AQЫF^ۆoj<\aW̪c)άS=t7 wow>4xSW[߈?iO~о, g|=_q7ٯℷzwsA!?h.=^\ͩKxkw>|F4?J7~<|Q2hi7Ȏkiz`/'g|S׵^S|-oϯAYs,ڭ[[t)uImt+)߄|nF>kjC[k>|7_?XmIbub5M0ݒK_QNyZߒ>TJUWpC|]a {]όx+}^o^=On 60mψں>xoޡZ}~K_¿<;~~!㝑O<{|(|I⟍7nI,>xBh'')~ ּ=c,ͼj`3<%6Y*g`{ f_zq8\">gS C|@n ?gm/ om{E>'ZINr?No7ZOⅷ-S-->Mg_߂__c|uar {t%kw/ONKcO_ïIO~2JҾ<|4aW9__WLS>7ƞ"ſOys+,>'KS9YObsجn1\^g,p3hB;9a!ٞKRCTjJRܵԭue qS͞^jcܫb!# .T~_}"  SFi&?ȳIo:Ÿگb x7Lvzi%~4COTJ>~7xOxGt?o+|Ag#čUO՟7{_|FQQw ]ݿè_ҼuړŸմ5-g|7GsLj4+s xs%V]j9n5Ά ,KC `1ucjaDqob0JU_%H`*ӌa<$7ZQ^\PE?_~!4|#Z#; |S[/~\Cc?t3<{?6K៊<˺7|)XSwXo61_'P/+B>s $<'?Kğï |k7)o/⟱o Vy#W4iS}ej_^+е۾*lSѾ|j^;O G߃~xB|z'Cu/k=TҵMN¿SO |% >7,pUѥSK,BY7 dzjTSrp4]/|T|k;ZxO~x_6 d_QxMǟ<}sⷄ*jZ/k604xIoo6|0xho^=˿tiA Ox3^.ׅu/^ -=χ~!nY-"NXC'}O 2ߎď^yK-~} 4@~ X/5^65T F~4˛3Ǽ)&38x*Uqx\G:_Tc^L]z.SAԗ eqW U $ץ֫S+u%2R2] Ğ S:pҾ+~05McGjWt<^>!~M?RXQm7~xfKOĚ=W 9s?w<->I}?lj. ~]EgOiiC[k^Ҽ]\[CwM~oٿg8c>YJ28,%*4xL?ߧa~G4K:]Jic(E_-Tn6u+O*sXV&Wj5\kR|wHBO^g%,BCn|'_ o~7WT(ש:?bWÿ*S֝ ~Woÿ*S֝ ~Wv\/`>=Ck.?jN:'d^7U'' xKTGÈM^$L>7TS?|+C%oX+*W0x?~/߃?4|>߅^(ڍ>!;Ѵ"—|DKOR~ k"UïV<[x*⭦.4xß^$DŽcf<7=ɮZ1i|?⟅?S?.|ai'K񆝥x+.񖩧x|Mp^0lM?C}OW<6jU*d)W*kQ̳'J.dbMk'O #e )7?Rw?&Mijk595]xI^I4Rnm&Uc+? x7 [:K>=ٛ'k?K3d.oAigsc>l^) ?FG,炼) x AxOSS-G]A<_3iWoxV_UecO/4SI5]P+N*ԣ:q ,$aQ:'"o n[HcqSt3\rkէ) Y֩JT78w-9Qi8f70%eײ߷>477? EIo K#Ǟ<~#bgҴ>* 5n.eI R~cŭE>,/f'?O/'Ɠ|m?#+7ĥx|F\_??ǯߋ?|3SD5̞UM~\Y5{)~-o2⟅=G7vbs'kԯMy `*Fu¢)+xRNΆ*/4:*P?Wb:JJI<.Fj+}c *KZ?kENF~,>:Z/')4~"5P C6|JthK$*_OuE>|? h$^GG:x3@-rZ(|,QG? v_G/h^:qAg~+e>w>k=geԧ8-Nd2 BW$ >cㄝO<Y<^&#)sJMaQT 珯* StY*uN2c3<C sdkxO k>[O_ #^UҼMDx|Jzn5'G/}VPm[ ?Oյc~t[oM+Sվ29tO}#Z}!vko'M]HP;v:?öMz&߳?nm7{Z?ӥQ>05Sυψ|6l9>?¯cuN)ԼIu3e~55b ?v.u]*S ^Դ57E[N S+?/RYF,Mb'Jtp1bTB<5K?|f/}xyN4<>)BYW7G>_Y~뺽/#Oaω1{.Vω4 Aͩ/|M~_M7_|<c2?꺶/Eg#5$пj[t˟kG:}oTMFvg≬|7IKeajݲ'kσ?c|+_.| *|3> >~מ1 }oë?]vGx>]gOS1h/' ֹC↥ǿ?߄3WǟQ'~ %C_ S? |)|_7]~ѴQѡ,}5:BU4+וkS8xgNOX6WfN:C( ,FE )eo>TMb\%0&Q,3OiY+6] YIV?TxѧE-](ڋ(2ڛ Eo*/5#_l>ka$Kio{_?]xfZm&ŴSofGg~?v^׊|?>տo} |[ };~վ*᳾M_ ͡|.W};PoJUכ8TJq%eGPe(~TLKuiJOx?tkS6EȲ.SǂI(xzރ]CCu jxElQ]X%Qqcftj8N|q<Y9c}R0_N4NB!aˈ^yV[`玞HQĺ5rs TԮtC@qxv%4Z]X5-.^I4C&O퇡|U ?'쿮&MQ?>(i~(OCǏ^6o'P4};F=Ï|D}x[⽜W Fg<6&\EhҒ~ XJPC WESxZ!ԨS"xy7WO*fRaO/T*QRU1TΥYЦl~ΟA.'Ə |JK{)ś|L#ӿ>+.&5PBn;h7>О:1k>3ߎU֙kzn}45ͮe<~ρ66 о3ÃMm@\?h p5S|-[u` ,N,F+J˗t}%d>ům.CsF=UU/G2i]㡇n-C(QT9ZO1 ZO|<[_Ns?t_5_ch3.Vzuxb:I-uߞ~&|5||=3x[_.~?gGmJQ_}__/]ZW5|+?S_'~9=<?3Ǻ‹ gĞ)y'fIB~"x^῀qk!?ƪ3r\=a(咯q&aOO?x\NMW/u1lŒk:Nt|OSIa[^FK,lapquaW+D~ڏ=ft~*SA/E7x㯃"t/ ]2i+G|kM _-K?-_5/>~̞=୔?' #v0>&O<}a״]uě~$#%+O~>1x'(xx'⯁C_~Sú_.ιXz׋t]X_4O iZl~(m4$iu([|b>|5]/?e=m7V/0x7>60a1 +ŭ 3> }_Ծ KuoI);?^8u ~Þ<o3|,薟 g_fy}fV>5|>nmWKf^!w>/xWo'G3?|In?kѨ-gZNk i_|w 5W9?~2஛x Ǻ.K'@[kw OĶ45p|:dk/ĭ+O5xKC|etυ>1cŚ74+:' sC|i/[_^OW?Aqxzyĵ3+ G<ϱ9rC6(㳜e,:xF*ή]^JVXZ9'9oju֦:ʶ"???GG)y_?o?f/icO:/$! ~/񏊾[~ɞ S)=(ǃ~$g:_ڗD?Oas ͯ/~o牴{_?XMCO>H_Y8|?ͣx[G!7o?yz|gK:|A +Z_.>?@|<)Đh?}^_'> iW>"/|A񏉴im>,gu;?iZ[NX{tx)174n&O¸ܷ9lj2UiPXZ֣\l`i2Y407V6G# TUTY?qr8K=uO*O(_u7#@??e??û>52E6> WA<7ǾjԾ/RF컧szGŸ?|Lz?؟fho~|/I±/3?iAcĺ|IX|:- Ƴ–~)~j;xSK?%7ڏVe [ve>}Ưe?D~ 7w/ ~wOG\t?X=ALf|EM+T|+>$Y0|rxwQY:T$%pIUJ1Yw,ES:Si |xl{c8NSt)Օ8FukUlѠBs<!^&u#'Jjp)# ]xS~6Hb_?ݧ|/ 믊7`qk/eOk[T hKO+xK⦥ QFa #Lί;/ ?o_AizW>~5x LO ^|4Hu_=ԼLπ)_Hot gŏ^Zem#QO>1Яta ]CL:|{x2k0,Ìp8Wq|I5`$]__x?摬k 4?]+ڕ͵7T}vsʱm;;|S.RO̿ysD5ԩ摎&2tZxګJX)gRW=uheyJ֣UƵ*/my[//?GJ ^<-gZu|5OzoO_c(|;¯%?Hi~f;¯%?HizXao錜_xТ?fv~,$?#Rh~߆4":DzxSu>#Nɴ2}z}?_>Moן /|o }O{Ogv΋c^ L:v ')7w׋|:XrF{;NRIW˲vgEBܫьjyQ25%8^~\=ޮ#{YaK#̰JN#(J8? 韴 [_Qw_~2|@~O|W |p|a0|5Mo|4V75}kk_H+~:Wt?? >+4Q]xw^֟:<)-?i"&Zo뚭 t6"M4^ŅWAW1xzO gY:_9: n+j4+Fzxxl*)R*a(:pIkJxaUiF:թJ XJ+ aR~ūE>iO'?/E pm$QĦZxFWCg~?w~|ag/īWT 1KᦣkjZ !;^8u'|34u/iAPrJ'Gt& Y*rVO L]zT)ҡJI1QEF[rl;䥈To*WԧN>m}~)T+:VSbs(S6:J<5ӣ7)a%(B^և͵?XnypU#FPG( Öpi()F ˝G6?CJx?U?_:>#_> |#u. #ߴ~YQ>3? l4}oc5]|zsqRƔ#T[Z G Z_TWݿĿ? ?gyh/ xŏWx%|">g#৆5OB_|4>)3]rz=8o~7Ÿ|'_x̿ /-/_ǟ sA7C_x[|'Ygd|)Io֖:!jz6NJ0}n+Yu3 d*+yQKªxHdpδMrG)il>gRs3\!){Pa'.J&uԍeKQտt8?2soSq5/|I| ѵOZ<_K-57[KzEc"j2{?~ 5ெמ.?|7IP}uW¿(dψFm??g.Y~/xG'?ga?ǟ>"&?_,?>4_Cqe/ O"cPb-|]""Yt^moiɮ 4TP b~qrzdD,B^jr)L1\`qWVX|Ɔ?jQObu&M*MJ1_,Lr~ h uϏ>|M}73(S /_o_,?'u_?[?_r-hsKOx^ ~~Y@ #?>x-=K:> 0,x+x~= OLAb4 T(T6NF'K5Ri(\cwSOum ^H|9ci1hWZ4=wTm4}_qk^);~˭/Ŀ~zuեkx^k?tOh־JW-ׇ5yi5]*([*Wt"Rbr%QW2اCj:)ʻ~`eU39V7hP' էSNj~_:[٢Uo~_ş(w¿7យs߉>?}j¾"#6w5+[~!oƓ"ѵ|8t_ړž=E{+YD~ŋ\#P<3RƑ<=^_U?汹4E®Yy_=6Ts5)R^7NU0gU<# B+aJLMWSK޶ES S({:*PԔҠ+ gz+_׿k߆x{Y{GXk0tcD2niji _߳_][g?|6TWZ N}VרYq~~׾:ÝxQ)W٩sutXzQu3*INps f]^Z*51cZl FeXʋĩw0T,D0>YZx9AccW0*ЯW0l=:bKVrj2x}.u,ࡺ {]a=M!k'VYfGo Z&.?y)8d{>SI~5~ _CKoH?}l?~7>^'ռi|д {?\;}ű> 3?n$UOŞ%oY>NjZoJ9 QRaUêT*(QNZ NkҦ<=H}jFsXʜ)jBq+Y% s+<0I[\%Z5e tW%cA9_ׁ|C_هN-G5_~ nJ1K]LPZ_;i+Ũe<o7|k~ןxg\Z?|):?ycaCS'ǚ5JHN eyG G5ag5T0XmHBI ՌgjBUxNx.ڛ*.ʴigM*'F1|~jF(`|=g~ҾW/7x+|@Exu^@|Cix^3|^xXs8'm5:|¯?jo蟴y¾<#[/mC?k_8k_s&~'_kƙ0ɽl֯bK-ߵ;?ߎgR_a_؟$wG;~pRa1? ׃nq\@z9KW~=Ҹs{],VKRqtl9ZRӵKk>{+"ິ$ )wDdb߳_C}t j(_uJVo'ӴOxKҭn5CRKm-mt)e{YncI?"7+x[0Z^.&Zͥr,0AGK=ps$q൵iOj߳:|mS\j2RÏ'WP9]CZǞ6u6Ei4w3mg?eE噝,?_fVNXdT#Өf/ )S8PxXr**t״^v;9㧇Rq.z\F*O(:x_hReR%Uޜ\__u~ߴ<7 ׉o1chԼO.=CItkzit\wyZgxC|O}7WO/׌|~)xOQ:i~>?|%մ?%xB˝;OxR_?W/v1Ӽ,6\|W[ß X4;N6v_ ʔ+PccK۸8UC0a1p rQS̪3B:X\FddKaU"F+,kjFRµJgo]]OOS=߅/ O{?;#⿂o߳_n-VúqC]x{TS~;6כg5usmƔo x!|*eѸo  i.ugZ^/m_,xZj?⿆Z^|3ocV7~#3_Kqk,ޑׅ~(XxkJYX>2  @?[πs}hGR:`{S A}cn<%I,¤gVԧJ0RgG:ru9cNέ% n 04ͪW|^\έLdhJIF8WiK | {!]y5n&HKeU;ߌ?}hhWZ׆-oc]gJUWp/7CmW/x[Ǻt$(?=׋xZ9 Z;x'63j3|&ON8گ^2⯅ ~-^]4osx:\! 4uso5mF~ ռ|/<+i e+s,ka9O-rաř&| 4 W.ou;>%(["?5_|x7_O,;OZ>]o-?>ᥟW𶿩~^ Y7l> ~7iQ7|I ~$C'V0/~![mhh:?|c_|o 4m+v/ ߳?1xQg |<ӯ/GaYxSLj`@x^4?nˏ|ao?/?x^K᎓OǓ?Ϯi'|7Y|L>x{MsW%eyOd<.3%qAS!],;1c9ɳ:<$[,.,}l6geW7 8a5`qy5*'^8X9p)ՍQG*F j:JZI?d|Ae=Ff߄^?c_ǯWߋ[./:g|V |A-ភxSwq- ?kφ%6_x ڶwj_K7ؼ3BW|_N/2OƏfþ毈kZ<xF0iΉ^owߴO ,Ѿ(mo4'4]xg~?/3V<ioG_xy[r;OĿtl R _<+nIn[F> m/zmvS9tI7x{ǁ.x?wë? <%j^-ǿtků>e֍ ]G_o'ǟwO?~1 o]GmcO _V?}O/H6xOؗ_:K7~|d.>9G}D6 uĶ-z85ij~Kg$2W(k-y4nIw'k?g:?S1[?g?~1tY>$@<'_5Y8QrgpDexn_^x/h}~Vzoدeox{_JK> < |R^/YڪO+xK⦥ QFa #Lί;/.G|IΈ<W)kvz~y_xwxg>߆|_ ?:Žݾmuq;C>ӯVq I˜9V.>Y^8Ęڹy~->&*΍eyxkbhF+rjN7V/R#YK:sc[bO |uv8Xi_ikPhv:/k&]x^(ֿh 3 ME~IWYg7]~kŜW$3wQG+M瀴xs@m-/ ZzfM^/W3~?frĿt?M39WDhR%2VLuZT{Ua3<jmTtY'G [0֥N5kԔU BKB4kkaPx)|4T m7:}kšF߂.,nYş/XGwmr0.'G5dg7G3~?frye)\C6J9FYKb0իq4fK_ L=zqx)(a1仅\$:ќej*RՃL>&MӯFH_~OUk? xoj=xNJ-Lhoڧ#!{O޵~ hh n-᷇gwQ^>-׌c^ͪƷqZ=?%oٛʏg7[*h?rZh׍IR%_U)b/,,޵\|URn8}EO,%StS( N]C)A%V< jpPq_&G];U|'g%ߵ@oԾ3 `B|1}v=>]^vK~oiqosMφ >#|z|t}m?ֿux|Qk~-[:7|)"ֺL{8x fo*??|Y __n-g&߃B+OoD)5ZvjO%׆d:xp/~T8x fo*>F:)֔ 5#Z;ЭJrR\>c(ʜMlE SRSuSRZ&}<7'~ƞoz^[j>8 4=;Imꗶ |ׁuK$Wx_B~7~+ooqZm_Mr;_mcV~5ma׈,Og7G3~?fr]qqW'Z(fUb2iC):9f+AN2TڳE 5ΣJvC3:ƹӋ̩eJ1>dԱiT?~#gO_|som.|-$(~/Zu \cOŝg?[;/mi:=ݟ?⏆g-c^SPMyb>9 H /Xc]>>m w jk{Ep/~T8x fo*pg9l)Yx^ԼE]CMZvįk.,}7KĿt?M39Q _:&ONTge:jo5\R *)+SQqb l3^nk˛?:ZgoMVgbο]i_|W77⾧KP,::$w7"#EvxWjOwSYGĿ xO9"o/~ZxOL{ x?|AZ'oZ 0Ŀt?M39Q _:&Om5{:Zq҇O$ֳڻ(9j-*j*eNX\ƃL,W;sFGS'5>xK ;u*b qej~V #_3Fkx $?~?+sgl|qx6qF-K#"Wuoӿg7G3~?frTK:aʔU,/ S+{/Q.li0< k??+ q>.iz>!h_ïW+_ Sŗm]!]2IR7 _:&p/~T`!N<4~XJY|Rɳ)RwG J#F&XUX*rS'Ru)cի)'AмMq[Se=6/o ZYx  ~صY[E&$KĿt?M39Q _:&G\sԇ+4W u#OO )(<_w˰*#E(*S+ѫGJO뗔'Om{ln7իOogu2w^S4554 R {oZVZpW -DV73~?frĿt?M39V0kTZ]:nSf{ E //.W< m߳pX|V좽Rup2|V*ҭTd8/TiXZBH45]ǙU>#[/lCko8ߏ}ǵWoĿ'~GFÕl+;;Q+;; KYH.m` 'xFF 5>xZYIZԭumF};DLjl4*Z5)4&WIҚN[xng4{ώ|aA߅:ƣ/+?8zuÝU<%lymYiDVMwqcK}JA47k]AM1k_Ka$?9?_oxi|sqwm}+/|c;G_|v4x#I˥M=gО:1k>3ߎU֙kzn}45ͮe<~ρ66 о3ÃMm@\?h p5S|-[u` ,N,FN<[Z$Fu*ҕG?`TUE EiTQ\҇q/W#u*R¬9U)J2P.ZOu5As, 5SƯ:__\wo|{/+oKxUskךoᯆ>#OK O i͟SPs|bc|-Lj|Oui>o1V$m>-x_N> |9?Ļ߆z^څ犼Ont?Ox? '7EVEߍ xkW5|+?S_'~9=<?3Ǻ‹ gĞ)y'fIB~"x^῀qk!?HM|/BZ<' Ž34C0%fXeNYX2&aRYWOĘlxzt:/ϟ g_TļV2.:~ R*]Bt** G4U[~zx-ɴ?ZcZmῂ_+-B/.t h#š^][j7^>#<~3͚G<~-U~_W?aMeEv{Q]D]Gߴ!^ o-Ŀ z'l.,k?}#W5Ki:޵7~voW㏊vFk:ּA4"~k>_<ҾᏈk>)s?~"e]7^t]C:Nsķ2mnE ڟliku>_ZWǏ >1\j0+U |cÚNj4oiWu}FOA|+^8𿂼3.hx,00|6UnZ\)}WK 1u 0ʾrrcx.ci¹m<Iӆ>R ejIӯE(`!էOCK 5џ[<[7:o_/5ÝWY~9xZ_ٷR=Ưz7_C:7Y'l5+x/׍> |3F*jm= w#|uoͨC(;_|_/Wci^:oiqIIO$E *O>;XZ]\.O6+a $f4jatb8o5|/'#o !xt?Ӿ x=^: g5~*iZk_)'~ 3\8)Sbs\:iRIӎ:cW >x?8b40%&mW|u?__=.jA΁_(~[_ ><{9/׏|A-2>x'H#-5?>1xF{KkᗍGCGâ|e"agmW}[!($Q1;]{B%4xs)ե {ď&W'Ïh_ag&|!SMt_4_N5?U]?ko[%l&]S.>:UR)Xueˊ~Cք' V3[ пT֊֍z5hTZu!O{|7W?K|Yeև_xz~/|]3?Sſ~΍.|;]#?::ޔsy{&b>u?7W[F+n>*-N]6[R̒~]&hbW$?k~W$?kW ៅ?!O+Ak_|H+&O VnRWT#RPӝJTcN.rTIEo&I$m&}E|:_9z|5/37-k3[ƿ |9/~ʿj%zg'R@GW_x?A'7>#$ ?uO <'Ÿ#9S^3yG f𦶺/kz?7ou"Zn5QQ:v~~ -J)TJo4 o( 3G|SW>eQ|UmőJ\ xW8שRJ!*t֩j1QR0rtMTNOUG:UkTQ9(ҫVj4)΅)N\ӴW͒!ifl,O/10?g{ W/flk+;~?xZ/<\xᖋeⴞ#/>DĻ/xg^:_,4B<-uOqiO|I}ڄ5N0:(7ZbRQKԩkN\õZ)|sF\pQJiV"iBxz%)QsQTH?_8<⏈|Wm3ςI-KAwOMiSIis¿8#|mO ÍKŋJgxw>o4 ־!jrxo/YO0S&dNӌhʼiAfʔSwWK8TҫGCG)“:Ԩ(6:h ױj+O[8bҤaX+Կ_/LJ|a=xcN:/F|^ z{_iZ|A?<'cU4Fbů'fU1wxuY|[_]@K;) ԯ|I߂u+ ^Km-'Ygke{s=~mrҭZRhVB48PbjB5%% CZܥET*U9=IҌ\$w6Jt BtkN1*ſO?&Z'"Zv?K#nu;P>h_>1ZxJ;maoSX޽k_-Nw㋭k|7x)_}V^ 1\h7NV匥ZrŻ׭,L)PVZ֫<24~rbcBSRjTVH%Na5+8BְRib;^֟7tW3fo=?ÏXA}F5&ajIo+]|YA>^1 Vzlu "׀W/63vx[?8W >#6<{gGK4ߋڿb🆼<xK-E6i^!&AƜԡVxJt*c0QrabӚr8Э在%Nӫ/xtԭ =_c GWZK_C~#ͬxW<|nGt|!㿈s2fx'~ sANx1mA#-س>jjZ#4>+𭮵\O^ҕYPWN(:5#nhUJ$0V#),5U(WU.SK N짊G "**NHEmgk& <[i,C6gλBkK/7?mS|cKFMž7χA/|3-jYg/|OFUl&2QV(Ju#Ra:*SԧRs$f4n3"jѭ^4)I{g9V5MO:+Y?l㏋ ,5o)Xڗ45>{:?'OM{Z_]̋sU߇WQhO&un?開wi/:t}_]XÞŝ+׿ O_ x3ƞ4;] ~)hv^x_ usz~ 15/|oqhv}hpjSV2VJjQqNZm;O uiԖ"785cZӛW*xN++pXTK7MJ4*R=#IG|!i/~ !Ch,~=|Bo%i֣|UU烧^FJp~rZPI$K.Os^QP0(((kgD4N?$w?gUZ%}MBwWО$˿ |o|ƕ6|_3g9!Cko8i_ѡ3g9!Cko8i_C_)f,ۍ_??ߟ7R?:ORIe֝_g&OZUy|R1h~7C8uĿa;/<{:wsחw\\I vҗŧ)8qwI9Ao;-nRy2Tn/NN)aRm=쭫{?oci_(!I4:rO$7Kh\Iss7VaW *ҝLUl]J|&Prvi@a*G EL]IԄa_4hЄ+ꮬLԬFOlx..gI Gx&Gh77mkg'Zu R^꺅jeo-Y_~?? ~9|Cχ׉ς|c=:jz-oE*?jo|P 3ᬿ4=/^"uZ_?z>\wRE\Ѽx_Y_.k/3Sε2h6Crb{j q3Y&Ki$4x8V"bj(c'<-\/1,poBj{]y.8jTqwu%Ufo*hJiӖMBt]*6{??gO~ fxG>%|%w} &xwi߉|N(Kwj~4bM6ڥͬڝ7 ~3'cM]@|\hn4|mW S/x`hFo OᔧDQ|he)~?_?]sNPS&r!qf`4)r譭l1WVV8nc(<\8bqΔ]'իjzjNrZо/x7|=w;ߴwÝgM|qۥT-sEwXǂ_Դ+k1 Ik3G٫cٛ:soGqo Y̿hH9Sl\YS[\FW Y>x%fk;U˱bG[4KJa^Zَ.qv"#V9|Eia،V1Rú4;ƨV&jMŢ~ ?dG wO?xS) Mox_ӼuUh:ur.?c>5&}ރᥟ?~/ ?fO |Vq;imx'Ğ>k.:M?uk {?oO5ŖYT8\$x1̳߈rG e0̳*bqT]zGGWS/7cs*8R•L%j["* YF*. 9TTU?']rQO۟ Ogx~3xCo=|@⿎Zjx/A`xc1e FER#/7?/1W o376 u?_oĘ'P1RjdY]L&gMgYGj\6,N(SNeqN8UщleE[u*,M]-~|>)ٗ?.!Zῇ=}W(|H4e?>?~);g,?D?QK7C{/iM}!`K %! 7'?AXa$1[XZP1*3ƪ|>R*u$5FUSN.)?ٿV?|K^/ş > m0xSP׵ M_Bѧl-xyutO4z%'% sggqe7j!qsR ğ Is\/Wm&l'ZUӴ=lj)|\~uF|I ҭ[iSܼ_ڗIa5 ͣ/Io?п?Rn<=?ٗ|S]O$mN˹FVd0r?g%,BCn8ˑF.19R6QmZ-! GJNrRvV!d|U@ !|C_}|t5OD<;⯆ >su}K^e/|< ]7O#Lo 4_Q-o/xMw ?_JӾ!_?" ~|g'Yx6K|sx[>_{+ӮƞO CNt5}*kiyPUxVU)ƊPږ# TSi+TU4T%r̯*TI7ܣȩ^ji6QMmEJRQ*|w>L_(>#B-ik᷄/,koK5 &-b}2#Q_|;N0-Ĩoj+xWؗKwW? cƺ'h&S7ai<,M/:{m?Z욦kmu^7 ^%} >/o񵖭VuC2k+5] 7EO\} Z>%/߲čWUWkӵ_|.ĩ |VW ?h^qq/5Q<#6RСt/I҆&%(S:r2է`b|%UJX<5*8~Xw1UF)R*8.!ʳSΕo2.HЕHa+Ebu%W>:íW>,|ևGxɵXxJlj<xSĺi{xG.4|'gE7ZHfeOot-?Zޭ}EHBg}GV|q 3\W< |O|kog᷌C֟?at|~>Op+7W|?}j|i|=Nï .?e犵8k>-}:YJi\=ղJ1sZթ4jTQpW-t+V5,TcZrB"[ CSɩ-ԫUF9? ʝ9{yo"ķ$n|Jڭw=./Mφ<`@4I 熝 ѥ7ͯ?j_۴ sTNfxO.~"Sߴ_Im/xsTG⮽?C~_շt HBf.mZֵ_?5_ki~_|Kx{Uo|9|; c_>'|Ym|K}ƺ^d[?/_Z}ѼCskOx[|?AjZ'| HXMڽ/cdFZ/l5K 9NYͩ|75=;m|KKƞe]3Ƣ/x' 2Em|>J]}m·'GD<TNhFV%U/T?#;<3tmCL}[_xV.IO =O/|1.!}wj-xsvnCUF2Y珉_ň$At=/Ouo߄]kl>_h_3Z嶭<9[I{⛃]/h|Hoz?I|p? ƭs⎍=\o ژdz}mkv-g:ԌZW B+V"/RS'y*Y&:yp*²*t҄i MJC1s*TaeRԏC28,N2#uoBG1Gf_ǎ? jWƾ'gO{Ow3⏶^Zo|Z_Ȟ lO<9mNj/ qd?kƃa?&O~6t/ď۷>+xaexF9):7BxZwψi';] ~)hv^x_ usz~ 15/|oqhv}hpjq}4=JV{m.~D?m|*g ma,Sl_4eBE ӂYN#0u+¤G+yV&T1T Zѭ# 5SRNas 4\e ӭC(J5pʽ_?a_xiŏ j./hߵ1$.T~,a%W|g=Fa}ºׅ-߈Z]0,xPNL?gMߍf]r׮aZ|B<3s/4uc6summ_ڏǯ?ֿv7Q/S?~Lu>|mxVu?t,n? iП 5; o\iڋBkŻ (񏎼=ikx>_[h Zl"5p䥆ҎcN*O,,0NN1DⰫዩҥJWI9MԣGUb;8Tq5&LveөMP^_YT_5nZxw 9mө|~?w?į6P>6]x'_O(j߉fƩi> A^o?e9/uȿ n?ړͨkln~ºNd>X^}F/n}K~؟0x<]CA[;7<7.<ex3Wڥ+xsŞ,|l_m?o/ٳ:QmkGxoUkд/>?{gxKNZԬ,|%Z~+lS>?:jٔPԾ SOZZsScq113 !'I:¥ m9Q׽2JjR+ QKV+h~gM[>]־"_nh."xZoφ?mKl^|QC?9x(ҭ))i?I w*֚~o?~ j/5oh>.jr|!𾻤|Dk[χxwRRtj+BMTKgJ+GBQOJs rJ5*be8թ<,g__]x[fMXTZ҅8NBNӭ/<ȿ?hߎ|1\f|I#Q4 ZUόKXOFeiicI=#_xLo>էt%xoH_u:+-t?4.[>6*TTW.ڿtZ8WJ~9S9{ԡ8F.Iܡ&*t ri7 R<e4$`4}GNm<>xcO?kQkx^g~3U/9~ӑox_<EǮxB?^>Y$1x6kt'5 .=+Z?Mω[=͵e^9s^|s|M/ Hl|S|.os7  >%ShgK_x94QYќ:r0ºoU0iǖU'Oao:1ĭ_+̽qwq6|n+y/Y$cZXl3?p~w|-şs+W>Mo Yj^)?j|F]oE<9xD}@xQ[RPvV{'쳠?ϋ"5 |~FCBx?_3QMf]i߄?5?Kt_ZZ֍jW|VW ٮ\D1qZVWj'eІ 19QF7+-ԣe4rl6wR|=jF3J,]9QEdEPEPEPÿI?`UV_S|h'\CE C?Nk]9/ofM/fE.`[ y־k>!Io'kݒImfu?t hc2[,ThQWUR>UcRegGV[MUz5tL\9|ujui+>zњӒgz?~?b9+7ƕMH|?]Kxyƽ[_xKAŹsϴ^\R[|}Zb(JyJ3 P,Ω08i9AF2_TR##4RںvٳU~6IpW꿥@7!-6ofox"Si \/4+ KS| B|Ss]_@Жt-R-KYӭn"\&{WIGOּq㟈GH|񵾛OOq%d+ RuD[="8?nJ+KڛSo\ӽ-+^ǻړ&qIf_+Iq^2j^#y|JhĞ;.|6?/"%xTxHeu|[k44qk*[J֯@5 e_u#xbߴXyfeY%FAs (b5TΙeihf^,Tap׼g :{)-ԯͰY1᥅xZs{Zj*kG 4#ѥt} >_G,OU|= {? ?M/"c il?YN<'#?_X/|'o*{ ־'Fy"W$휿غw%qIkyC{1_>*^%{ o4^1?L4?|'Dg WNxoQkF*I87 5hܚ򻺙dDYwKxZ.]_pϗ$Q >__O?#KAi&_Esl?YN<V//I[|w&-5^As/fP  Y3^ {? ?M/"~Zyii B - kyeyk*Okwiu=ʹO ʉ$nC¸LN y熯G)PNbi)85̡'ߖ[3괪Rl9ӓ)8 'zi+E~L#s1W(Gc &W9 ~Q_?L? ?9D? {6 kE~L#s1W(Gc &Q xOC@O-53 !M_ßCi'G+?=|wa?0_| dr2>=<%|~ޯ+彮r+/|N|Nլ_1;y%Esqi|\5a|>nG|>{Gn^W 4@캷?BgsB\fHUiP[ %̭E_Hӫ^Q9yۜ$=k{*+SAJs+ԚIB^AUmw>Jg/Kjzjyhu< /ڃkXͫ|Z&ڛxsIP]OQB̶n077xߕBSIJqm'${]ڜeV[isRmE^ײ=A3H|(Io?п+ⶴ<^(IO\?nxz74(5 j+lqiΝqsR[g HQ ko.owi9Wƚφ}Bkе6kgQKcrB̳χUd ;!g LJ.g|uE4<;=û= saqe_ x? o<O]G2h^/U|5>&wVt>o'Pռ!ro xHmQK,_&#UbV.!i &U'q+U*uN' 7N)GwziR-c(OKe(7_O-|)^&^5w?~Gٻ%/ /k5Oy{ tQ_ŏ š\xY}h1x+?_>^lje#隍#¿6Q𼚴^ɴUm?OogiT,_&#Q g/?4iܶK0Qb.&B:9J#bN&p5+ʆ JFS J:w 8! cI<=8 N'KFY G~0^^xk|+lmo]? /-o }/;W]K?i? YKM/FUJJTݝ9,L1wN8JpHǒe R⧆JNJ5NJ7NY]Yӫ(UZBbտ_1?lA?iľ(ω> ~v1wIqcpkixgw;%cT)/CXՠxF&ŸS/گ<K_}Ϗu+'Dk^ҼY=NYKM/F_mi5D%*xu,Fj*a*S8 4dYM:U$Z<^Vʤ=׃Pt8eȔ' ^4ibR+|pG?|Mxv~ |E5LJ|;C?|I|%Xkԓீ|֬,5k_x7ھkxw~_ |E5xN/ŏ|QMnC)Exo~jM(> xC|S੬!,_&#Q g/?4*I{X{hG ˈn, ]WfU4Zy*9 eTkԄkƌA19R,<%5pr,.T8hS.He2WOE&/^)!~Sg'ß|1is_yWᯋ~дo|:ּ/㛹5/[kxSM___Nb|:+W(5ϋtx&7>/Fc>1s&:Ki:YKM/F_mi5kNZr5Rs_uJg*ƸrL0O7TVXl&$*Ota8EB,$1yV28jThsd}:*Ukc[o>!xd6y|ML:7 /? "#a?4-*h߽֚zucYX|R~57~?k]'G|=xH,/Ei_{V~n/Ks_YNTʜԔ%u(rI{&9.mRJz+?c<7{'RS/s|'G{Akg>.?s_:Z] ߲n|K~ %Ori>3oO6Oh/k7? jh?_lռO?_2ٯe?eӿ|_mi5~n/KW*tnj*A9njؼEi4:تN%W:tGH+B"α]k,gQ r)Ԛ!Ԝ刜W㖡w|gfz^#ŏ\~͞$a~~5f1"u_D5x;Y b/x_ M?Qk\JvY~&_ >!Zc9w_|ERmƥ7tx~o%۟ j?,_&#V2 쾫_ +7TF!8r)S5ҫR&U"p/|\eNYVq-4C>:?N5?|/|=ŞO~ E\UğxYZnhz-n|Qq|Ys_G%۟ jھ"&J՚jXҌT#*EJ)Js>gK{n1uj*ƍ:۔(u\W`QZTW%۟ j?,_&#V$TW%۟ j?,_&#P{ g/?4K?i? E~^YKM/F_mi5~Q_~n/Ks_@TW%۟ j?,_&#P{ g/?4K?i? E~^YKM/F_mi5~Q_~n/Ks_@TW%۟ j?,_&#P?<(7?dR:~gê?imM0_᩿hZ})K/C/?%[Oξм1XjG?ǍcK_?]|Z𞘣? FFk,H-56qgT_m'%G5o'Jm9JZ8SNnwqvkubX&isNWu%T-]71_t~qqxֿғQ|Ay; 2xJ-kω^'?~&|>ڧ5o\hω>7'>Yin vfQkW_HomgW+'(ۍWpSILpm[ޝO|O+]4is+&[{/C w+M=cD/ïx/h"?e#ߏ-#msχCh!խV嬖Og,O>(?~ > Ə4hERt Z_kNv+^ gBo xTG-n-:7wςoE9_ſjvz6௄0e5H#c%+_ڷ ~.xŚ6zޑ?G𵧆>+9cyxǚ}췚f=~/Oi*9ܔ%gRicbUE*9ԟKNjth _SC**rg[F)JQt$FgЦ1*F3_g'&k~mu/Zk|_V*Ӯm|G7ô&mշo\C?S-~(x;D~ xTLj-OVxPK+˝7Rӵ↑/k6e{kc}:ugskO%6e_Jx[6'=- }῀=fמ9־<=W፞Cdz{vEG4_xO ? WI{Qi3_B;ќe '5sX\M\Wׄ'O)b90 <4^>^>;U/JԼGo. |@t]u޼(h1fp~ҟ(38kiO|ẏ~*ᜟ$|>%xW?h5|eA:ko jM}`xGTԬf??|9oE<-}Gᆩ0|B> uV>~]gZໟGV_|5txcV*n+nsW 7NRr!FpWU}b_6lXjoIZu! *Q*:.8jT=\}W[STJ#xl38kiO|Ù?@?ߴ> > /H^|xN?'o /IӼ=x_>k%oh:χ-xOGSOoL~> [Q6=4υ?|iRj=}^%~0x> 꺮.V2\F5Pt0ׄ:#KZp9ʕNLIk+Ok?>%?f}#k~#7O[Q[6\xt n33NkMw"Y5P=u,FwG*TK.^Je mj2t(Sѯ5#SLU!*J!UsP˲<´*pK %V#J4!9~.3<+oo _b&V꡵^ =6~'ڡ_jh- zMдGQ~$H_~9#~;5/otOz{i^-Aמ?!~-i_XhZY[_K⇃B>x/ů^3Ox_O;kϋ#ĺ3's?^KBt[ދb_';ok?xsZG?/~^񞻫M%M%>!-l1?n.|Ka.saIs*qqQl4)chNFt1|FWyx<ЩJqqXB7e>BKVIUFV125\&-KK>,(şkOFa..-ᯉ "O줿ugVwΟw/N6柩i֗jfkseemu'>㿊~|;|c sxᦫrCL&6+_~hZG[ K|?мIcRX| ZGX[|07_ ?h|w#~>" f_ڧO3cV^6GV_^Owֺt_\_OD 5_ /cJ/λN/ O 'CT*XX|JWV*̔\agjg1SXo⥁Q ?N ZS|>Z_~>_P>?|N?i3ڷ='CҾ&k:5V-dռU.#Co#Ѽq_VA>#v_V/lkEO EkZ|\s]Z)MI?gW_ٯ9gROkӥYNСL tRaԫ sNrЂXhUFiq& .5mak}J*ҟo'-o)ςs7^᷋)>j3ß+o_hZ{ß>(U=~ ^Ҽ<1=NƋr>]2~k{|a񟃾xv/Xx_7o.-t3[ÇÚƷsx@RbiFPUۦ:InU(RRYxMJ*XCKc=(ƵE::sup5J^uiFp᫥B1j C|qῆ|i xѿx~Բhxw4j?1|UI<{;__[__jm6:}a38$0'iV8<*`,OxMWF#{O? ~ @}?¯(ֿfk[95S S 5׏始~ o~!<_\;=s'τ jfl|5k_v?b?Y]:g>3|R񗎼o]nU𭏎~$'<+zzo|eiZ^J^*ؚnw 0Pl2x>Qו[pqj\P8^!QIFq:x{DX\;͆ted_#_{'pǍoƋ.xy4{ĺ4m/E]SD-a]GJ \XF?c~ui-f(5 ge_xP"<+4^'qx&]sE4O5 !|vLJռ;^7Fa/~W?=LJ>.?d/ko37i<_ᯊ?'kM_~:WеM'_-.Y7C-Fc\#O^ZQT ELa(μg,ҧ% 303aK1sFҜN#;֢a_k~"?]&մ/ |5K-FmeoZ"qVjMJPF)Br\E*XUq+ Vuh*Ou:1N3FJSw)>hTk*4'g9~%E5ǰ|1gڜxV\h*燓Gn^KF_ OU4Mr%t (еˉtmNk_пE6|gsm.H]c {hUB*s+5%'>hΖ^)Ӓ!W%Z0QfN:NPT̖UT0%*y?(Ta2:PVLDҧZtݸ) SFDiUk|_V]aEIfp~ҟ+¾!Ŧ>?mi~9M x?C {>D_~ko:/Oց#oۿ |m_5yEŻ/Ao oˢB4b_Ə: ^G>*'í?I=_>x>1χ!\xZ/ SuTO"g3FaSZyJRJtAyI:GXzժJSPQP8F^4)bgל1t R$R}vé>xu 7Jҵ/~Vޯei 'u]V;t-/W4+IoNӬ|C\jZo'-o)ςTEwߴ7ן}ŏw_=iᏍfKxŞ3yx'~3߄Oλ:ŞNag>5ԛ_tm+ᦏ  zw&^ 3^4~$n^~}G@W5uBHVUi\74yq*.3PRTƗF"J%*\p8,W/<9VBzխ1exN/EB>38kiO|"a&%o*4?, ’i:|-XЂnT]Ty]_|\YMm'@?i;8$rb!įC 5-j[Kź~x[LΙšox6RbQ= |WgQ7 >:~ο kM5l'iz֧k^34~wn!x߃|)྽:Yޔ>W֝7:x~'ey{|)mĴUa1Sp'R|.N TZIV_UЯI9AΜ`TVa꥘ {*R4e:҅isb0UFÙ?@?ߴ> ?N ZSx/ß◅|o_ ⯇ߴ?/&m?:=|"SF/%煵Y?Wj ЬIxR+Ú5ޛgZ3Z6>5û[ Ÿ_ǎo3)x^7gV?޽k=7>24v/ uT*u+K&๔a(J.RT GۍjׄSQu="JSN4`QʜaT,='>jL/SɟE{S] wL+~ѧ&Q~z+F}W/+$zwmF7?񏅵/0.X~!x^V=C·-|9?9mumdS࿉ا?~ #JƛbG"׼?Z |WgZEk7<ƄY(:E*8RƄWSX 9`\q_6TCIr数T 1J8Z!_fp~ҟ(38kiO|x?m;|/Kľ"O x .jw΅mQt |Jռ/Y9_ֵ 9|2nt۹ 7 4*)D ,loυkS?Hg{O)|: AO VLto½s@'/|]i#xдț]|#z!?'C'>ռ!x_? 1Lޟ$me_z&E?:ѕ(`'gC.(J3KjޝZ5%QBu$Ե5F:u9BGN\փIƭ(G!u*VRO8է%ZwAY+G5/s^k~7Ez'|'JA ť_|V>$v(iOog q?U_|O\l7-Þr?J$Z|=cWKGuӦY_\[{V)[z i^ ?g(> |Z5~˖9u_~'|6ƿ"?_!xS׋[QN} Q~*IVeTeN:啱.m$VUuUkBtԹRj2Vk)Yܕ%gZ j~΍:Zo^E>3k:=NZ_D~/67Zě[{xIl"Vޏgu K/gO8jWUxb5Fz/ُeĺf뷾%5 y{-;N]x ~Tz^t9ԔZu9%h-7:ZS1zx\M 84Mz4hCNqO^ NjXyb29+/bbqxj*ᾄ ^*=OW}3ik]SEltFٟ;[s dV1ʥN@J|.x_ǟ _|V{a'ڶ%xe-Η>DI-4\iZ4ީ 6i9KyW,Qb- Va~~:mk>S|!i<1quxw@ћg3>-4CO?ݏ'h|A y7 ~⇍lg?E;4 _ַi ]iv~/?ϥhz}kMh}뚴ןMÙ?@?ߴ> 3m<ٺO2Ş}բյ U<'f OJMEP/5Q׈tSS_D}i7F֥RP1xIg*U)A:yLçN4(7ThII7% X o:׎|kW_Ҽ7A6?joP[,43G4ZA" c<o,/ 1#/|%7}#V~_> Z?t-N4Mt?Ai+]os5;Z߆|/(Ҿ*?_9]4uxoPX6U1qmaьo¤1Us DgUBq8jҜ)`K3:Kw F\kav,PU6-,=WVa:TSGRo |U_u xQΟݞ8M> NgOqꖞm~1n#xZi@?i/\׃{ul~o[-?\u/֫.|kuEckves]C/x^E :߉}}]HXSNu}4U, BY*nY capt)Eay}Ly Vd%7S $uVp٩T:Sb"UXMFd ??_ >%|9w4kzyOuaciZ/%j.eZwNӵ"}?XӬ-Χ ) ?#?;OU+?ட;/?Ż?>~;9}c;Iu+Iiiw c5tOĿ /Zh4߇dGα'c 6Z6zѵX]ڟ4~_|yZg|`WƱ^]7QV\:útXhK^^.e, 2Q_ڼwׄ"qvwƼeW6yV?rXL&.CG0aK塅լWy9NM9,)`M:u1م\jbgUZGNNiG:8O1?O'7l13"wFHE|3RI?ɮU+KCYm-Wy{"yFHQV|<x$_ (%kv_Xx>lg?W_͇EY~4GZ?gx7셨3zܞvV[ҼG'5؞}WOqǦm6`g|gUR_FjKJ7\ajp2]voflҋ_Pc/eJ2ŴG]V|<x$_ )?*߇m$_袗KGK0Aq7WݣTHV;xO:(%F{%o%mEs X?*߇o?" gKV|<x$_ (KGI0+'l9wwx.~E/ғ"wF+tQGKGI0+5lq_+/Y*߇m~4'1.~(|p4[Vq->/m`Lxq>#VTLi SџU8(qQS>YA YhQz;8>7\&'w, ryk1vGU> ExΏHEOKGK0JYx| |а׏" g^+S>2u<#._MBVO I>MV9EGEiZEus0Gq:E"(//Q䓌4%Nq;IJ/x&i4qxtN-qQn];J3dqm=8K+x/Oo,~xO4o NNOf~·_ t;[c[BU|98go$hD Q@UEUª@b*Zr&~ҬTo|Wnu(ePGyIE&ڌlļj]s{R:w? ܹ#h[_SO5o|D5x3_+mw>4>֭Ḇ5m\/JdgEČ i~WL7ῂtcx?W-}sjMbm;HkJP6뫛O,QK%._U9=e׹oW7'{˖̩q759jry_5MFS{FRJMYwI%U޼}O:OǏ"iEGtoLKkG%q?mt_w6g7OU޼}O:(GM?Od?[p|ofOwb:y~^?toÿ7^3ћi엧+s)q7Y?9'"_U> ExΏHE/{%a?Yx| |аg7EҏǏ"iEѣ_]Zo/?-+Oͳ+KyV;xO:_x~3f:i{%5|Mklu2_t^_٣:n @|;OF-mQ+Xҵ[+=OME:\{"yFHQE tdrkpZr(MA3c-c{F)Og?W_>Ѽx/U?<?J(GDiEx.'-+/"yFHQV|<x$_ (%F{%_!g?W_͇EY~4"yFHQET~GG.Xx?p|ؗqg=?WyǏ"i\?O|1x#'쓫1[kυ)Ƶo 7hSjPwoouW$wC:($e(ћ8̎QjҌWifTZqFQ|2('kM7t֩E_¿ a _8NoGw3|)tou=Ax{'Ӵ}^]#u}usw>呺]CcX_ill/`<^u/oqoE$r&wF0(ѫ9sO R)K|Wrm]Bm1^5I(oU^N-.۔lW=7:uq;xJK~z geͫjXm;m\O7׷U?<?J(td/ڍΧ6~vbo+˽Bnnq<1E4}aBd(G6e(Y_JQQ)E˅J0|JE(uX?*χo?ċAg7EҊ)Ĵ}dxKOͳ+Ky1Пa5ߍb|E -D5CT=w'V5[M}[Qf{ ;OQIw*߇o?" gEQ39c*\bd=Oi;% 5J*J)MYOr%i<|No)wbWwVߴW A3`A:-=^||;x)of#ztص-/^?gM`Tx@QJ?F&G5#Rmf-'@u O@zzնC^|E V|<x$_ (}ƞza?Wg?WyǏ"iGEY~4ћi엧+s:̯/"yFHQV|<x$_ (f:i{%5ĸ92T%[Rӵ;ٓĺK3ꟴRn VN/쓣_M7KEg㦕K~:ZhV>#|@4XmZ׋?T}3FmD?`Ҵ} +O7W𧆞xoG8pF]µ8,6k2D;68!E[Qۛqm/n:izz6*sVSm5#B ǁ-,p2|@EnQŶnowj7ޭqWSa8< CE2]XEyIXeSrУGZŊiQj.QIl_#9%"6/.EjX.]f*ȃ,096?aܓyG ;?I.IW 7,\v=4]L z&RhVEmս367 Uoooڍߋo^=Ŀ5mV\]W mqoŷmۏ}Q{l uF85U7nR܉%+7fiiSuUi(]nյ"%qKarL׬-{_u}))hSeUԉڮSԦآjh9#ˬ8,cbrm٦8Td]aQiM"Y7W+r!cjfUǝ2/&B\(⚝B`6 wHf=;6 wHf=Sarv펨iU(LUۊ,TW%*IuU[ԋuaM-osi;m)q0ABĨ֣iBZU#qMU}]_JU5#Qkz*=W^noO)ǒMФ4bA!::1%2%S=+7rDk" 4ݙcYvlYxzvlYxzSqOo޶ӨO~0}mc쫽Ɲe6 wHf=;6 wHf=V?u~&zﶾMƮwVGilYxzvlYxzG74?᧵L?}m|9n;Y~̓]"N̓]"UOG74ޯg0-Zk/ٰkd]C7ٰkd]C7uӨO0}lW{eOe6 wHf=;6 wHf=V?u~&zﶾM|j{uiTvfw Gfw G'N?{[OWɳ]}?ӵ5޲.!5޲.!Z:oi'Oki6sէQvE$3}E$3}GQ :oim?_w_&`>5w[?;N_`zȻĆoӳ`zȻĆoh?Q =awkƮwVGilYxzvlYxzG74?᧵L?}m|9n;Y~̓]"_p?j-v]:G75oGoƞTLqzﶾM3>ʻu}ߓf85w[χk5otY;'iotY;'jӭ;~Q|gWyggEggEN{[SG_u4sG|;Y#}>N#}>U;~oo{:h#W{e 4{{Y^?oN?oU5:[n&m(W;e3>~fqOfqOuΝg_eoO{}_Wǂ6E~ʹ)qΨme7w|Fh;7w|FhVۯt?mgOk+x{ z<(/ULuGk/ټ{S3Gټ{S3GuYko:{Y[_sqA}wg}<[Y~?oN?oU5:[n&l sS>Qogzvogzg_uΞV4\x#dP_G쫝ﲙ|?V_x{8fӳx{8fh?mgNۯt篫"?e\}ϸTyǻ>#4~ޝǻ>#4~ޫGYko:uM==}_*{}:յ=)=)Z:[nӬ5=i|/FȠW;e3>~fqOfqOuΝg_eoO{}_Wǂ6E~ʹ)qΨme7w|Fh;7w|FhVۯt?mgOk+x{ z<(/ULuGk/ټ{S3Gټ{S3GuYko:{Y[_sqA}wg}<[Y~?o_;ӾYWFZǿo\{qoMj?mg_USGW]FoV{ۋ}mcZz9cǿ~<Gus^tb=kzv$.+'䳉"[]ۑ8 AG:)t&,ym+{K(IbvnoL2uSvxޛjڮ.m}NStme7E!uzvyWnnny_[⯩mUj.[&_&ȸZKUʥ bDV3q1hI,U}2qۥZdBY([Fe'u9qܛ hr?ɫYgsɌ/(-5 rER˒j.ZkY}^.}{?gt>_?f_7xܖ.'1f8_aCN\o~^m}Z_{2?vy=VtnIn1mcw.%aO5[Z)*/WH9egclt.Mdb$*Z"Y[r%D*W`xga, J&(w׍2!Š5 ԪUKEorBLy WoڦkT=* ϐ, }V,}-Rg \ұɕ] ޭ뉺X\,_1a녛܃w6z_G]nLr9d# [3P,"fR=.Y sjM먥AVoY}ueٸCrSl yh 4Mw6 JQ 4PR j5mѺoUB2[;Ij(UiEzWRms{okia녛܃w6z_=p{n|K/wc +gr 1رJ͋B* #4Ul@ig{jfw85VeWrL[Y4 \%H2[;33;jߣ{oiъ}A=/Y7|cgt\'ܣ>W>Nܯԓ?<{OF1WoVط[H\,_1a녛܃w6z_{;Ku~4I;zjߣ{oiъ}A=/Y7|cg?\'ܣ>W>Nԓ?<{OF1WoVط[H\,_1a녛܃w6z_{;Ku~4I;zjߣ{oiъ}A=/Y7|cg?\'ܣ>W>Nԓ?<{OF1WoVط[H\,_1a녛܃w6z_{;Ku~4I;zjߣ{oiъ}A=/Y7|cg?\'ܣ>W>Nԓ?<{OF1WoVط[H\,_1a녛܃w6z_{;Ku~4I;zjߣ{oiъ}A=/Y7|cg?\'ܣ>W>Nԓ?<{OF1WoVط[H\,_1a녛܃w6z_{;Ku~4I;zjߣ{okZ]Mv|}UtW\\US}/_ia녛܃w6z__ -\\xw~.?xӿ9{>Oc9G\~Kݞ:V~ϥz+{-o[߁o~[G,^qaׅw3z]\'ܛcG>÷ O/cO ~sw%y/'?ײ;h/~Vw=קF{yiaۅwhvi=,i὏nn%ۿGr^}%z=ZӣWc4m/;p4->cG?\7ܗ={w^Kݣ_W]Ztj^w=׭nq_Ɵaۅwh?}n{tUЗۿykN^;OӣW;4zX;p4p7r^s{#/vʾ{w=^uiѫsiztj^Z}{~ƏK}nq_ƟK_Odw%/WB_nծ:5{{?N^;O÷ O/cO;4zX{{K :?*K߼zzէF{yѫsiz_vi=,iZ}{~ƏK~ocۛ/{{~?ܗGG_{ OVc4~wF?VutSFzqq}÷ O/c_>UGiTŷ;qﴵNmŶoW=蘟՟,i1Ʊ=?ɻDz5!Bu4[n5J۵mj+zvߪۏڝ<_[ ̘Cy@c~dZ;r 4Qf+/}T^O$}w*PP%Α[!^ 5=%[$"Dt o-.66Iv@KkO)}m~_}|[Ƕŷ_ٳyvdtN;v#q6װX8>OdκSwMhӳ02%ow(_\qj.cr܆[_,V8۷jӛdD2\H "# 0Ų4$o-d,* DmiGX0ͤ-\VւAVXُtqnhg ߋ}߯NEuo-so;oNN \^h^lp7bBw&i}Cv+^[ʆ FD[n3=SN#vyQ죆0C&YuZƚKinOM .9o+-]Oi:Uc_.ctܤwD 0Q(.EkI{-ÂEEXaRJ*ϳ.>缔ˊ5r[9c77~ˇe\iMK'bPr=VA3_s]xkRw(?&qNjBu\%<'-,IEXF* ƌwqʁNsc0T(:jS#:MY0ˣn.OKH#G4d,@ NfY%;@aIom!f5iJI[rUԞ٬0}0tRL`!V:EfKL C6Ғ`WILcCY59'$74Į Κj>C.qPTe̼ɸ8r9,d@EVBL!Zi6_ ]s D.jv5wV%t' i*mvMjj8F+rQk#{/4=\F\I;\ Wj@&,s'0{Ң/k! Kڄ\E'h:kKEKJ vC~Ǩ;Í򱜋"@E,Cqu !LDcP)9*W$jN/AAH,l;Q"[j«kF .V]l 90I6:VN3$ʵ]kumrWp|ZtTj.kdrV#q(,"Fa=̱T1;.x;&, spAdzu̔R+EB]Ȁv P| 'C}V10mnM M0G[trTc 06 9vJɖXcT %1QyQX&:b&Id0hA6]Fgᰣ+j̢i Lza$KûÊ\&qVQp$ljN).82U&wWMDR n#qhPU6_%X[#/_yڔUZUm1L&lMə> l*0찐e#t8aj7Ziؔ %ZX _& !L4@/Ĭ^73W  )vG-™F@Fк8+b94AM"b0[!0ٖBbK5C.M# c#*^/f &m' Ln3rCqtW) E3$w T Hq!<;`{d75ope s]t1wYɱ;U{w0*o٥_./~쒥fՕWJWMzա>3/:匱Ք.=Tk~.&Į;>'FL1$ ,JX$ ˗r9!jr"R LH?pe{6Cq FBڡ@ɣ'c9>% zĵ`;d+^^Rf!vpAPBn[.S]zOU3s XfE@suEJő&%6/ZjS-bÛ}) 8#yy_XJ᜵ ~}nMv˷9e_d6㻪uIUȒL.ܮsHpwC) —KE$ru;BzRXahʡ "vU a+_~5]Zwݛ RfjȐ E2 cݲXəV>o+r0V !rLN8ȢKr[k8`Jh LiȹٝQ$Gflpr E)!X3ׄvj6ؤsK"!&E|C"+fe\_y{hQ2ܙȼf &i089N~;CrHo̐g7{_]4޺=vUVB%řal1g5,grūBD: n2,.FsŪ: ׌nK"!&?{2 qDn1oճ *·+"&gp/~MgÄ=XHݍ^D``*nܩFjOF^D'P=S;1#b 9K`AӋQo0*/ړ6#&tVԭ UYZu,Z#5Вi$ʪlZtnJlN=J*ϨYհKKqMATNNk뎵R5ReX:TX-Le&pN%[Ǽp?!1J){u,> +VY83c;mQ:*+MpieLƛI؃Dsf> Fy 3DrHuhzmZVҽƧGqKck5kdi%KP< ڋBڕpt^5(w"P;{s9Fqt[; yFi =馚͚i6il٦ifi͚i6il٦ifi͚i6il٦ifi͚i6il٦ifi͚i6il٦ifi͚ir-h9J܁=kQe"$i۪J(݄Z^EV骺ꦝlLDDDk3=6mijQ5Wr|]YP)]TW G8~R6V𞝶5o;궺Q0(׵;}[DQe>oOTLJww@=F-wGzbz:{4׿ıZwjw*~=jx~-[_}￯ }UWVO]Wm }UWVO_f #興+t"?c63γzgmRy(?&1ro}t8jaCJLE缆™6ZjVJCP"Tҷؚ-M?P~LcGܛNX15o$[>s}D.ix'lN9^ʹ(vUַV~ ?eWt x)lw?fy߆>W`BevEW;cRr+F.3vLE] rT5/>.B3<1TH*N1|q%5V ' EۀW?DDŒeH4T#ogJ\k+|5X={)$}P/^y$-b6ΎCֆvWuEmPb{ _*6&RӨO~nٿbzuSruUE**ޝ_*1pSЉE+_:+@9\h<iMO &&pbRk]H܏pA_!H#Q{?#ZVhdV0#B3d1}$Š# mT3eueӭ mlx9%,=^&)ܫ_IFS1q&rVVq<1 R=!h[[Q EO.DElP=M,MErf2.5AN\jmɸE,5/)32ED9Ho:Ż A0Ůbpf ⬮؜W,|]zmADiE싖葚r,>OZS>9Lmqjsi<~u<(qQtsdVD%υ@Vdm@my{kȼP책c5BV 䉜+tn1zV:&oQi 뒪m} bp#2"VHf.LMRM ^Y$v))ZJc\!"j5mcӥQa䲱$S|TNin<XF ^"^Gǒ>޸Jvݫbp3sHZVG&˖@%GMjWPIar ݔީJqelƱmm MA?W겙I)(`ne ` x\HdB& Y߿ wrR(ΰ$s{[ӕokϭquG 0/(c}8A]PR,򬼷E9MT[n&Qf1ߩ/}}͸9$DIf-Im#e B Vps#ҿ&+(fnoT8 k2cX}ݶ6""8 ;8qk su79H=ܑ5SnXph qyh} }ZX}EnlLomܥ[KrSFŹ+y am8VʱUX Y8 !*VS1xڗ!-ɺ2J,f{2oIk&lԲ6K r۔1R0,u8D#F ̰ˉ tδ% t6ub/HK7$nȟ'vlo8bpx| Hr -r3YKDy 2\ M&~FI͈zlZkf뗘x=ਵX\uc!F&^}+{cj(Xj SX]hMUm3DBUށ ]hj Y0>PBu<9SgtN)/dV4 Ű\52lcZ^3LVzQV cMuk?t蔱3EFT@Z͓Y֊ͳFDWLm=Zv"Uf},9_G' ɮO4O^\x07̣e)*tQnsؑm,E6ec=}x{}!-O2q>u$#zPaOpl # QBHZxx~ɴՀ, \ HLH_X^cG dZ aMBd2.d XᘘiZl a+״WSQʐ?J\Db!u=&fN#p:EQCwYtU@5XhU{# ˂%ཉ;q1+!J 8tVԝjZƹMxS $Ir'_! elvdN,@!-JbE: 8\:`VA"N0F(T݉ 6E3|Da@ uj,"k;G9&8*ї>db]Rrp/ppd@`bݖ"`^CdUHx(x=5_\^ղW&5Ҵ;-piJ-dEK cIVV)5&50MlL2chږK% 5L ]PX_5L(0~UL[4p{t_ r jIş)/'&B %F|qgDM S+.w~inܓm^p,Ep|!=uǶ}..?[[kUID>q׾õd$cTk33:Jit6n%'ytĿMO;4sMt$3虄{HD\BuKA2j.)/P¹SQ[9=2Vv2ť+X']ͲkOכ{8Tg«MC+pq0B` țeLKpU,)R}; $օ=;5OyΪL|y"(v#gsGSDvA5䖚wܕ/=Ɠz4s(iR1'caOk3+)N/[F;/pͅxy 9Lq)g7rk\86h;:i];v[uQ\{Ͳdn71m 6.6w5@ه9IQ_H%,lF<(-ϳ Jr'":_@4#!o|oj'I1>'egns ˍP5ofP :^ Z.6ǰg7g_].1!5`= #$+3YjTL#NE6"1St, 8ކbQ.G9;j*o%qVJ@3o@pR C p ĩgUkrbHI2g0ێCOBa&XF 3.md!09/s(y9N`ALa2VWɩ/%y3!S{ [l`^ixʼnLvaH\o-:3>'I5Y"%k$l {,El8{vm[J&4fNBWrtlt S šɈRZYVֹw%jklc4ϒEyɊ&i>Md< oR"_p =cĈƎ8!A,rzs.H 1$h0ElaQ$sUpNHddD|0d)&.LɤGW^"ad>32>&jC`qC¡WV)qqlbTB7|xՋkjPۙ%] VG49rT!PıjUb>*švW9hZ\F=EvyZ_i|Y֓u5µ,p0HCrlbaVWGlc eJ(.4ygzlzr"xH!+yAHreF6$tJ$:3BzJL]u+UsSu6"z/ ٣sM}m" MW\6!foJ򼈍޴M&}VT}Us fSUV.ϯf%9u8cTEHJe\L : Öa9;edFW F/9‚kB<#Nv->F@\( |g'|4r@T}ݸQ!-3/MhLe;+de.bohc f/llpm6i|=j-ΛЭgE%1V!:dԸ"VD-*i*%,YmXNiVe rxv\dmdZn2kE+b1g(B-j!uD Q溱x0-;)l}p0vc :ڛpl*{2#+"} ZȡrMidZPV\&ڀGcZR!ij#+yL#=%' DaUT?0MGӤo1X4Mj~4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4Mjㅡ*p\Qbu#Ȁ{ӶB$vۭQ[ɃUkڛz;Q]B5(f%oj%z66Ogmꩫۋ8Ga9դ@p?}Õ:G:TyH".oo(oj5ZwP5&z=j|X[=ʪo'[MqgtG};#z۳*E۔6F#-ySKqܪ$)ܪŽ99hf0 e8)Sfstw/<Ʈ3N5;޿v{mE#3S^۩/ORX5ƩwR®FU9;ޮ|q3zwJ?o/4 #BƩSk5nꙖ9Xn쫯T,SR[#ڍ0lbli+srJ*ڛVmwn׿wnսWT(woݪWv.rU>'#:ZgR}yϜu Uw'~Sϩ:mX'u׎';A5Aky{rcɝ?{Gӕ.PlM5ޥM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٷv֭^W_SQnM;}|ƨ!ZyR,V;)! :8E6vkEh.EեE o_Z^m^mo=ie0Pc3\eҸj1#23&k`Hgk1(K\C*\UC L !({X5УIے=T޲58Qjڇi/SNuT޿Fri[%O "y5]ہL}{fW[Uui1+bzi~:뢥JvjEΦ]^USx .v6UǢeI,9dwH_ܗL6 7MϨLj#-K]:lG1>:pzZ5W&nҥZukm1FNRڢ-o)&Ga2DJt-S'okVSرk՛6mMVMӵSM4;ej?{ݾEk^ȮCrc ɬb `z7aNŃB jP,z6n;Ux*\f&ArDl?r͸QwU#{Mm1?术rlo-xyNص}IhU!ˀa`ƷToj]R<+as+qU/m̭YMW4aq^ce%ksk>ice,8Y&fw[PJƜU*Mq@O'g U*E0bb.l֝b-p,n,ֱ kp]b&,Qk0\3) FR_woIqlZR>%űkH; Ι6VkuZbgۃ (Jܜ]<ԕ"f}]u"4o]7o߱b˛ydvc4׽"B`'#:=[frpg͆˺ˮ KnmҥzvmطS5< ݧV,Ɇ>> Ukj/AT`IW)9fS$-؝6ºK?b׊w.0-^*AgԎ0N\aS]ޫW]kk[ڝ7'ڪN>-U۹nJS]uqZQ] +pݩ$U i*\W߲-7%Inyj-Qoqy {hUV3u^V*,%űkH;޾YLzݚYG4|j_\ުFmE4SOZnW{9_uU &:6Dm(ۥU)ߩV 26DoOHtOFߝk4`02FS>(,\a[TϧIqlZR>*4R~T8QUL8җJI.N[MZo Fŋ6"ZGi\Zz%#ZU/VUXRM^Nuڽj.[*}}G㠕 鍠(j:LAi:D:uLOIqlZR>%űkH;v)`9rR:~.ABFR0}TWFG֤*6W'WGU}޶ůG&(܅^Qnܙ%b g2%7nt#*IZ]^ Q8[xuvݱ%Y0fDHo,7 w$"CLL,! -k5f`L$dLKIوΒص}:K?b׊w3tyk:K?b׊w.0-^*AgϦG<ѳhc-xyNص}Lix#6:K?b׊w.0-^*AgϦG<ѳhc-xyNص}Lix#6:K?b׊whgWYOZ˨!ev[fW `Qz^QbwkTݿfUm]6Nx`+"HG6mů 3\a[TϬ"Ox< 6٩M#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛C%űkH;tů 3gM#hٴ1\a[TϧIqlZR>}4<捛E-+q;K5+뼕qpS,SFyEzݺݛW.nیOUϒQ:fᡤw  ST4ۭ]W\j͛.حUخV٢iƿt7?y?\_b$9f~W#w{48N߶}MOsinC0s.SSyP>ðgDʛ]uDMPb*,-,ݷv;uVfQwU'[Cwre T,(YbawdZڜ86:7E^j5Vn'R7mEuS{PdhP nhuzRV;qtUasF$2m n\J@>4em MtrVĶ!MG_ lZה޽~S޻rUWJ.k}D0NJC{iev,Z`m(]Ewkׯ^]gamncYlsS#bVXU⽴ԱǢ,++ɨLX?QC*+%51`@5f"Q{ YJK+eM&ޘJX\("z]e%%:$L[5vSױh DlJ]=vlyl7Fvk1WsF!^SwUiUV,pI UeӼMM\ةT4v&u%is]Q^z»]_wr LJ{;tޛTB8{yB5(|@ʉ']59+z˵0*c59DH&l[!E 5kY1a0)ID%s"7{:2A}]j."Pתn8]r<څ26ې><ږ•1(PE$'y2MbLxu$ZQ3[1[*&5R[eFS%s!1^w6{K$ܕyS ѧkKWK/*ުݷnoaC+1ND:ޱ=ݕiW:-PŽrkDl\Uۮw㾢b*2,\V,<@E&'` u&cor_!SK (crxYdrl/TbU rRA^Y (OerؠIEG&&6ǩNÒDMndۙIUU_Չd>@l^Jf~T^M6]RTqݕ lX*+W[qb2V֙-MJ/҉uYw)JJՋ"^/\#pqU6ikA7v{Ȯնo]=n{VoU|GpSUW( %u̮Vvdnu@r%ԢZުj%ʬ0v,AH5!עfb312C|*Sg:t$%1LDi2k"eHUX+y9#`HϭY4AH7nc[@Ge7cX9x3,լcQ$JYdXXu}F16 gjIӦ%-HSrN_ lZה޽~S޻rUWC Z@f7$OܔL#D$7}BHβi{۳d~HEXS26! 6ECHT*'LVh$v)8DަGHyhJs*d$23;Vh3!Qua!EDK`E战ȭJssltLBu1UBShds*jTFW;59qXc_{esC)O{nG`Bvmh,S\D6 ַ%Y ^E$ m] F2֨"Oaw\-e2/&, ,r:`1Tm/{]ܭ6Vfj9nBJ^}=9cT׵2 peS(z7͔n=V*Y[ '_UXWZUȾX ' 'Y7M{ێrf$ڽIM;W4|)_N*:.Q%Yh+JUr҆:*Da{>Ȏk]ҕwF9NXzh1|hE77p5=,bg`Ku]Ql٢F16*S\Q|V/Ӣ1ȇjs *)U#\/$mt@6+-'7m,*ÍƸܤiEP"o'qw> ӵ{nG`B/UbdBR<\Vzrpma~CXl/I23 d+iV)E3>xKrg?퐆Y/ &JDC1s);rOB9W w@\*n-h_Z21 {B"LJFjYb_!| 묋#a613*JZI4HW 9 PVY jSYEjc2Zjpw> ӵ{nG`B\!|4%̖cAinQ!DD1ٳNOnEyS(@AZyQ.@nlv帾~AVKR~ۏqt >qFrƧafXn dȦ- ħ w,Bcس b5.l`a2!&0GieVِmB6\ݭm}n+6-T8L6%$ץo"iW8 2י+a}d{Ƅjhxjr^mh,SZzV<)s +U"%˃GJmm+ mɜح~r4mR4sp{{NQ"@2Dĥ'W3q:g`g9 %'>hJ85Xc=Gjl8ilbZaU64*l`T Տ*>ZPݷm(v,hB,n^*6"oQmfwR&{ DNc++)rX@2k=%Y~$T^W4|)vrо1_1j0ULGvScJavH8BQ$lP$oPN<ֈ_E8l ӵ{nG`BwsA!MY*znjQ:clb)`F 6f## Rekg[)MY'Unj)[HY\rIp"!t5A!&fF nZЈ'u&fj"YIV{W4|)j&5iOvY忧gjڽIM;W4|)MOvsU|+?<^ V{W4|)j&5iӟX/:Ajgᝪj&4^ۿX?Ц6sgS:>Uz|3Y^ۿX?Цw> զN}c}W;9[~Ov=w> ӵ{nG`BiϬOgg5W³Og{nG`Bvmh,SVM93^ V~yo>ڬmh,SNM ji>_u>᝜_ -?W;UM iڽIMZm4?Χuz|3Y忧gjڽIM;W4|)MOvsU|+?<^ V{W4|)j&5iӟX/:Ajgᝪj&4^ۿX?Ц6sgS:>Uz|3Y^ۿX?Цw> զN}c}W;9[~Ov=w> ӵ{nG`BiϬOgg5W³Og{nG`Bvmh,SVM93^ V~yo>ڬmh,SP[ss0aSC; q79u7`i9=l-V,߻~;\cZv1 f,a0]d%ΪKP ƺL;@*miwqAذ!-$X@%1OL냚D^iq͚"O'UD6l߆?w{yuO oa7yCﮱr5_ w`Ё F)WHQaӍD6qcQH4|{qo>=OZ̫@-r&&1GuDqf#.k Rp5>/e%ȼ.wtq}$p"/Ėʫ<:?YL| 9; 4LV=;*1svчuQn䛻] 䅰.xU.J qz4"5[d ڊ.u}BcFmMDUdԝ)7".UIzTf7#ǹh=iH4|{,H|:m U;ǜz˃W'c'$H1|ęI*,0ܗ;!!Dё۷^\ZCN,x,5ǃKJB3Rl"1!] b鯱Mb%9Iq9 4e#ǂ%/OVq8.DGum2Q2֙9#+ Z- 5hF6VRo YT69#=OZvR87㿧MiUzpz){描q֝=GǸSFsx_ǹ}ũ꽵!~Gwe#s|;zѦ^%WzmgG9gjzmgH_ǹh=iH4|{4i8WU{YoYZYqo>=OZ ]' v 'Mk6o eHq9sJX˙[e_Ju \P[q]]N%NUQ%"%]3 {FFE=֋K!`#HCLi%ѦkKmb#y45oP2GiIj~?3h"Ox< 6٨^Ũn%BVfOi%s -jܭ(\MѨ{j[RNĬj MKA$]_&5!sfEsCU,-<&q D}* 2׮'RAٮw_qƛZMV[M5]5SU;UkϏ[^ c_ʐ?t~P >hM~/kj//hn5oy{GL/!*@}ӶCBTM7Լo|վ0l;N w R4ߧvRV痴t;d1߿/HϺ4~ڽK:[>[^ c_ʐ?u B&N45rD/L$UoD-L~=:QMYW 9b&X9NʙD}~=1bQ h5̔tV wY#XզkSmb#y45oP2GiIj~?3h"Ox< 6٨o}qr!JnG#"#MFn35߻uo}؝7BjV\٩=ۯ Իw'<|l%([/[<$ZlLNXUorb9Ƹ%\o)eN#.noٙ3XCqS3eFWsP nDLUoZk1!ܷi[#kKHӓ%j/mXڭp^7Gc-s:ciaUiNW8 jņEZ4YƱyJI,T83#3lhaQUV/Nj*w#R:tW9ѡZW}@{ C_ܴ,71yMp$ )UK$#L) jy# ġ1(7tÅEU*)w-ciN'*ԒZM'ەvRKƹ ]غ¦[W-w-E`#Oo'h}e}J%{B,.OaUi)L՚ ʯV'|r@4 p=R'ŘopL腤)mz;?\^Ff:6LȘi pT*IGLxQy ԫ!%cjΤ  Z1 -kup!-c5 lVL7<(ݼ&*S/P$ڬz k&p)Lo 0+ R; x1)sشYhy#=7Zu"l1qEvH3ߺTս7^8jp7Kϣ5Yo;QS\.Ԛ-6*)(!ERUHߢbu,(baD^Y]^B (:ۯGV$ mgrzkko6FM[{Sqqǿ&WNDFAN^w4sze"% tFS03ƁY Jw^vܷzmWEWh廖ꦻw-NQ]ӾEtTNU;g B H`Z淒A!QN冧&.45 Vwm=wf4۹qcj)ڭce1t5[j6ېYR]EPv{n 'ar?0mi1~@~lf@cN@&y8%qĀGxbkcp'J/bs.)@X֑"-6H.n:¸{FٍY̴+Ju $I,0 \ڕd /`!drlA:A%07 l+6YZ,2_STmU<^)jaI䶯Zi=ise}]nqJ-S}ͦD~珊nb7r !ƖoGkd5ib* {9xaGm>A|"V7+'.%%(moethyҺ %A66TE/2~\mj넓s\k" [`a`4b+Y*qR-[YdLH @k3:duo[rKZd%WXVFKs}N ah:Ķ3!Bam!FZqKnr+Eor.~GP. Ǜͯ*\N2Qjd%Ē;.<6tDj T[a(XZ)9J4Ffؤq#t Y]2!({-NLNr0)mD$D2"!.BR`Mfj{ FJNf+`.A[ȭQESJ\{uYϰVnAqA0xp{i} 6&koMqr&4_QEJ%GckTY^0qTv_1\*2!BK&㵜T:M*JFqDJ)2P@һA~:M+| mcD0v#F( 4pF@$-z^>5(vK(V>drMM*+Q&+v|HVbCY[]U fŏkU2VEj'eRu˯&+Hk&vV;FGAN]D+-DU yZ t&VdKqąsh;ʗGmZ\[@=XI~[Qb۔fl,z ;fGXTWVV{=F`/V Ygv#!!kY-bzI#u"+]%R EK{8I$%VDL= IxEGŞQyqU T,R,^ReO_?d{2=ջD9Y:H+59`ʞ_(iV,.o43fҜhl8L8[mWaY!Oi(bba"r,Cy)xX Rx)#gzc!+ˉW#*nXg5 g:\XEWg~d"KO c$6=lW #vTjC3&Sy¤et=K2_ ~!^* 0cJ$*;Q̡఑)M~(:(KS4C#c@3d6k'˧I "t2v U72/rFܒ3AX`\ht" A2xp'X& 8HcYƑ4E6|CS9hSN1ߒ`,=Q`􁬵qa[K2BwA }\ǥhYG-%E%r|.ajIFQ ~n.!2ˢ*9VRUwC-=6 xWcTJX<*.op$L)lSjWTK.3R4@;v9(-Mmg,MF[W 7K+P(@֧fl̂TGe";e씪h:~WZ r}5;7OEln{.{S k; A8IB 94xDo R–9c" xsb9T+-$sJ̷@L#pDH}b$K Av"kFPP"P]T4XB*c.pqLWlvKSRU-<Ҏ59ț,rrX*׮Qi"$(Z_݄SXrQjͪ+rh hA!NÏoIh`8c+l6;|rx!wb4GHwS,iX/6W>B㱚&k7 vl|zuq Whv"W?TCr)s DrUV' i 7RTJR`Kѣݲ+" RX:aTB Ll* aܥ('N,Zm*Ӑ ݁&p3K  bRR;OʂDc>lkXeS:ƮXo =8hNVI, X-r4=idF$N:ZPG!…H`XNYp"}]rhz*)i,\ '!:[KhHqĿ\dZqYp C¿^B,Uad8eR/fJ>6B?VnzoH-JZP˷'􃗏Jd0 vMsp߅SbIy ;N'8XM0-a Zq4?BBq\͓ <,r g6d4r<*Jcz{u".HcS{ſ_2{$"7RtfԢҰ%c X F+ЛMvo& VWS G^ LZ'Cq8,J|nD7dP@΅/*P]mZ$?8Ddc(VJvJ |bD Y$Sw Wnp_)\5|J++%J#kZܦ00g *%T\;Te R8G1[᜕I9.d+F-lj$ Wu#Hbc E&udMߎe3U کR%V.cx X"p3quG yZEH9QpZ &fW&ە 5{=\B! 5|L3- Rk2~T{&%Eɑ`.BfNu0Yد区}i.|cL#]`t\N0y >vbsjp'9mŜ*6'7>83(ng53Pw'VTxst Ъvj>!-xAo>tFTc-T6,vBAW硵q$qV$s專|9 `׌ÓSpo%l \rWvR#neZ;UT.XGFұ2X8b4rezIn]Lm buc "SJƻȓP,C,$)hbIeuuL Sa1)b%b!-JeqfPĆX,1X6Z62Xb 7 uCu:M^snjZKfc 6n@ޒN4KȩN}+]Oia$E OުC?dۮM~"/n4~Q|I_sf}y'oW᧷wW*pj{O?p?]܅/9E"^7}uی=RC>{]q_?S;؎M#i(6:iaqZET ^;uʅ()d=0,uN0NՎ" &fcM"&ft;> x685:;{#n "v(P{j+wHWEXBd(RԮ^2vQbN|wPP|Z8a\hNJFDa]{'r'_RШqMEa6۽Zm׮n*] F!13*\3z^+@<}7N}HYsNn379~+ 8Ht e/*|E,OBt\gY«6hF *>ܚssZ#"3Ev,F0HG``œ"VE zVy>k+ݍ<6Y: w7t}bt5꧃8:)NƖ6n$6U(Pݖڛ)k6TbۍVlvubʭZ 1l Nc$r~öhq8j덲FZM mz"m%Zu0Wfa6[P 9s(ap,i6Yfa/hQB *Xac=V02=kspL.jK8fdyHʉNKu˸tu*Vn`L 60a Ωhr Ks)0|Ų@R0F4j*(,1zE.#|T֜M4Ш([l%jU61;{iEsRضzc״O&dUu9>bƫlmg UW#Ry# +m6t,Qj QSNսMKCZw-KbpHq4n$ f8D !b&TDG{tCHqIa^Yf^FO<yDO3r?/s`$D(cهZ7q"ܗ$3!'2XŌb2 xXUtp3 (l ؐD>)08RZQՖN1u!yDEgʱʍ[ `9:;ٷ`\Ccr@^,m+vNJn26,KyzL@\*!RۡBŃ% 鸢c>R}q&^JX1o"e(#vOFн0lJai"OIʒ3<"l#UuTf/9lܖǺ Cw&Ġ]u8գ TEY[*S͌jىjW~!$,=ř/`K:]%\];y)"⴨f"xHm#̼{c*vgh ?JdGR/q2]7 8PFo(  })M8qȎ8J. \0mmjU<4cv*ŧrT*P4첵:Ka;D`y4g:@ 5L͠DT~r@X ,JUl8"TL^{<;ܓ+iy0J؛w.iPG%Ҫ\w5M Pma7ƹU(TZލU`i QőV \ib^IX®'wqq V%RH{(N<tzltM#'# YHvr7(a\#i}4Vt~ oB*ܣeeDt;d5dŪkqgT,]5#[0-Zn`DB4.քfd\ hI//7hTհS[{jmfպzw)}}}m~/k_gf"u" !"" d b&FgHFfc]#]=٦kOfi͚i6jdu տ@>ɧ$`?͠8=F.ɣh!r Uމ]ԔX\X"c2_Cq s X:>Nd9GfL5tZNzNg;u(֋6rZ֗]D" NGJB5BYeU)W}̮\֬`;#0%+:v%+:7̬}A)!M՝H^ʛ[I @vHW;)y͖]&|)Aqsc BvY]- UE 7;-VnY6kP36%sj5mjۛ%yygշ~Nygշ~R|u}\yi> cy0$6KXɁ'f=?(}O{|yùX:ǞL =.͒<`IwYw6KXɁ'xÂhKG]Y\Wu#J\Ur̮j+jŋU]ުٷFQL,ڶ9/,ڶ9/@|϶͒<`IwNl?OKyV߇%]9V߇%]9>=?(}O{|yùX:ǞL =.͒<`IwYѫB y|wV0BJU]Ѻ{˚SZYFSvJ۳y=߷du<z]c,ڶ9/,ڶ9/@|ϴlpVҭ$%b_9s+:ҷ/+mqSɖ&N^_YSb}MTWO͒<`IwY=?(}O{|yXD$7"9eCu*+rBUԯb\:7Qb/SrȺN&ٜ;6EU!;>gjX9L̔;uBcQa9s+톧N9Y^=?(}O{|yùX:ǞL =.~HP@Ք#T3 ZP[7OysJkK(ڊnI]vo'Uygշ~Nygշ~NpOuǟf}l?OKsdu<z]c,ڶ9/,ڶ9/@|϶͒<`IwNl?OKyV߇%]9V߇%]9>=?(}O{|yùX:ǞL =.͒<`IwYw6KXɁ'9X:ǞL =.1m[~tm[~t~w\yi> cy0$6KXɁ'f'=N;O#-gyiF i<52)xbԊm5Cgn(96$`fWe $epsٲ=͝uQX똑ѫ#09c;7Vv4hwD8*QUņ!>`D9%8JĤæ뮼$vޘ*L6$NR g 2Q囹@vc6 W4Y0W3/xrP‰ˑtr O5]JlNjJ5l c,_r$b \H"nh KSSf򦥉֡vfs֗$7+kxsms+ eE #.̩21.)e#kj$#`󋼆Qҕ*c\SljGC$!!k*oO0V=+8:X`M])<=!l@u4}"r#|!FN q[Rn4U+ [/d@W:u,@"d yoi{T[[Fӷvč*fՊZYc"%JvXCu`jV YNd7[M{͝2#DjmfXЅeWD^/_{E[P2v]X[6?`$ 2Jla|0"uN6HY5b\dVflxK|æ SlAnauvIxՆaNdO'b(w&#&&,pNuuFea-TP7LK $ia=5b L" &uJҳl ^ϞkNڕVfZ:]P o0ʼ7+F/e[ MMs+pv,3do/l1h| G*B8&v f/2,}{F)^<"b R s2ݎ&ҸXV#֠:k5'+PnYj"MJxtO[MIu"҄a2tص,TR쮙11n9:uX1c 1Jɂ:oWN} %Ky,$yG% X+\ 3=/X#/0m B+ܚHP&2\V ucg.cK#+!̩*N2J]yf&6 nՑ$ˎie<\u"$. 3hL@` a;>LnIAM1:Na 7jaM\})/̲e%\\O!f\ :{^]wNV୅XK^dfyZZ{TX.ZM8(˪ѳ"8[zCݶU_R{V9v%uGy2BN ?Ђ3Hg<0[,J(|Q:7m2YCphdls!S.."1#MpWX(57"i5CRĄ;5w;%ZƯe̕3=Oc׎r!?Nn㳛WI%&+qdmy}Waq|p#Z.N3l xs$ (L8]tF[ks)2D"ux"DpAg\+GY=mxИJF] _'*6Lr̬ (GSKgꗤAIlZfTP`)m!sTũW0InİL@%3fQ+ $t b;k9ෞC,gL).!Ós3Q Ӥh[}ۣ2a-HXai0L, MAb a[J@)IC Dba ,vH~YFpM=۬R$rkʹͮ"iJxǿ%#Q`eLbLTcHĘͪhLR!Tg uLRȳm\ ƞ#6SrkL{{ju)+RCu[%).(^mH쪷-ZR~7MK!ݕn|+_`;$8Sv$AŃ =JѻKRu j[`$R e8/aog9RmE=}^IcCF6tɧ$}"?OH3V+ɝ@qrxWɶ;<>RKD]_&4lk0I.sfkM{[X㾥kz\3ު}OjݫVkv~O!(nRKGS34ňh;ǫ$imq(V>&MP4iy0^kҴj]+wOQ z7dnR$ mbk]j )꫽<2zvQOEۗWRժWړv3)RcL$OL'+NإswWuW]lP3j+ 7fk i9aPE/7(. =3yT%CjKcY"unpC#XC1%W6nes n2^U!.oFtH3Iͧ4>'x#6W<`X<\='^-!36oRvXV+#J\F*Նsl`E@u ^j2D*I5 [ fQZJ/BئSLj=Weuz $PG݇6#R513Ԧ."eHmoNo3xnKQKk3ɽR/an޸8IY<ˎEz(XUֵ|f-u 6 GE@q's@8 3Iͧ4>'x#6'/ON~tgv5sL~|g=3i3Iͧ6i?_;9Ҿ Ov3Iͧ4>'x#6ڟ=~J6~go:> _'4>'x#60Lp j||+'oM|0LsL~|g=3i/ONtgv5sL~|g=3i3Iͧ6i?_;9Ҿ Ov3Iͧ4>'x#6ڟ=~J6~go:> _'4>'x#60Lp j||+'oM|0LsL~|g=3i/ONtgv5sL~|g=3i3Iͧ6i?_;9Ҿ Ov3Iͧ4>'x#6ڟ=~J6~go:> _'4>'x#60Lp j||+'oM|0LsL~|g=3i/ONtgv5sL~|g=3i3Iͧ6i?_;9Ҿ Ov3Iͧ4>'x#6ڟ=~J6~go:> _'4>'x#60Lp j||+'oM|0LsL~|g=3i/ONtgv5sL~|g=3kF(Q(CC( +WrUĭ ,,EZ&eBujR*֬\vsX  fHFHB&Am3xfwt:vQCDf^¢fNcytJtt:bvyNkyLN`i &y!dNp 5 X*HV 4wT6ގө\͵+kd@1w@/L]v%V,ІgZr b.3(8̛S%MjiG+`A1s\#]0'oӡ\#]0'oӘ?㱿X^}q_C:T67WP[smo`Fۏn?G yL|io\lү_:> 5 #4At#4Asn7k :ϳJz_;Mj'm<ޟڜȞ)[| mǷ}C&Pqb6g+vl6qB$BFL^C#cE\FTmM+S*Q:6lnX &|:ـ2U[nl #)kUcT@?!TXbqT~N*jݧ7-Vnw}6ҚQ]4)E7{Qsz:m |!|nF3k |!|&"DDG]#5$tJfgfvkIxCsb?6_H{]r'jO?P7]܅/9ES?1NWlA&9eEviAb;tP2zABUaӃJD-5+Mk}PwCfe UuvaQb7XNƣ;۩X=DÍ#z *Mn(B|]>ލ5Gq62Vcqaba.4I"0˞o)5ڛJ)meUG:z/Ա68Y^Z{P5^:jGMrչH{LYQqj+68CZ\xzC6$wCL\ݮXo'g;ěжnFej\}PȲ<ʢ݊cȍDŰ77Fr0RAcJu,DGJqMt2n]SnN>c)+{TNRʨ=+1ntfKḽKunK[iTiS&X`rTu8̄:!2{L"I#+ҰƠk;V}sw{*͑ȱ$FvˁRnkvqͥX]m!X9]&G"P}QR2fenk%,T7աb4YRM{z5xԄ@XP,J2Fցx}#[Kۯ)otkrE~T_H-J޹f_<M8)7I_#d,xyFDt$PHr0.KKvl\) B-U6&+Ye*%"0kx cUP tI U)dDH5d2T)hs|ivfi͚i6il٦ifAXM?) [T <~RA_LMh`a]"Ox< 6٣gu_Iw[6ZnI<]U1BKQŮy6x@u:o9Izftn- &KrvV7~)=NKwI| c<> d I$ &S{۽ {aqm{Slߵ]^$: Q9R}1^@ȌILo붾eiM +8˜Зߑ!("-4FPpFldU*dQ0O K*U3I/)dPڸPGOd[6dGp0TGa6ˁqfӲ[мV!Zy8TgF )^?In m3- vs3b+GFY6 odaHf|:npZk:]Nl\ ,PmgY.OLIei o Jj/7@Eo()fƻlkڮ |sd#jj+tTPqaA ܉˕_1f-V>f,Q3L\l<5W9g kjB26.+8` `|,_uŃ#q7m6hZgBӜ2;$ul@W 6@{' c͈lN1)|8T$s,8((ZR2fCqBdn}C$9[2xJpXU2'D*L_BJb" [E$sgq3tI [;.c|0J0d_H2"g(,1(`JI}YRD- y/bEĽί*7jÖѨvtnC5nUV j--e؊$v] $aJO\n;~\$pY~5'"p̛a6)y )v>mOv:_rvap@MPi& G3 $Y IP -Zdq&6Y-'^JHfJ`ԍFb,}D7weބ gfƓqPk FsIنZmN͘0v$u[\JAF~ECG}Kmf,П!ܧ,u$;h> ZK۸ nj#ћCM; y 8ۃtBWv6! DSO0)ѧ=7e7v6mmqJT\ڊ)ڻ.ݿv;nWrGMѲV]&\ąv Ww:1m1õidUɀ^9%n' 5 c_ʐ?t~P >es-|ݿ}*xoWuǟiMB;d1߿/HϺs+)kθySƫ|;!*@}ә\K_7ouǟg̮x:ϳT.>Fd1߿/HϺvc_ʐ?tWySƫ|;N/m)HCQrw&3/-gV5,HZ~ ^ڪլ)w ܱSuu4gQخS,)s )ffbt鞍L!Wsvzv4~/XSOjq˩Ŭ,/a@JBJ}PYӣ mkc;SsEw_ŞbO2T:[qT$x,Ju$B$EIrdpIͯ'N47<%KZWdkmM"nR{\K t+M!0sNJW13ӻ0飗w'~lg%.wdž9r(&7uS5bV}#43RKA^B` !7[.`DBQLCSJڙMز F&1~y\2.(]·x_$,'0نg|lqp]"F+r+lw(Re'j#BAH^PEPf6y/EKLĮ~P,zXdDpG6 E c,6)brB%cWQ'lKHKP\1}#(EI66[2VH&!G CEJY41Pb945#xnAH ;nH/8>cm 0nۉ?TԖt' |mU!IH&49qJn/ &QWd$m=R GP^oC!6Ɖ^YwKv.I I]_A*T4  ݓc9ZHU^߷#2 g$j/#[-% uY,SmDŽ(Jr^wkQt!2Ʊ(HOf۸*'*lޢvZGZM7-΢wu{-_Bc6iA(r"ˌ B ɘ7Ń lba[xeド)&̀b+{5bALHץ!A=y(Ѹ@\Z,/sAM(`2NJ:}>3Qlrq T]ilh2Ү99Ju…Jw l7k;9 D0Ci%ZkZF~duU[xKNտ]x@juoFm礞z eO,558/I]7#*j3lł7NXB~Юt^ ŮgB"=F~z5ϼ$6q#EѦNNt}]tqj-:v!0&tXψ|MжPbaoׂ t6G~mk #r$ v+qɬmQJ{ۻsmAm[[nhov6}mޮC/{Lت-ԙy:E11eF'=/ks ?PD[$^jPZ_ymWo[6V)RLN+E`kbb[ad`48 wm -e(9d*'YjEIajF`*-pW \{\vtd,q4 zǙOu8V a ;A9\j#ggR)xs0k&^"ٺ@ܺzv@Y+C)NII}зU.\HZ0֭8+5,T.jkQm%IKiŶXU;xj1Nb/) @ط'3$qf0j\ ͬ۹;;guK]U\TR:jiڪj}wۏjn=}}~-%SeKRdA15g$&?;pE?lH3chÔHgQ#vDǯpP ^Hy e, r60ê!Chxv bUR0蕽R [.+Ր q8l4[G;DKi2zJ!:-S0WDÆ1./~, M4֮M4ٳM4f4M5P2GiIjdu ՊgfEܞ0xmF#rxWɶ;<>RKٶ^]&QM5SUV(mW˛S^oM[ۮ-*j}M|[޿qNߵ~6q*ňH7kmU{QFuN5%W/^>uAKLdbJGP3#ADDt힎7KMyԗ\9xԗ\9xO˟{OC|^o5%W/^>5%W/^>-?.~=7KMyԗ\9xԗ\9x::ߧz=-5R_ersR_ero?^~/iכI}㗏iI}㗏iO˟{OC|^o5%W/^>5%W/^>-?.~=7KMyԗ\9xԗ\9x::ߧz=-5R_ersR_ero?^~/iכI}㗏iI}㗏iO˟{OC|^o5%W/^>5%W/^>-?.~=7KMyԗ\9xԗ\9x::ߧz=-5R_ersR_ero?^~/iכI}㗏iI}㗏iO˟{OC|^o5%W/^>5%W/^>-?.~=7KMyԗ\9xԗ\9x::ߧz=-5R_ersR_ero?^~/iכI}㗏iI}㗏iO˟{OC|^o5%W/^>5%W/^>-?.~=7KMyԗ\9xԗ\9x::ߧz=-5R_ersR_ero?^~/i菤X& o7)V[RfvRKʚݹr Lr۷ku\rުx״xyP?XjK_}{NjK_}{[R-* wVuXjRS:Dk3f5&'4cjWc b""H$H}WN#@!?q^V/+/^Ӛ+/^վ?.~gW>W^T5umߴm|Z}Ѿ&_qVV+/^Ӛ+/^ۜ^;5zQ㴛 }Xq;IUz<Շ椾״椾״;)s<>W^T5w p|*Þ-:wL{}N! 3 JC(\fےv*pوEu-Yn~覫NmsR_ersR_erڡ ٰ }.((( "J"tIצv}SVR$de,gH5wcX7*wTmU;K[UQ[utq[NUU<}V׽SVqUNXW$ 0p d{ݪSUo^S~-roUExF7[M;V_t6ϚxZ!"3$#遒$cX)kIxCs"O6k_H{(`4X`+LӜ69dBW8sQq@fgro/+j\jfmmNw4-ܟJ건*g8 TMVjؗKJ0{xcn(]kK؀9PkZxQZ`ɲa:Lt2 ^{jZ>sjL}᱙g'$ T/H vjfuhTb*MqYoDpgI䝌PO]Z}]w]9 \W@+. U8Zb,5q <xV'.k nÚdI sט9sesB"֜-=Vx<Іь6Q9LHSPJSvi(gR oS>U(k X)f'Iw蘝46f-hD:8HeT"`AIq%٦kOfi͚i6il٦ifi͚b#y45oP2GiIj~?3h"Ox< 6٣gu_IwH&,@!H9F%+CXa!3S>< (5 j䖠JE$[P9@9^f%j}ڑ,1Y `D+~ei>5D b44 ٧i7*Y.U3N8||GNOvin;zZkʽr:˕{Luӎ7|O';w> ^o.U3N\g/}gp.y<ۿNޖyriκr^9{?tw}~Ovכ˕{Luӗ*Y> n'fO ٧i7*Y.U3N8||GNOvin;zZkʽr:˕{Luӎ7|O';w> ^o.U3N\g/}gp.y<ۿNޖyriκr^9{?tw}~Ovכ˕{Luӗ*Y> n'fO ٧i7*Y.U3N8||GNOvin;zZkʽr:˕{Luӎ7|O';w> ^o.U3N\g/}gp.y<ۿNޖIwg{]r'jO?P7]܅/9ESy/1?术rk R*~)2K7AEwS-Uye{͔ȁjhBJ(u#*'/km(O_䅈]T r~?gWyg!搎ˢǦ%OFާy?e 뢗Κ$uQuJķ״o J h9+uz;hU-qT,XA!VF.f@ɀ fEm9Zq2GElޱCF0[1i>:vG蝳}kؒ$O0.е-6sH!) ^ m.iZG]7-PѢ#m(QotIuAŞS]ֹ:Zyo$G'ܨ7Q|yg$}7.n䆝սfgv~b7dݑ5.y8̪P5lHZK ,lLk6muUWs_ȕ,23ٍYlIi0#+i4A&IHMVqXs :[ W.0Y %Anf<@@,!<.u]R:g֒E[5-gr:J6G~Qo{r(GX``ԩu2= c[4,qnB50GxIϱe-82ٞF`I dn,*7X:QqT: ̋KG>()͵(sheu67/F/ ,NŶ 8 3:- nxHlaȯ"V`6xF!d+]-beV--$5&a/Zjݤ) &QB'lٝ6vDDc*9?&/]5m;<8a\SdlpCrT@bHHbSVaprd"qy:W!Ё2jM'_pWP,@@XBqqelYE>,nBIOr4V(fql-^n=Ⱦ)SOzkU|& ; @m!&z\D>(r:[KX4Ɓ931Xn$; QjB7vd5F\ ^Aod-yI6M3\cJR<&.umXc:@X[HJZF1!^"̝ahgɀqi55Z\kTBs&(-6,SX}NyZ0Go ܸ%UrZѦDŽVv<8jAp3!%V.=< ԥ+Q 0zV8+cjlQ0HLdfbd%fcܘF%#13PFQ$%Ʊ%C>(蘉b#y45oP2GiIjJgl]_&4lk0I.w'<|lѳ$͛f-_L.v'U'Aò[I?I*t!|z7 7Ga i24RUe'kKwI}qu*IwۤHmtlPFB*0)5o&1 T=Bfon[_K[tGQP٥^ie=Lj.IE -k4Kt^SiSJym^, ѱ^6KuX _52Rv(5'㨕sdhA.9Hc GCY:n=n[m"X1-CG *B=pQGy'*NS8quKco!4zC=>k{|0wGq,S𲂯QI F֦TUdU%*RuVyI: {, KZKXdca|Sޮ'P{"X/BL>RkyS)-}6#vn3S`65JgCR04ʩQAoꭌYDF:'@|C5\0q>ש m<杯R~yGpwkoꝴw;?Sֻi=Zk3zC=>i/፼z|vV;IojI YkԿ߆6QNש m<曵zNOV;|NTOVf^1OvKco!4ݯվNvzqvvz4g/፼z|ӵ_y(w}Sի=kծ>ש m<杯R~yG7koꝴ\vƩ]p5Kco!4zC=>i_ǫ|Tj5OZkiϵ_y(kԿ߆6QM=[m'W'gzm'\3Mf}R~yG;^1On'w;i=Z;?Sֻi=Zk3zC=>i/፼z|vV;IojI YkԿ߆6QNש m<曵zNOV;|NTOVf^1OvKco!4ݯվNvzqvvz4g/፼z|ӵ_y(w}Sի=kծ>ש m<杯R~yG7koꝴ\vƩ]p5Kco!4zC=>i_ǫ|Tj5OZkiϵ_y(kԿ߆6QM=[m'W'gzm'\3Mf}R~yGFJ[ $B~o /@<$DeTܱ) L:+n&[Vak!a*[*2"[ůXXN7Y6X-r $s^GzlxoaFkLƱTyYG%bjr>V`YQggYaeoe+ahiv)(wbI6L-Cm #mL([uNB3o]^uX뱉cɛvR ߚקx9inA@FD,coksYcD 8@_Kwa`Ězz#tg1Xwh?V .$fX/Dy\%򘎯½s1Xn ONnqozx1oo}KVp|N ?3=_i:9>K1_o&ٶ{B KVp|N ?/?'mI6XU8KNoVo߄߃mVoN~-}}E({qP%ۀ>XNnLӈ2{QȠ BKfPԷ'Hҥ (!0 JKw#|K^XJS4 rClH6aقo I_ma_t6ϚxY_ma_t6Ϛx\}}an_H&ʔ^b^n]o*L=$ExD"6MHp8ֹRՌ՞fIޙSlzw[/6jI.hcE+uqi9v uP.Gyg" 0y{yPbbUvImyD-H [jDoIs'a6llayK;TDUapZ8Dfó2ݸ:0BbZ9\64B'1lTPl<%d/ m׻wF0U?X&MY.@ɕVZ+xȷks#u5ę # $k_g~TVŀF{_ru1b⁝(V\͸đ!FXG.mCûR.l:^=ve ՝jQNm+Ȭ,VF[O51sZ KpjklyEmQ%q[mVௐ#_p𭑑 &[HrQ#L?m!At^;Y!La8j5)ǙF[ICVxuo< Ą(UBC 711@9aNJtf@t#3dSuwh{~Zr;w[BTioEL[^"枛<ũO Q;K8L_&9z4 mvJ9u1mr剨J8@JXwVsǦיHO<6WORZ{,:FU,ԈjՑXJO]QK, q.fv𬟂HJR;7#T%@xBELh?qJ唳۩e7yH}LDϐ:)p@2ebalD[Q~<,:mN2w5!˧Vsk4,㴫j1X VY9tfqݏ_[uM 1 6/E>2ٞAm h?gNF$"AƏ0Yt&M*p\A}2"s&w.}h0DŻ^eź:32HJ_g7ϱ3K; bS:C쯩T1&Lqr$n}dfZNt!ɒWx3.ЧDd6A_V BfNUkİЮ @mXԗLqڲq|doӆ9Il .z$F4]z^[B7ӒQLcTR|>tjsycܚe)aRvʹ @mBbo;Xq̔.3_C66h68(Co+Fcbā z<ݚCe80UPh{,|0~V}leheL` rJ;s?Dj9+ֻ&Qhv|7y덴wJn*Ҥ|f>nv`a8ӳbphU,z4,909I!;0ؘ"w*T4}ł,#vUj]nȽ,BUoz7Yz8Ԁ "@en"j8[fX[a.ۉf~W]*}{l{ F"g&*s1r^p\h]"[ΰ.dyER74v  R0I" !hHFaF 4¥fܚiohbo(hFXT_y70}e-D&$@2K[ 3-ɆhIždJ6Feբ$Xїxt f~(R) r\d=d'S>(?l}F-qgɪ*rNCTKe-6D$,o. dG.J 5@B'$$RfD ZD:oc=du տ@>ɧ$Blch"Ox< 6٣gu_IwHRSC}J\in]mڿnI<]V*J(&r,j+N&2i[]?ʌۼiYݴ'TQ6kk&9h.kh!FaYs2k@Wѱa Yp: >(q&I d*4阝cjuc0s) Z1#1Bce$M^NȁKkϣ yUp/tc<Y*$u &i(4^(:퍌[E&ә9\:oI!´;eO, ցoZV+AzvJIhH>G2tmqRuԗz?0Nk)8LNVҙ(6M8 `{M.mfXq3ke 7wQc+ԆCBc|b>pԐt6ȂpL"ؑkDc5 CJ1tb_gwVm'>2.yP;yp9*d2Aq<ژ̢4#_QuH<4>lfgʃkfi*c̤%It]l N- Z^kipvO(?NnGwx6 /D"{DJa<= v㻎 llg;}60x0)]rL.X$VYAwOߋjttNЄhKMG:ꡪ1 fZ3'[ah(%StJpmm#yFܭ/@ZK6J>j\Y"ਗɪZWi >̜ x)*dV`G>ܫ^H>: (xSp hI/2`)3$:V,y eoѭ|!j:ovW} ΩĈ$gqs˫Ya SpJbflmqLc犃TE9^T9TǶ[·MѧB< n>F5!˘x5Y FVnF қ)˔VŪ]ѾuNU_{b錜m.l*Ye8$a;cOEI^Rwe@F4a]wi& UdW$UtrO}r/=/ezڹ][K8dI,1+j)"sﶴXڵ :!qQ7q G/H*\iQ+J7>-:U\x}k0zJ"=N F );@?r#XEVS >$7YlmKk\yX.87݈Ҙk ^S0{bN6^SZSA*b1Ob96UZhBۡ|AzSZ7[mKn5(_}j-/I ic\.5JENds эY9NB&LPwG,-x6i4&8z"Yh"GhtKm.MtH_Kqɲ $ҍX!v5i Bb֟ l6H!xi CIQJ%ZS6?.BmrUo&%.\\B}]`=Фf0*JـoڴB+b2uA"qBeu.ynF erMrfVo;'^u]b\/+鏉Yl̼W >!b zbiZF^`ǽȦ&z%Ve ԺQز]6 z.*N/K13=Duʳ a)EgJdqCQQjy(26AՎbLZ5bKVzs7;6Ƈ-iuzV PjZb$q1pX;:EPGOOC!9(VE. Mޑzޯ:9PJe\$,՞H⽜K2D6(YHs.Bl&K^ q7s*A_Q1%AIEU5ei2P/$*u $y e䄡5R%-eF33r|+DpJH U%pBHt%$bӼ1ALO8싎4!φR0~'di*9l|THFDfQ;Ti"^wLSEҜ%aiLbҥVV\@`{ ;b]%ٚ%حiʖNبbաʬ~L6NRaRX-_aԦXZȒL(k&ì.XUyϻJ:,J-¹jsVdzږRKӋVʩBUu5[X4q^F/gy.5HFEVP?%ƃ&A'Knu1M#]ޚPR/f+@lȥz̜p,/c9Е a>Jp'į%՟21;G Hr(Zm]8FIdEdh_JVtzBS) YR<'LٔŶml>H;$bS}lEUEcĹ?F+mٍ9Sh=@ᄲ+ j Q᩶X@SSjdvdJu*>Hk7$V,u)֋j\<74lVP|\䭤 S6 $ex;;6-5dN`Oqʍ+N'Wf?Kl̬cRkKRrʊ!)#>a FCxRtɨ}M3䈺I3h'uF>8̝]cVE]8A;Wb" Ѐ.¤JDžDsh\ŕH)EmuVUSͷ鴪&>3G *ъsrox􍐅87R콐jXD5> ɭ♹=%kZ75|Iy7XUr:fɠۦ}SVEIAge 7fKP< x9 `_xf*I&~&Pّ(h2ihR#đ58K3X@uƉUfFQnbhkhJzX 5+,(Lf3z,iDBDWVPHI&1RXBa+k FTm5V{hv4|*קm揅AlO'i|?3~iYۼ\?^;w>kӘ/ʟONtgv6=;w>kӶnsG MzsyS> Εlu|UgnsG Mzv.hTNcc*}?_;9Ҿ Ovj.hTN 5lO'g:W;AN֛MU 5CxP9<~J6~go:> jʟ|AWxnsG Mz\\OeRcd*cMr!לW8o-.Mi[Z[Ԧicճ^Ʉ 06kRAm#)gH"t-uXC̊J5BD#jS z?g ^Eܽm=V\SjQUU^U颛vz몺jizn=Q匢osl1pl8iD:j =vm!V`*6Mr;FogooYžozc2[Oj];ሤئSho-ѧBګWVhdrhnw@3)i)SJ`1e! `bc$:1jDz~oʩZ/tf)InAܐvDIbm8o@c~<=؋2Y#~ql]\$cQC-JEI6\}1Z}h A!4\za>&eUG7D51IL*Ulye׮h 6wbFi78 !sV%O^N2#n⛬qU'%Kc5%aA ]KV֔5'Cyٲ+Ke&?oѐnOJ!i6=~i7,V&~xM@FcR5Cģ΁/vLY_cf'>N  ju}7gjU8gVI,bJ%W_؆F[`ͮE{; RPx5/II3f4H8{ɉ17vh.$1`bqW[cbfiF'|a3|({rF_{Iu|Kc){q&D FAth.NM#MvYk޽95_bx[0v} m~- zE2d>dRBLclt`Qy3JKE@GZGm[Zא5ntVOMY ɝ1RrSX50>{"G[j,*ܩlZe6Ij B t8XD{?ѮLÂ%m4?ѮLÂ%m4W6l5!G'~͛5$E O???lٯ 48N߶ýMWsij?{8|ȺOw6&o 1 _s|7=R|7y11?术rk ReV) fKVwإT:ޥ V)%J̀LX⎼{oHX?Zܯu@j7'C6u|ri뜯.zh_Q{/8,W} ڻ(P}Tڳr Wti lLv/TOzy^o "Gd͖]o^e (P₱R"N㚛WM,{Hl?G f}7_{G蝳}PC@r{Lrm$ȖR(w"O?WwWkks[.뛭u RSs'ÑFL3-v:FV݇2=$H'@}zlNŋ{j]|0W;t 5ڦ-6S8rs/z(m35R)+Z̉5WP4k;Dw,A DrK<6cۅ AscICqX.o.LOoRskoTcFV ,neV[m$,Xs$7%82KMNSI)|bvGO uP@N1 J>#ZQ1g{BG[pNJ7TJIPlP5(iRmcz;=d89ߛ+,!7~<˯s6fUer˦C}/S"ՐT 6Qngq0"p0%`% Q8-L)Xy2[T\5(m|-yLf&y'y]e J()Q+}t-cx`kT~" fE+8?f)AiƖ%@q+Tm"6ƣ[؁=;C0{3U-$ †&ߔ0]27wz9c165ǔpPtoS![ RITG-h bЩh){}~!̦c)gptlGMKYtӶ0 ~^G{x+N{aݫVY;ϒb7Fk|i.r^Q9 e Asv"1⪤HSmpVcB=MV9ՒnݠI]B/p>$R43&3begKKZ ⻷'qJ2!USso!'1g%Q̯̺ \;}x3Jɏxa|:L0:@l+f]͏c鐡~iآPxDՉrcmZ@pm.q&揲IA$K/ JP-ZYC e+FSdN,9d#dBzV=^^z#O7ޝZER(yh?r$ꠧH@u 3mRإʛ餽Ƙ4q$k޺VٶNA$׬f!5)>KX`ZL@vPɀ(oClmQfqeR#.}xa|3:s׳й.1IraJk3: H/>N/*Vʁi֦8F")&ݶ@z"رb{x4"*sk!܁lfTs MC#́8[yLT%(ԬPޖ"jws;2\-Qb8-IK;L=3d(sh9 6M)kyڊĜI5J(pbV!eY&9\uٔB%1A>3DR.n2s*]K[&֑#!F=yen)%~j EUFG'|@.%30k)*f/BaccuD$ 7MX@ɥÄJ$u^O]%(%a!OވU?]H˔(~oftMm0y? qYh`]s-O:318+1)J8@0+F LQ\aJ\FNX׏,,&q4c#R=禁q0'RF$k r\ՕX鶴6Iu~q\VWV9jT8֮ilU'j s[B쁑ȔI5)cn1h]qL1GfЮNI83ptsAZT&zX{@*xzcب9\Ω+!Sw2o Ŭ$CO |\D2jomZV! ˉ&Mۃ"ɴ' S2HD68R%픣{,w+^[c aDTݮ)W4 daQ( 8j]֎ ϠKWb G3"Q,zBg(1>,XZ C줰 V0+]~2n|# eKdq?/I8. ":Co!2存6A;\ wĖ7WZ-d-U&I҃k$LTZi%c\H^6y#[.+"ާ,/ČYVvK\c!ÊY@wDGJ.%~mL:Dѳr9&,VDO,]~'REY`}2(~.ZzAq(SL#;& %O/W"CiMX9Vn)PEEQ⩧nVVru 6I 8q$0Ysd^콫DO7AEtpjdu տ@>ɧ$rlch"Ox< 6٣gu_IwH\*{IA(v$7lԵbZ11u$ZH%c#},`s㞪dK~j3t"#n!wCY}K0./rvȲz1rq/Y]v#luhpX*Z@<xՌ=KlդnU$0G\zdQ,k2~:@-:QYjR|,k\y"s#$ xN+B|"KA$7ew" -j0=]Fb*-VzyٖD%4cHd3q34:^uX)syc5{!oOB(`zӞ$$eȮ c_As9_Ө5)ec7wŒd, *c BϦP=S23XŒ31I[:3 ,#fGR%)L)?*s{= ,\'2~>^57@U N.fBmv 蒐+ ]e1K2`F5H1T DR%)Ҵ$HiA-Z(Zdfq)`bDԖXSpen&nMk 60Dx]ZQ5muSXP lumD0,rEZ Ӽ咭 %Jni]nYǡBʖF5*j8`W4ʦ`Zb\IrΚǘ߁mCsl[ 7OcluyS Oq1# Voɸ2TU7p r˞t LC/ۏ!sH.5ņ;(#bT@<^:6q,V.DSx3;(bFrVO(0aŠy)aTᾼ6!: I6)|( Jx"Mk9r3 Αp3@ @%Ȱ"jY [L euR VB$6~kD*I^Sq,!P $cJ$EE6JI S 7aTJϱT7fHHfDUtΡ dQJt;l %UBkHj{$鮤 zjzD@Vef֏#`Ic S.1w)$I#``ޚVcedT\ ]/(7lc蔍1ķ͍7mC Nly0~v+9})aPhxP)Ok 4M{.ƅQXF76g!i1s(U/V9JP4#C!QƅK7ڸ)oSߧzZ:AMerJy,aH̰Ѳ(]Z$A4 okQT-.<;dM=P$lJ7/H}H:YlP+gE}e1ۍw,eTf^A|=K ]e>ĐlGG;Gx ,2.V1EE0kg(pf:bzI,J5E]vI coߠ{M21 p&Hs8Y1yҖ60 M.bb\M2BR"lU.THW ͈D/ǰK#%"yyBr!p$3^,RG(Nģu6̜]y*IqDdv d3' TJ!nQ6Zŭ"o}]װ8wV$T+nȐTbr9`%NAA~'piU 2Hkf{ jTLj ^QZx5R)2&!_xP#"h!Qtcne;rY8Wuq2!]-Hi~d$4i"V9#CH9\4C9[ 3 (+hɪi},D$V,*nda,KK(1 #F@TDhw9̜ ?oSuسYE1+*bI6r O(`BSC:jA2tvSi(/s%AWl>HPmM? -ohU]n׻(%} 7C$'’ST<5Nd=avv~f-oH"qj6wZ" d `Q)| `8_Uiֲ$kqDVA,K$8 jFZU c62M` +1ԯvkEl99hLB%ëN æ7tpME#Ȇjiju+T1.Ahd9mt@BJ TNCҍ]^-]{]q=ɏG&q4˔Xbc:S!b4krEܟYy#rr躾q~YLq?Yx=ɺ+,FIzPt]Mw;Iͽ(I (z 8,&F[=c,Oֹw$H)MP}G&圇M$.e+BŊ:!|4KyGEHةdqau>Ģuӽئ{S' bZ_giT6 H#U s54\RPDMt^Te۵ks28湜VZea!jfI.Q{Ɯ2m.K+tG!` Oj2c`V3x^&aK1;X !cL+8k1+u3v?4c#Qd!1SږKJ>r D{xf0Yy"IX_m-4Θ o຃F 2*ra+Z1 SXL$vK̭Hm)ȭ7MPV3U2"ˤ9:oK8EN uDFo[ed6B|́Q۶YR7ܶ]*7-O /8o Tb##&]#{ESG8[[{샔FdM<2efc&ʑYX18*%E@{Edze~YY]ZRRPp0>C0S,Pkn2&AAL-`>Et qGo?9=IRv e|*2q rl6:_e83Hi p, ߶x1m*Efݽg6 qExy:̈i VqK8\]bANkLS_uVZU41IУDA,;I|:`-iȝhݜ((VAdv /{ejZR6We;)r5  9bi4f)l"8k'IKf#yn]fD<[T,(^$TXdDa逐B2A4zww,=udqqB#@zܔ䚤#LO2vLC>5ؑe(fL m,%JĬӢ؝ʼn*7.*_!hytQ\dVbhx*4!I<6TDݶ1HhB*,ʮ;QuB#4݁l %! JNRŤ'"0R%WVH1Xj%#nq"6l(MTha(}xe@fL=lo97'ݙ2lE PXkzvom)Qaےբ5~l``!E۝J1 qIhv+h/ IX!fԨܷ5i[f$qS ņ&|iaeZ僗 LʘKaárr" elU*A_GBO0⪣R|=?$wY U4sjcq3RS+=W^%7+N՜85TDBߒ8׺X葝@S%T(lڒmy}5' *UzbuH&X j{u$VJޡ3KB@ Tj1ɧ$}"?OH3RW;gh"Ox< 6٣gu_IwH`^KǠ3 11=㜒f%dK" B.úřVd詳fƜ0SWJKdޫV /$@)^d-vf dq KM^݋cR%^$yJ%rg_U xJw$_ƅnORHLHX*s"\o8,bAMhv'ۺ)V,FV(u5$B`8T:E2*t^|+LLI!KC7¥L_!s^bkUiօxlLudi& <egݨ:?wGr{q+KJ-:(J"W9RuWlD5e@Ɠ t]@$D?/njH n'm E(n=n<0C˹i{͢{8$§M\(K75)(oA\6 &Њ,w[2# 42#t cde ,qGJL@AQCRa cˮ YHR'gVPE*vjL^nFJ as!Qi퍄Mz+F%obV"o&]v"X5eU kjjU֫]6)޽}ڪzmn="]Xm+($\儉3"~mL46#_f(WXXޯӈJ9<=š5i{ w肘.';}ibZ\Ϲ1a;=Kcm$S}IJDxQRc'w9BIJmkLd@3 o.*,_\HWmp6cQn'3kBYpƥ(cv{l+ FY9|~s#L6VmӪ+% ԣ+K^#eչTy2;5߽mh]º(,mN.oBd((n@)]Rjwl GT=fb:jGZq>Ŕ,bB$SB.Xo'c2c۬d \p.T7tuˊڜ(8U{&7LSIC kՕP°UE+W.%R"ʽWGo7[qR֬Q~-I0[ Kd $PuCi4u:jKak _ޚ/OF\Arݧm\jjkj}}n?D)Kd1+ebfŁc{CV-F/s~:Ik]wDB1e ث=10,H6 60 T֡ǶtMXjt.+rzu '!Y~PqNؠL~C+cuZ%[faZ0yq͋&h> ㌝vQyE@eLofgyk*n^im]ګB^"VI9lrf lZ-rs3.-.n96/qJ{}oڸۿ& 22"QbdbDBDƚLYXD8"f" E@1:!GxR7(cm"`DILb3TQcκ6#h*RH^WR*mj SmsPU̺Ppiv㤼#JWU1t~,VZk5c{ZPV/$Tuef8%/Ht*c+Ze>gKUlwIe*Ւ6ԦkXwk]k5b\Ć/vc|>"#D9Q,5=qĸ+xα:2$hl;?^)q#S(#Z2EaҼwqez;j*YeX jw.ZۖePJ 5k~AĹ.ymT6d9I Lƀet;Jt#2t6ƚֶ,`&Ȥ%:-+%O$ڕ1$Rrc[%R,G@AOLq0a&D%:E| BGFž5٧pE)j{}E1483߻urW[K)qBUӎJΎ%P&K/IR"Ԅ3Z5"'j,P-\IUٛ4ֱ̰l3Ӱ8@gD=}#{;:1טzt+tIlXM"Q]hxlRpC@É MLzKqT"<)ndFپ~3tQ[erۏn}㦭ڭmmWL8h-m( Q`D""nccL?H2GI!:@8Ekםc`;w\Vq~v 9u{]Z+wskF, u72U!L?ĠF+7SEHJ4bB҆u]hhFrmJi>_m/(CwjҿZWb_oHdbqĎdG)( Dhlj%Ji5|vu;]ZRu3G &U $cԐ᥍02(F(Hx!dȍ@F5e#eBaOn$ؙ63;&lEaќ~[V(^C*oJy;VkpWUQ1Lp{1M_59!F^XZ.(J,y;ە6MDY1SR[^;T>嫟r8#2#nG1OHTt(qU;* 4 Gxk !&6;V+1Vչi^ ZwKz=9r bLiaAvb,qX+Ls;xxS>ܕj"Mbׯm[vޛTWrZzNo6hz{QjܹW4QU[򒀓llݝG7X#Z8B{@z4鯹krmni6D^[BV]zmBՔ ilݫйN!HDuk$ݦriWzmUTS{FQUNoN{(G*IƱ;Ѧƚ핌W'zNb}ޙ;ӮV]Xm+($\儉3"~mL46#_f(WXXޯ=S!+jXjhR%@ LD`LJ=ꘘ٦jM4f4M4M6lM4ٳM4f4M4M6m{]q_?S;؎M#i(6:ۜrj:!䜷 KyGE9Ϩ܏s[҄б X@6_ˉ-Bt*MvWSm_EW+ٱ3u-(k Rh4=$NoSx}aM^ԇ4ylBa.jBݱ] 'Ljuݾe]]%[CA&o?FwIZԦw.7RܸUWbUNgz7ߨi*{70[D'|u{d{>P 5FGs{ݛUZɭTmkQo1 H .ܗ& V&>RsT@Jv^EawTmzikon'1v/0TNZ\_^-S&`XYг* @f ss'43śu4>_mhfe|_MU!lu,FTE2HQn?KK$p)h:Hb&!~srs{dt,Y!X\jت)*UeMة>:r NcF+#b +td-̩3k({V $Gq{JЎ*xD 9U&qC98 B_'$vJ]AaU5*~ajYdXaûnF^E`lb 0 %gB0Mť %\^ fԩJZ W[\6m$Tw r#gY ,fGu>$1 D5ų ncQ"; hҶ9pW7ťcm2)kjLĽ7m=Ȥf%8$DKRbMus)! a(1"$dRj01iE`!s'I4#-dN0o#y뉅4'7Kvƹ%C ضK&}qh$eun./P\:̅?;oge}uv4*$iLbKt*8UEeZ s4"6/bKeFw!u岖 IS@i)U҆S|}(BiǬwRIL͹ dDbT&eGrjvStT!OQ51y=)ԏ)J֣"1/M߳VnaּccU J Ps㢸 *䁖lsI O-D-BErRSQӘeBcd A KR eeT_Ũh GŹPҐy*P˳JACZ_βF#0tܤpNl#tuYwbćHajaQB6a"B= $2ulm P)EO j5I MP5`2sm eiDŽ,pX}yw+_u#򁼴ߑׄL]$C5~Y8s5LUn 1 DgL 6!ő(sPÚ \Xrϐ%2ȴ}]HԶ0u2e\0lt]e\ 9=\,Y`)]>E+@W6f~e|B@ gm̎(+C6c 5CA3ϓ2Ԇ"2*YZ ›K]I&ڒ28lM4sF] Z= 623#6Ȍ 2c%r HMa2 :6jdu տ@>ɧ$+ɝw'<|lѳ$Eܞ0xmF#6my0USr_〃ay7&q<5kɼ#7'hv_N.-@HꃗBui-r뉔ٻ]j%$av-N+:*K(N,"eJw]I60`L,c 5HfLDODLD^#]0Vh.Z*Cx.rl 85 Py=r@oME{I V*݂mgSܺLFY{ _N˦/$jdVU LD\+V?qjԅ5'.4m-ٚtpT!fP%L TB:-ۛP(' JŅB.[hvؘ)Lčh}HRo7*E-a xgN4a2JA̕K9lgj?1~ujA@S,+s@=YzЉ4LD0_~Og?X׵6$j0f.1/ωr 41:4w1)(8*O4 -(B˲ Z6JB5ֲFcVBrC>hWa_<Ge;a>T*R0;h`PA3GQgSу=HbnDa=+ G "+rj. 62cx)D+nc1~Kgs D )/'w$꒷\m}l+}VEu@9L#b@Wb bd(be bx- =>=Jˣ|s7ݴy"%EytrX̣4Dv`tJқ AG.=[1%z\K$ w~`qunZa)l T V1m(0[V P L*gp>ͅD.d%k#L6Bxc!DPqeY)(DZ[\?NJqNNȆ'2Fqf2!StrO+3T jAO=({/7NrL3|[&-&`H$0…hIے ң#1'l .No [y{qe{wMl\i8c`dʈŋ,-I|3鱀m"& TJc m+plKva0ʞ'qV̡%rr!ɝXv@1b?JWu e{e4W"!qm jɬ.Y.@v"VV͏@FMD'2Dqik!>*\N2Qjd%Ē;.<6tDʛr[ ImT5A5Zڔqt& k-066 )2CMtBv7&c!e;ϙd' ¯^Tg`|Zy 1[}H$r-2@(Zac }Bi`pQLzr USʷUy똟@X,CA9.l)i++E#)&(Z"R4C E6Ygv[y|j1KTI"DxW @BՊEIR`.͉([ӂl.hfPw^.֕"TQ*tBRFM:3X7C`AL1\dc\?&`MuZ-$X´qNPj80a=.)*N`H.*&G'[٤B&1OD+{8"gCM[rFxP962%8#7a]QVe(idmFJb"P⇞s' :֬n0+J R)ag ^8c~VaT:=1:ᑸRڜ*1-OI8Fr]|_\27rXs MSY \/(imbI B[, ;w+Xl{qJBJ|!q*%XTwF@QbvAʲ.VR`IPW F6\*Y6d[;27}~1 6/z}:SCbV ɋ3iZj OƳr0ܳ 3d(ـU G</i:icRLZEv EZbA}"q֪a+jo0`epց~$ dA(7Lp+LBcDPoyH~ pc Xɠ߄;;1]`s@K*@ , ;m#]fAJ'֚fMBW T|A[ r<Wur k9+Eɑ, GC jiiVj!z\cB EP̄lX`61V*LQ2cSc+&1$| d1# k؈KojOKqEeTٰ UN;\Inv8ȉ9L UBa{ye> ]J (7EowZE\0%%4F1Y7Nfbrp$LryA EOOZj5bEda@ذ[R32}$C#'K%VE0+T& u)"H/q1Pp: Pa؈qP\ :@&!NÍX<>jM(֔^DŔfUs6k/iXsp0nkP00L92YjJqKk:i͚i6il٦ifi͚i6ilͻxCͬ8+]Ok1xCͬ8+]Oj}}af_HS!jҵnb&WfuڦD .\a;`qKJ+/fZSֵ`W. J!&1P$A쩢apllˍdСN1O3CK 2W:95}uwPV/qbv?M8Qx1"RBٌq+`zW5[H6>#H2C 4C( Õ8[=$ݦBQJ]*c5q$s+d~B^%w`/OjYPp'yFDy9dy}RڕVڥWC?G5_0ٸZ,7l,-ر3+@9ϲc!0oxv6NpBD\VdD bR'1S n6J"Υ$LQGQæ'1S ۹y̖d5m?HF*ͨnt80p dèx<+- 2,Tu̚$Y-Gi 3W}"G`ů.9Mt6X ǣ%?>./=6#Bsҋ.xi~Nl4ډKLr.@Z߂9#yHAi\B$"U,L#`ho0?#V*i+v<4+FcUZ\<^RiIܰVVȷ^ؙiJs)uYk0X:IK !}~13'8K&dtTW ʰ'b7Ô2d~@b#J&Ǘv[33$# Yq\+KK";1KʩWM`dv-FSu* bf3 gJV\f ix }l~[A+3hEJn"[yj3rEk=#EK$7nś)`~Rk;dr%υe#!jVV+vXBCzܝZ!CJ*kd׷h$AujԹOUqoI͎T&8P^{v`P[nb = W=- 8UH ֌c1HPZ'ćlثBl jM0RBvW b\Ύ`F0~ʱoMS?7DlOEe{FrdwQˍr34ix4EHĝ]q#Gwvl ,D@)um ;ݷW!MɯvNxd0Ľ|6Ik3" GBRrMykqM;N0ē@^Pl$"dU_a7B/y<;v$%A~?G֨)~^@\_Y+\S$IzQɰ2=TJ+BCPĥN\)dC)RVx/D/1H'a@ɭI͆x##Ar\{݃Q$wp$bnz\s;tR[G%@Ϊ͖YhQ,'T/9=a/-=j,qu{fLg%ZiZ Q]!]ɷy"U&l*ʹɌF ezIAyY#vSLQ\tm曪z+ UmXVaqX!IQV9)c!FPB @`hkBe{K !T89F2&{30J O"r<*qVQK@[e`Ui&>y&-Ȑ1l Fm l;P3@NRt1>- &\0y1*s;]nC-rLd!{ PlGyl#7 P{9i 6X<?"0I.G GaHe* ]֧P;*oVoR5uU(74".bՑM1~ &rԥN@==-wuFL~mhvv6i놬"G>PPs!\(M&{3UTu3Eiɣ f -(`KS&mo CV-B_eVI)J˚v7Q˄JJ Hm=_t+ygR`eΤ|<ΩgQW0DBD<.mTg#ܾԻI <܍#=T;MVpYn269)ў`udbJdFu-"5gi ĉDBb G0rP#CM4v4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٳM4f4M4M6lM4ٷw5)XpW$ 0cw5)XpW$ 0*F͆t7?y?\_b$9f@5!G'~͛5O]a_~[wmr>]osoJswB2aQKU*R_ 봙[7}EܕEд;Q*7%ApI%ѷǼ^Oپ&JC' ]v Qczլen7E޽~onn 袧ΪuiJ!WWo 2 kѹhzwR;RnTؒF#zL{ǽN4'o@SKu]ֹ:0Z+G'ܨ-OW͜yg+.qf/KOdM4ڰEI SD܉1h v493De,8_C˛멯UW-kFHhR {loP"uBdsʹַ_wV%j$UV(wx|ae[F %sgڨ→Wh .IM!((2W$ϙT 2j\5d c310:Ƒk Yr.;U4 )wΆﶧR(+LKuW\($@hK I1,no1 cQ{dn9[@ UEYټ TTqlq1g7 P';Bs{WX"oJe5& fls5C$b V!UZdN>1Jc ^?ٵBfL6 xLQ4# 喁V+9SRXA,GY>bi4%RCLϓ 4Oѻ7ou!AF<ئNa&薣|vm1N)Ae5U]w2,P$2dŶQR-2bjzcG2Ċl]|*/թSbr_I/[V'UZue;ZR1\ڻR͛!rĞ$K5>ɉ[G#U%&N_?YEWeXnϏ@ͱy} S;,+M.J;xY3:X+E%-KhTIMcm)u 'd*mOuyKqPtip+]!S~?o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>o:'/>:'/>KM7_/htuGt؜&x؜&x-4'<^_br:s_br:u?XG_y{GOΩ}gΩ}gMb~@c:]~>=RHBjnu5EzwbS]˽Eku}K>i Hz%m4񆲰-3"5"5DDF5ԦJfg ~"/n4~Q|I_sfvkIxCs"O6ka? =ú'SSUyO6)|!=.5]ͧɨCkaB")ܘrohwNWlA&8<=#Oֹw+]P(ZMP͝_)圇B:+.嚏B9KYi1Uu*ik=xus$z 8Beuu*Cӵ$ls^Bꑺ_CZItJ&PۊK޽ej34VQ†HzD2:cn=N#4r7tu|},:Ύt;zUy)r>PuΔso)g9_$a|r.qO͝/iE= lТT㑌"D]M(P $&DjQ01YP5׬WuYkzmվ XPsӂgh MՎ.nn+/+^]ʖUzJnݿ~˷*{6(dMX6 h}6"[$O ߘ-“)!2M%"{HYJ6ww5ᤰ+hjv+Pot/QԒ9V%^. pGwB݅I淋$L>k)N^@|@fü2oVzj5℠:qQ%m:O#$IZ!zNr(49Xf٬Y UW3b-rȒFlR۳evJ^uW2d{Y?Dep]E Ikv݈*k6m=`lnVcw+AeK[Nkf )[{yJw6mb$mA9KZXZh +bbޚ W 8:l|?/RL]m&Q*ҝk2J٩z=qLd*AQ3 dklUEjNuNYM9c^njQpKzN X3]f 'hTjfQ u}\H?%AE-K"%&rFPEkE0%BLib==j7HA See(7#肷 ,uզΆ .h$bH (iRV̇`hTgm7V:-h3=mc|\TS b@EM&u- FDpɅ!k6cmʒXqK"YҀssɀ H(pVя2_ R0wc PA͓iVOx>;hbf nZ^I"S'.8ɌB JGy4̒Ր⧭!nxAM9-q&,b d`> InCiVl`h1zR2</ώ \qu5mRL-IiԮRLU u 2V-F0,jɆ8IIUVM5͚i6jdu տ@>ɧ$`?͠8i Hz%m46D^iq͚"O'UD6lמ߆?w{yuO ouimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/ChangeCodePage.jpg0000644000175000017500000005574011665471334030260 0ustar drazzibdrazzibJFIF``C    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222\=" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?Y˿MƠ6Vs[P,̺FVvM A\Ǿ IKlnHsl3=5!.A2۵d|YBaNrq4Bpż.^2н_7X4KM=vg~e@ ohxD-,t=g&ЈY|b=YR; /w6pUj$z/n]н_7Y~'ž?chV" !Qst&4ދz˧s{cs ŕ%W G Sä.R.?_/' uGGt k7}Z58mN7n*Sz3^_]Xi:̚Ak#cHQ1K`I Ѡ> OvIB_yk=Z]M2G)BǹX\©Ad{i=gd/\/'}N,= OE OEהZ>GOd_/.?_7^SJ(ߋm>1t _yP}NoŇs?sI@_\/nR>GOd_/.I?_7^[KKt{~,= OEW OEWח pt{~,= OWqu}NoŇspI@8_[/nSSa[/n/2t{~,= vOE rOEיpJ=}K'"'bihߋm>ړtd,_y-Ta[2/nğ/6G(X{i=/')hߋm>x[%止i{&7P|$uT_7rkާuY/ dU`'+gűG6`Fgcr?o%V Q2,B+㯥rP36"Oľ{r(Rnry#;/?a/^O|m4{ղ[hݷ$2sߥ_~tFS37M7ws}ℯwDfA(+} ~Ƒ%$dXu@X6Fz⽇FU] **ތ*8@:{Ym9.T6m&(`Z]9'xɭ,!cݞj.#_=K;Tȋ}jz'WTF˪]'(ҽ_\e]|W@u_U{fk^ Ӽ=l.u9fmW>bBq_^_1{7 _ Ɉ_W~*_LEWZ]G{l,ʏ xUaӸN_U@y_U{>Yjko.^dG#K;/'½Ob/*U헗pXY\^\ooK+$rxxKm*%ѴCoުrz|)Qꝗa^1K  Ɉ=[VɵF"d 8POR;U>Sa"x+3&"_1^E^_0Sa"x >&oLER__U{M}ze|D@K@K;/' _x_A9"Jk3*q KrIQo#Wx$IIOM dvхP,T1 Ȧ̖h0 7F %V- "KdyDmͺiT˪c9lA;Y]^3GLin327nۅ -Col~oٴQ!_*[e6$ryr}9FKrVT;/[ʥkqi&/;1GZ9XtW? iߛL~H: +HL~L~H: +HL~L~H: +HL~L~JT[M }=39JEf_떺_gB}ERH:+ BpXY\^\ooK+$rxS[?aF%葢fcI4t@'ѮK[{gXB 8HC`#kWz Kos4 7Z]Ki,[P;@ixJ:0wl0im@M7]Wll_ĺf<\ӲE-&]ؐ2)˜WiNI--Lj5[9 yh qc `v:kOֲ!m7ew'ꡕg98Y03ʐ>dSɼUw.Yؿ.`ӚXɗz|FAϹ|$,/̚/dY 9'w>J?Ql.-VTX8=A8U_ x>M5Cz~fH,77.F @ +YԚhu?*8dwMT嗣NJӢ(((Vټݷ'n|zt=}*jk9^ŭ+C ;I8aTf‚zgѦ"]jb]D'&Npr}{ZwpsB`V/qG9i#n++K7I$ч*}Fho*3g wQ@];S+N@f9NT ?п *i@h_ӿ?G4/ ZtPg#tO wV@];S(sB.Ef9NT ?п *i@h_ӿ?G4/ ZtPg#tORTxSGd6!v5?( }:]mr wƞ2?vO|^ksax{x# /"'`9T=xװs!{V,I "%F8`AC)`Эꞥ}VUKgQNX$wZ\܎p,5։hV]V<,yj$~ m;!:i,lV2;r2[ZWt^`-G Ĩ;(ŗxPMEPEPEuINqrČdO#@'ZMOF&ٚAnF]985ik{hc!A$ aN~G+OyU-[hu gyMnYETQEQEQEQEQEQEW" hyLi*n#k`pyvKE;cO_Sq^'ӃfC|vv|Ԛcs/"srz:^@uS[=Jk. [Y!t4Vfd*C$Ү\e?69yh lBFI|#UAᯇ7rxI^gm{!hc @! =6^$.c UJH\qwfأktk|O#^^<) 9z {%^'-zx*Cgc ;L,,㺲)  q@K|#rG͌08?J`#1FP0? xT*v {w6UB\gZ4D^˛}t?~߫]*7c9sۃ* ۅ.z"394̑ vP:+^IYRHRw2;06GOO:8vƊ9ŒP(+;Avd׎>VKϑO:6no_SE̅]X_}] GC98p:(Q@Q@Q@Q@Q@Q@r wƞ2?vO뫑oS470r}8<d1~9|g`9z9=OIA>?/:B/8^'54\e?W{xY_U'V.2o ޫE\ECq6_&cjdF[A{oq,hѲ0cvH9׊+}ZӦ̉흫 I𞭧Jt].K紟nwś*30.2%AY&s=ͽzR?ۖq.!'Ԍ(';wGyRUhYRQ-!F`YCdHޏyg ߫*klLq)9ӥy~մos%q[K$WT'|`?w>B𝆜=D'LY`U݆=RΆum?L 5akNcL/Kf:l+ o igx /S[ɡX́1Æ8҇fsi Οsw˫Mu6{ *G\m|c_khZ԰`]0 2pqk1<;Y^ p+lbn`7t?}TEj3Em>[{y1}W9?7/x7^60n4,`ct Ϙ67rF0zq cLQlyPK:Ic]/;K@JG XhB 4{$$DH}\?l?4QPg$׺nΏPaxdwUr3^ΒWh.B޺ o]ό?g杬j_ġcV8Db)lc HJڟB,7KqhJrrJJ_@;_G6|A{-jM9%A 00Xc`]sԯ fk>79y`3"񸏙C gTu>0A(޺ ]xᬮ-n{{{`^J3mP'8$d/ l{]^tQ{wFܤsMSݒ鿷?E_" ޺ o]ό?ϢaO]_"YQ) Cz|aQu>0A+>=>vho]ό???EgG.ZVgeqspKȬ`z ;O\* Gd듎r1/;Zn ZlNdB窣hR/޻ .y~6#x|/yO$ӗȒE*HlO_ZCәc5($]FGg~ggAz?r0꺶y5m-ђ8fz?+!:=Cڽ烵"5:夗|pyJYBT 3r0Ng ./as+uMY|G_{Y#7D*IGmBklj>gij2c{1*6~NgJw 9G\[nZmۋilǗ0f8 ڻ:9p ./as)(~_]Qz?r9p ./as)(~_]T"EB)j'n03RG3dtde2n 9ְ_c۱yϩ]5q:iִ[sImBV?*Ŗ(HJ8`z;η ܭ F`+qϧj][VU 5xbbI ZI?( p:sU#LX. fH:J۔.=lOAm[Eƨ?oc˛=^q紊Y%9 81}MIo>В+o¯z-TWO gl*M RIbg\ U g*}O-kpʪr1ݎ[?otտ_j_pX+?-ާpq=Ž- c)2I,.͠pLt_a777,4nbI(Ptտ_j[Vq]v-U_Y],r4W] j/5F-Y],r4W] j/5F-Y],r4W] j/5F-Y],r4W] j/5F-Y],qP[[\ ,4P'ӧ_S]uE-O j/5PY/O8?R5j)igʐʦY )1mW[u>9m dFC*wqͰw7`/FĜ >69Kqykg}<Qy{ǰ9-wWZv!ukMVK˂E+UQT)' ֵ𥍮K-ˮӽH3pt&4oy_d;=֟cX4}J  pG@gVs[ꚍe[\*x Xc c?T}C}ΰͱ|dH@+e+/mUJG^y C. >mV;ʂHYm'99Ƞ / j6Ƣ{sa 174ekWƙg{ΣiuY'jz#4nV=FGDb2r Fy QEQEQEQE\?]q:i?;+ Bv]/ڞKki, dVS[njGg"2<D2"S)́ԓ * J7Nd6# \9}R,qԨ\n 1#)wHV* 6rm?Rvj(W-UY L{=Z/Q2GjpUY 6Ihi +"LI8 9&:iz% A+5nCVܤ6fƊFka{oxq̥)ʒ@㓌gQ𞩮w^>)$=f%W \g7%Վw^ɩ_ZTU.H'q%PǗ{{nmp7[gʹ=X(#j[^^]nJcqom)O2l޻v{W1-V -"L1tӼ=i%KapeP.@P ũUV%T *H :`k|6Z6MؼWyaZbJ9CxcpYmOMJ+gPt沱d/#`.pUOuO{h[(R[=68[(wbQ27(8=hk8d%A %OrFptW{^5/ 7шR|3b"L =7sXz'!o/-7Ě[A4!F*8'$Q^F|q/Nbp08mL FvYxq} PbYvT'>Q^9]K%惥2i1,p,U ܖn?x]-׃nը\EyZ;ʈV/@r*Exψ#3_5zlh/aU`)|ĐN֋^ M@Im khnm$I^6v@Eyo]gmf[SPx#y{| S_,75;Qf;& ѐW O pEQEUTmt[V*V$lwG%(81(4?jKa/,@r}$ ȥmlr]66SO8noN>5yu|dL-ߎzu8dxF < =^|FQ7n ytn|LieO1Q2^Xۜ'ئ}<'nvy.7o;{U)<uM;V{]"ΟP \0hg1v=y#?;ϴNoyݛ6߿vgI`[Y2[}+(ɱw8,$(a[[m2JCubtVku $Xq87|K^cS{[nb$hĘIDӑ5u8i?n΍4-%\")GrG˶1ԀM [tcmmi \K~- >ӿs+H[3M)-mNtw">p3*^l|+/nJO|sGdŢPBr3χ^@dl,kyevN0)mmN L&#p^I*ň~'ͦo}v/\ Wmf{$Y[rG*@H<z':׆!c^I ftz0@Q@Q@Q@q:ia\쵵!=C)`Э鴗A>o ,f\pA?E;Y+Y ch\>XJ˰on\82ÚmNΌ/jUlT;G_MU-]>=>M*m5ѹ.0'>4ŧ}0Zj qYxcI;G_Mj]=剣J\i ˂'`G' N G8 Ҭb9F課߭Ztv? /&ΚUt t 28=s֮ VGQF4PtS>c@?ht@*Z>;OV62[ۤlW 2EAqcW+xEYWa0=}MZtv? /&.΁&ҬdQ ۀ@HeNG@@c_קkO;G_Mc:ZS\%LFXTy@䪆f'$Z>yu3,{ghOS;FMEC;G_M5_Mcnq4h E-cnq5]dn t،{FN%qߚz[@/QTulln'K[$j; ߂\s8V/; ,&d "|c RQEyquqEFEӭ Ew$b3Wk 䎄qT3%Z]JiRd"6p8 Eq>3b.ocZFL2\ .aRPa]w*.^&[0^gtYb_sF@qΊ(((((ˇk?_m?Zڇes!{V^WtyѴ~l-D=u֬\e?6xaG촻-|=d: inyq;?|K6wpYntyH-c] Qۈ8$q]|7/۷g?/owCŽZYeyg}n|UquXxYsQ`5?1i? UXnx[ž7|A{n y+9Y'1K)p*eo^Ja39s8Qa=LdB]9- +:PDo~2ŪYBH!ĞYp*08;rێx;AּܲQw:-ݴR;IF\o*1ɮ5qbUQo7(A?)\.]o nؐq$l`[2.tb{>"xIVˬMWA x2IWQwkZm6z%!Q-ol4CRXR5ԡK{FeWP@SVOFыIGKY ċU8߅8d)oSC% ntc,18Z M ʰ9cBQbtBOjxOD.&Qmdo51 ~R?s7oOo|+z]Y `qLWw6,Qm'P% J_ kX.x=쯴;w4raNZƗ:mֵuavWxljDc<@.6\{F$V:\ew:Uu4Oi׺iK2=Mo$MٸQt\#Mk0(s%W$qݝQEQEQEOkn{f\lל)ijIsZEuil9`o<O=hOoy:wXlUln('򮦊@yد/_. طlKn3%+~4ãS|7HJ-lgAެI~a޽&{K4Bg$0e@mȨr3Ǚ?o#.#M.+KN 5L1Qӏ`<}m4K˿ȬmOKj *G~N<-`K&Km^WTbN"I?-3WZ k٨ ZKd/L`ݢ(((+O u.e u҈w4B HsE㎵^fȥIKIр#0PA"e?E4[$ȑEy$Y+Y ƇCxHHZ6 ~H9I b0k[o?o&>;A7r1$ g2GV/-l /5sW=X4|o?o&N$P̄)*ÎFC7G MME M{Ϟ355h>{Ϟ34y>zQ>z7SQFC7G MME M{Ϟ355h>{Ϟ34y>zQ>z?h'vۜgjAl&b 2OKh/cM{.'YXo,mP c C f,2}WS*dqr=\C#:kɣ'&%RN}Xܜ>#ЋYE} =dBxeʐOB;sڤ k }->0qs*-#+a `<?X*n[U[cQ:3 $g#j?JxKE$סK$V#V#BI䓖玔|#]Rgǟ㞴+D~~ݲ͒gk݆OQ\M++OOK{Ӯ"aFB.B7 1,!P^"ek08mx_S\6 .^:`ʣawem MycY0˞;Rm*ԿX-:S-#g6ђB6[$`Rc%={xhc*8RFc80qfNЮKasSa4C3@ȗF2:@Er^65[Hasjq`K"37w䎵EPEPEPEP\Wp-mCOcc6[bqWךxF _*l6QE0 ( ( ( ( ( ( ( ( ל)ki.b֐f&5$W$+[P4~>͞t11U.ow@97O8>c@?ih>ge-i`X#rjxlUlYKb"\m!8Fv>c@?ht@&O[\[>h2gerA,f'O;G_MZY[%6靑BrrpMMP;FMEC;G_M5_Mcnq4hT?cnq4}ѠQP;FM\}%x`>M93±kjOco6[bqWךxF _*[ QL((((((((k?Zk^^p襧 q1Cl֪-б#`]I$G/4\08d5"?v20)+P?o}fmGM(b 8rPq߽Z737vCT/pX29# 8sw=OC_OyvVvomyyZ6~l-F\a"# u A8$P9GԬ--mC KI(y w4: 6"tByTcs$tۀ0GRXXXdF z ˏ\-EaHcF-Ȕ;n߰);wma)xSψ/tMa0g2={9Iw .^X4,K)8<×В8lEPEP\Wp-mCOcc6[bqWךxF _*l6QE0 ( ( ( ( ( ( ( ( ל)kAzy@3Kiڢrm&w|p21뫚vii_\$NBA5M#TW7zz`+u?3$#oRbW 4+igiwZ[h4OK%  ɝ <9->ǪOE99IQPI", ,l OGunNBmWKx 2\L]c.W,qg+ţ5Lj6zV-aaPxS8Z=\lKY)b466@=Š^S6t=N[Ѧ }nc> v uzQ@mK˻8.lV!,#Ѓuώ ▩^fTxX R x\?[P"7Uu&.[ QL((((((((k?Zk^^p襧 3\]֟T?2:e?S`>;2I\_iWfn`U(eʶ7 zJoOico}~Rn%{XC\o,#Iح^7ov|s@5h_kbӥb/j*˜ }{㸽cU\(+6 }hƗϭi %"7 2( N@^TcG4KT2MqcxT3eb*Zk߶~Wy38隚T۹KÁlc֟o!|߻=8ӊEQEWp-v\?[P"7Uu&.[ QL((((((((k?Zkâ°ڕ$IV F~nqvᨮ<_&<,RiN{G27I<8ۏƹV [Ictu_|dp<۷hj_o*M/i|7O06j!m?Xm *ʧ7w}n֓Z.qzm#oM/i|7G&ڗ0gM5 ]?6 Ae{ BĢQԱ<(6 QѢQ:y|r\{;D#E"v"/6k類V2mm+Å][)+T2 yѦc R4/d?/k?JiehUW+*n2 C(x z=E[i?P#ϙM(T GD>)_" I_"k+[UenYC?wcpzIs>r[=PGB哃qSF~cE}K 6O}\V۟dΚtvmc(v|rNqw^i\Գ]1#XUv'Fa1kSę¢cvڪ[i͔6p0.#1`'p` |M]g3G-Lq)*tC*/p!TZ/͠i 0 -aUI[5 #I9bK}&(nIT eA߼2z=-49ܫ O}/J>!ES5oyg>׍Hݢmwm__ntIxl^_ Ynsʘ3VUbEΒWki_rOE}/K 6/6[qԦxm:CVn#`oofK9c2J q1\c#;v9( Qcu':7t!#PHnJȲm7tM(pj&ٶ\,CPΥsvלu/l+7=]4*$@a^O#:V{\w&/>1M/&ό_R&g[^4/F(W(`RTVz}%ٯ$X.-ye sR~bqŲr_& cϔ_5!͌r.!x1A 8=x.K{u N^(Q}?0ܔxC.q~KӇ}"[Y`)ʜ k?<%!mTb )ʝ(1)M$>~KӇ$?M Ѭ6P6ߜhmNK OG; ==SH}bWhj}?Mm?ũ vQ!^2c- @Eyaf~g|ߘsT㿷}Wy/uޓmm Je|ņ-?3X®4iKTu*-ٴ5_&i_5Uz}ja_&5YVRԣWi4?yE|/SYE~+:^}^`hy4H,ryD{}v?? :}zmc|S]":ddZ4eͩ9M]ՖHn-m ,B=:?1SoVU#W޺wOLw]u/u-KJԯ|>*2Xvy3^W#n&R%[!K$ݩ lb6ѭ yvIv8'[n峒˔ >YnHo%:*|j5Ywt-c.*ML޸k[˗ơg1* y GI'6emjV?uH4 SGK"Pc:^7pL]N ^ȪYu\AϟSi %̷4k2Eg4qTsq³mbr~-CkDkrGn-@h A_}oٜݿ88JK"ogјwOYIhsHd`;2=+h٣[_ Bdw?-<;Z4,QX'W tᇡP{WQG%G45؆=#hڻpWw cxWO=WHVAvpcrA>G%G ug<]+\e)SG*O 笰wF#jOֻ(Ļ!{4qI6S)i>#L\678힕G%G.["y.%#61C n*Y9&Yeǘv>8;uQvAsK" O53jzc1$&%Qr0$n>QG%]S;]W_:nhG2zYd/df; n/'2+m^zS]FI'ghlp (>.=se,Q$K7^*I-É@p@uEX.('+pڤV7WY%VTԉBwOj֢%]ͺt۷nϟq>H[{?zqֵ(خwP}?~ZPxX:S7ЭJ(X-F/vg-)d~Z>%!k0} x?VSa'G)'*j(!n'$9R$.F Fx'}+l^sp,Udu罶Yym( ޅI9f;\$,1wXY$޻*ynWv;Eomf(,6-vko<mڦ-lFOAkG:G{s.gs̻X >,c?Zkwܱ-'-,:\AN>)3YڻY2y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnH=[MTKP}B-̦T^9d@;Ztۭe4[g)9v&WGʸ3'8/xwU,"Oiij-qnωCPw x[Bu KПJ͍խ.OHT-N70: ]xYI/FHX/4:;2ZGӴ{o׊9l#]HPQH^:6췓UI7eN!Xe1?,|y? xG;Vi-tIO_ne0ĿLH 2_QY؎m>9x-EXUF0ṕHLA]SYk$8'at%(2G8%>ɧW4Yo+llȬ2۴$7NJ\1UwTѼ@"!=Ⱦ]Ge*ĮC) F >V _ģA{nUr17Tm'<<5wi2Ke;뇙B`b "ffD QdUU!zKWy-uFQms%H& M<{.)pNWtz,s$qO{k\Z;{fݶRKDrFq%Rv:/uZ,sq!es) .7"5mCgTGe}A͗^c}Q[yjeآB,7*$mm^BX]"1kwu@C|wnp^kZixEқo-dGK`LG 8RQ)Imbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S o*Ayx49g{h$ xMV݆鷑G@5 ep9?BT,]j]KJ_۽Ԍc1yWd) Va!-P7h(מU3>V҈m6mRm.-BS|2Qx9^H=k// :%+fߺ >R6 ˖+rKԭPrElA!2[uLA#f@:oyZnۄ?fsscku>b[8%h9܏ yR<`s^CIgI,<5s wȐ{ 7IuV/N@hڷu94&"5)Hy&1Qbv%TVn"-&[quq̬ 8JN=^E}DRK{ $l J# r SNouz/gMb86ܣtv9>pvm59Bb4̤ XYKouqwz<齤 pK# ߜIckjf~v: 9qkcE]H ciـ{I5/mK;N!yеp#ag%:뚆%iysT8vI#hP[ ~jtz-c..\!fg@kt-M ~ͤG e%Jo+ۦv`U=Twp5F%.5ʞ8?ݖi\LȠ?0-$`w_Vx~[C#FrJ o6c#sk=KUA%彝mƪ(G6XYW| "xXVemk dث7d3.Cc,9#Kfun?E X=Ћ6冓ό [I xRemBPao*[Bphl 7i{[Ǩ[ In]Չer.yc?t[By?{o߽^Qk6z~lbY|+vp*|?O VnYndu]3/ʌFxtσees^E$e#behmijZasM,g<\@)YnquoeZ\h.cevF9R0}a`i~(7זf'F[BkˏT2#Lrj_].;iC,&2ϔ>y06IZ=>gXι8͹ %\Zjt-eebBpr@5Ǎ+]ӯ%E/Lla;M)վ>6/ya&3ݻlj ZȀ̿3,&HSVdMBѠwKe+ ˇ9•qڌzƓ}$1YQ hls@'^?jH4}NN]E$Fkʮ<~Rc9ܨ9 ōgvgdH$F U;ڽW1$wXJ-\3ʑmnx!RAݪ+[|./o( #^# [rJt-I{62)mq; ws|qVf&-P7h)Y3>e֋=[M.. Kep̮жHÀr*F=tɞ L.#kt $Sx/|aVS4 ou\R54l#*6Bh(؎2; 7Vuv K4,$g{;˛8no!Ix G#=kjq{qEvI}$1 Cp*k-=h:t#x4evySPw/̋8uzY-VJGA#7IJ:ָmWNk&x?R<1#M]4]CrjW,tT ez<: &O;ɤNY 3LqkW7zM5@(\t> 4KyVB[T nzm䏨|cnCFwAb$J0[^,n[axfcx]0M) |9gL)cݖc$Ntr@ulڤ\Zme2&r̼zx|Ck)s9I˴.4->U8Ǯqy}#úagR{KMNPmvv|Oj (ccMwGn^T׾llor|Bylq$O"I|Z2By6O =ƝK}Qe ܩ B: Ero|_.eI*q c/Ycm k'=?"[IlHlTc"7GokQ-A5Ķ^O*iF1pG/,NÂr<_ac#{X6XR#0xs/m/./A{Љc7 +1HLHqj?fҧo==s,CR?&lz~F/|@:ͧ S,p=T\gAU#kmZ$fVwy_sۻvsv2]GRլLmz.yk"y%dyU`˝2t-/GZi$.-JFs+OFܱ8kCFJw}-Layo!$W/O 4cidgZtRɆI0Qe~n!M6PM౾P3Oз!W2G8aOQ@$YC-ΉCwqq{kh BYL`mW?3=ʃNƋej ꮺ}#Y>leXl/&4 +̖T/{+oqPA~O4c4^&Ӿvyoqg{t&5hR 2 vºmPS]:{.L3FP3XY>bGN,8.٧_Y]?SyM$sQ>y ڸ5< 2N腖(ʆr=9 z\˟7^wywo~;3D6:N}$*=+-;yWp+A#3V_T?ؾ/vCghZϣ]-̱imLAmVNz@I:3\2MoyRQʞ@ldx5\hk 6W%DlГM Oo"ϵ%E j0@s0ˎr-n4=ܚ޵ޚCLg`f@|; -[MԞD-.4`\Bpx r*F&5+5 Sw T,ȑ$pdR{㱮_Kc~2$Ք܅0}O*fI Hx4^W_JK ־pH/ICRX[ sPjۥjk̻Ze% ֣Zk+.h dbpw|ar}.@i|+V&Xn͔! Y"аҵn4{iX{^[إb<&owpAdR,VAs*9 4֬'kQku"Wxb3(8`ے9?icMQ ie[Iyc?k%hq iE]W,#)f]_RXd&Txm_}}-wZ!bgp:f9 N1Psr=3K[;;kr䤠43>|&pJW\'/jc[8r3)ܭF)?) ƻYysk,^|sIpTo N gξCgqysg ]ZD) /ܣgq~֧kh:Ťo=j4RYє^Z?3 ڧ-'H I—te o9d'-uNQln,`\p{F`Nz 4fXkϱ?H)&裕Y'*VUۓǦjEvh&-nLmd3,ؠ1ݜ֙/3w+A m,Xsna h~'^/7,62RBԗ/l4mGT:}NW]сc.1$nZ iV-;kkDiBrcoN/ies+ bG@m^%$%g$y/[Uԭ"Ȇva 6 qV={u3:"nUbB:J\<.wIm.uչW}0[1qi ($ 3cZxVUS&H-Y6[$b~IY`y,~'egNɞYD"3=<3)?ՓYGi$h eeHI۞s(yy53An{6&@ l1!T2\;96[S]𬷗dIA༑M1zPQckjf~v:QA%֡h%B$vrw%p!;#SZc!EA'lJn`c̼)#<N=YpLtdxa{$Cely#UٱŮ󠺍Hc PN8Hm6mRm.-BS|2Qx9^H=k|M$Şv]kO:<lH#9 >lWbH4I,$H,5ILIӵ߼}sT|~]%"m]%2F^W!4N20UՇ֬ kuuJbgx"K8Rۂx ئx;Dx෾1Ii_: ryxr{#]@(Fhd=DNhcXfm\FbK)"D] )dH,ty[yc ox䍃+rApA<-ϥjgItBAY A>jmFoxdvh*Y s򝤌= uhuh:ԡƉo*^kx4-M<όt#V<Mh>y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnH=[MTKP}B-̦T^9d@;Ztۭe4[g)9v&WGʸ3'8/xwU,"Oiij-qnωCPw x[Bu KПJ͍խ.OHT-N70: ]xYI/FHX/4:;2ZGӴ{o׊9l#]HPQH^:6췓UI7eN!Xe1?,|y? xG;Vi-tIO_ne0ĿLH 2_QY؎m>9x-EXUF0ṕHLA]SYk$8'at%(2G8%>ɧW4Yo+llȬ2۴$7NJ\1UwTѼ@"!=Ⱦ]Ge*ĮC) F >V _ģA{nUr17Tm'<<5wi2Ke;뇙B`b "ffD QdUU!zKWy-uFQms%H& M<{.)pNWtz,s$qO{k\Z;{fݶRKDrFq%Rv:/uZ,sq!es) .7"5mCgTGe}A͗^c}Q[yjeآB,7*$mm^BX]"1kwu@C|wnp^kZixEқo-dGK`LG 8RQ)Imbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S cq 6p!fAU{0`)AwaimQP$@(e}jn2YJY5 O|v5~lt?æXIcE_!b3y;B+Vit I(aT]K dr[M[tmB@tkB AzqkVQXMeuݽ3 6gln]xGӵȯȊIoa$-R[aA\O>MGEma{魼Lrd05ǿ<=iPӤ+\Yw%l8e@Bc#5X/<= += vWZUOXaT)+G@@;Dմ-Ph,EJ2pG$cFՄj-n[DJLFa\`' rG'M,ij7-,k}#/,pGy$!T(jdrE? ˫CW+,ʏp[eVu',5 K#wX&W*/ 4[MmK-/W(Z̲lTq+z𖓤CiK:|esHKzԌu KQq6rZ dnv̧ʼn ,%tٵ(,\][4Ⱦ[,rv®#P:lCT{.{X !1*qGxpwGqgmq[\g#1ܯ` SRCxKEcVq,kg>t"P#Fe;'$t{K8.u[meώi.Qʍ\ Uo/.lỂK]h$2r/u XMYf9 K=:2Grx$T^|%Ai"RN,#m,# Ůi6zŌnhۘ  AF y'#"2$r!Jʼ{rxu{mBhYn]=59%ɜ-`8;;_#Ӆnh!Rͷ~m,0MkY\V%;f]HY㚒 SO[tv 0>le6d\߁{*EмGmumhM<]b؈\NB qM7Lcx%{a,Hr$L E=jzQ]\yPl ofS*/g |ǭy/UԮ˾i[{ǖU"-)|!͜Xizi%{537vw*O˸rĶZ]}ʹkH1`fF Մ t.[iLLODBc\a b [pO{uoh~767i-71 Y>o!O5ro]\ckM,';lk,Ҵ]-;YI|4dH2c"# <Ώ<7Kqo,sA-eu.H #:BI.Py27K$('۾ M- ;K!.~SӂG4\ mqU\ mqX6>8-Y MoP0F6g>j'#i 93K*)lMz$ͺnp_9eqw=7gx.gbn3NvY: ӶxmGijiqjBYʋ,2GqUuks'.кдJ9Wd%]I-5;B"e3m>} hZ5ޑizS^\:I 岩@<[ [4>%h E\gp۸`s3Ib,g}p#hL A$RȂ9BJ,d/Iscq'6p%Q-uDiAz<T; P}d)mb[뛫CGol۶I`]HCÜ!<>UPkB%`Z$2;̮|!1"ZflJH̱H<ty~aX+o6|-LBUQpX;eVP[Kh@ YR&2cm}onuKV-2}pOSm嬈 b, >G J0e9)'ti 綞!&Toa?.w0` -,QiX)̭>6mr8Ƶ Y*]O{qx`1-弄#6\g\A=FE\RAe :& Y2 e1\οp* ;-y6gHmld( ua\*lh0Z;2[{P,yvAE<я$u{xN=ڽzuКxՠ IK$0% 21@:K]NYt/4'q0Y@Uagp:g/ywmݿU8%X[:jдnR@\s?[SbGc;۾|oZ ck>}twwW2ŧ,0y 2.1Y: I&es5wH H G*yq:CXmEH//AFg,-daPQ < Ѵ6([(YTX@XFW8ڣ '\JK[tK{wf/3l;A}Rvjl::\j&eʦrG܁QͪMŨZ> ofS*/g |ǭqee'R}>S[d_%`ZYLA'FrnXizc=6;H{ym$&KvN3I$lA+U??mp|~LmnҬKgpG"{1GԌk}ti,%tA~Cx?]ӮR×:Mf;"(LC晔K =bIm5.G7 cp[{?t[By?{o߽^V~.-tc,s(kWBLm;0q)/.wʀGnDipC|=5uؼyA0!^@p !:[;x]?Z3ApNMx& Okx vѢYBv-˺9,],s@c?hO'm׊5 fOr}SK/CnޣnX`0q\~)A?-K-08[ >eQNqysVӬkȵ5q,lB [ t"/MKL7Nce@+vH#9  =[M.. Kep̮жHÀr*F; /wyMsYqʂW8ܦDb2ܠ)ԓN[ ^ 뵳%҂^[m(qeQ&Fߕ;@;]wGӧl[7y0#ѹ08մ{kMBx.L0 HBH>kurH3U[ =b-1{I ԟٚ/?dw{|ߍ|[MR @]eDs2qBjlw Z4Nu"̥`dp8R1޹?{QXo]:bF+"!=Nc`Y 4_i uYUǐWoL~ag;$㼰L $0? q6W;+ EyR-4H<۵Suekqz/@EcpDkcKqNIUòе5Wz{6qZ-#gqd3.oN7vlڤ\Zme2&r̼zgiսis=칎pTH>Ǯ3"iämndpYϘ<>wbrA˝*C-võCUhWRaCPann^i}FeC`qRCgqysg ]ZD) /ܣga^ Un/n5(t#Q[o6!nA4e_ΝsO.\"` .v] 3yeډV47$bqPSz [K;$l]K#56#Pd Ҡk+ׅ񥕘#)'M;Xc[?#s ]W_6^Q몮W_6^Q}Jh #Ir3Q|K5iϑ܆Sx HN ea&cqYAhpø/k2ǸawS<q r iϳ1j7Rr'q,Hq<6#մٵI G!M,eELy#MSKrh]]bhZ%t|2q\Gu[.Τ2 AL>y @PDž-NYКH4 |ٮZn_$K`Ts-׈-H@DdC3m09ʞ:%4{;G ?xR9% u#]Cny5TvT_3./S׊Omt{+I#Ea(wJ0x$XM&PCLK9/.kD!9^ #' O&WdUyUYTn ! $5KmbxwK[B$s\O|q>}EB̊c-BIt W|@  ->YLqRJ2bm ~J4GpW)S*~%F9ps#WzƟ$Zay& )VfdA|EUP2ZeǛXtd}wب^Do{:Z Kkm `Tǿ̍@b*^YBwGx2GZ-աme$.G!a_e*_Agc\^Q0o-WW>bQy-3V?~ͥN$zzXؤ~L{'])DyɄp#%2ZĺXt}IOKmt7C;ev0Z^Io\[ؔV6cp|cZֆ,l.什<0ZBI@ w_Ğh-(U[ *`C#q'SƚmƠ+c}{f+ o0Co2d3p ".I) [R,g`Rڮ~g_{IA]t3B$66F|ٔ:_NM6i4V-Y-ި^oW}h;⠃"hi:׀7g}-XQеG[b <ۆwXF$Olu[xgd;<8k7 ci>lJUY' !v6EkeK4 k` Ta#."fH0|^4EڤA(մշK-nI!v*i KtGauWP]JC<Uհ`1]Ůk%V7 kLKi&ݛ( 3CEr akhWvRǐ&/Kyݳ`f~O/<׊4{};X 숤IRI"+F8-uɤt[&WP:+NH\{{[ƕ:B%ͅWr[?́cT$.φ;b=CU мGmuu\ q&B$| yM[M5 F.Y . TrA;iXN֢ D fPrp$r~$ƛ&~K<גJ.NҊYFG$Sͼ5{"|MN1 + [ij,m7RyPx7uer 2qȣMմfݮ4Br%*8%I8 i:D6ZHӧ(H[9$=HAm>-GPԵCn%fFm`\y,X&)nzzlV6 π`2q=^ 3=D` /@Db9;׹rzt-xJ<(EsMWmD6:F3W/tϴ|EHͫĚݺṠ|qq̨gc;A@Vu',5 K#wX&W*/ 4[MmK-/W(Z̲lTq+=G[m"1d_*y.YѸ}2nPw7˼ejZ|눡SV3#p˰.e<,NxP` Ag_g__|7۷yٌ5j[M[tmB@tkB Az'GfL:o ƞ>mecbTt-wY/b[]5beXI6@Q8B+8@0S5{)ёU nPguZ7ۼVOmc991Joѯ.4hq)u䵤ydF2|V[:5)<9s}kQ. r>iHx$PD+cag=}:KүmaIAHE'> ?$di~iKb/OxSnaguuC nsld2H@$vwu( Mdx~S*武o9Ti a9cz?7UYM5,[[ȺaϘа?#f\dn]-?Ngy!Y涔F,wK*+FBwʩ @$/f}`6i i oy$Ӣ3*I9̌;UiM>Tk{ YCg?C`EswNΚma}esg=˃f1e% \ 46hvwDwj3 lܣʩ\\IZm)iPHL!,C`Kcn xJt.#{1e%Kё".Ō2@$\˻ cxu\%p@=9CV v{O(<{;E+/"tV{շ $\n9 l-<.>IgR !qHϧkdjwi%ƫ,f{QK pێ6yI%I>j{k_6M+^s湸G9ڠw Ҁ;|KK[eDF2pr0r1 r:<-żrFԹ 8 sWc5-oW9#cMx5ȥȲI*F*pst7^}mhns7gߗ=8 Zuhuh:ԡƉo*^kx4-M<όt#V<Mh>y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnH=[MTKP}B-̦T^9d@;Ztۭe4[g)9v&WGʸ3'8/xwU,"Oiij-qnωCPw x[Bu KПJ͍խ.OHT-N70: ]xYI/FHX/4:;2ZGӴ{o׊9l#]HPQH^:6췓UI7eN!Xe1?,|y? xG;Vi-tIO_ne0ĿLH 2_QY؎m>9x-EXUF0ṕHLA]SYk$8'at%(2G8%>ɧW4Yo+llȬ2۴$7NJ\1UwTѼ@"!=Ⱦ]Ge*ĮC) F >V _ģA{nUr17Tm'<<5wi2Ke;뇙B`b "ffD QdUU!zKWy-uFQms%H& M<{.)pNWtz,s$qO{k\Z;{fݶRKDrFq%Rv:/uZ,sq!es) .7"5mCgTGe}A͗^c}Q[yjeآB,7*$mm^BX]"1kwu@C|wnp^kZixEқo-dGK`LG 8RQ)Imbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S cq 6p!fAU{0`)AwaimQP$@(e}jn2YJY5 O|v5~lt?æXIcE_!b3y;B+Vit I(aT]K dr[M[tmB@tkB AzqkVQXMeuݽ3 6gln]xGӵȯȊIoa$-R[aA\O>MGEma{魼Lrd05ǿ<=iPӤ+\Yw%l8e@Bc#5X/<= += vWZUOXaT)+G@@;Dմ-Ph,EJ2pG$cFՄj-n[DJLFa\`' rG'M,ij7-,k}#/,pGy$!T(jdrE? ˫CW+,ʏp[eVu',5 K#wX&W*/ 4[MmK-/W(Z̲lTq+z𖓤CiK:|esHKzԌu KQq6rZ dnv̧ʼn ,8b<7hn#kP( ' z ܳำ3ܯdIV `"HF(졛z3{W'Bڷ-l sodY1|Gcc9rLG[dlڼI]۪W,N@i|+V&Xn͔! Y"'~ u;IWk{9"XF ~gQޮE}ldv!633[>^NOV[7~̗^KZI?Dl' `Eax?]ӮR×:Mf;"(LC晔KO?O=ګ^>Ӥ}* ?D$$RxC^O@< &aĽ6/,n5?qWZ}07;FFO$Gki}\O̾RNqIyh_i_b+ wEk![pb"E@ 1x*|r1(F| $\vF}<2\j"g?E1 D gTs??oҵw>|mkx`p(ĺ Ψt56]@;!KiC.w ##`# [K;$l]K#5z=cR?Ò1<:d׍YLX̋!m?" KF-Esy,K.wvno`7 ה.:?#ik _6^Q4uCcUi.[cay#/~F"y6Ѫ|X?34I, 2׬n/K8ۨ-wfXy.vpq}ǂ!_Am?&-F S9XD7e9 ;gܐdz66h)[ELrɜ/$w^Ziv1Rr M DpfN1q_HoXEԞS"&[ah<6݀)ڠ! 𶅩:]ۦ>55ë[\+䐩l[*n`tź@I_^huw 9SBdFqhAgrCw*G$s7Σ<\u˨mo&nʜBcvX[zwEe~I-ei$wȬ%[.R&Ē+6#򿉤`g%Y t\'+ׁ$d }s[̊*3*`$!4|I-qOnbKhPdpK}IN'ԯhhWYLehI nbD2¨x5ECk4B{[|0U\R@A|AؿFH# cYoĨG N.yxjC:d"L6w2?E*̈#/ȪB67xLXkw |[ȍ/q@TKAivMq-ʚx \K(SXH+E1vͻlԈ899\K[K,u ^6"X C#R*0\o6/ya&3ݻl6>Kwwus,Z}sp"pkޤio W1̓[tpTr54TTiravIoM Oo"ϵ%E j0@s0ˎr4Y/պO:g{b<&S.i&êC˨Z&2oѦQ+MDkms4R4xM(bR9Ji\EooZM<8Yp$'*׊4{};X 숤IRI"+F8eawmE#_zΛ`ŬpmQFs<}[:5)<9s}kQ. r>iHx$P@$Qx-{I,J9G(%׿8wGձߴ'ug+rIY&22˖t$ӳ “kt_;jwwsŮ@B[kn9_. ᛑF?:J4u5 "K#|qFР@:aulZ]]ȸC ͆9>['ZjH8ItKic.WL9*!*{A5{]JKRkkK3mf]j+ <pki-Be+۷YAN~`ZH#*7FqsY$F吕(2@߸lGZ+`zpK{;T,QLl*'@E5ޱvAwseuo . WE9ng \]' VYsF.d;@?7 ЊZ{Pm ']+z ?Qӥ'~څhV9U #`R]cIJC \!Ӆ껃8f_ w5m:漋S[K{gI9F(1˵RIm)DԴt;y.Y$ϰyRj;d>R3гմBP\ d8*r`J÷Qg{no,N?e,%sdF#- =I4ྻ[=](%ռv҇XLe(|amXt{:}FUws ofS*/g |ǭz\][j3>˘]lNTC\z!<&i\:FlH_5.v*(iLҤ:jiGo<;T0UXm|U!Qd5vn6q+i-fYT6*H8$7w6p%ծߴBn]9\FzVRH95[m.HcmT3I [{Qu G4jio"o*p2_hq,P7Zͨ`3CpF *neu;y`佬" )R V#Pd Ҡk+ׅ񥕘#)'M;Xcr55I}qs;{7Ak &Cd#|y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnEdz66h)[ELrɜ/$w^Ziv1Rr M DpfN1q_HoXEԞS"&[ah<6݀)ڠ! 𶅩:]ۦ>55ë[\+䐩l[*n`tź@I_^huw 9SBdFqhAgrCw*G$s7Σ<\u˨mo&nʜBcvX[zwEe~I-ei$wȬ%[.R&Ē+6#򿉤`g%Y t\'+ׁ$d }s[̊*3*`$!4|I-qOnbKhPdpK}IN'ԯhhWYLehI nbD2¨x5ECk4B{[|0U\R@A|AؿFH# cYoĨG N.yxjC:d"L6w2?E*̈#/ȪB67xLXkw |[ȍ/q@TKAivMq-ʚx \K(SXH+E1vͻlԈ899\K[K,u ^6"X C#R*0\o6/ya&3ݻl6>Kwwus,Z}sp"pkޤio W1̓[tpTr5^ ~,m'B͕IQ:4$>`$0S@FȣlIfQ`ya\j2[;ww&sw,ipv~pP"S7ِ&Vu',5 K#wX&W*/ |Qɦ F Bfd% $$j k+~LI-|5ue<7!LjlyYBg<3^ wWWҬ5 ƒPT#:pڅ$3.օ@- 9@Inp֬. {Z(gx7\l#x-dmtՉ?)c$۳eFx~BH@4,4b[@bW)b?}lĚ*si*ih|!JCޫc<O׍ޢ,.2iK yCb]>3c88Xtżdv F!BE nBq:kvzky\ںkZڼDDUnmv}O70naG=sn`p0'=Ii0Fc[{$渴u{mBhYn]=59%ɜ-`8;5KԵ-FE)N?1r'wqy}lmLkD2)!q8 #}*K[MPy4HU@9%8ӎ5|Gm_[E.'HI! p'^2-Y>Gs*;nF8%*p1}G;p}3z隯+U??mp|~LmnҲ.Sds^Yl 97(]~|~<+y\&=ݧ.toj wtE5P3)o*jvZ97 m%@DDe 8#9 VnoMa 2W1p'u{Ji+K 65H/l!j*EN=0=+NݣN,cw)@Lr-#`Ĭ h[xFSnŽB.`$-ÄQ& \8'"D۸ͪMŨZ> ofS*/g |ǭy{=22f ECd;H8Atɞ L.#kt $Sx/|aVS܃z#ַwiַ6QQq0rA|78l\_,NޚRYL\0`GC03qvg zT]IȖM7)eGIʖelG= ]Ժv]KEa)rs!ag+PծK帵 ʳGe7d+r-wGVc'~~۶ٱqOscHόH-][pdkDtnHdH ;k\$};z2۹HUZ,1!3 @^>DwǑ+A7 .E# *7UํnDbg ;7:*584YۈG@DxqkDvݬI~nq*@E0ovz\][j3>˘]lNTCUZTsei{-5SIa]ḆR yL0hv;<DVnoMa 2W1p'u})Ōq:xPe( EXl܁qҀ ( Mnn6\`?:Mnn6\`?ɑQc#~hhcctSe~iEOB'X6>8-Y MoP0F6g>j'#i 93K*)lMz$ͺnp_9eqw=7gx.gbn3NvY: ӶxmhVf&-P7h)Y3>e֫6YM.;N]uuhr =s3mK:ZjwDl-f۰3|T1Cе;gBk";t'Ҧcfuk} |-eSxH^ i"}Kђ6p*xL(4[,[(nHxR.~f`g+{u -RMSV;|n+o_nlO^)>$9Ke*D㸒EbS~W4A =1/k4;뀄z$Vz?#Oy^ {V9UfeQ$3 R Wtz&Z/嶎7m,Im p=i[ ?2+) $ Ӱ @(&U]xU44o&HmfOku2/sJ+B<5(ci[Õ\aL`7Mh e/ ]w|gLYiGИHYrYU@^OimaKby(;[\h-. %ySO25Zc(%v: ʬ Ё#6zȥlLd&P.۳:eZdm+tYX&|`rRO]kbM'7o$m< -C#MҨ~\aK$N}}^llg]6'c򚹭kCFJw}-Layo!$W//E}n67 :7~Fh7ʛmbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S cq 6p!fAU{0`)AwaimQP$@(e}jn2YJY5 O|v5~lt?æXIcE_!b3y;B+Vit I(aT]K dr[M[tmB@tkB AzqkVQXMeuݽ3 6gltMm9T4g%kpoUn1 GQzUt4ХمB1Hm.{1szfEoublb 2[;Xus#"F!ppb8SRӵ ;=WMҮm]5K^d"e"Y*7v6z@; ]wGӧl[7y0#ѹ08VnFPJ#1̭~hczs\Zh:ݶ4Zm.ꚜւiQC0RejZorYx˧[M9Jf`c;pXt}>^^6֦VM5"ɸnXm>%έGouZA<$r̪X iC\>#MTäMk$\] {SIwF AٹBPx8>g>yfnvW]wClg>g?&6\}YvVv)Z]29EW Zn.?>~Cx?]ӮR×:Mf;"(LC晔K;hEIћܒ̢"2ClCi7 B[Y«8 ؂:~4mǵ"'l xxr1;B锠&9c~bVHGr4-q])7b0(ȓP"mYA؏Vf&-P7h)Y3>eּZ彞hdM3AImK[!HV?_zdZjw[)` ݊)nA=[4[K{(9E Ca6./tK']oM)~,]&.0R#!⸻ 3m=*y.ΉKxZ&yK2T6#xj];@.%̈́V[PA"d0W9wɐfjZmrZeY_2G ܏+U??mp|~LmnҹjgOpl$2G:a$ ۲$@5\xTiْE>{Ym$* C{hZycȕɐ?"ltayz66h)[ELrɜ/$wMcᶎ nڶ?ٟ~߿{x <1h,|vi{]Kpe\ȼn/`.NE S7r,u6Ad?"sVt[{B{m*4͐0=hVa!-P7h(מU3>VҸ}[[<lL[ ۖF=o!AԿ!k+)swK9 I"eXASrD]㼺UKH00.뜪",ҵ.mN ⳍ lGkJ8(A /RBvSǦw=o-n fi2@U爭<6o–Q_Ƌo4Q9'.DԡmY\ yK(l9 Ojkpqvn-wXZj!xGw$AkdFzbMMnn6\`?ɑQc#~hhcctSe~iEOB'X6>8-Y MoP0F6g>j'#i 93K*)lMz$ͺnp_9eqw=7gx.gbn3NvY: ӶxmhVf&-P7h)Y3>e֫6YM.;N]uuhr =s3mK:ZjwDl-f۰3|T1Cе;gBk";t'Ҧcfuk} |-eSxH^ i"}Kђ6p*xL(4[,[(nHxR.~f`g+{u -RMSV;|n+o_nlO^)>$9Ke*D㸒EbS~W4A =1/k4;뀄z$Vz?#Oy^ {V9UfeQ$3 R Wtz&Z/嶎7m,Im p=i[ ?2+) $ Ӱ @(&U]xU44o&HmfOku2/sJ+B<5(ci[Õ\aL`7Mh e/ ]w|gLYiGИHYrYU@^OimaKby(;[\h-. %ySO25Zc(%v: ʬ Ё#6zȥlLd&P.۳:eZdm+tYX&|`rRO]kbM'7o$m< -C#MҨ~\aK$N}}^llg]6'c򚹭kCFJw}-Layo!$W//E}n67 :7~Fh7ʛmbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S cq 6p!fAU{0`)AwaimQP$@(e}jn2YJY5 O|v5~lt?æXIcE_!b3y;B+Vit I(aT]K dr[M[tmB@tkB AzqkVQXMeuݽ3 6gln]xGӵȯȊIoa$-R[aA\O>MGEma{魼Lrd05ǿ<=iPӤ+\Yw%l8e@Bc#5X/<= += vWZUOXaT)+G@@;Dմ-Ph,EJ2pG$cFՄj-n[DJLFa\`' rG'M,ij7-,k}#/,pGy$!T(jdrE? ˫CW+,ʏp[eVu',5 K#wX&W*/ 4[MmK-/W(Z̲lTq+z𖓤CiK:|esHKzԌu KQq6rZ dnv̧ʼn ,8b<7hn#kP( ' z ]z]Qn\w,…v NW'W/Bڷ-l sodY1|Gcc9c:Fuqga%kz:i*Iqs~@n:dY{g#BHSs"-wGVc'~~۶ٱqOsqho5ͲMnv!#*m%ЪK[:5)<9s}kQ. r>iHx$PDmj$P\Wig/],I.4MKO&'2ڐ `H]i ulZ]]ȸC ͆9>[zc$ilFp;}8s܅ )5y=ƙu{iw9:n?yT-Ž rS_׈R[[GH%2M`RTp6"a;@ rVl#- G9fUfg,NIb㡪t*d6w Tu2e_a x--ϣnѩ?ku,\5ҖNW 'J.k:>uZDwqk]HqF?1oueI#C&݂f*g%At؆w1\-N@CbT㜏LմO_XKqoX&u iI[g0a3^T9ãxKEcVq,kg>t"P#Fe;'$t{K8.u[meώi.Qʍ\ Uo/.lỂK]h$2r/u XMYf9 K=:2Grx$T^|%Ai"RN,#m,# Ůi6zŌnhۘ  AF y'#"2$r!Jʼ{rxu{mBhYn]=59%ɜ-`8;;_#Ӆnh!Rͷ~m,0MkY\V%;f]HY㚒 SO[tv 0>le6d\߁{*EмGmumhM<]b؈\NB qM7Lcx%{a,Hr$L E=jzQ]\yPlRȿ94}'VvLZ<6!nncWX]*̜c8'AC1m St&#M/B}*k66kVۀ>W!RlGIKƳK3 .NWH}}Egb; x෻cUVfUHC2!2 wGiMe[h{؞9ĖР8&O_xeЯ"nВ@;)peU'PCFk{$OhS"w1a ,[l_69UF t߉Q@ \އqt,Eld $UG(_0)EUT .ln$~>p]*1ב^#EΨ [H/X'4#P#ʗPa9]/̑=V}suhchvI, qs7g}-XQеG[b <ۆwXF$Olu[xgd;<8k7 ci>lJUY' !v6EkeK4 k` Ta#."fH0|^4EڤA(մշK-nI!v*i KtGauWP]JC<Uհ`1]Ůk%V7 kLKi&ݛ( 3CEr akhWvRǐ&/Kyݳ`f~O/<׊4{};X 숤IRI"+F8-uɤt[&WP:+NH\{{[ƕ:B%ͅWr[?́cT$.φ;b=CU мGmuu\ q&B$| yM[M5 F.Y . TrA;iXN֢ D fPrp$r~$ƛ&~K<גJ.NҊYFG$Sͼ5{"|MN1 + [ij,m7RyPx7uer 2qȣMմfݮ4Br%*8%I8 i:D6ZHӧ(H[9$=HAm>-GPԵCn%fFm`\y,XZYm,_YtHlQΪl䑘߅9uN/"")%TH%Jo9keߴxO7>gI.K uH-5\xTiْE>{Ym$* C{h^jnij"<<ʂ5v*x ORƻYysk,^|sIpTo N gξ vȉm%Y }nlY-䉁@ȬUQ@\<5=]HR)%{QUC2m^T1,_Jn$SDHͺ5bL(g?c6.d/ܥ  D|1YBGu2Y$%= Fz [k7:/d7֖y#iexpA 0 |9U1Gֵh7PĘK(' b}*jIirLiJ*+rc\>-^_jzq- Qwo< <ՑI˔xG  jv7n kx(䄻KL8xSD(atuhb$'T7 F(<*xy]k=yϷɹ97 ˵uVU?w[N!U< o5I,RՕLkS9K,mmLwTc`,hwm2%{A-vpdM/0} hZ5ޑizS^\:I 岩@<[ [4>%h E\gp۸`s3Ib,g}p#hL A$RȂ9BJ,d/Iscq'6p%Q-uDiAz<T; P}d)mb[뛫CGol۶I`]HCÜ!<>UPkB%`Z$2;̮|!1"ZflJH̱H<ty~aX+o6|-LBUQpX;eVP[Kh@ YR&2cm}onuKV-2}pOSm嬈 b, >G J0e9)'ti 綞!&Toa?.w0` %d}'N>h/W~Rp63wM\ֵ %[ n> 0żduP+" cPLK[ІҝCyt#g4Mڞ4n5^ u4X] yys$xsrOI2蚔7wgf;.Js:ܨ4oIm;jwBiV(I%./l+-u9eӧ<0Ide9U=$t#uݿ7I92 m[*C$Ybg }ѸӒajMwkI{ez,  $`2J!@7?,ξ_ؿuyWv+W3;ZxMaoscWJ±BѹIǕpW05ooeOoC?͋_~Ɍn;j6z=\|\4Ȼd07$t~c=s$ 7 %@} W_ƋIe~RTFΠ =0I  Ѵ6([(YTX@XFW8ڣ /a}bNɨ=\` \;yv dGɰմIK BH ʫ'="hiQP7pٙ,IB,AE'; 6:,RK_ ]YO Sڤ1"Vd<׃Auy4Ak0*.%9E\6h {vI ˵P HpPR[=j8 &V6F*w't-wY/b[]5beXI6@Q8B+8M +XG<1}X{3yy67.QW^dE$JIĩ\0 kM'&i6ҽZ&9X2r@ܞ4t.l,⻒d Va!p|1\;k*N 0# ` jlw Z4Nu"̥`dp8R1ޣMjvP]-̢%xg�.r0 #&45Z]䗖8#FVwvUݵr29"m!KmGqe]X2KPyeiȖƑ+W]N{En6q+i-fYT6*H8DKI!E>YBGu2Y$%= Fz ij:Wθpu9-Lc27 lSbN5|9(.cˁ#rq˭[MvKB72 ''9F?q4Zv˧ik,^ȅOm'Q5X% ܺ[&a+k9Dw;mr!wML.NQlmgpF:Tԡlet#HdfU 2k@mF[K֦Ί~b…m$˓],֞೎-04ıXn_B(&+|.i"ng/a[KNj{*T>TylH؛]嶊mV9.h-dVȠ|AqwvZ&R-5ߴIstI< ?^cRl4'OKKs\yo-Wv1IBAgjvpM:*#2 S|õ\t{K8.u[meώi.Qʍ\ Whܚuko}ŭǨC5f f IPHmRN\<5=]HR)%{QUC2m^T1,Cgqysg ]ZD) /ܣgaxY],x_YwIdlȬt88.t5vaMmvS plpy%IgrOimaKby(z66h)[ELrɜ/$wxAӴ^;IIBo#tg@B7pgXι8͹ kѵ >H>`'+βq&Z"x /t[XuQOh3˳/:O<7+\ц Eֻj7|#pܻXHQR^jnqko{Z[Ov-eF9`0=GrzuW Wk=L -+,IZxoR -.wiPikiDatol ;|IirLiJ*+rc^qMۋٺ ]3YYO[.g.YPFI*&'9Mۋٺ ]X]2*4xlyX1y/cߚ~ mq<61ZDm7!T; ~fib%SYxe-X_ĖqPZ-0 <3Ẕ<.]ǦB3LZ@s܉n1'\rAv ulڤ\Zme2&r̼zx|Ck)s9I˴.4->U8Ǯqy}#úagR{KMNPmvv|Oj (ccMwGn^T׾llor|Bylq$O"I|Z2By6O =ƝK}Qe ܩ B: Ero|_.eI*q c/Ycm k'=?"[IlHlTc"7GokQ-A5Ķ^O*iF1pG/,NÂr<_ac#{X6XR#0xs/m/./A{Љc7 +1HLHqj?fҧo==s,CR?&lz~F/|@:ͧ S,p=T\gAU#kmZ$fVwy_sۻvsv2]GRլLmz.yk"y%dyU`˝2I|YaӯZ \-k;A~>SW5hhV{ۏ1o-$TJEȯXB5&4!P^F pxSv4ۍA4W;]@g\A=FE\RAe :& Y2 e1\οp* ;-y6gHmld( ua\*lh0Z;2[{P,yvAE<я$u{xN=ڽzuКxՠ IK$0% 21@:K]NYt/4'q0Y@Uagp:g/ywmݿU8%X[:jдnR@\s?[SbGc;۾|oZ ck>}twwW2ŧ,0y 2.1Y: I&es5wH H G*yq:CUnBOc C4.4m?M?>h.6.;x_XӼ@wrjz7zkƗk%1]}Ql,m7RyPx7uer 2qȪg<`l-M6fK)RPK"FqIƹ}/º8tWVSr>vȫ$,Fs9#5|Gu{]^E}*.`7Z i% I`l9Q@;ëin ZݮC2hT7Z-j+ x'ab8]KجnMXc9M6Pg-dBJ%-a{!nL_b ?gF^y ˯hvyI-6E1*W?+|0q4ZIɨM14u}5uɎV#'*:ttK 8-H\1 vz:=燼AegxJ7vL*72bH3h%j]H)X\9䃌wZEKs(^` ? cnHI6MF%moy%ѯ$]*wm\Hyu}Hj60Eb%yQ1b.~Wc+aYjn%itnUreFiͻ\iz KYU pJ3=pqx/Q>tm |)yOPL{nsI `Bz}Zj#U"NKS!X̍.X9@Fk;jf;&XrH'?(ܜd:grVl]PtMLBv9}g)V=ݴre$!W2!Sl`pv7 eBx.ox\H]}!wGӠo5[{73\"G&v895(tdp#H;D erH9$ 5QjE">æAurpI;A&5x,{K{h 1,V2ЪJ?ɇ /` w{YVʕ1)ϕ/[6&t{ymUKZ t{Y2('`)x\]ݭ?fԬ{k MF7R\]O2Bu1br|<Դ;kM2 $}{"$G6[g݌DygtxAڝ)\-N̪A'ws20W.5;˝VYbKTxxbpW.=>u&&]ZDkqfY6لBRT0|rTW4O OkWw68ԥinIbxUPLW F u^\wV~ H Ÿew(r9Xw^+WKfY!h,q+88 fD?7N3+˽<"cXhS[]\;[1Ih%A yܹZeǛXtd}wب^Do{ͪMŨZ> ofS*/g |ǭg/t/WmNtPa;0*OmK:ZjwDl-f۰3|T1CSkrx{XҡӧHWDKgِ,qZʀ9lGj]伵U{Э2 մ)7:/em OG}YGq\ Y˸ wԕiA̫:`({&/6d!G!7}O70naG=sn`p0'=qpxtmCO+OX/ o 9F3V.5TiS1%ΓO;ࣲ W,>`saQu:tcoc>&kH7.' 1TZݾhQlX Q\]i:GsZOhgS< y%wqԴ:KTtgQ`,a-*%vjl::\j&eʦrG܁Wjkpqvn-GC VS ˽rEa$ʱ<䉉jkpqvn-VvLV67LqK;FX柯@(\tƏ +8%,{O ה.:x:ԡƉo*^kx4-M<όt#V<Mh>y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnEdz66h)[ELrɜ/$w^Ziv1Rr M DpfN1q_HoXEԞS"&[ah<6݀)ڠ! 𶅩:]ۦ>55ë[\+䐩l[*n`tź@I_^huw 9SBdFqhAgrCw*G$s7Σ<\u˨mo&nʜBcvX[zwEe~I-ei$wȬ%[.R&Ē+6#򿉤`g%Y t\'+ׁ$d }s[̊*3*`$!4|I-qOnbKhPdpK}IN'ԯhhWYLehI nbD2¨x5ECk4B{[|0U\R@A|AؿFH# cYoĨG N.yxjC:d"L6w2?E*̈#/ȪB67xLXkw |[ȍ/q@TKAivMq-ʚx \K(SXH+E1vͻlԈ899\K[K,u ^6"X C#R*0\ou ĵ m)?B6pCA>TݩM6PM౾P3Oз!W2G8aOQ@$YC-ΉCwqq{kh BYL`mW?3=ʃNƋej ꮺ}#Y>leXl/&4 +̖T/{+oqPA~O4c4^&Ӿvyoqg{t&5hR 2 vºmPS]:{.L3FP3XY>bGN,8.٧_Y]?SyM$sQ>y ڸ5< 2N腖(ʆr=9 z\˟7^wywo~;3D6:N}$*=+-;yWp+A#3V_T?ؾ/vCghZϣ]-̱imLAmVNz@I:3\2MoyRQʞ@ldx5\hk 6W%DlГM Oo"ϵ%E j0@s0ˎr-n4=ܚ޵ޚCLg`f@|; -[MԞD-.4`\Bpx r*F&5+5 Sw T,ȑ$pdR{㱮_Kc~2$Ք܅0}O*fI Hx4^W_JK ־pH/ICRX[ sPjۥjk̻Ze% ֣Zk+.h dbpw|ar}.@i|+V&Xn͔! Y"аҵn4{iX{^[إb<&owpAdR,VAs*9 4֬'kQku"Wxb3(8`ے9?icMQ ie[Iyc?k%hq iE]W,#)f]_RXd&Txm_}}-wZ` ݊)uxAzlVt7!=*_"H̨YQw9<^I95ޓ/ idŽ2챖Ȯ!Eg,/t_ >}K;e̎xo$w?-_s25z亶 Β;̯21nxdBIOqQX˿˹c}G'+zco]X@n im$En|eǿ~RMsgM,M:K}n*.I(LgoAFc-o#yPAD.N>c:c }3N˵J_]îh1j3[IuuYI\d @s k!%FGiӕ1#D tٴ&&ycatI"9)ɒ BA#],㼹la/>9EG*7'r3_Q\~-yĚ5Quu-teU#rLN2ƍ˸|C^XDzY"#$g^jnqko{Z[Ov-eF9`0=GggjvpM:*#2 S|õqr§K̒Y h4[m&&VirØß/tn=C[O+^Csٚv٤,mUd[ylI$PA F柤G}Z[l5ۂ9 sY>fo,[Q*f@T7wZ🈥cmw]]i ңl? ;~z\<^o=%$Έ'T1K"B,_I%[ )9SZuKK-JL.m?Wt;p0YvP]k=yϷɹ97 ˵u皚>m񝿽z~5N5{kK6Aq7*,1QUK)fq- HgIdC'Ga]X]2c#~hhcctSe~iEOB'X6>8-Y MoP0F6g>j'#i 93K*)lMz$ͺnp_9eqw=7gx.gbn3NvY: ӶxmhVf&-P7h)Y3>e֫6YM.;N]uuhr =s3mK:ZjwDl-f۰3|T1Cе;gBk";t'Ҧcfuk} |-eSxH^ i"}Kђ6p*xL(4[,[(nHxR.~f`g+{u -RMSV;|n+o_nlO^)>$9Ke*D㸒EbS~W4A =1/k4;뀄z$Vz?#Oy^ {V9UfeQ$3 R Wtz&Z/嶎7m,Im p=i[ ?2+) $ Ӱ @(&U]xU44o&HmfOku2/sJ+B<5(ci[Õ\aL`7Mh e/ ]w|gLYiGИHYrYU@^OimaKby(;[\h-. %ySO25Zc(%v: ʬ Ё#6zȥlLd&P.۳:eZdm+tYX&|`rRO]kbM'7o$m< -C#MҨ~\aK$N}}^llg]6'c򚹭kCFJw}-Layo!$W//E}n67 :7~Fh7ʛmbv\+) uPixlAUO?"Codk'͙@l TfAb5vew*2/|1&xw-#ӬnƭPJ]&_1.WQZr˧OyyXy;`r >{H9ŐG4+' o)s;J;' da2W'TIP@q'$R+X4VX2A2H-e c~dBnYs}f;nWg~1w| (IԯGcVrwu*%w($afjkʟw<~6wՈl Y{륻->`͸iwy8 `oRH4VU{+I@8o*@J9S cq 6p!fAU{0`)AwaimQP$@(e}jn2YJY5 O|v5~lt?æXIcE_!b3y;B+Vit I(aT]K dr[M[tmB@tkB AzqkVQXMeuݽ3 6gln]xGӵȯȊIoa$-R[aA\O>MGEma{魼Lrd05ǿ<=iPӤ+\Yw%l8e@Bc#5X/<= += vWZUOXaT)+G@@;Dմ-Ph,EJ2pG$cFՄj-n[DJLFa\`' rG'M,ij7-,k}#/,pGy$!T(jdrE? ˫CW+,ʏp[eVu',5 K#wX&W*/ 4[MmK-/W(Z̲lTq+z𖓤CiK:|esHKzԌu KQq6rZ dnv̧ʼn ,$>0Y}#R^&#(ՐɃ( ͪMŨZ> ofS*/g |ǭs`KuvnNwtI"'y8(lfG L4MN6K`E8GBav;Ue9@o6B}oMкP Fq0Xմ5KBIy *.#'=&][|%{-6Vx6fY2yB]]('ЯS<)gapv.GtW\Vay]B7GyPcTUf-,I=*5twӣWUkww" o3688oC\m⫻k m4(M/OIlŕ֟>Iqq⏶C eEX)%c` >|~w~(eMZ=w*3}oi7yv<>vXrp\˸u0 MV|Fki.52)+ A"|=Y-d6ڄѱH r1DrA61,l.c)$['8%<2A#H$sR\k=w:64F]z|+šco8Ta.[N4 YrnUiUѼ9wtZ#c\^#Wot:[M-mu KiesL6@r,<_mN.IEDfU sv=<5[TْK>{M&mѤ.Xss7wvǨkr}V+n`3Nћ4JЫy-i$?(\P{mFpG9;sՋ=wG,喫csj%X # Y@N^~,z}ͮ뫭?]᧍).gY"w )*O(E55MPƋ$0]>Y^,,I:n2IiC{.h&i#&U6+6G`OAG-6]"yˉ; XG~jۻ(VᲥ1e¾˸u0 MV|Fki.52)+ A EVZ8fWh[$a9S#Tۺ??g3t9oOƵ?If~܏vMisfh.&]eE 2e,%ֺ|0Ai y b`"R<(+ &BxlyX1y/cߚ~ mq<61ZDm7!T; ~fib%SYxe-X_ĖqPZ-0 <3Ẕ<.]ǦB3LZ@s܉n1'\rAv ulڤ\Zme2&r̼zx|Ck)s9I˴.4->U8Ǯqy}#úagR{KMNPmvv|Oj (ccMwGn^T׾llor|Bylq$O"I|Z2By6O =ƝK}Qe ܩ B: Ero|_.eI*q c/Ycm k'=?"[IlHlTc"7GokQ-A5Ķ^O*iF1pG/,NÂr<_ac#{X6XR#0xs/m/./A{Љc7 +1HLHqj?fҧo==s,CR?&lz~F/|@:ͧ S,p=T\gAU#kmZ$fVwy_sۻvsv2]GRլLmz.yk"y%dyU`˝2I|YaӯZ \-k;A~>SW5hhV{ۏ1o-$TJEȯXB5&4!P^F pxSv4ۍA4W;]@g\A=FE\RAe :& Y2 e1\οp* ;-y6gHmld( ua\*lh0Z;2[{P,yvAE<я$u{xN=ڽzuКxՠ IK$0% 21@:K]NYt/4'q0Y@Uagp:g/ywmݿU8%X[:jдnR@\s?[SbGc;۾|oZ ck>}twwW2ŧ,0y 2.1Y: I&es5wH H G*yq:CUnBOc C4.4m?M?>h.6.;x_XӼ@wrjz7zkƗk%1]}Ql,m7RyPx7uer 2qȪg<`l-M6fK)RPK"FqIƹ}/º8tWVSr>vȫ$,Fs9#5|Gu{]^E}*.`7Z i% I`l9Q@;ëin ZݮC2hT7Z-j+ x'ab8]KجnMXc9M6Pg-dBJ%-a{!nL_b ?gF^y ˯hvyI-6E1*W?+|0q4ZIɨM14u}5uɎV#'*:ttK 8-H\1 vz:=燼AegxJ7vL*72bH3h%j]H)X\9䃌wZEKs(^` ? cnHI6MF%moy%ѯ$]*wm\Hyu}Hj60Eb%yQ1b.~Wc+aYjn%itnUreFiͻ\iz KYU pJ3=pqx/Q>tm |)yOPL{nsI `Bz}Zj#U"NKS!X̍.X9@,/tE|? 1&!gR +kg2 jl::\j&eʦrG܁WKWipm H]-F5dRyr!CyAbڝۈ8e9!.S+N6T9, 0Xue#؉! f8ъ; EZcAj63nfDMrbpr#Er|2SCoy27:9t vK+uԣxn5etRKf=S'55t-èu IQnZֆ,l.什<0ZBI@ wZ-=D]rL^2Kn&!)cc*ryc :Oihvx. <|ι zԇ[l֫o&7& 2*w3,o 7K5Ɵ.K(9  $!ˏDkàmJ,w4Zݺm*p$h#vZ<5>uo$se pVhF[,8e\q7c;M3>jZU_i򘦄J 0PI $Vggy|!csfP !y d+Q$&{ V8ne4wqIkoS'HNxܝ&OXt6k `SLx+5ɖ& -L0uCHD*m$(-?5X]wG}:=Eu[r.3aOV5xk\ӬL>ᥖ} ~=XuDou ^ReԚwYwileOu&GP@\LIsϫ(*Gl|mCȎB?oC\X|}t) F*eWt{]6Y~VnI[._.iEi𕶋9_5Vu2y,@XT^Kbk7%~mw ; ֳ,{ q88>w ?p),w"wdnnEdz66h)[ELrɜ/$w^Ziv1Rr M DpfN1q_HoXEԞS"&[ah<6݀)ڠ! 𶅩:]ۦ>55ë[\+䐩l[*n`tź@I_^huw 9SBdFqhAgrCw*G$s7Σ<\u˨mo&nʜBcvX[zwEe~I-ei$wȬ%[.R&Ē+6#򿉤`g%Y t\'+ׁ$d }s[̊*3*`$!4|I-qOnbKhPdpK}IN'ԯhhWYLehI nbD2¨x5ECk4B{[|0U\R@A|AؿFH# cYoĨG N.yxjC:d"L6w2?E*̈#/ȪB67xLXkw |[ȍ/q@TKAivMq-ʚx \K(SXH+E1vͻlԈ899\K[K,u ^6"X C#R*0\oM +mPnkZхg Sb[I2:cnɦy>m\ڼqay#a)+J4gP\Oihvx. <|ι z'ntMJX@e%Jcj~Tw4[-&PmUufP(a~8@Ԋ5M&Dդx L xYdn߰%fA\g_h}_ٿ+ۻߌq-HxE\Y)*#gP}Uf$ h]h~y~} ,*, ]#Q+mQ\wkqxn0.׏ Jc<2Yjn%itnUreTϊ4y4_AZl̖RdDA "r_up)%)R}W+2HXrFkPU] oAxJ@jswVV.P=]$eШ8()-nZՅVY]Awo}+E O#WcV qv:O嬗X-2,svl(!Z&Kq]H ZJBܘ,AvϽ<^(b+/?"[m%I$`bT~V`h&ϓQoXbi^ko-@G9 qnOkT:t 6q]l[2+YP0c> V.t{xB֕s'SnU nd đ0g5m6K{- 'tfR2 s)QQa;Z[.Q39@ܑKlKK-.HK^I+DU;J*ڹeO6l`K%6cm8\2V,mմIK BH ʫ'="7Vuv K4,$g{^|%Ai"RN,#m,#=CRF\E :B]s)bs€ X_oZt bLBΥV1> d`5$մuHtu D&MZ4%uL䏕U/5t=Z8([ rjȤsVF Y*]O{qx`1-弄#6\>-N _iZ4z嶙e LC;8R2&Tt4n5^ u4X] yys$xsVMoe M, $eUs #03TgXAjo`k>]F$Qr*IB9$5ׇA?ڔ0Yh{ջuUIdHFxk\}:2I^sp%Xpʸ8$n$vg4}_XԴ;$1M *`I ;UfG]M_6bnC#*o̠B@ɮ:V5 ZHLWq˾h,㶓fmK-,5 Gl=Vk,MA [r7"a G%:뚆%iysT8vI#hP[ ~jtz-c..\!fg@kֹmY[!x4}1E5K,#NzZwp5F%.5ʞ8/m7JMif cC*AVQTgٽ t l# בކ40?RA߸Tڮlܓ\]Po+m rj e'xZ=>gXι8͹ Cu]<GqZYHe :߽5mbQF=.X>t ; ܮr;F^;MN@ke+4$/˅ VvL<6!nncWX]*̜c8'AC1m St&#M/B}*k66kVۀ>W!RlGIKƳK3 .NWH}}Egb; x෻cUVfUHC2!2 wGiMe[h{؞9ĖР8&O_xeЯ"nВ@;)peU'PCFk{$OhS"w1a ,[l_69UF t߉Q@ \އqt,Eld $UG(_0)EUT .ln$~>p]*1ב^#EΨ [H/X'4#P#ʗPa9]/̑=V}suhchvI, qs 0żduP+<5MP} Ox!/FShVJ4hΡ\t4n5^ u4X] yys$xsrOI2蚔7wgf;.Js:ܨ4oIm;jwBiV(I%./l+-u9eӧ<0Ide9U=$t#uݿ7I92 m[*C$Ybg }ѸӒajMwkI{ez,  $`2J!@7?,ξ_ؿuyWv+W3;ZxMaoscWJ±BѹIǕpW05ooeOoC?͋_~Ɍn;j6z=\|\4Ȼd07$t~c=s$ 7 %@} W_ƋIe~RTFΠ =0I  Ѵ6([(YTX@XFW8ڣ /a}bNɨ=\` \;yv dGɰմIK BH ʫ'="hiQP7pٙ,IB,AE'; 6:,RK_ ]YO Sڤ1"Vd<׃Auy4Ak0*.%9E\6h {vI ˵P HpPR[=j8 &V6F*w't-wY/b[]5beXI6@Q8B+8M +XG<1}X{3yy67.QW^dE$JIĩ\0 kM'&i6ҽZ&9X2r@ܞ4t.l,⻒d Va!p|1\;k*N 0# ` jlw Z4Nu"̥`dp8R1ޣMjvP]-̢%xg�.r0 #&45Z]䗖8#FVwvUݵr29"m!KmGqe]X2KPyeiȖƑ+W]N{En6q+i-fYT6*H8DKI!E>YBGu2Y$%= Fz ij:Wθpu9-Lc27 lSbw7Zig3E$$bFuW;g$('˯hvyI-6E1*W?+|0q4[XG-NŬ}1:IrXcDqor£K̒) 4[n!UhĄ'x@=Vt KTiTT-fz@5;˝VYbKTxxbpW.=>uxo[DKi/U[veo$LfEg B%u} G-ԑI,SOj`ZVq$Z"Fmq2aF[9@/tK']oM)~,]&.0R#!⸻ 3m=*y.ΉKxZ&yK2T6#Լ1#Aa6mn,#iaVUD]#!ADLH 2_QTnBOc CiMe[h{؞9ĖР8'kqxn0.׏ Jc<2Yjn%itnUreUuwIWhuwVRrCBq./'ZN //4;mr!,OR3hkY!K+ӆ2doo9ʨ>WGA$,YA8eclFAVRM[MTKPMBdLW^yTH[;J_ j3WM>ծSiyhз 權O \w5c:?o5pH,[Sq[ G$%]ei*Z'%FDu[$1SЉP¡f ;Ap0õpCu]<GqZYHe :+Q$&{ V8ne4wqIkoS'HNxܔ/-gn%XK()]X]2 h򱱺c_2ǿ4@yG]^; %і9& mqZk`?9k#mpWG\h)QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEWt ii${Iz\H8 WkmMԡ!{8x2a )5>>G_6^QY r}P"[MnxE;WidUv7o {4Cܶڜ?7coac>ކI| (xQo9c9?77=F wcyov0+^U m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU m3v1Q?=mNa01wU8ߓ|s`Pv7oU ou;1^^2}1`pHzׂim⑵m[,/>wGyor~nO'v<k-tG|:OW!E/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tG|:OP/-tR.I]ʥp3WALtQV* E]n?Zkg-6H_S\7FANY!W,9a'O'$k>ZCe u('fFp?2yrOh?P6/V mqU\ mqG٢IqaWBPTEз߈?Eз߈?EXMoNo-/"(Bޝ~"([ӿ_EQ`7;EQз߈(o zwMoNQE?GBޝ~"(o-/"7;EQE[ӿ_Eo zw,з߈?EXMoNo-/"(Bޝ~"([ӿ_EQ`7;EQз߈(o zwMoNQE?GBޝ~"(o-/"7;EQE[ӿ_Eo zw,з߈?EXMoNo-/"(Bޝ~"([ӿ_EQ`7;EQз߈(o zwMoNQE?GBޝ~"(o-/"7;EQE[ӿ_Eo zw,з߈?EXMoNOX-mJEuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cvd/EditMenu.jpg0000644000175000017500000005010011665471334027176 0ustar drazzibdrazzibJFIFCC|" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?CF.޷_ Ŀ>jhsk^ |GKM^ơnޡ'|dچSZ >9c1eY7tHʩ, @waVy |h567) XdBAI zH}߈lt>ˡi2uXzKnͧkN-m }+YIf??#%j4>Qes_,-*9GJ0n8~aMחb1297@q&G{䰹##SITƥVIK\ I)JT5_zQ?  !C6@#?9 rAğW c>@ $`@9 񅎽Zԡ>p~c]F淪ۉROx]Ott;k|6|1ZWO?5xuΉ?x['>-SMmY4;K]>VXwOjh/%-Ђx-bI/]>'|)we!Xn9iO V-0X}l+a ZRt1,/cUx8, Ly30S`-:َ& Vε avxkg"4o7G. ,]F|X< [Xi[ntn܉V(nmg5WV9W};_xGC-/6U.eӯeٚOse2]/G8LF5O2W7a .b*q>aG U]:jЧî$*(P,>"J8Fu岥UC4<^>_ >zzћMҝH7. ,]F% ѿ|O_'1CKCYWK=KB֤Zyw\]X]Z]X}CI+A8|m/iIhZvw>$Ҵ;Fhm.58M"{mJC-vVy%u3WC;Sb02α8Fo` W3/3ag^f_(y #ΕبV pul65kWSAfyw75*xUEk3g|.#FtυDhn@/ot.W6P_7o>i5jM :3QB%ݦ%\ǯ,e2k+-s;i-̺n<#W)a1<5rX|VS]KR4ԪJ.'3T*bhaZ8?cթgQ9K*NF'Δa1aVTKZdNr_WυDhn]Y:O oڮ~j62Vw&vl9&r J &J/Kqu,᫿.=[g- Ei8dl uC2,z9G ~# fzNRTc#Rޥ~|TFf_6T#?qi0YץVBPNXCT} _K>?vxkg"4o7_x#MҼQu4yA?mu/]U 5c5ͅE-6\ ^.ox:ƚ5 3Nմ}.-wNSPۤbmf0ꨍ=I'|EW5r X>gxJLiŢȱ0QCZ2a18l\b؜=Z:j X<ʦa`uibuT8Zp0\:l9)5YB!o. ,]F% ѿ|z[>ctAOy ԖjMyiٙ:j4^x~ hrIckVx*$B6( kXabc =J8fXxC pYU:b*a 5ZkNiM\1K<$pTV:uڇM^ '+*{K|R( (b`I꒍yAQ͊=WYG[f[Swm߰[a~ %> Bzg?~̥FG8k=?A/ dz߳Nz'o ߎJ<7xpAAe?4qWa1У`=4ΰs,SF:SaR֡gbT8 F J(bl&W CI/cZ8Սz>ҕ_ -{>qi.k;_ZGmo5֞z|Dzkq*hqkcqjp¾,<m;'X|Xޒ7$Vٮѵ*S^x|Y}n4r ^=KU:E{os9~"?.a^L6CZf\4fWzuh},l,,XYUW#aIeҒŬmY0ٴq93 *'U/F|oCk];^KAmV$QErEm3Qq>H__t ޏi&Z#\X;J^5f ѬZE7o2j?l?7@}ufC!/ 1gqXU8Mz537:R)C>!Zhbya:tchX\odN$̡C *yaNt2uZX<L5[OMtC:ex\7Eg]cGa5Ƣ۵7!|98}oWJkU`/Μw}usmlp(YawB[E ?Ro~~ھiڴ֩Kׄ%MN ;/Ɩk2E)ҿϟV?475ீeFYbTSlOp0qƔcѤxZ،.9˰xʵSpĪ5UT0puV C Oy|`%׃uox>>/5)oWk& 귩e*j .YF{]&M [ߪt)Կe GJx:hZ.}eb՗Pkx@f ?#xus|ѡٯ+WGa\#qNUCم/l:([Ӽ=Z;_T~sxx7,յB|n %n5%.wCdw| xS:$l|/isTϭVwm6~.em/X 3%iK6mP+Q|ѡٯx(f~c#of n5M0+L.e*ܟ-1YvZIPQG?o?Hl%6 8Iqs:Uqx51UʕgST¿e,5h:o~|D/<XF{/Aƽa5¾ YLztڵݤ:Zuݵ8oo5Cl?g_xk?Vh^R=Oy$^oku;hPE+0E̮Ьr弍 9 Ff|ß?hok\YEn/Uc~<1y0\w:XކiƹDl?-G:٧Q߰C@k_ |CV淢|Ahz֩'l/kYMZiӉԏҧɥ tJWU1 XXr Քj*3\ҕx8Bؾ ? hq;Lp2ŷ*FT*5'D'߈g|M=~#~"<< ?~ӵ6o4WOEnx]2$;_ߎ[oz틬~^ 1}ShZkK|s~2po9.:o|thk:Oÿ UocfV~|+6𝮑j:MC".zRgAuqNmGNoԃ#QҭMF6LD5K57o'S?>'XxS|)⟃>!~3^X.Mo_JF |MMM?j[y@]J~ǟ~16:W__5O~^sotwj]sǞе/5b_hZu?5j}_d׮>*V(\8ie(qN69ZUЭ()ag^0Թy/x3__ooxc uO&|b5C~ߴ -5Ht Pa,!D&,Oæƌi?R\ݿm7 M돎:m}FGZ-uo_x"Z._\uqk6~ ԵXğP&J |NO_u7}oĺ4_SS *H5-BoJq{n?1;Kkg^/ͩ]g¯_ľ;4#P|;M'¶m[ĭik[MWStb僿ᇭ<2QœJӌIKF'(J]zK6 .txD_xsKqnK1Q| <|^}y/kMWiՄTno㍦ X.u;2 mB߇s߇OkO/'O>Fǟn~x_ UEЗZ/o^ ѢOif64MF?|uƖ*Ux\sjPsSuO_>'zD7Z͕Z]UqwwOzlZ#[Ob1ZY^˩U .U®S(c\Wc4N猫*7.Sdx5e8LFOv<\jz֝imkI??7?fυ |]_E~ s?oW;k_[D4wҵ Ww2eu=֟NzΏҏ)Fʾo8:pn?8GI&jb#)~XvG RU<;9F(bVrMڎZZn E|Sq~7φu07φu0+$Ci|$b|%^<c*|;5φ3*Rp5.j/԰k׎J'M3X|elv/+VT&e`9NmԌ*QO~~&Ɵfމ_|}M/ xH#7"hX7fI|Xᆼ]GGO* ?o_ ޽&m/':/5{[O6F-<8/&41,}[Xյya:}<U~?1;G+(M$7߃q #)$?Y¾ONj}YY,[ ʰ/RXe %9kԟח*TpJ+ŧø ε LV#2T1eVBSNPZ)]EsAOV$w?5??ᆼ]GGO*|l,hKƝ(x'ះe=77 5?3gυ| ڀu:To"@9X}2 !Yxgn-6?i6JSşO/"|A||:|UF3zhw tYbnZ K)C3ORKN_pXHFRS+:ڦƄ7v7JraqUaBkƝH}8Qkzϋoeu.:{5 xC³A~V1-i )!on5 ӷ]OFR7U|4oOE-vQjq{xCJмMx:ZC}gBI:|ARף^k 'Y/.4ȣklio`Swsr.> Q>Λce |{-oPtM|=CR7sO %5Wv;6g^5ǞY2f X,miQaR"0*eS]SGuke?O~x^|5S]Ԯ 7SQiR?jҚtÁe­9|P,ԣ}>w呻嫘q5("ZӥVN9^5)PqO%~ɾU“>0|f5Ļ4ω-;_|Co2ź6cjT$|97SyZ~‹ xJ敡Sh_7x~O/ׁzFG7y,N"tZ%/go? gϊ_¿n'i۞#t <6~}cZ_߇ -ҋ_[u:H_b? }Wĺ$>,4l5_ |2[O k>|%K:iǯ7RmA}K֭iW̾=:Ɵ!M[q;t|gPZiz6okscOon&t3RHA6yCЁ/*LJki: j5˰uG1TBUzUgMK(֏2qΕH*W[ JG J.SthҧN)B\RJ*<<|ex?/cZ(]A|wω_2Ŀ{i๴xLh:z{i?.{>L?h']5=[ெ|GN+º|io:YKoj><'k㋧jnӬ????RRGߊ_ U<:V(6.x?oh)㤟>k:SR:ztpӨciGS (P ,}`ja|¹„',E`RTUibTM?ڛY?h?ğIÿOCMx[0ᯅ"yM|-jz'|Ioľ!Ǎ-sǪeW65֭?dOWk~ѵI|G٥Z]牼U=c>"CPw@u?Bk̚UsHB?@BE<JBZ*9^u| `Rr?g)֭*+JWA_ EeTa(խF8eR#3ƃGRN-[yG_6Z| 4~ _[߉O |G:'cJ:x\lmM*+cҮ/~))QCЁ/*<T.|!Jզb:Uic *F5jEKrO)09*S(348Tpjr8:NHJ:T֦LjS߶m͹T9ɹRj**eŔrNHRT`b2+oSω5CЁ/*9h4躰;WiRiƿ7|7.wkV O5v?}6VRv`C1˱3֥UnC=ZGqzsgGTՔ+R[4v|]?8WxW/9|m"#w'ҩ};åO׿=6Asm4 qFvYoS{Z 1_o)?NjW6?~x!5 [VZƏA}m-$Hgh9#vVR 'Ӓo>m ^ׯOω\=O qigyo'A4__>x]7ҮsM:O ӼWsj4=J iP\oQՑߩG ]7IwԵ;^E⇉u pk4k4ԼM XjV?kW4{km0Eu'xX5|>5/|1:ݶe. ^-. ;REme{yfTT$)SV0i΅:8r>Z'ҔSz0N(Зx~j4ڕl*Qb&SFsOl'VWZSUTaA<,q{ot~Ϟo~0_uu/ğ}s0jMjk3== *jwW{/|oO ^t'N3Egc m}=w߆>1h^SfmE>MF9ϋj9a־!x͞ hE:M{k(o/%oٯXcׇ5ӛŤ'+M~gѵ=_zfyiewweayqwkmq<1yꪲxr9Byf ʵJ):4UJq%RΦyΞYZURx刔!kWfW|ͳ߶oZ/mi' axcZhJo4׊.;=g~$[ɬ鮞 ~ڮ៊i6|uRxO15|ON⎇/PRzǍt]CsxNҡW0BC FEZ3M#ۻB5V8҆\C P^ʸG43,B2l japp:15OnGXU$D7Y#Uу#JU $ucw:?xº֓O xGhVuc*1:989:hJ7:^zBڗ4-" j7g:גhz˺ yR$yߵ/m>$KeJ= kP6{&hڭm$'4?֯ĺY:4/]lCio޷ x.φ|=6_|"<36[="OS<9gxn i x}W? Wk(o~c1؆U|su.G4 KM[Zi 5 Tdqd7[qZjr41OZt物84%MJ㣈գ,,iש8FWK5u%Jt*QuRsЩ@g`P@ @5\?<dG|IcL}J]6MfWK=2Tmu 彆uiWp#ҴaT[Gv?+oSω5 ǎŴr-Q[Pg%q6>{%òa%iEJJ2/G> ~6IpW꿱?KI%ڏZwo)?N/jW')$QN_Ծ+g 'Ɯ_HQE~||\#2y^WU\'!sȏy_2~!~h_h> 7|9/U%HxĚ'<=wowausil=Zy;b)8uf*4]ZժY}*4))JukU)SR"8J*Yt'<5>USQj*U3 Im+,~(G3SǃcT?~&gڅvBGwK<-.J|7VX៌f$~߳_⿆kxjJ CվxXŤ:.=g^խ%1x]<}'"刞zЩJ\e_5 S8Biⱘ.zT%Vxj6'PΝ9jx V/NT~Q1%)KFcEUN¯/,V6߂'edž|'iᯄ?(>65*7M^7tm̾ןþkK隵_V`&s!*cR*7Kx7>YFK^(.`5wuto Gs'-Sg1çj'K8/<5mQT M>R@>#>%E8};L~&èkm[^Ӵľ6? tt ҍXӣN"UУQ9QPUcj%w(N34 :^sN񂃍Y]arXBK48ox'ȏ<_(`dHHR@= PH;_W9k?乡bM;w+ M?|ɽ|mְbK-ߵ:ߏ7R_;SRIe֝_}8?)|WOcMQcN/ˈ(Q?R>Mտ>.?<+οi/Mwgğ^}1=Iom-<|J74)5R<_i\ci|\#2y^SE Wq}3Ï^&oym?mtω)' ~ Ҽ9+ ;7]ׇnme|5o>q DN~|}=jo_bocYd𖳫^_m.Ao)OZW*'8=]s|ѕY`3*S,ѧV.5qSU9MQt)ƟT 4iF0tC0˞Q i{8`T04#BJ*5ڃ'/> ]Ѽ wAxNU'|O>sHs_/[xfÚ-*Nίox7DG{Xt L(#N-b8#+{h"4DTT@ FЬ5oHoQɡxfRԬnEŤj6ou4Sjzriz\]ꚓB,שtԡ F\Lq3Q`pnaT pԡ XjiJIMՊZjJXj99J^cquVlvaS*ΤW\4v~ZI#/t [šQYc^yWNuzQҼmˈ,n'Ӭ(hq8uQa*QթIT|5%xROU2 9t r%JrSH]>YiJVdM&y:5Ɵyg_I{xNe_kZJge_jεy]'ThN{z۶_oscwR5xzƚߍZ~i2ټg Z%ϙ f^%cF*q [҂:Pn 1\od}^tIT 9›rc)9$l@P`+x'ȏ<_5;?W9k乡bMN;IpDaRKd' ze+ a?e/$[j?iߋuo_8ak5xt1ρ>37i~u=ϊ:Zn7ƃ`Ox>[χk2Onǿhχ_ xoG(*̏E\|\xC?m0gio+mwῆ~кׄ"x 7#^x4QGV=6'ߵ7&/]X~߳ĿXi{CP?d^ҼW_YϏ|_|FxFÒxJd:O&oY}ݞ+o<1^i^,+Y~~/~/,ɳ*S U_ η-,DcF%E^rr:ae]գFXzկ*27 jUijOեYJ u*1*Ta:iSK!|k'*τ.etχZ^Ǯ|B4==5&+Em'B.燵}kǃ4o ]_ovW дwm:>$gĚ῅"Ԭ!iٿoiٿogW6|=G 5<-L?~&T+b!CF\T)ck*jNJ3qҧFSU)Q]b(ӞҭNS:qIpUНZu9F|;i:kiZNg OӭTxc@ '!">M~Lp?x=Bς~ |~?[=L|# 'Ěm> ]M}]}̶Jwm3F#&{xnIOJ|NMJHE:`NVx'\+G2|cۋ9tՓCk~v_'+($/2~1™_qP.Cf\aܓ1j8lU'CO 8˳^m˨ViVu50qǺG O |f8l%Zk:%b~% ѿ<5Dw7acL6mcz.-nEҦ0}Gr'[Z&hEױ][\[\}_|N h oxuWLXcMNX^fk q.-UtaB_TCf(qʖIV һx|0:BubcFn7Ju#$<5Dw7g|.#Fu?|t ƛۭm.{f ],- Z;MiEquawqkmuau $/q$aO𾻮V=&iڢ]Jl5飕TX4+q WY[|1{\e O F?:[yx|6 ^28̿ exb1~',)pX68:T^WbZ6*G5Ңeղխ_NtԩV)]Y _K>t?\A|t٤ 47ڞL!Dy :6vLΑsɬs2+ <30i_%aYMwO,HR*xx> cr&V S$jZ9ûVSD,Z8V:RUX9S,=j9}] _K>?vxkg"4o7_<3_Oj._htVwwqZ]Xٳ()+,2*-ˏD@<)o#RF8.QHZ=34+ ʫ̰3[qfj|7atq8b(c!JSRSJ/zyNyR S| SX[TѧagK^ZN B:a ;uR. ,]F% ѿ|o+7JG $ٵwGT7vlwa61p'mZx߅=h׺?4;Vе:+oMBW{S{n[݋ŵ窢4'ׇ+#\043N5c_(e1S2#"~F MhTˣ5qbpjvV뉨f2I`*'a1cSi4erN_\䧋pe zݿ<5Dw7g|.#Fu z:>#n4cqodZ-E=7RZŨI5 ff{"Dg0jfZ솉 βn+q[ƧL`˓yQϱ}Xt#X̡g.Qt'&5', U7⫩{*g|;Vt'K9jueBt+BJ-7#k֦. ,]F% ѿ|x;,T~2%O'tvҠtYRmAo wol,̎]7<oZk/Z3kDZU&UQ{&q$0!P oO xwIl`i+R'/Z8C&JjtQpU͔^!a#O0xf2\xdOby?/.?<5Dw7g|.#Fu=)Ciu=\Nqs12+ 24R|WįmŨl@u o$9.Pw>^)fy V{18p燭,]l,*kB R!bZVWspee W4pyl*VQ.zhӅ* r^ҭ)rAN2s]Y _K>_z'j}4)4ii|֖yese{yeoyn^ 6Iu+-yjkswp!!->[hj\Z]Ziqu0M{k/ይW*X\y^$'8\~;>ur`3lNYʳ*؜.WbTpX S)F?AS+U Xg qL/S'aqؼfҡhURTy//]Y _K>ʹo/5ɛ#^/M[mOLum*RMJ-m2֐}L P] Khz֙D ç?AӼ_jExB]Ȯ$Hl/c'ɂ+{;s,v{UQ˳:nGGaJJO6`cW¼GBiM,ɳ ]L^t<0⼚.x:8[8QT_Jc1OQGutkC^®Y#蝾Q KB]FtYub!}6]KLuOfkEK`H `[5b {)g]\X--9Y_MKHy%Utn浚; ?rgXxqyDl  b N< zУ,BVJ(RW_?+|:1o4cbx,%ζ*p$FExow!O5G/ .Y>ƫO xRӮuox^i-J]y$ZݞqK%ճ[Zjw :_75 h\ãeAiW;Tyq{-AmծQ o^9|lrdR֧~mf>ҵ־ rXYk,#1(cQԭ:xٶ2x Ukbjasz2XhU,fbe0VsT:Jog/ .Y>ƨ% ??|e_ jWڎxBԴ)մ-^KJa6\I=`b(1n mx@};tgOl>}[[_"o>Xe}cOU7K1ꪴ:yjjcV!T\ڑpkrI.p> nts*Vsx}r ݔ~=1/ .Y>ƨ% ??||axvHJg56@L.wqȶ{i$\"4;YQ'u!qaxz=G- ;]^T>k_:{{/K;k 2=eYO_.kTRWb*ƫO ohclW'ҍgl`5KᡫO״I>6tݗvOxow!O5G/ .Y>ƫ/7CD\KC7IRNB]4(Xy$fPں/ Xxzƍh&Vꚦk2C.ou)6}6$ZKj^՚)RA4uPp0U_ 8^I.y> rs04 BX50Y##`9KNnZ5c11_J+V5:҄?xow!O5G/ .Y>ƫ9.i?%ZO KqCKn#ha"Tx-ѮR-7އw\n~+’+쫈me_$L{J V3ƷLֱwbXH,*¸~"pbHt(K1O/IV!*հ29j/ecNf5xT+Cj^>]}W~[Gڏ/$)m^!BE}gq3$m^MzeY^hu_H/4Oq#If-:iqχUㄝ Z8;01L.C2+1TpEogNFR`x?'C&Nx {  Ix쎔Ĥf8hsRN@xow!O5G/ .Y>ƫI5="+)u->;+o-$KM-dMJK%䪖LBbp,8]mҮy|/'nQgMFU.}n'F^iZXU羳YǨi+uMߨX㸴\W6^kEZ! SbӫpؼƔ>.eK R[3ypUWWVu,. fzӂui!,dEVRqr>& ??w{Ÿ!.hC&7WdykOOgOy#V^6^S/&wiX׵ SH xwK{'|sxo =v7Ecb..HOM/y%g_p73 T@>?>)_h]h$%QqH !EP m/?5sF_Os߿lky3|%C*ɪj.qM|^K9a8BYNhJJ49T?f xO¹Vw|O,n>i`\. F1i(ƾ])N8/i):^n W8ymi15;0?hث(" #Þ}S~%ׯkx@-oW ?KO8G/x*=#Zώ#Uz&7ڌ^G+ãĮWGI}?JOj>% ]M yc(YXdB92~xͼ ~q$ laG"!'tO-BƎ ~6^-Yqak2ꔲg(1kKjQoZUa(ЧӖxc٥UZi4pZfJCGzS{*ʷ=Oً$~qH"OoBA A #W?|Ϣ麮;RiZUs|8!|Sƛ[K}^h|`oBVƩǡxS}?Jկ: 'x>>;xw xL𦫨hZΕ؋;l_\@.ln'̶#~rQ7 s2?J/L_-W׾OO>a}=5O ^]W[3LN.\%(<<)sEUa3lj7W 쾳RT)SץBq>3԰qؚ1L Z:/TpK[/ĺ4+էΔT RNU":|ߎ_gdΑo>hzbɩ{RM0^ZXx}?째Q{y. Wd?ڕcx%7Sb8+IU.~Ǟ9Ҽ="7%O j_MoXūϢZ3KgC'b+x'hx'~#SO  c,_{ò.Ժ/|sP? Zյ2`wg3ǀ\G8_ 3\x>20o5 ]CQP 5?ׂ|uAixZ|JYj|1/.x+W;Qz{xNW_jZ'4!.>|hkc\?>~P 44m Fo^b f/n?<'qɛ/ψ-|;'k.6i[#-GO7??H+5*?[n:|<|{dF8R7n5渎μ^><k\=hKl77hC O  FFBt*b1kdOc1eY _K Nxz,JQc*sZnn厎n}e{iut&n|&RÚ,s[L$?:3ox'~-KV$χu '}3V4b9l4˫wm#e,: y[ _n[?Ae*29Y UVm ȣ~s9;~/Og30># 'yuƶSfYf*"5iԧ#.* !Vu+Rˆc2Q=>35 /kxr+dXL]8\Vc6L3\ das*x>:u)TOwm#>7!ֵ .Im%6sb[um"6u(8W~$/:mjG[use-SK,XV[ A 3jh-c"s ~(>Xςsbk1+b$pYyaVg81rWJP 8j5p_chK lq lFOC2X "sR>zr aVܿ/-<}y>,jI麇u4y5.oiκƏeo!kEk-2nCLs_IGq]g9ԯ56׾ Mk(4-V_ 9YZlPϟV?475cC?߳_> N[:>/¦y_7x\>PP^ y|\%S)?༻NYU\沦S),xr{o3>/5)oWk& 귩e*j .YF{]&M [ߪt)Կe GJx:hZ.}eb՗Pkx@f ?#xus|ѡٯ+WWa\#qNUCم/l:([Ӽ=Z;_T~sxx7,յB|n %n5%.wCdw| xS:$l|/isTϭVwm6~.em/X 3%iK6mP+Q|ѡٯx(f~c#of n5M0+L.e*ܟ-1YvZIPQG?o?Hl%6 8Iqs:Uqx51UʕgST¿e,5h:o~|D/<XF{/Aƽa5¾ YLztڵݤ:Zuݵ8oo5Cl'-ZΡOx>H ]sFմ 9`{/'}>jGKfOScC?߳_> ?Ti7?c ]gF6fgYa)1ȉ,Nh%x 6g9vc-43,ge:uf3/ l_WTdѣ+*L> O.<b80x-T+acE8aCnF|D3Z?`iӖ1R䦪P#:?ʨUv~&XǪ|':+iڍQ*MRPl5(%[e/ $ ;^_=gW'Ck-+ O O:/Oe+W^c,5*oT?6(k~:|C|D2xE|EXb_ZpV/FY=qauEZ m]XiTx>k__ZB`-}~2Qi_jm# xG}FGY"##*e{cC?߳_> zΝj߱ZYǟ٢{[^RX'GXNUp' xNYLfa.>z_[e8lel.cKT)ԩyw,EZy5gƼ-ٿQQp+R hc(̱UHRV*1ƜR]I(]x>WK(g|0a0+.lKQWO>!i^1ωl([_A CKӯY[ +{ԵKkZMҷ_oD//ÿ6"ռ'GR>.cծ/vhcM<-:?ؚgbuYdejTT1aR br=LKOO9!+օl6ERts2+T=RWX~Is^}oE5ԋ%͉_OX๳h&HS'gkǿ-B۶Z~Aq,p[i7+s4&Fm80\M :>VIA~I?^fc{?>+ W9F낪>gxXxj FӼK}pjN,ء0:ݼL-,,涴ߋ|3g|;ihϢ^Cpko5OǦ_ "no7\2f@?sV42ޣaA?/=ga \A7LX5^LLj5c|. *ugR1x N+BX>1s6Þ0`zGIP^1,e<~U,0Wk(T)ц2VS_ 5 7|<>R|409gO7 C51akek A8S*:j{wŗ mZxWwz}48|9u>4-[6}^j3^ދF%2:߀)2LxRy()7DŧY\MqEqE-սW7Ý?h/eG9 F~f_{վQr5qH~qy(a?8?Wn_`2 C3,S =ZXXbbVk!e,FsQ*19ajeKaq4W05%VeV5\Ռ__|1}i~H"/BxKSk{[HF麜h^sl\^Rӹ7+ZM1%~5[ jľtx&Q𮒞]_ML2O=ʋOh4mh[چ3Ý?h/eG9 F~f_{CY֯b02W'/he+-"XpLl1ڕ֡ ]N*HNexUccqe`c11S,–5<%cô՝ qMΖ/^!־xf~* ogo|M̓New{jpE`-nK qwa~*7<#}KMeı%q+G[2-އ[j4ﴵ>V42ޣaA?/=rvO=@*Jyَ\N&y'3T\F'BuNN2qF7K [FRG˛ f͆ 7&m_QJדKͨL.:օLp\;?/ 1't6_|$k^Ɖ+]}Z^Ysȫe-s̿;X_zȲNE`j_HK/`8Ryt2, Ĵ`bh`3,Ggٌ<چ6K1GJ6~ٶWxIG0Waxk9.xpU,VB<2=:ԨMUi?K4=WMV> OZ»_ YǪ/t nPFZQ\шMfGC/i;u/ ]Z-!x[]7S[-J7X>SWtgq;s̿;X_zvC\)fISQkUL,M,:#0b)b%IaGJxzݘ~ C 6"IӝhdI^: )SO:(TSJ*5$?ZCML/K;D://X*.LS!Uf{z> ,%iakXiɪi)n}7es {2au G+/|}c>.7=8w*߱결! AißEN*agS Vj~gq'C q3!07(43mF2HSbp<61P ǯo ꍠxbh-'HgwjVr?/m p =NJ;t._I7]>>oX 'Y䯩_x~ݭ.uT/,t6  a37#QInR"sqxm,ij]\åii[q4ZF9=9 F|? ?f{׭l>gaqoq}wa" 6uӵkMOӞu .i|I65ÞggG9 F|? ?f{c/;K-q|e!U@#9`HOSf>?=$%PE&)&ѓ[sH+ŴR9qF7oߣN ᯤ1o3UxK U R\\zSi+UUz^#qAX lhC.s5jX1ç!WJ0*9R*7~vf-e4zm߈5 ;A1qeݕ/ZCxtK'оR|U干4{^siXѮԭ47^a5cvP^nU?s@~(<Yχ$b |-Au^1|0xxG13x\TƎ#0˫q{<>;N"X||pg*&|uZcJkN̨զOZ*VxoZZu0ѩ >}KTzM3~ |=f|=k[Zh/ ?R.. _j$^yuBw&x[gI?%qjw~Ոү/Zwyg)ÞggG9 F|? ?f{0X\ I[PX^"p_̱ن6>SRL2Ac`)cO#4g )ϖUNhҝ8O pp-\-\vaG ^ S /R7 W·v dl CSWjO_jh=|2ֵxOƚ ӵ{A%i7;s?v0?1tqK|*#qyOy&KG3j.Ib1!9G<iO1*|VQӎ*.#S뒪ah~971Y/UCUFL2ipɝ+¦FXTUiVTѮiok4L׉p ;zxjl<*r> 㜂|cb㈩ypl0(µ1|b~,?M4k}gߵDjթZèCg w^[Grw1*'C~I߇_~* G<JZ!KMே$6ǻv+\]Y]]Y&[=31zc<=) Y-cO¿$? x;ojM['.g_ ?o>#} eb-wW4;U?]XU:&adLMH”e[>Ãz 84p8͗өN1|JS\wMoA>~VIkϭOhuok0hXͫɦXb"}A[D{~x7+ƿ<+/M-"O_5ZJ:ƵծuxEѬt%~M'Þ | O&?.~%~Ѿ7]ԯk6;?j>6q߇^<}WQͼ\ho#"p8,.m*R^ԭ[%J럂Kr?_|&H|7(/%Y^_*ts̫2ou¬U*bbpth12>>ߴ|R~߷O5k:?H],Zs Ү&$L?hMEtk㮗. 2xO8€I_!yZ_F. ~ k |wOV4ox]7~OxA爵OhZW jzdž[ZM]ִ_~ZBdž 7'h(|=iW:_ً.ۙn-%_t1S/> ?"8ƖKWadue9n&x=zXX֞&j(lUJM2}2uʾ^%\9x+x\38ʭ UOB&XHiJ FP_ ]Sy5WC~˟>|5q6s@x:ޥgwۼ@|}c-H>"bX1jWRi?_leoBe|1>xw>|{h3xfGf~ߵ|1?ZމÿWZԾ|BﭯQg4?h Z08eQ}*|\\* ]TÃx/N)R*U|4f*pk]%fFr1kWw,[r:ѧ*RpO> b~|Mxw_ |1o'7]/cƹOU:?π?o|$ֵ}Qtٝ7/ڷxUGoj-*hckTK^4ST)1 6Fsm,'t *_[3*jSX8Sê*Ct{Z?n?E{Ke?~:a/Ӟ3+|-Ư9,iL^.+žֹx?]PoN*tq2Nstf+3VJGK,?iQ*ʭ*Ȱ% 1KWWsı/$퍆XCU7BR_?ಟ3׀>RYm>#O '6|ue5oj?<jNmGƿ ,[^.i^nOOl>7-o>|#-'Txo|?|GcD֟g ~jm;Kw~?;'?Ru|<w7>;:Q/x#]KxB<M::.hߊ񦉤kz~a6"M'ak> SΈ?_U:׉[٧d ?I<ga?x.x^޽g*GVաGܪ[WJ=:F[QaV秃.;\PGܜg u9kNj*êTjԥU=)~n~_?টS/ïٷ᷍1|:'ψ)/3:Ǟ,״7Sl   i'5N[gN}j5*,]xЖ2Tpr`ibgZ:Jt,3U~ϗJs81i~!? o_C߅:h|Gk0V"o s'cFe괟)wuxᶛukm6|>epЭ/m-U`@ޯX:ӵ?ZއAc?Oc~~~%'O*~8D|&_xw]K>;> JּC3P/HҼxKVҼwGWV?ѿF sxi#k\ţ>`SPUEJQa'JiԕUJ~c%BH)Ύ \fj\>S*j3peg*㾩RsyÃF~ϖ^&mXӒ5aB'^?W?_~3?}/} n&W|/^új~*a[YihZM{iB8oz/=?¾RGiy-|l+ٵ? !"ܾUXx~Fj"iV`ͫx->`kbɪzN"8,\w0J1xSSqq5Ihde ZK/Xicpa'O)JqPΤaZ4]:rHRW4g5hl7E~~ EAx_YAᇈ>'>4>YxL>o nuh_iz@n5<><x_ڣlK| E|/mV}B]kHѾxK;FO=lg¿? |]؏gnO3}"㷎&~~7$|A6>l(#mI.|K\@XIb󅂄eBk[F.Q|2֦ :U~a|5\Ѽ>-կ,Fxl*\HކXUNl _0ntqUsHQ9cJTr&xB+*wC-^_.hC__^"/u{ >xX^a,|#7Ig4[Z}߱ ?h]ĺox+]PeҼGO/ki7qsF;J+i4B^)Xh]音O<`:|g楪i9^ҼQƺy{qxR⥑tNHoOү7/OྭOo!?@k?ErÍN<,x_6ld_|!Χ>6.! 7LYMP^ӥ}[(WZӜqUZΕSQ䜰#F5s_S8F>ڞZyOb'lRa sZ:JX*u2ө|@#I3ˍnإg= ~EK )?c\~֟?eO-!u |A$uo _ǁFH`o?C&|edPG"O“p c_/ÿ_ᗁgس0*Ԭi~:|`ӡ;o+_xg~'xKI%|GJAD:?@ٵh,2Lpx,Db\07 f#BWT(G_a)ڶ.i5M`1R1CuwxgmbsxeR *Օ,5G5z.ou?x|1ٿ^<,#^PxOD?}?6>Wrk~uREo|3kZn?姅?|)xWm |j1C|Z~ ZX%~DzNk/3;x Qx5O C6QU㏌ "Z_YҾ4|BOm'~ï`xNoX濠]iOjҬC6l'b1*ge*`+eURW ^9Ӕ1SьqңVJƍEOԖG0y]ZJqK؜F:{JO ^TgU_ ?ۣߪ׉[jG)1]HcXԹTU,UAbA9pA𬝓vwWvvGmm~v9)H*sp&r΢W5e{?ۣߪ׌n?1n?1=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GUt{Z=?=?€=t{Z?GU~c(~c(GU[E?l 9C}bZS=?¿ /_F|{>oqg=t4. MI# UQm`V3]6l-kݱn7;>W ޽>?x?z.?_/v:>7YN[OZӭm<'GG~о3Zoq>/|G_-m~" 6 hZFVu[y쮴O=gCG⍩ʬf4NwIF51'dݑ'MT-iŽ/ug$-62*PPo^ ? aho^ ? akWH~>*IK-cῌy?ŏ5Pg^;o}+F(l1gαx԰Z}]/?դQex?iH=\eqj^>xVW'+[/>)hw:EέWulKoj^`8bL1ԧ.|VѦ,Lb(1aj*N8x|Lh톡nWU)a[Cu\>~5'UӤ0Zw%o^ ? aho^ ? ak?hy9koZhO_/~ߴO~.GѴ߅4 [y㆗x-[EVSn]*c<9(jGw*x[%wiHkvKQվ(Nmh k~tOG~ xC^!< W8 R.eV8׈PV 0ϲ8{8V faS7b0uJ*qӣ)%c)eUR )SʼOF\&1o^ ? aho^ ? ak V^|7u۷e<+߄_> |[Wz&/=K?|-? oa}B -KB׾,]+oVZx;?f گj??ߍZ%<@<Zj:D­M'N2q~롖e9&oZtKt8*)ÚeZtO *qq*e(T>"*uʭ Ig7VTUZJGN?ӷ#ziW\ G#ziW\ _h~_M6^C>zJi_y^ L7e=Ou/P? %n]_~Gno6>hm7OC2ʳ Z+JԨC5S•/+7R %8쥋`qTʎ[NaU«OSCo^ ? aho^ ? ako?h|=?@~>־|׼ΟeƱO7s{[xhu F%?k??nϋ|c_>|bU?_# faox E񿃴?žվ$x{[yCs~ӯRgQaU4̰1xfЯ˕SQXz#SoJudU .))qToSդRt&Ε*޽>?޽>??Mc/ig K| HooAK?k&4< axG\޲Ed5%~ |GU}o?_?^jo |%ygσ]y_Y|Wti-F^ơi~/u>!ƕ¬E9Ӌ'ӝ1IJNrUiԩ*iԍ< N*5yjM88)3}lM{,M.<58ZqujB:]o{|4+{|4+[⿆> ?/s/7k}??gmr -4J46(׵]vݩj}7O#~+~ :'ǘ</MgAu]=~Sҿ4-xIqzn[ʧNSbr1xQνzkRJ9Jx|FJ.[W1! UciJS5NR>u,9d*xSu{|4+{|4+Mk I{(N?*s /Ok4w S>4z|@?éAJ_Լ5[!O#u_l>%??޽>??3E`xQ»?5E@߆~0x\y} ;-tKo Υ~)j> >;[(~-BM]k1-+KU0x-/oh'4N(IAm;,4#]a:FWC8Zp:O Sngq,]KYA7R:*a*FIisN"ʩRE~XJQgJ&%ZQ;{|4+{|4+7N?i_|A7S:Zxu=n&}M'կ6?h_:o_~Kx[?|mX+z?#Ŷ.g-Noz߃j5bZMVau4c)U+(5p uYuef_GLn3ƝXZ9G\k*4sͥS9F1/iwcrq/<> mfFSs_֣Ὲ'F|KO3GjR[|0]_ϻ:.C'&L|A ,žj5_ׄmx:[?hO "goi|ya__>~~,E+?)Ψf-vO|#e]x~'Usiot048N' 2ڧ'CtqO[J\ :sNvmF >.*bVk)J%ӟ#ziW\ G#ziW\ _/m|`4I|WO࿁^!|OmC5 麎X'_=nAu|"sx{eC[Qi^ |cUzXh*[fKmmGJ5 # x3@;FLEHҡVS<%9ENWdyM R'TWJh>ֲ:cJ\\pM8Q WNQcK%q"$Sԧ8ԅl$3#ziW\ G#ziW\ _ ~׾8h?ٺZMr^1 ewox#]sIxx?TxӴxK6_'VϋW4 m7 [j'Cl~xP:Ziz܍Z+i]\4iaPBi5:*dwtTP&KW 1UcOԥ(8֧tݜV*:r r:,A{|4+{|4+ǽS yi0ko;yWAyMxÞ1C/KK?x'ϏKY5:SJI xP1%Ԧn/?I㦧|Y~~7/ƳuĞ3ABg }o7;#_׵Zfk¾>t-sWPͧ7ZTӖ"QQjQT,MʶoZkO UӧK dJr)Ӆ x^ыeؼZG VJ*rTo^ ? aho^ ? ak PgygM7h~v+[<]{E~Ǟ(~*|,<[^ ދ ½5h)0xmZú:X5_ OҼ\妧(JsN$IԌjRUqSJrK]QѯZ#ziW\ G#ziW\ _?/D~ʟ|+J&OKOYFmx~+E'vlm!޽z>!)`guMVKz M?j kAß֩Q.%>#:׌#U~(x>-kw>6Ek)[땳ԼtZ刜aO/^xJUWէ)ti\KaUJe(\TRRaR}O_.sz|vQ2:|4SJj׿OºZ?׿OºZ[5;/Ii/?cYXoG>_S|}7w~*Ga{?{<_G>|g^~8"jzK| xhn}rQ  _z:xIz#Ҟ-.H.qe5eYSk'hG$Q jJ3ìN0%:*0~*1S2a*S ק*"o^ ? aho^ ? akƯׁc:KXմe~'/V|3BKhv'Mn>,־X{K^fGu{;M&?g?('φ^mwMg>)ѿK*.>3|o |3kG_E|Wuyg/_?$U#Yb)ӄp*5H|b+naC09FEJyՍq V"<,+y#,<- du% B$7φu07φu08B~>g?Ÿ |$A_oψP|;I'gsoex+4vMh@GiV7¿ۣ⏍^SGD>.ƿi@חo Nk,^ǾҴVo|=J;gOO8pbuN ;0`e%㏆gM/?7mg|<:ok>->şɼ+>7?Mן|- ^|i'4O|KX/GC{k$gBҮ(eψm~ Mti/x^|Qi4|?i2iQk6/hmuH)|} *AJ18p|>aGB9rZ8PNZg({6)/YWx({0OU+Yv-Bt:~ΜgRTj1T?o?8u_Ϗ%xL= [O>{<+xHBBҵkZ\[?diG}ƒ,ngQߏ7R_;7WƵMKfÖOKi:74~>%]z_+A֚.5MwR78q_QEJ9 U5Up˅ZrR ũF4ux0C7|s3R?f]TRtҜէ+ƥ9JN2i`7Rt_;y#ޅxkψm=CW~1FҬm[CJú$=4"o=?KOQ|7 ZҴ? x6 _7=S:'FzljW\мmNu<;o } _:&p/~UgNJz4*ӣN )S4!N)B4qF*F_:_3u*7:6'Z8ՖH1XTf%WZc 'cW|;/+?u N'nÚgm/Ʒ'>k~{-cOQ qgǾ"-Լ;+oE}J,"VԚ/g7G3~?frre9JW*՝J4u zH%$RJ\J38xl:Е7<:xyFp!L"0xCi?$kO?\u^+_<] ׺m禦OR|[]+i)k &qc%ŮwCurGe? Gu_O<{oxv?ּ]#($!%ַ^#|]q[[%~i[{3~?frĿt?M39Rc^?y M7K RpMӯ]Upp =ۖ59P9J΅L,eaAŧFx|;t(JET`Og GF&%Ӽ_~=O[cj/ҵJ]wH>7I4mcMԼ?]ic8x fo*?+$q_6v 5:ĭG?,,𭶅6EPU㻭6bM^Ė_tG?>?ho[Vn|SDx7O}:|7x]y&úd1siZUe8x fo*?29bBjԡ˳Ec8x fo*?4~ >z/7A.-n4wM 94rX <Rٕ~ſ3tacO~RF=*|H~|G>]xsGϊdXmCG|Svm,Z}!׵o 4{ȶ/wǃMcOÚ}%K/}Oџgw_ᔿ|s_i1>{kn{q yk7<گb]1_G_BԅSUh֭^^e SN*RSK*iцX.q=9Fa:F \UbKNH$&&䟶B1BgO t #ᵬ:7? GxMK_d}cBed wl|skm6?oK _O_:4͝#I?>#Y[|&Teo~.D_ ^j6t M.t][|eEιML5ι6wi|E|xJïewX+R@& ۏ~oVc3Sx7!Zfς<y1aC+aOԼឣk?vCi~5޶ƏF}ZRhe،,qPNedp?V%a04iF749JPf0F'8_VR9UZUN7͈7~Q|2OI>_Sƞ3OzϋZĭC]/x>4k>;ŧxZMݙ>-4Bꍷ=έM#E5z&Ꮙ/=/x=/[}:ҵm/>$4BK{*XDq|_SWt|G4xK xW/xᎉWMuMj{ xoV4c_KmHԯx}_4o 6Oþ=m<5[wDÓx_<|WK 𧊴OW::?o5wS&wkjZ^~Lߵ>%;xH(|OP7|6oc::#֧"1ɦ\GkXľ2Ԯ/^7z_ŸxNOx᷄Y? |1š!xZ<XloIi6:΋sjKm|I-{]R}<[.mo'AO4ms⏄>$^Z t_⎫i6W.Ҥ*JN,n&Y7*x,aWNoYS.%mJ#)RZVT'Xwʔpta(⧁0RFJPqS:Pq<> MOP~ZwIG\xW1k>8~&x'ěAmѼ3z|9/LЯ.btWu?i? "Uŭ\>.kҾ |a6I ➟g/fknjGi?|,E>+S<[ eZ+{=xSǾ Ս柫~+ލwj>io6i~?~- [῀|[WXF㟅5O^i>k(>|tnb7$+y'f!?mRQR:թAޝ %<l=IҶp 8:GAKtaTfUle\]B*:cxN|;n}7EO]˥Ƕ ޻OO R׵BY<:#Qo5KwuӼoijXh$l&I议_fgg?-<+'e9M㟏 K:>4Y6t9)ڷQ߈'FW;Z&|&Q⭇/kςŤxX߇/u_ xSX-8o1lu>rgSupبVu(c Ա_[ϱNhs~17yRQ~\T^apX kZ7.bp'OY~7Ʒ0ԼU x^GGOBK=?_<}+ 6gmB{-`d· Ay"ό.> n>/&\E7h Xx>.?^?xSL_Gm8z n1hOu'Ժ5h_|:}W"}xOO?:ьj_ <⟆M 7tVzOx]Myoi~͟ZMw⧍<#>F^ o?9?KMǃZZ%͟<3m n] G%XNg7῅z'<o|kW¾kk¿y5ZoOA*oxNQÞ,St C?|dmg 4½Þ񾝡M4[Mph:}n!> @uX]~3c};u,Oo^2 xnٓw#uHP}?go<1>Y|rK8$o)4j> > ~,i}Zo K-V_iσ*B"=y"4tueQԵv<MKi~:QB&5bRWTUUIC&Q"rT5iN~ʅ|4*UagFNj8Ϭ`k~1^\XL*:c/iz7> ޕZ?ecx%;i&< )h"oJ?tOOlS. ~ǯ>, {ǟ@oE_>.c–:xRQsĺNJk:[EGKz/MUj? :NZx_\>> x/vO_6?i:\Sw7 ccDhmvVkc~t5ğ@tSdCT6_WZ)baYbƽ U[5/Q(gVY"kV_i ֧Ssꮜ^IѦ\gGeaMrV&pTR+|KA~)sP՛ _x?]|mƞtu? x᷈#{j7^7lt۩u(\^1c42D4:צhzߌu O;NMo^5]i5dм3RZxWXO+w~*|![YIuJ<;'j.է*M5 j:s q]z8E %Qe<צL.=9+N,LX*SxpL_3%F5biC1QXƔ:KkVx_[|gx_>A}vCaegūNL}>5?`AbKN2/'?>oFcKo7)b x O ,O[ۏnď4V⟇_-wx'Lvw?~%yHҿgx&k|h|-Şt+ hB_?go➣oNյIxnL XǦU+qԧ){\TUZgIY'9^# R9.gsqRJ9Q,.Q,>0P9%GxI1(EU)/̏_J6f&__ 5Zů/k,"/J_Aú^("M +/^z`QD?5 }U૟OK^_Iu<&Q j<9{; &OߎOX0Zk:{n KXu73Ş(uo|EĖ,o|aOk3橩V6Wo\XҠO^xw:Q ~'Þ(n|kw_t{B^M ;~(k>_|4um+*s-;HZWO7w ῀tKR3xRfCmv :j MNXQ&oT2-,c'R agNn4 N!U)85:UiWXYҜ%q};*mFOiE_x k\𧌼4|y}ޙ-ׅ>+[G_]q'Ŷ[5 +kh`Oe rB߉<exoį񅽭ᇌ<"k>xkQ9'ajo|~>xgZQ׈.,GnWzoÿ^;~3#͉ws]qx՗*b*3.U^i^9MI-&QJ׫N*TeNRl>Y s?cOٟ⮫CY½2o?EW'7~u? ǧ> ״ Pt[h杪hZ4w7pO/#). Ëڂ6FĿĂP&> 6N~g|FG_Q}sP wY}>KM>MGGK{U:ZԎ'"z$sUhKqXS̨{_3%{¶+3*ga+KkASVN* ixXa1XJ4Rpt!1ZtF*&'+'yMkoxBռ9I_d+ZN6MG{<;ijA{;g+QKoX?iO'G]#?Gӭߠiz~\i3=|?jhO@䚘NtcNrƄ"'a1xhEEU,EJԜ]OlTuyS{Ib(b>{sbe+l×񏄏K/E!|>GG>|(gmXcmG>;⦇ok: $QK\mß+^ƝKĿ~0x_~R'}YiZ.wezv8h..;9!O@??&&Jiʤ"+g٫ᗅ<'M7H?xGtQgƏk cQ|S\е[xŚ\~.Ɖckh1hvWG"z$-#^N*U$X9e҅j`+F%iF4I.i6.9J뺋tq3Nj8D}koG(,5`_m ~#|@Ua[͡ kGV-#XtX4UjwW/?I⟊q>>׎mQ+/i.Q×C]aj~_ < a'^~oLįΥ^jno'ח72K3'[)w f ǮxoykqSq`~v u=BI-店W{{m;M4+7ƕ<\XJla0j֍0q^ F*p%Nf9ʤ,gnT^R|Ҽbqew+׭ZNS9KS~?޾6JqXxkĿه QS|q=^ !u/Cx߃.|\}՝ܞ |C{⸢Ԭt&Vt+~?޾6JqXx_¾x@WV<=o N-Bi/:iwOgiڅZYC,JȌE~Q?҃:PkP[xi{*QKNSs']ZX~(xZ|Oԇ,s.<]->uG4;lK/?^Oo|svWVt:-ĹY:Nx Ǟa}oudOuK?ÿ'7s~֚ǿڣOwx֫[M_ O.:G3Dg/ڧ_UO [<-k-?ğ3xǷPꗗ:FsS᾽EAx_G|Y_ q-c~xC'~6u<ψ>]?^5Jݴ~Y=oNJ-?{ ~x\ x'<+;x ާ#C|E'<{675: }ݍw'-i9;➍{?Ǎ7M7:O/Ɨ^hZVqKkƏsu6. Pt2xn][Fu10:pQQ}j|$*9z|)Qq,u<^udΔipuQ*/NqbyXa~aW~/4QS d~|c`BSSh5Mcុm_ Zt]o:|"G~ >m_&GP |_~ W?/ xK?:_dmsHJ^iEJ(2[;߃-<ƙg3 {N?Pk7޽F??O^xCjVPkL؏ı|>> 3ᧂ~74 uK=gG>,cM埇:h-K?zg?sFbIRk W9Sr`3ϖ2vueّGQONtjG  Y,MF. {ZUJ+:W9UQQU(QU)K{(-za4P~+Cܿd3Yi\RM>%&<3vo-kM)|?_׭|h|{㖷V1CZgľJѯa]tHl|EWԿOmI~F$6/xO&1|}-!񭷌G,"ғ?FtQ?ٟc~E/?j)<#㥿iワxY?\dkCͿ}D1%ƜM<.]NqXz9qX[Wp+)VY&YѭV8*CB3̿2ʅe psӡJ2.F3d+a*1_X*GR+y?[!~Ο ͦ?QGN3?k W~jWOGWQ#<h^!}+nM_ßռm73i^-3yei_>+$k|/ ZY5GcJY|HK~γ~ҟ8AtO߲ek_<1U9ojW^_| j>ot}+Q)biV^+IBlk+ҋUϩj`iEF=He4*_^iR9#N*0^QӡB_爭nEԧ(K,&8'̿;h|O*'&V v߳=sEki7q:r4qD>}ե\^\Y.5|??.'OO?g_ j?t>>ho F׼Fx[Vt ^ƺw^Εnjjz][Q#>;'#7_xhx6OVJ( .>'[xJy43O`V8@nkc4G7._74^7Gk߈ B5?^F Ze텤BLTЗ+O(9:XFAaB. SYz֞SʲIuңZjn<+%)akǗ:wʫtpF8NXLV.q8_ُ [U|:gH|UvK_Iw_O4O~П Q/+ƾ67zfK>5x WŔ5^o~)Ql?2տg mh _WIō;Ϋ_xN,<7;~5'kKִ_.O~Zxk BVWM~ O\xڟ|sᾆ<3-^|W{~'\ӯ&@΃ iƏxwB5:x uS]|h[G^.'?|A|yhQGxž.&?KEâح_ _5yӭA& /`y4dԳ,]jFc a^Օ5TH„1*K ϰDpQB#R58!O?j?~3zx?jo7mF9|03/߉π>3xSm/N6=SϚꟿ#8-THRXO@Ydti~-P:ό|oρ'ß:y{$־%kω)CƺOkxzV4..5|_\Te| yVjJ Y%I{W-c%AX=xx^)f}B0ѡ''SZxnaVU~F.Y%G .[ UU'RxQET((Iae\֝A^U<-gZuz[$w;y[//?)CN?e{?F|#g M㶏eמ_>'4;m!jw 6-~'q{+U{xm?F}zi> ~Ο~xQGa8>Ğֵ(B?No-5|{#e|P3RKMcE|3K=Se._ ~Ϟ9o~xKgH>yh6|h&|V/m֞$ׁ; z|Qrc,#(%xc11ź|yf.ԝ9<ZKN .#E,=<:Z,v橨TܮJ)'UTgxl/??w xºb WѮ']Y;N? j|/wnt{je$>|~Q^٩6^8; w¶:W>|S&x,'mx^IxKG Z$zeӈVTZӭR:+#Z4(W*)(M*'Oj)9^?.TܪFq%yG<8ԓ"JJU_|?񾑢>+PƧi?hچkH^gQ|u=?7MΙk[xo~ߴ _û{~|~S|d>%Uо3~/zOd+–.??V{i6:f}M~-xb4O:&^->X?Te CZCgF[ڨS[7ǙNu*'קG N1xEVSCRu-)bqt3yCJ>ҽ\~:݃P q~|Bu xX Q_?=7߈rQ|r&4/kP厣Oajkm\]'9\5|o>h_ a/i8$i|?WįW |/{*N\|b|I;oX_Uҍz Ty8G٩<֔` EUHӎ6k/R_msu|4~ ix΃io_x/ux?Ix5X?VMJыPu_9JJ\*SS-WF*QxJxWJx*T ou(3NS*8覴WֿY7߅kо<iJ_]~g>7~m?y߄c7? ˡiZ-?^yWz&i^5ai񮅩[ >#|<ͽ热tˍgY[zm֗xGQޝ]/h?VQZʼԵN0ʛsh0[Y)JST]9ӥ;J4S m:U 13RQkQW s?_DE ? +| Sρ[xMxWT x'!Ʒuia[_ZkWe_nwYZ~#gxs_m?h#ᖟ~&ѵY4>1WkkZZu|Iյm'7pѧ'J8< 8xӲi.u)Jy<58VJjy =IU^8էYS[32Ղ|0X^O4:$1_gUЭh.O|=#=|>!px߅u-[R]kV\O Mj:fWz|>!R/2W~2nMK(sqF|3 O>/~)U%|3ƻͣWVnᤒΌ1rQQyfUSqC )G/kN{HW sR ɬ=5N1Wچ JJqc:Вp,]Y1  ^¹b76~>7r4mCZ:(]t-V?N?ڵ,?e?kZsGR~_ m:|5l? 7j,N QS\|)߇B>8C&X^}F/n}KgًO.<[Kl?xZ#Ğ ht- /Ӽaı֮-+j:Z(S'W.eJH{Jp8},?;)K^sX15jը*>꒫y1a*Y8QmNo5_[[? >5a=:O~ϚXt;?"YTRQm7ˏ>jO~&x^źŏ3SuǍ>+izDk_?5/!__ f;_tS7C4f|Iڟ<5g%ƧWԭ )W$/şj+ОN*R({*j* [ ;&]p½[Յ<4*uBSRj-ZZ|k _|߲R[~JH [x?<;gYӿno٣ԼY[~ ]C|u{2]4jQ[YAݿி?/W]%.hYd%+=Uֶzٟxpkyd@-Gg֎ZҟW 3T~x'i'Քw*xGG[e{i?;@oC$[~?Ѯh?vi^5/h:ǁ|ehw78گ7FޟO^*7towogy:F#|e,ZO4~'mrᧈu}CX4on^dӯ#Y&D<;e?~|LT]N-Y<=?> GmIW^%PЭu)/-t[ojwevz?4K h𦷬x͹| Ox/|%#-v>x֐0AG`?!z3T,ʍes\,[0ZMR]RXcYE,2`a*ja|c?3xWmC=7;/k6>$ZO­/x+ßOG~'|9_6 W:=oރohSnGii^ QH<56ufi%vĿl'.=ό ]NVMcLYnRlp?SB5(a`䱘N&cR,jBSY/uxVCR̨U:nxWb)8d)҆YKWC,jy+Kǰ|G,|5:឵ Юi$Gh=5Uv]!: 6PxO7t_߄)LYkuڷŸ|)?| ~TĩWWMGM[o#(wZ76_Yb{ x7T[[CoX/>)ֵm+Ě'wl9/I%d(Nύv?Ğ"%>&@+ ZӼM?-?Bu3ƶZUX\_N4^]['<&.ˍV9y y%)ԭJRӣXyʞ'T-|3Iw~Ϛou_?DaGgq':/tSZK m{u?"]ZFV7Eqzj~"/m ]LEƏ_|V>%4GgO~ů>ľ ƭ{ T7|!j.Ku>[Zj ?h߭u(Pb1JTu2u'J*u-1p:4զC7iЫʴ0zue{FiJxFJ\q9e.ztfuiӫ7 NQ_1W|;7?]GG5wÿx4uпG3_}|>ri:?᫾Ɵ.8~#%au_ٟNQ_1W|;7?]G^i8ޛ&}?Tgc+֝/ {I=f&FmYctWBsI'7IGFq:0 7O Zjn0m'tNq^袊;(j$[ei߄_7WտI,?~˟ӿ+ʿg%,BCnW$?k~W$?k굯z#*^ (5 ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (?(|)Uoj?wVN֮fO90/G~5/?>o{|bS ) \\^5 J71_t~qqxֿ~-5g'pw#T~96Jq~bK-ߵ:ߏ7R_;SRIe֝_}8?)|WOO7yG8[. >,~_~I^ < T_pu7|Skz\FG/:Y Y=Կ3>:tO-M 6w|_&NEMVm\a.u /~2V^( ~|1ŏ?nt_Oi?V)Bgn{i#4ÓDu{⯉|w Z{^:=& Ϳ^gimgX,: /]w/q/|`DҴ?ZxN_?KœW^C^6AeݯQ?Ax/g/u(5xzO/ u (>xbòϡڂxݼS Ŷ~0湧~H~f.?GcQxE~K}-~eo[/s6_Ml1ớ蚷u{]S; kxozZ=![0kJk=6o t5n1p/eW+pժ:%p :0~QZ\#pӏ~+>iCS#,UhJ9{4Ie:x4lDЫG~73^&> /ß#_ |)COw]ƧVC&;U G[izVU9V{mcXX;ő|2M/: g-6.ᣦ]G+-n mo74MmV[/ xW%41iζ3+`b7W(:ipJ%%U8էƷPUjf"O0j*{O펁x\|a>NxG6hWյ#1妍ቼ75oℑu1{k]⶯E֛;xrxsS>:_ !|[[KHO-<9\~=lSOB4'um|^vA[[x;[FU "Z/1O6f+Vn.54<7D2IҴ={R>%Z׵R孇u-wCfVzs M7N[N\GN8N%µVfI*?ACF*ճ,ahJYӫ%|Yˇ%Y5j*שR4.V8ѝ,U/ D0u*aҎ*1(Ppx΋KQ .|A&vMO?9_z燼9\liZumH5EIXjbĞ|[='ēx{?o:F귞Ş5I%Ε[X[i!X7O&t8,cƩW^$oxw [Qnu_-MoSFqLJloj4]O% G^-?7uhzKˍ?l{+[[Er\dL7kU*ὕj`:y+TTi!QVQkaNaeYt,J;RULL%¦ :}lL[kaf¾;X|K~7xs\oĿ:g|>yğ?jxSM.,|Wi:?v6ڟ5KgE<%wig 6{]|I̲qqqKZ7R(bjbɪְ|<*ҫ*iWTJУ58MZ9f3 ج&VXe^Jttg%]GЫ^/Gý_&&0xoX|EÞd|E>Axw_O_]gĩwC4_Rj?_G!qJ5o&tO_oQ=5/> GV? WǍuC(Ҽ[x'ơuh{B_կ|= W'۬:^L6֓.Y7ljUwWo#s'(abׯGU9[re4TڱYNU'3ʰxY :%)uk -;iZ*^EWßTQE|V$.N * WIae\֝A^U<-gZu|U@ !|C_U@ !|C_7'E~P"VQ>o(|N5h {~-4ix6=SG%mxF5sIEOsӃ]RTvB%5*ҧU1Ua9Ѧu%3U*4h:Ӎ*PR^ *T(uBJӄ%]l៌tx'|)mch{x;5 j>$ _CG]y|ix~ĞUo/ÿgOĚ5?/ Y,9мc~ ?TCRѓ@sjK m<>'䛝*ju1`S|2RbcZp*R79$<9jϞ<0ե̹hІ&2jxZiK6T8U9)?诏~)Trƿ?f?,k G񗄴CÃ[oz|kQ<56KZ޻i5^x4/ xQH~|acxW5im>i~ cW}RN]?#_>x?8? '73hXҩ:0x %uV ** 5/*uN)(EԊ;N.reu(Ŧfz`Q_gcgM[~X|jb|/.:궞?ewRִMr[W7WFMvo뚗oBbS[E>"OW%ԓxd}&īsu++ދ)TS ՜eRN3[.KFb>BVEPtjSO Sԩ JpTVc^IMSs 5qӜpt|ҩE'7Wnj=~ ♵ =GQ< ?SkiM֯sxJR .}P:mՔ{>3}4=JV{m.~D?m|*g ma,Sl_4k:S"ʽ*tNRt*2*FJs)ӔUźr2*5jSUZJNZu#V:e(ƭVnQ_5xV>+5}^]Rwŏ|6|]">oU??x}OF_x[:'|15$>'Ѽ8uiEΓ5~!^+x(xC᮱#+uDmnw^-<)/7iͦ]"Ԧ%[E5' Zn_xm/k5W JZnJj3W:c=PZ*TVM)Ԗ>.H**KVph[V?gl~9>f//||E|+/ok_?j^>񯆭|+n/~P~ 4O>5VO¿ž޵w+C #EJA::U?gHІyS00TT0uZ5'6Hѭ}SE~{|5~>/U?ǿߌ_ 9{Rr|W]nIOG?+}?e->9񶇠j4Ƶ{; V /^/u 8uxާo>{ IڮX-҅gnZVΡsKӷB)ԄӥWBn-N L\H9Sb8JJfɩ4Oݜ鶕H(JpjB5)QF9t'Ÿ7EV@QEQEQEQEQEQEQEQEQE~PRn7 O!}]ͰKKra~,_tk _|߲R[k5~5/?>o{|bS ) ?}}?[g?p~Iww*?o?8u_؟$wG;~7Mg'_n~/MJOA|/? nq\@}!EWQEQEQEQEQEQEQEQEQEQE[$w;y[//?_ڷI%sZwyW$ş_h_hWÿ*S֝ }PӿhW-g ~1ּ?M'g|cw㿈c>_׊~jwkMŚ͆7,x^k6z bm;|G_xV~,t}bOzSXxi79{Ÿf^ x_#-+x|7K_K7u]oI~R "WL\:9f4VԞ*8ŘFjnu$9{yԭqt!?6ٟCc:u[o?-Z\(U|su TR/Jv"t6]oƺ,-|}j:'v>?~^(ϯ|lԛY||;[+Ǟ6s+~_>)uN<}o6qNP_XfY6oqpgN5 ]sBNcOw~ 9m?">6t#POk<.?`Zm{<~wN:o ϢEOٷ}^%~G4|jJƟ_<+>׾_gn]~35 3V>VYIt7S$PY=YRujO-pogJ^ҬkӭNb)ԧ>֥zmG3*񦢕:\QV#_ 'BUCgĺ|/<}]G=kVUΗ|Rl%gMCX>i .ZƚEл ÿxO xGK?|4>^ş|}_x_|A.;Κj&J)RNt*SJsANg<*nԱBRQ`UV tU֭RINQzJSl'Na$uFE(QRWSEod?Nnψ7~Ϻ-G +|1Sޭs/.ny[.|@ x: mCZ3ǚ45ob/k+kYknt_(gNn40%RJV EVYR&7*EYJ#:YMú>4bciFЍzMTaG_*xzj(PL5 tJ0&~ӿ~/cP>O+-<|"_^ο o~^>#:xS'|qy?G^#qVu-`?nŦw@.l#Mo֑<uIEE:5B#2ī[5˩xKdܰtiǙ%9SWle|EzTOF*N3p&3oZ<~*SSrH2 4(߲=f嵮_ߴƣ"Y7?~05ekjM'VvKWRPh/L~ >o?G_5φ_n%~+9mOc~ 궾>OZ ?G/x{:S^tE7BAQsT_Zwv/J u\kCӧ ]Yl/fWӖ]k5k9՞]0ЕIJ7^UBjxy/ooA<ix jQOSf?_FσGc0ypڏúRCsb ߆f?׎._w:5įG]9i:u!BkiJ.FT' fTګ jʥ},԰8 9e C'%TKҬU:5~,?^fx./~ SNWmOx[Uo l#V+ZӼ7~<7?xg:~']+ WV9!RPʅ++ЄD%4WȺƻOvφ|u_ G_xߍ~*_~iw~ ]f ;ǚχ3xAf[ -J-kKMsZ߇uqZxsJ8%ƃy.⸵> c]Z 4_+Fu'Y#|nkUNcc4I;Sc0rIJ79p8Υb)zxx:x-FZ32V2tmY^Sx;Ud_ -~=^6:u|g|P!|;oxc]?Okt?|-m~6mC"@D4O ,\:G5;gGח5iχb{saq |rܳh^%iq(7(96Sq +z,eu}15B)ҡNujU TەIFOkRI]On_ٗ5j>gA1)im;,|74/Ś^+կ_Z =Z^gC.~9JѼ| 5?S]ĉ4Mv?I;>>7$#ѣj9G\EJ.qjPԠR99FW ^өB-EOIRSZWM:apBi[PWRQo~|o;ឹ6f}rC5[MOhY^+ψ|9=VuDҵWӯ4KO%j/^G]6¿> x53w[> Լ[RZ, Ο|yyawK*ZʟW簌hb2nk{( $ʕ *~ZPҍ9#ʤ:j]W:\PRr'--}}h/{c>1ҴXhz?>3(i>*It_x;]h<)}j$|Gcwc~G%[ľ/O^wE%-S.xsڏ<=ZsO[ߏxdjԍYP9Ƽ==*EG Mxb*KTj2:~8ך)SxTqa,Ey^hE֨M9OQ_s>x@oįෂa'-@WÞ&^E?- ^hu>0dt m-': h>h<>8τF(Qҭ[Rnpօg6zrOjO+{a?.>/ڿ>Nc|1^ǂW;ώ|= gIy[\eh:Vmx +N^_k%|/t;_O}|Wτsx†᷇h}E׼;.hz<ڥRi,D(xz$jѭUtᔽ9NpteV:? 񨝜%GV2iT}+~~o@i;Mo~\|D%xᗎ>7߄Xu/Z_ŢSᗈdگV/y[~ Z蚏q\uQ?|4[¾sHi~ _|gφ?B.qTu;m+^ծ-|=M \R]eR:2/`qr7:hN2QJu)9F% AVsRVp"8LG:zsDFI(诉|;u+? >#i~+<E|/S@4?|I |yD6ßJ<]E 2x;r/5} ĦgI:BIѭ =hAF^:#V rJsY?*YT\*sGVV8ϛIh,k+O6("S\],7/j"g|'P5x:Fx]oPkxχ~;]dMa7࿀vޛ^_M֚u >Ox3x/Zд$^lũ<7+XCJhbq8|%ѨڧybqXzRĹ,=7ZHE7RT_XН68W88՗NVK'+}E|ɣ~?$uO~-?ź',tgzi$=2ܛTԫQRNZfiӥì^Iх:FTg&Wh9SjDߜ)ީRUaNs ^*8c:ҚU)_+j~(_߄<A3xWxNg4:Փ^3C9mxOǚg<}ZL͖\lj?m/%𿄼Oz׋d_e`^g42O|Bm#Z_O A׵ iSQZIFNLE %:j-Φ/J5XBb(N5Qu+RjSi5(:N*N aSnKJZVmڕJ>YN)QET((((?oUCm[:Z1a?PX @e5O+7ƕ~5/?>o{|bS ) ?|Zk?n|N~*ÿ*S֝ ~r>|#I/߈w׿>7x෇=|&V Rumj%>ggk^&q4[+s}qF.y.22)MBˡy>[Vg( JRvsIJ~rƒwڲqߴP䨤/_ !^k>M_;x' sOx[__<  ?iυѾ4|:?>Ԭ,i Bz-ׂ'x yb_/]_=j(YifixoK> x>Y> !xsELk'Ǘz7ll#O{bWCI!|NY+u;HK__xV?߄wS<=Be7oav6V$9PxoPF/[_^%9]9"WVxº^ugiq]*UNU!Nq5[0Ru1˩URZƪXNjB8nu*NJ6 9iF4# %8Sbk`0Օ _+ƥȭcqC)f_hچxf?u|g}k;O>ӵϋ~!񞹧YoB5\؋|!!iO 1Ѿ >oU'+.[𗃼^:-߀gDռ=~?L?n<6quzgkF\-j^S~Q'<+=gƾѼA>XEqwPO?|G6O¯|W>Ҽ9߉zO]ƚN|59o4ӵ FM |Q<y>IjvL]l^%֩,%ErXFq*Kƺ0Ì":UfNPʤoFn0?UU(YnUueEԥ9.7B x[xozĽVVծ?1|rᾼ?Ŀwi:2EcoJլ=itdquWg z}3ߋogm;B]b_#獾%juO?=SY8HVx:ڍ؛DOͮw]~_/O]KV ě xS,?h>3i x2/t~[GR^7rk05 êhOC?4mEπ~!XxWt[io5 [m~x^nG Z񯇭oOh6x{[{ tdj^p% N\*aV7 IJ)񜲌F6"[C.*^ʽVSJʧ5ɎѓRN2ԣVJ^&~!6?-uG'?F<>n5q񆙬;+[Ro>1>]GJ5jF:~ߴng|:q|WGƿ ٧oQ/8GSxv,[wW~l<9ao_xR-'XW~ h.|O}YCߊm{B|COc^ OxX/,EGKXx&#Þ"м_ Şլ5 xG|AsKL4MbCK4EseeqմIaI +GU)qj:xl%e*q}𥇯9G<)U"V) I[ 'ӯ5gn>$'/՜?j/+-eF m4vZǎ.K5 ԛ:6?7 JO٪_~߲ƯKnόZx3> }h߅G|VWgFlFC%?%_:5oW⇋< k_jw۞*o~ OywVgVv6_;:uփsuE7K_xzo"o>WcV֯tbE#iީ^*7Vuܭɉcԥ&AӎUU',>[gUg*Ӝ',]LN&5)oAbxΌ*Ɨq58uz(A7J' Xzuh`18Z?e?a4|#ƭZO?iόzOQ?ƑN|QO:|1?_ជt Iχ_>,ֵ=S+k_׬}oߵψh_hC~ߴ֥/.eƉdhHm~/jڗ«[7|џ>>6%I7V>+5}^]Rwŏ|6|]">oU??x}OF_x[:'|15$>'X(:J88)9.]%J^#^,OfP V>>g^$crڹF2:4)+bb*}o[nnΡ_h5~!{ oמ/YxvWxso~=Ҵ{u{kú3|)?|$?| OiKꟳυ?j o/z9\_A_/_ ~k:iφ~"xY[g<*|cjJU4-;O|i u|9{fp>_ M][iZξ~x&Tv'~)lu#σ>%t?|axGW{־ŏ9> ?RNW'/v~&}:=WzZ+MuBZqh D^GC։3COǨ>&? |mSƛ/=?I?Z qiZhn4}Ua}~_KmK'Ge`.ɡEݧt/IZ ڏvfu:=[m;?/ KMcZпe]IdqE~|ym឵k_x |=l|yۻwM꫉S99Tujprc)M:ty*%|q`1z2RRтTyRs5,YJjps~ʤ=:ԡR~߲w?~'h#mg~w9?IC -x\&V]OW4|c⛟S?`3_<)0&OzaJ\u¿4/k^o~xg:i&{g}σm;^ßo<@ZO~~]M=?~u߈ gfJmr R|]im"]ú炵xox2x#9xM[z.{?1S '^.ᯈwzN3ÍŚ/ĽnB64tP̣8Ul-L^rxԩ `(s,)USVtTVRENbNo5ƨBP.8xp~# |ߊ(B'ﴯO/{E'6zk"C'ī/෎x|MZx{\mlo_߲ߏ>|G; ]<#u/-lj_t&Y;O @mw~ ߊ.%SZ ,XԴ_~?#Og~!Z^?oXEM_ x7T:ohg -ͬi~'ռ]-'jz_A>+j? iF:%WJ?i ]O'~?ŭK#Ƌ7">W_ ᖡ/ĚƟ_?<}8|3{;n,k:-uᏄy>'gukd YP2*IU(c?rL Tjv*BYNTo4jY27Ni^(0{UV%z.#B8Xu9Sq3Oeg/<*ǺN8O+O (i g?x=ֹ?}/M7 iOß $tO[^yOTѼGw_w~h^0x_=_C𿆼]᧋?+_ xu/i^'^e,lu#quVZm\w7LIxOfA ?u߇:~#]ZYx3j|\Z2h|? I|CmR]eh/c3,2sI}cOU :V5ץSVUJLF1+P(R`%҄te͸ӧx*8iˣN]xs7v:־>_Dk֬t s1}S S+}?i~rkm/>#G ,>*x¾>*.t&/_uoxf|t>)!PWoZ-Ish1>~ď <]KU>3|?xEq\4#~~j5.kwt][:׀n-I5ٿ 5{MWA~!hx?/7~!|:^?7ڮ_%g-쵝TmW/Xo.sFB]F&'x%iap8'YTbiw,VwNMoLlq^ VԡO v7N)5TKV5p*I|K=_!a>O> {"s|||E?5 M_M?A>IQ|G{7[ş |B3omS[j|]_/ Vmk6<31Ao}YkޢlR|7m3ľ,7|ui~O;nZ wDžY\h?ϊ|'ýuFh:Ҫ֡_䧃yJm:Qcg^WN8|v#+ɱ(]:u̗S Oܞ/- ,YP:nS_ɱYtUiV8Ua D]o3⮭0|=B,^(^]rTHgzZ߉nD:OҧNҭzzqF֝jS*RjSZg(iݛ/vb*rqR\UmYΝHxI"(((Cm[:Z)?oUuL/ŋnߍ ϛ^TCko8i_W_c+?ி?/WWů&CV qҧ&OZU_I/~ӿ~6IpW꿱?KI%ڏZw~QVRc8]'Ɯ_HQE~QEQEQEQEQEQEQEQEQEQE|V$.N * WIae\֝A^U<-gZu|U@ !|C_zy |n~>? ~;|5?.|a)[ğM_x~9MwB΃'1Qះ^85_xzHl[ot%8Ն# NSoX|Ve g,&+i*%EՁrTʣ+ȩ.Uʨ9I * ~$|_|K/g_߅K?|G=+uNžUl~ӿi'E/|iw3εTm߃|E'X%tR=½#Ş"?YM}G>o=[7|cR_9x;Hwj>-f _17t3S xJ<Ki&kFNFt LxiSxa'%V X:&3.X%W FI:tj^JjBp}kRz9iƃe\%\-4U+R%\,7? b/x_ M?Qk\JvY~&_ >!Zc9w_|ERmƥ7tx~ >:w@K7O/=@xXnjtem6>"h>6_ usPaV5> [$ϯxZտRˤxG>9j ?l1|&]ύo -'_X^7_|;? xK%TQ_#KԯoxGZYmgK>Hm~/jڗ«[7|џ>>6%I5UqQelE,\FTlfeѣ|NJ.=I<]_iĪ53 JReisqjѨqWgJn5E<4Oy<,fğj(/M2l=~jWh?Y:-:5?9O?:U4o_k~5xK a_|a\0Q6xn}U,MK5 UaRJylAޮ&L)WŹi_*˲ʲE&~ο 4^G~X|, ߋ~П|+|GA|C^IԴgR߄mkKO>,aOoxPį~+玼}xetxmSG>ZƧ ui|8e=ƕ%֗KimxݏxQ%xXtU6#BA:梶.[CV1Uqo*rה*Q_~RSVTTRT8tOkU>x GAԂq*إ^}Tp~&Tps Tg/~3g cǟ3|Q#K&gm^-]o}|I|'[|Ik)Ewh65omͬ|/gA/mX𵧌ntxk^}kF,ukin 8yxv:ߍ 4k?'xS ' ^gHŸ |3_~(xsᭇm,|{a4YENXX|"-u?-~H>;/?Sӯt)Qÿy4Z=T9xjk*Ia]l$\}'(JRG/cʜUMqXuLXj|g:-^\0*/KIi t{è|_x?ᯃ-|n|[yx5xW5#¾8#ϻ yeDUn>ƾe>*{S ߆мAkQ~]GEt[Ok>L'#Ao⯆>]c+t f//4_:Yl>$Ck5]JI^bigOQ5yBDɛ,$:uq4iUӭVY~/K~iAsR^>2'*S S´x ?~ýGEη|#/ h?mgUeo+F=x|'[T ÚvbGś\5XF?`ƽ4~ O.) ~5ſ>ิ h_5M >$u}^\/~|Qx'[>f¯6?iu'g= ǚ 񯈯lxcxᇇc%ai,缶1=ҩδjz*QNZax^8p({*L=m^.J8v~Wx+g;⟌ _?~j>9ƥXuIOh^'OT?c^)Qi n50~%xu x[\/P;1C|~2t_g_RE_x 5MW#EuCž#9{g%mcC<ʵj~)}jXEjJ֫[½JեR*Q|L+Z-'SV**ӌgBX*8FR*xETcV#?s?1Z^hghýwZo>úΛ|B-|AxF|X< X\|l"@şkUR^? coznku@æ̺_{xCÒCl-e%x]t5P?mR~xž R#LׂϊZ=|T#Tц⿈ӿMK|m.r]CEng/Fh ^ aoxɼs~6j4;W+^/Ӥ|U:4XzjXjyr(^m6N^{o]I{x¶-T7OC94|%k|Ig5?^kD[+-ħK<[/ Js~?0|lx<XOËvkğ t׼qNg3xBYt_;V#Yh5q(XGV[FRS F}Jqs 1X֓PRU(+KqN5k5i=xJYn.G2IEЬ?3o/7+xr>/~?7|G[/?5ᯃaWXeρoƿo ޓO?:f[ᇈm!xCxSmM|} l? oum#5]W6 _\v?Wx +N^_k%|/t;_O}|Wτsx†᷇h}E׼;.hz<ڧx%|;槫xwLk~/x'+ q%?|Géxƚ֧}*-Ÿ E$|'gT*y}HTxb:tYf9^XdN?[Wu!RLU,e|Lg[6SIUy)RI(S0XO2,!j+nQQUNFP._g Bڟ|{koدc j ??gώWZ.4 ?S?.o_Iٯ<; si_SB֠oo>wG" >$|.owoZ,x> G~*|lg֧ C}E[~ Z蚏q\uQ?|4[¾sHi~ _|gφ?B.qTu;m+^ծ-|=M#_h1i9|_Vxid>WMRֵK_ |/6} F^5"\žcVIX~q*kpT궒8֥Xz(Wi͹Uw7ר*h~ &Ϊ})BW5EZ23 _?ozNJO^ [>>+U?Yxo; iSWxS=⅗yY?kSm?_7'X@8iٛľ:Ӿ=|nx\sEρ0oͺdzGf~/.]ˮX~ڿ<":||G]gYn =gIҼ%y:ߋ=}-DmtωMź|[|hេa%\V/xOwkk]Rh<7Kc8 !Ya.QriTbR3[V?{C_qu.gJwuq>KJo𪔦fEjU/jBjziS/>4[lj~ ~zmkß 4]xVk0#JG<_!x?i~k[@ ?hY>4kq;Wּ#zFHޣwfu K훏|y1oIK^}v/|+xš<M'kψ'xQ"/^! ]~V.~?>xċO>#~qwΟľ3~xŞ CֿYo >qxoty;[ CK<9ZQJJnW KVwUp}bS9VRЩi=(ӡ|q"˔)^t% 8l U: =0Tğ.f~_-3k5|[m_2I`4Eѿl wLҼAK1z1>ӬuDo2Úl9mm^P.8'#R3xjs)E<]\_KSYJISap:Uƥ 4pRJtS]\wK T+8Uuq 3ޭc$?kw?W|T>~MմW?ŏ +{ No>1j|*lM WGx?ɤλEw,cw#M-S:tKOn#Y𞫥G,4OLmOټ=Wu>&o*OiL&Zx ~мyxC>"խ Luo]i u˝;.g Tpu?040qnm:aV&E֝*8:jJIέlMYM_\RS¨uZUqXiIi^l^iTT)h†8/(Ii~/%xCּ['+~ |m>xwᗂ|suo*(2x_ݮkOТR\_$kV|>U֟کKCF<];YNXRz5zu`{֡ERQECH`?|'_kW>ۿ uvc6/.ɅSM>;~1~jW_HomgW+*k _|߲R[~J dݟ?S {e' _e/$[j?iߋv?o?8u_؟$wG;~(p;)|V}.GcMQcN/ˈ(Q?R ( ( ( ( ( ( ( ( ( (>oXn?~W~?K|Yeև^V$.N * >*w ?_JӾ! '^1]|? [x> %{Vi㟂 |B֢!^S~)C6OӼ9gǟ!!F] ];In#_? <4 |xMu<3j{X}cR"eï͜ |rS_>!x%t=Bwc?/xºIuBz5gzK SեaSRJF?ils2Ju a8p 5Y*NѭU%VR)ƍZ~ Mox^*е_]U5ZO?~SX| ;W~iFmZBgGD-2M=t]/ ~Sᮙ'j 3Ŗ.X^? |:| ͦo7V4ސ5cR3CPRɷJx:F>D*s k((΍IӖ9QPr|*֚,V˳7w'ShKZV)?{_d?b&W3xcuQ_E ~JmۿOoe߅ldR>;x/6Im_[Pҵ&>T?:> | ߈Gs y\b*'^W|EJj58՝z:)rUV(Ԅju)9BZU)N+ste+sB 8J2E F^wEn??;&ϭM׵? |6m/iVq|!i<5c8񏁼MCAiWiasBJ<+Vռ)Q̟߳o_zG~7е/.5ڣŞ(" :OMG2tt@d|3]\|?Ht~QYNs4N>TQ0459NSRJUZ~Ҥ9JJj>ӟ-J&eF0SNHERTqxeOtiS?=_`RO]G h7|AM)m$q?xźV(sxv j1kZ4> x#:ǃdߴ?רkI/| EKOoj?c啇y=oGfS#k~?;?=ҧw~n~!^eƗ]ɩEEg*'Bn,U(N*-bmY%8K R\єUKIIr0O=,"1`x3n$/?i~m–_ rOdž;Kg|mA^~2g jG5Z~95k#K|-ƿo?Ou?J2ThS7Edn|*;SW,UN2ҧW:9' R3|)?|$?| OiKꟳυ?j o/z9\_A_/_ ~k:iφ~"xYG:S X[x 2]j<1=n|?GoK_~)Z:Z@-ay+믉^xӧ ඩ_M{x^$YҴ-4O>F?~_ٷŞ:f}:nj$xSš?'4U]sDZu>wx;Pm_TӡmVon|sO+ڹXq)X)SeX74W9VqjT_ SR ӣKN,4mSY̰krϳKsHΔ1_XDt?`3_<)0&OzaJ\u¿4/k^o~xg:i&{g}σm;^ßo<@ZO뿳}7?>I;+oK|I3> ^m!Zȿ *K-㹼i:2-ījw<-+G^~W[]F ib &gQTX,,-:ta9?}E8 A,.; tlc)Sc1ԝ,~*)[[ï~!kDŽnmK.3i|{]Sh-/W_ĺxk\y0ߵGox[.||x>g -ͬi~'ռ]-'jz_A>+j? iF:%EC݊ Jz^Wc%MIԔc'VGSjl\=jU{I,MjR^~z*{igx^楥xEeu(>(|f7xW?~=uͪ|/__tCOn9 nψ#zn M5$EeԧG ' eeMLTiR,SF4%JbHU:X,x8^%N8x`XÙߟVoj_OZVGA7xCmU+? |cWwk.o4s{sh<M;O~gF&x[ϊz8kjqTWXk_ҟ /|}5V:GV~9?w)|>|Q4?@ƹ5ãT~nu1ZY*U^EZyPp]VMABU)Ƣ:!lqѫ )Pa(J5! a΂ F/*Xf^ &MY6|8d Ut]+ e /Ï^*OGÞ0eޱM]ojlQYR:/Y7[ ehSڥ2$VYJeR0-]Vu*h:kNrrNQ%'N8Ģ)QE~PRn7 O!}]ͰKKra~,_tk _|߲R[~JJ71_uqqxҿ~-5g';c;+,S {e' _e/$[j?iߋv?o?8u_'ߋZ_k>w7kvh=YIh_iW:W>|K_u=3^awWzVe{j[^F Q$iGӃO/3cMQcN/ˈuBDڛҿ\S#uBDڛҿ\SW jostJ:s"Mn=i__.|O +Ϗ79+?~й?7G4ï>?'uBDڛҿ\SW jostJ:s"Mn=i__.|O +Ϗ79+?~й?7G4ï>?'uBDڛҿ\SW jostJ:s"Mn3j$[ei߄_7T-hxG>w^5e][n|+[i^~"?xᆉ#O<;jGmg Lq?7P_OZw5u_OZw5uZ=oSKQTQYQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@>ۿ u|SH`?|'_kWf3l'_au?#71_uqqxҿүƿg/W]!\^4_Mp'aCGɽl֯Kă_|2F>)xG1x.m;ğ=x~PхɧE4S}{; {e' _e/$[j?iߋWznJoQwp "8ge8/Ux5/ܕN/~%Wiz%.KٴWZ8au}u侜M5hi ̖c&bTu>?GgO[мCĺoCiia Yt%,>0x^ GG <{;/%?O|4˭[HB#˪ZExS_|)tsjwZoz~0W|51 ?Xk'|=xTm=CIӮ5k6xto]6[.g4Dk߄4=9.>o?u;߂xCOO/=_ŗ?񿀭>$|8LJ ?[I57YΧ"9ӥcF11х9^ugZ N28l%EeB1JvM5zӕX᧔6ßx%Yn5 U堰SWAw4|-.=COio"Oxͧ CⶅesZ>xKvfזմYZ+??<[i?_ Z?m/hv> ҡaصu; WRIí!&|UV|??쿥h~1Ƙgы_ CX~M?OŞtx[זXwͶ)/?nuQ5KB_ ޓῊ=K,ut:XFPjACwi*j7$(՜ҪJ5,i18U*kaBgV*xta]RHc+^窜rV}K3iM<Mff x,*lE<()a=D劧CjqY^1gkӫjj~)~'!k)Oا~6k>x3➝|Uԥ_hIO?E->'jzPi:ŝ4૾ό/+SƯ<[;um?×!mď#-'\xmC#úORG?jog5~ҟ|+xV ռGއx|0K;[]~Wx*[<%-z='||I hia&.Ǫ_Zc).hZzj:`w孥+ҍ '`x[uW`XY&g)SVM_[/G8.Q}a І,59C00*NUdyju]Ҭ*JkGv|pGZ{4^M f)  px>+q&7SaXuO?j%??Y|JӾ |I c·:>ð|J<i6u-;) j!!k9/'|rgڛÚ&?_~|O'W񇂯/1? i/l_P^躭%c{˥jEs'QipGʲW,5.*9-qu+c*QK2ѫ8ppC0نΕ.i^\=b%gZQe14# N~Rt"xٛWWOOxźF}sE5MO2p?vYk^.<>n^<7ݮdxo𥎣cekVYޡ\jneLZv[x6-_IM[O4G*?RaIGbVum"V~^c ƾ$m}:۟| W%$iZ=bhc?p51jt|WJ\7^"hRrCM y\ƌbs>& Ҝ^,kW \ʦIG U\F89:%ɉu?/mOjZ?f[=Bᾓ_ \YmwX>m >in3č]NյM_zW|Yо*kV)AN]>W]tk? ,\ῄ[3𭥗4to/yuo<,<{}-߳5>;gVuKσ>!xug\E_x&|1}/3Ciwk蟴W]9ῂZt_!>'x'UkzOZ[:--nnCa⻍&EmJ+h⑗|VGĘJ<>O d(9OTjT -u7g;\5狯Zk?=RMSGFд xBԥ7|?x4}7U/t=V __q/3? qǚ\4W B.~:t>#𖩫_XI"%^5ū,CjW>~__r}7W~6)Pj;~|1<3sjm:+CDZ/U<5]xBgXx>/ 8UjSf%WRtja%C5bs*3*MԧU e%GVV7j+~>zs(š4cN Y{N|YKo_ gOR7lve>|,'ϋ*J\OjzdzKۭ3K Rě/Ļ |F .)<s_^_ۏ Լ?Qu}'Q{v4 f(a<+x?V?K|Yeև^=is{9rӇ<iB*'nnײ:_ii˒j<&'zt|VJ՟|;¯%?Hi~";¯%?HiuM.|?|_|=>*k爯,-<'Ddτ⿊Mot'o1u/F|c^% TIk[gc^4T*<-8:(εGjt(BSR*x|-SKJX^j'RQ:Μ%RF8ҥ*JB'^NZ4)ԭ8B_U_0Nyo}Gž :fǺ׈<=~,!xo_ YƫcO0?x%GƚIu[~6~;|$o񏋮u-4 x>!̶sɩ.IҦ'S >W[ ,%(ۚ&5 R*(pSMÖC KZ\˖ bh*1jJXMӒN^O/.kjC/ƻxK@D? <85>>~&u^>oj>4ev]MK?=|@ ku~g:׀>%xcXmF/xZ|k!Ltυ2ex[9گ- FQ,3CEіsNԿ$B5tyNhp9R:ikuP:ETQ/W|6ϋ^ $-+Ş W to|= ^iڵ hz֖ƙ}w?we/_ ^W.Jw5 1ᇀs /#W,l`i_c}:,u* {G\UkP!bPRΜbZt]HS*iQk7RZii~|>|4վ:uƯ߶'/iSZߧ|5-kN>yߋz%}x;\to$_MghPK|1 x-|,f/>Z<s$]x+R]I&Ahi0}/:YJ7^ҲR5KU:PY[Z*T:]2a6xď|<_C+Mkv {f; o&ׇ_9i2FجE:Tù;/oOV ѿYƜ)+J>~_ypؼfvW~ζSog:XjRj PQ^ soGY8Ӓ\ʵ\%J6Ta%8r&_FbOJ*|}GE|ǥ~5¶>(hkw^1մ i_n~[}SWi:7o3!𬋬>+g/iGž,k>&_&x^>j~~!B~|9yiZ瀵_v>67_MHIщO>NGN3y%W J\up)ig<"oGSN syB\ӔpLw('JIUNY+UQ_!i_쥭[N,G~x㖫 6o Q{|b|%uI#mt]AI}4=JV{m.~D?m|*g ma,Sl_4_rOw,lE|#卯+b،3zJc<Ѳ2唧Ҝ(aS{9C bghbTҔܢ|#} :<]%?h |&έᅃc oC?oWx#߉S^}"o~Vo.x>9xAԾwUQm{J%: }^ NB: *]}7_moD3zT5omf { jxkNu B uԣtԝJpD'91rI̓Ɯ5}GG[k'Tj~QE!Q@Q@Q@Q@Q@Q@Q@>ۿ u|SH`?|'_kWf3l'_au?#71_uqqxҿүƿg/W]!\^4_Mp'aCGɽl֯bK-ߵ;?ߟ7R?:ORIe֝_}8?)|WOS7yG8[. =s?oci\_9KW~=ҿ+ ^%8?6s|a |-e?oG6wbdg6W'e&۴j|9m8ߴou> |)n4~Dt۩V[bO#kZb{㶼.Muk >{⵳纻i(bGGTRG߳_!Cㅷ__ﵭ6Vӯ ӵxKmm?MTnum)ot襸{dHOf|Ee\? _,f3JJX/jSSe(ӡ9Яxr:߳~v; q8cRtq* \%FJ/ )xfRcRUIޤTd_'? <#my__/Dӯw^]+GѾ xJt[jzV6:uۛ bt'_~ x 4ߊ#LuO>/:Q~j V*|T|7/u~1,h )#ŵߎ<8fI *ժc*e<,ҕYN2*# Csźٍ TX*rUx̾+ܪpjPC? y,W W騸xaʲtSU) G^4|q'm?1|վ>m[ƾ!cuo Þ)?~ k?}q?t ? ? i v|Q>z?Lؓ߳?>+oڋo_ڟṎ^i>_ ;u`gWkcMiGȻֵ_هZ5ߊf/?O-|oECE}>"SyVw g:OtkĚg||pG/oIoxO ::v_Ӭu}#S5{[K!uV;m5wcB)TKRMƥ,:KeU*ɿk6JJ9%<&jżo%ZVibs(c%NҤ2:x ;ᰕׯƣtiü H]*~>ּ1{Wŷ%3,x_i.k_/l|Gc"-Hƃ߲+_$b/>&w5-|h?_OD𦭭#|C Yg|OӤq_Lӯ!h/mu+is'[}?W/&,V:xb֤Zi>ܷFXZܥ-nFaἏ U3V[cU[K1Ἶv1:xJ9▽ž^<7ֹs㟆Ч~Ŏߤ3ҠEŚlj< '°M~o~0C+ORϏl> i<-?࿶~SVCӾ*j` Ѿ"jog5~ҟ|+xV ռGއx|0K;[]~Wx*[<%-z='||I hia&.Ǫ_Zc).hZzj:`w孥uK-,䙷:Ux>>qҎWA/~_eyguP\"ɪ`p ^Qey-lw)J'Kj1ѭ O'=_aar?>Oq|NW^|HU> kkq+·þ- t__d@~x#Ğ1 Owj3O^.ߵpVҮ'˯/5|/Kֿ%g.nw |I~3|8<o k<=CĖִ />4FN|U"k52w=fz{ɴw 5 yy|isIEΏwG6}j|l:}&gT3'ks\:ӍX|!iN خ7*˥1wI4_c'>:뚷ū"𾿪M?|uswe/?a|~iJOY ~y~ͦ< եԵ|k࿉~3|I5}>[mumH^.~+|.|ODžn:O_|_cϊ~|_ؾ)x^%CSu[9KyJ5FO#FISRG0:ҩUƽ%jao^׾.IOĺM/gx39<5W^ {chM&Þ>%y_/]y 7W~ZooO_g"~>/žދ_>5K_š|,gNaIGbVum"V~^c ƾ$m}:۟| W%$iZ=C8Zدxgp4*>Sᚸ^ O2&{Y~3C J3, ,> NUS.bk,)VSV"')ԧX|0 Ӈ)<,jԬBس1|[v/ω~ͩW>Kgk\&T.w6}g;'o-xWσ>Pb|9i.c_>:~^+<1 {&>xt޵|Bm|=~%ռ=,?7eώ9|U|_Ý>ŏu^Y:/xW7* _|?7; s6]'>C|u9o?tO t?ZDŽm^?VK[xImR8e\6㳌5|fd\IS!(`aVkR'̸'S mIW=;<'n.tqXFb JTUy8RycIʫ83(+7:5YS*Rx_Fž;3/t'oOvI~ir|L/|e>_ڼֺ>]־}wuf|_㦃,? qTipx_<3 szo:t>#𖩫_XI"%^5ū,3ϸ es5qY/LOOܿ$e|7J0d*ХN%N?#KU1}gNZ:*V?hm5|ם|M~!|=þ5?> _;>3?_a|nd'~ c|7W?K|Yeև_ gepKJtGڭTԫSiNZkF^2NUUTTzT p>U_OZw5ƯCN4xs_|1wZ47|ߎ"뱏^)uxn^6k6 LJM{gÿ*S֝ ~V8tb&SUN%bRnFnޕ^ZXa5FɉB=' <9ΜG )ʝj~ʶq?j*ZUqjTkԌ7GşN>j |Q|)u1׾&Zͣckz5|Nூ>!$ Uߋ5X⽞7$_CM3|fa^#٧W?qx/ |e;|5l? 8k,> RW[|)߇C>8HUF)ή#Y:է:'1fZ۝I,w:^qbpu+O.S,YB 0vUԧa2| ]bͽcg>wVO/ ~֗? ~Ժn|CҠ];爼{ |7}W[&_h]߱׊>35&t}+dVJ獾߲ϊdӵx3E ;xKv_ 6 y}5] DW NJ 9֛E~=>kDӎ3·s跾.GxSmk௅׉t߅u~*cw:O Ol|xWG>8xoMCLmE(URi(sMTOVrZ\ƥYҗS(>X u)r^FQʼiN7iէ% jЫP~t.3_ OxWQ|{ZկUs5~? koP-+O|_H#Km3Dsut.=lzEƃ/v2gŭg_ ?dWegëxF^K|F{tҊTӝ(ʔR*s\S8[,e,ЬT+TX,iUq5TRSe^mR8ӫI*yxQQJh1Ԣ13y8xreig {o7/<%[6?xo~&/v_ +JEKA)]C<6 R%,v"xUmMEWpԡ)Z7IC5*5x_Ưjσg w>Y>xoR?5M >)hӵ?=Ua [o_7uٯ<mO?lx?[ռCx< MWĚ>/ xbNxwL|c=no'O+ի)VRs:)xejЩ§)F+\*YЭWS Vکdrj2'#ke N.QVTj ΍:* jx7g~iWdO?_|м[U?xS>$vz(ZfokAԡ5,?>?uˡxOۿi7v?kwǕ|=`q]Iu^k¶ojZgY:ʪOM^Xr>1EF ZUg̥ˊJ/gR52zT`ڥ8zmBhBmjtu],uXW]C(5S:!Go/)O4hYW2w?-x3|9) /¿˭Zmmo4g5wm> |I<i  xOfgAk횷xFO\557@wޔVqu99*ʮѷG3p~:o~c ֓Ox~1մ(ӿe?7ĸ4G5L_gǖ/?<=Rğ'xᦏ=!ᯉm{AiYt2jqQ<5lO5ZRLUY:ֆ49Vpr(e<<_fXDO^8VXz4kFס_~+|%pOZ~Ҟ?犼'j97x{E'n¶.jz"O>^ty(/3-⎩]5#{^ :/O_l*|}>$i7^">$Zx%|/|A W7ß ~#6NT)i.lZiJ+ pKO jn:u1~7;N <0eZ"qqBڴNWQRIRZ a]aFET(((((((?oUCm[:Z1a?PX @e5O+7ƕ~5/?>o{|bS ) ?|Zk?nz&M\ҵyZoSOwzmޣXi_^O=FO<ΑC<:>fi-],Wg}iڶy7^koilwmul˫iK{E-6Es"B}3,,ձl5:9c1*RR{UZg7[.xF ΅|;CQԦ\ =ZThW*2QxiMS{5*#N"%̸>kk7~7h&}Z>cVZxSoⱱӬ-ݘPFY>ZK_.x/[IVog#|Syy?eS_ih^g>^*u~]|9{^_Gߌ>' |*~#xO7Zj$,[mOPtZM:WMK8# ?/#We8o+G_O-q7MFMiVSG)Tc)9f.RuUqxb۞-h`F mSe^TP:(TbըbMEƛ UZ\6>N8j8?WχFj_ٗ~"|[@> hk>!Dž5MgAxG<O^E_-vtJXFt5wco5,z_k4/h>!U1XeQKBQsxu8F:'Vx(>]*~>ּ1{Wŷ%3,x_i.k_/l|Gc"-Hƃ߲+_$b/>&w5-|h?_OD𦭭#|C Yg|OӤq_Lӯ!h/mu+is'[}?W/&,V:xb֤Zi>ܷFXZܥ-n/FaἏ U3V[cU[K1Ἶv1:xJ9U֡:*?3o f8Gx|_?5|U>AOKZ x;z'ߋZώ~xBDW:~~㦧Jk$/ğ 6OٿY[?eKo>=1LWAO[[ NXx#x+F#eiּ]J|kZx3V?z뿅.musY^Etn𔶗1맼O~!V'_|/uߏ"x V}kixĺiW:}]·זKc},^ξof@W \C9χ8jXZ\?J9]S/p~2y"!摞o)ןC IrXs&Ɯ){UFQ䵱X+l,= F*J ɫ>x— ?h_~ֶ/koX}[J/.[xT|YOO/뾻Zʾ+x|;źߊ)']H/ao$u[{Z,KvXu:]WP4{߉gJ_&Ӿi(x#7<-me&\k:<[hqMڮqOY\Px3[-rr3N7aY:x,/b3.Y|y׎ eaE#cR\glޮg K9jVJt'xT14~h~ ~ ɮ|| 3ƾ W'T~ ~̞{j ^xe7||;oi_ZȾ >/EMUxKC? )?k?gǾ//+cƍ+6,x7VRק%Y'doG/uյ"UxVfOm>0k֑>VKiQO_xVTM . Yx<}Ꮗ>)cMb? x: OEl/{]+Pm+>+, >"ʸR/ɲ fX|xx_<渜mWƩ[SlIwhw<:[մBxi[IuyOx*ᶁsn|Eo%_GOƾxZ4?C|Uak>LoY kb=3=%6>>xK\>4oc|I- os\xmReo4&_> |+mCI~|=楥8u|ExDŽ5xKÿ|8}o k_zׁM O鷞9V԰߳5>;gVuKσ>!xug\E_x&|1}/3Ciwk蟴W]9ῂZt_!>'x'UkzOZ[:--nnCa⻍&EmJ+h⑗65^/@v-dm ßti&0ۆk-_Wۣ6^/_|b-SeO~8/ ϩ>3ǨZ}a$x0+g.͓b ,<9YdXlV#/X|&[BNj4j)•*4(rRJyb buc^ugRuU%R^SRO]i(_ ߰5{?$ş_h_h/my[//?Z/?XOW$?k~W$?kO 'O;4<;yg>"Smz1;KѓQMyg}{ǚVw֭3X+^},?}#<]ͼ5̓%;%p*1: 8<41^qO.r^*x|.OR*_<1ֆS͖KC>*a,FJt!µ J*х)TjqOE-?jm/qG!F%זMѣ14iOq,aa51̛˨GS5E:~DB#J5NSMֆZxO?4pxPHVx2BP/h-iO7)A.Wv6Z yu˝ Q-幛³Sm_k4cĚօSZt6?>VCM]m& kuռ+b<1{>Iyrw[,*\uEI? /q8a^ʍIUx$^&孺I, aK _ĺУV:u*Sg+_'(&xG4_ )~0x5;7>#hVVZ -xuKHu;[d[~(ww oֿo_/kڗ.>0]|, f3xz[D^#S˞6ٗ 1x\V'0 i伹0UjVKFaWzV F"1JRhIW=^gJ3Qo %3_̈́y-uz -t^|A> ֗_O=lj|KmWQծCBБaMSUis+;"iZa -Sɯnt-_ʳL [X?bo5?Ld/ݯ4mPZgkDZuj6?E}#@8'6#; 7_f}ǵWoĿ'~GFÜ|CO<!rυAul-h&n]LZ\&q\L$vO?M4[][~A_/:MƝ/?|8_u7ÝsJ<[lImkYYLWsCwo}|pv_+juvzjMݵճ.-Oủ ψ3V`IKUjqs tlet':\=GRoarN; t0jN%Q^kE5OԪTjS;Ԋ2kggm4 kEݣu˥h7iZnk}-OUNsvaAWΚydk//|wo&Z?$~ɟOX>*/MOǎo?u;߂xCOO/=_ŗ?񿀭>$|8LJ ?[I57ZL}TS嘺R9ISUasnx[1*cKNJ/{S BXjgR3V5o 6VNjup86~?j_ 4|gh/ֹ_?|VQzư:O|Ak4zL~#YŚW??Lؓ߳?>+oڋo_ڟṎ^i>_ ;u`gWkcMiGȻ_Z|Y|WO--k3Ql*7Ҿijw:ΏeN|w(~3OG<V{?t5KB_ ޓῊ=K,ut:XFPjACwi*j7$ʒRquO'e:?ҫJ<מ'a)aVu0.rZUUbq5UX¦*# ҜU*V:qtܥSVzhաC V.J~ʟ3u`~m~*~ZF}Z-o>-o*şHE?m=J|'>4?kؿKO]lk_<7O/)xS<)k:Y_.9xW?tt &7śm/wJ\Oɾ %?Ř$rn7-ф:Vw)K{"Cþ;c8o#gUib Ʈ'VRxo/f)8^&RaOs(|1_[/ Cោ0τ.D|G𧃼~> \ᧇ)Eqc'<~:j >|fOIjJST_ xpx/ퟴ>!X7o?ڻ[vkߴ 6է5ocw._-?1_w5^:JO Kis{(ODGj~,E'ZXI'?hֺf|Ki}c5+y}ykind7og|.%|&m~ 9lsu27 xo*'b*biy0*<,j,i—Tje^K[oڌpkB{j|!kvX|Aeⶏc~"__$m5$>'xJǀ2; W'~D?d߅^'ey욺'S׋)ykb&5մ kw2źMwş; 뿵{ⷉiÿ []Ÿuߌ4/}OxP%ľ1n7QӭxoH5 sLF~gkm;?⇂<Bm6{Zx\n4|V/eS6+:qʲOhgMx_q^"8F5)̾lFqpĺ^Ӗl,$WBxhYCG>ڷ a$[i n|c>%jJYuEmKyۏir5qƾO9~MVKZ?'+Ws⟆46/^׉|Cx/P]VxGeҵ FѢEͲ$bq,YKúsS-G1VKQTԮQ#N4UqIF|׀~*S.?~xsKY9 ?FO x?9~׃-)XO|[n>I4ω^g࿄ýG{m~|"ߵ#|!>"[@xC-q7O|wυfW_ /ӿ~|iO΁R|3|y+і j=VOvhséXջ][D'ğWd!>hgN?_U t*k_Ar̳ _3>fpҫ9u|> KχST˰ؚJUU;Ju)Ɩ.34O +9P~/x3,~_|-~K23_jc焼/UO>!Ē06W5lj, ]ͦ_YxvI[oo^Ax"?d؇jZ_Ë'XOW_ xC^7; Ï6] ;\ qvE~Ͼ%'ß~k%xEwu]yWOլu<xb6+n[{yԢ)}Ŀ1y?5͸" _YTqx9*XUԣs.CRUf0mO ۋV&*ѠXR^N^xXr ΍|T +O o|q>(k> }Sn3_\oFм9GIoxkMf,5}?j1|">>%O/~6Z\4W B)̍s;kk}'Z)CNC~9|mߋ > Kg$;ߊS[оk {[k}sNmC/dPx-4S_SaGKZY|gV[Z\ ǬN)қļ6+t*qjM'2~[zo#S_k6o'?Vs?m6/3JFւR]BM_I~͞5Ga:4SVZ|,ؾAV4 ]F*.U:Rh BTie=qdԾ,Tʿ(Q^-8΄\:N*xV=wC&|^gBO<|'OxFw|/C |i xs@W&o5. )x~u kZ͇uXxtHgMև" ^=@i^xV+Y|A{B> [Ś U'mry>[Ge0}l0CeqX|'f;,v;(/u8KN7e:ڳ˲WU Y44ҩtjҧWZT15cG*ͳ 6+,Ng u?|վR`vZ5ϊeh5:CV?j^%ևf>?xSk|Ck x_j٣H~ҺNPvOw_E‘&TЖfM5jWqAYo_}ý;J}';wžÏqWğ[]R_7 m/۽4iڞn4x,mg_:gމkc2]&G_ǚυ{/5MwAk ;Pv\^c~.93<)Gc1u%̰rSpU2|]`aqn4u%grLΤeXtb7ǜ_* %4'q6'<.8))ԛ1XZc_ \ o$SſKd>7&G=?Vh:i XmĶLJU5_ &M۫_ isxq[MBtm}PSjZ4.ot뚮}ooÝK/du=r⻿OqB ŷ&Hg#ėA_t/+Z%3iO|(}#gäƋa⏋ hZj^.~.7G)2;e40oY cs–" ֫ 'ڴ-X,kK\ lUԫܤ6g3|m:DY5{s7Í#ź5dž9 x2V\x^ƾu{&{'&񝅦_|J?_"-CMBc[YWm^VѴ ͨZ]ߟ꿷'i][|UBh¿~6M|C 5 ]^2(`Jq=lnk2vE~?|7Whe7}7H*w =߈<1Þ=s#YxwX g gnwk!VЭ(IBÿ\lP,*eAK Ab x^+O˸!exQNsbf1kBx 5F0>]MT^PźkUT_W(((((((((((((Cm[:Z)?oUuL/ŋnߍ ϛ^TCko8i_W_c+?ி;Q++\!v~IwcPS {e' _e/$[j?iߋv?o?8u_؟$wG;~(pRa1? nq\@z9KW~=Ҹs{],VKRqtl9x??"-[V6m&Eť>rlgO˲MisqEտiOߴ|Si-7Ï'S|94CźĞFֵŔw47vmy]힛gw7v}׳kgegkuwwu;3Pď$fC oh >!i>-/kZm^Ak~8 Z~&][2RKq Q\Ȑ{(.3:5l~ NXf ^V0M˞&QBs_Pu)fv-pCVUkJ^ST^JHƥ:Hs.O~_kV|ַ"[lt h!7f|駖O" i#GH|_uC$xv&{࿆Zχ?׊->x_u_~^|Q7}G_  ?ֽ}x'ڇ5K=S4:VgNUlxR{COK>IcCӒ߆#S-7> |ToW_cY}N? SGËkxpQ|UTJU1yY*|eF?mOM#ź x =g}+ƶ|<[kE=v+ guw޾ |Rо8|#c~oⷀ'AKm;Gc:徑zTPjƫaJ;1MK ˇke8gNxF'Є%BUFT14J'8u-o*şHE?m=J|'>4?kؿKO]lk_<7O/)xS<)k:Y_.9xW?tt &7śm/wJ\Oɾ %?Ř$rn7-ф:Vw)K{"Gþ;c8o#gUib Ʈ'VRxo/f)8^&RaOs(|1_[/ Cោ0τ.D|G𧃼~> \ᧇ)Eqc'<~:j >|fOIjJST_ xpx/ퟴ>!X7o?ڻ[vkߴ 6է5ocw._-?1_w5^:JO Kis{(ODGj~,E'ZXI'?hֺf|Ki}c5+y}ykind7og|.%|&m~ 9lsu27 xo*'b*biy0*<,j,i—Tje^K[oڌpkB{j|!kvX|Aeⶏc~"__$m5$>'xJǀ2; W'~D?d߅^'ey욺'S׋)ykb&5մ kw2źMwş; 뿵{ⷉiÿ []Ÿuߌ4/}OxP%ľ1n7QӭxoH5 sLF~gkm;?⇂<Bm6{Zx\n4|V/eS6+:qʲOhgMx_q^"8F5)̾lFqpĺ^Ӗl,$WBxhYCG>ڷ a$[i n|c>%jJYuEmKyۏir5qƾO9~MVKZ?'+Ws⟆46/^׉|Cx/P]VxGeҵ FѢEͲ$bq,YKúsS-G1VKQTԮQ#N4UqIF|׀~*S.?~xsKY9 ?FO x?9~׃-)XO|[n>I4ω^g࿄ýG{m~|"ߵ#|!>"[@xC-q7O|wυfW_ /ӿ~|iO΁R|3|y+і j=VOvhséXջ][D'ğWd!>hgN?_U t*k_Ar̳ _3>fpҫ9u|> KχST˰ؚJUU;Ju)Ɩ.34O +9P~/x3,~_|-~K23_jc焼/UO>!Ē06W5lj, ]ͦ_YxvI[oo^Ax"?d؇jZ_Ë'XOW_ xC^7; Ï6] ;\ qvE~Ͼ%'ß~k%xEwu]yWOլu<xb6+n[{yԢ)}Ŀ1y?5͸" _YTqx9*XUԣs.CRUf0mO ۋV&*ѠXR^N^xXr ΍|T +O o|q>(k> }Sn3_\oFм9GIoxkMf,5}?j1|">>%O/~6Z\4W Bg~%5z]O68:}ֱY5t^n6lu"OW$?kOڳ D?_?(S?o^j>9*j# |)5(Nus#jJ+R[eR4N|­8Ғ N_$y'8Jj#t⇂o^.9M=O~s+~8x>(|MSzm毯Yj |;]C!cG>'$1xV&Gu o⏇O~#M%\x7?Y~ `q+C^ӼWksM h6z_|}|1<9߄'ouOVg>O!?xVOß =O 7uO{[4ts~:}]ፎkk_}i^$왬xK+?L-/ xh |Ks{Oî|<ѩҭ[P*b':x|UIFT0NLiu*4sV *:Sj?Xk}K<]KO?j|7waϊ|R7'ςgk>LKBXxѼ'#Oa?&zn|EKk/ ^'֬4 kE:Ůcūh_ h|O Ěz KF^c.xᇉ_?ji>j2ַͼ֒%ȿ>%}㆏- /zfN'9xj^WMïh)^*3xOë6MRģFg5΂jx< ~jrPZy|&)'S.(eX:FUJnxHO|lqT8_ikT08RTmmWJ_g/࿇_ƿ~'|?47|vֵ?xZÿGom(fg\jơǦZ\c?_ּ__C 6S~)eKh7A_|Oο xoX_ |=i_;f4&O?7c^恦x ?o< UğCi6ח->)s_ 麥jhv[_ھER]6VE5{>/Vge⏴X'?>,\ƃ4mN_hR8b0qQ׍|e(Ώ$ሧ_9(PT_:*PJ4TO _ G RUo'|.)KTjxUTiG5 %Vs ͟>9j+ xK^ Y?x/T[w; SWxS-⍗yW?ksm? ~?j?Y 0;~ 4x7Cᗌ~,^/|/r K@j,XQ|?M=KQ|-u |_t |G[mon ?KM5Oh߳\z(KKUs}wS.-RQH$Du \G`FUYC8ԇժx{, l :x©Ϟ2V%ZV)abW^gSxŞUXJ,<-vC4SrU1Z8LlbOZ3⦭U> |C }a5?DŽ|5|9~x{VwՠuxOZokwYςyk <9uK5)S|V//i6^@4MgiiOE)˚äBٌcJJ:yXzŶyl)a{Ni:jrtҋ|#ƚ~aJR):+s7%N4ѧN>.0 Ϳ>Gۿ u|SH`?|'_kWf3l'_au?#71_u~qrx޿үƿg/W]!dSſ&xCW'pw#T~6IpW꿱?KI%ڏZwo)?NjW')$QN_+g 'Ɯ_|7Uߏk/?oci_ԜA]br9~>0x>ղ췍Iu1isOܛ+ry2cm5>6xmuoS|:7t l Gh:mu+Pn'fe1] ݽ^A{{g:ݵam=ZY]Nmmmo41##)#oٯ!/ψZOu w֛omiאiߎ"˲ήM[S3%,Uq)u牔iМWüT9pJoٿ;q81թ:8FyZ%*i>c:_xS{3xm$nj1qRLF2cbJ'_OW!͹lƆ t`Fٍ,9*ؼf_UN8 5AaS҅JJ<Ζ+Z+\i 0eY:uc*ㆣs?IKχ-G[_|Q~4N/>-_|Uo/WeS^2L9\|Ox?'/>90?Lؓ߳?>+oڋo_ڟṎ^i>_ ;u`gWkcMiGȻuxZ'j|_}<?W655g,s/Z#j?#@# C |Rо8|#c~oⷀ'AKm;Gc:徑zTPjƫaJ;2,Z>Op7NTaέ4ʵZЌ)⣃xVjՎ'W+bqť mWgFx^jNAM<5.?gg^ =T</ڴLN/Z|Z>U?#fcA{O?/?O| h~߱~x_4xoN/^ RVxSV!u??,־']hs8~~אMZo6_:4㭾+|K+KS1[kRI-4Wn[ ,tJR7RE|w#S0pGΪd\N+-1*_;eSpMȥž"58y~c(PkQqRiЄN^c #hzwY‡G*Z'ET;~ 9_Hy~OCa+X|Pcƾo^?ѼmqOj#C<]w[~%xbSqk+ȼu-ܞ=}tP?> >$YO4[Ox^ /t1OP4-=5JOkVqq o:ϥ]KLۈ*AKs<g8 K KG+en?/UO2T<3:(ai.UKNxYd08XӅ/j2;%yC %hօIUC?/09xmKE_f8' +o/]о$IjgI5|O[Yeg v:/گN쉠~ɿ Owgmg'5u_OïxR Mm8kiW_e׋uo> v%wk_Wo?~x@W>$i75 ^ĞKkZ|cns[k*ޑ5jou? _3K=O=w;xǚm> ^x gGkm;飛UbtWY~>6xSk>Kbqq5ŹQq]|i>_4OlWteҞ+/1, =(DqҌjS}a^، t-J:XIWгOJ&}/o5π&x;Aj$j/ٓß~x{@u[ x__lσtOm>:k ]S~2ɿ hY%'g,ec? ~$lq\꿯?Y|JӾ |I c·:>ð|J<i6u-;) j!!k9/'|rgڛÚ&?_~|O'W񇂯/1? i/l_P^躭%c{˥jEs'e"x'YW Qe6Q 9_bp p S8:ê0|eI"3ZYN4t }F[BcB$]УF^iT^5J07?ǯk~$U]C_~&Ex ψ Ui¿xO Yyo-ɍ?!qlW3gy^gQ)p\/f|'f=,f}˥Wr|C*a5b)ҫRyNwZS,>]fi5jVr]^gYJ-;R[ik?dgĿ x_Ɵ |C%amkMYxTLƓ߀+Em~?ÏԴZN/?hÞo xwommkxZ? !I6>fg *Ծ/ο |Bb:tk+]x{o/}|AvM.{}|KO?>:7KR:'-c6IXsxRť׈l4J|?Of 썡xs 3O֛peY_k*t~&T+/bEA|}KÏ^l~4XA}1 !kW/KoLσhi-Ql?M'iixw_7FچɯƐ i9]Gm| Zu5h//_HƅshgƟ/Of;_ ?&Ѵx ;$u>*~ž&&sY/wş|9~&Mem?x7 |!|Yshh; Q|A᙭Ƈ}ECMҌGU25EǚX̨իM{1K0:Tӭ QtVNT"qYfk?AR[ +JRJgSƿfٛO|_'eo~, 7>#o*xO77HxJ_+-#'º6T>7&Zh|:+cҾWR🉼{ھg¿~J~ <5&_gx^Z|R}?0Gbe=w[7iMX^<5⟅ F^>W,X𗅵7M(e?B JӞSGjUʵyO_|'1x3|5>%xgo x~4'<%j?Mgt G[/Iej1i8|Y4K-s9_~_-|'_i#|#/jwm◎4mw[a~xG SFM6gMm ^]Fk[-7HtڧOgU<;hK_i.j:/'gi/Z/W+f'ǙW_ >*x^;мGekzE?Rᶵw]Ln|^1J2hc,ŭh-+U-ŏZO.o_YZ\[jڝӿ^ugiΟ[Vm[PNYdЎԬ5:OxlIn.y D wh$ba2U\6"Fb*Q GYVT**WI )89EJQ#Fiʭ*ZQTA7()r˕%.Wkٜ|CO<!rυAul-h&n]LZ\&q\L$v 1>ku)}[¯:uƓ/k?8h:-9xVMBxKs)6Z}Gګo7ykxJs_&Ow?-7,t|q;u :߈O7>">ajj, )b!c8:u*UgJ8Xe|N AU0x)ajP7N>gI2&.; NgVK& ҥLD'8QaxԆURmG 5x~  ~ȿ}NuytF1 +MӭoEXCnn(#yO,-|E%/<$~+CG7ď3>)<<EI/Xnj4LM  /x3ßgXZ|:ƿsaQ^.gSA?? O:'<{? xsWuSL> *NԞ񯇾$#<%v|yoWA-MkHuII-DfUYyY玜[Ru}xU;˚rbpaFhV"u#<XhK FFn50pPgRZhTsNQX+5?i+?t?goKS|ywzQk?.xƾ~V>/g*?"Z1;]%K?(Bc7GD7$d:7h~Ͼ)ncGkbOENX.=Skh.~{L|)O귞!'5+HLAxWG"ܴ:牼!0M>[ k[<3}'м?x/o.9o?χ^(࿉><Oiesom>+^ះ1Lf=fvԢyr>֝L&KVU*)gb(ib"h*P)R :U^Rļf%xʘF18S3>D'&}~)7ukG/jz'5mogS_=k~%և3ghxksJ!-g!%'ߋxG㿊<97mgǂ ZsZ&:e~$18+T̲Эa񕥁yF7 ti 7*2u,m,W:5,&q0y^?qfTP<69NSjӞ G5 B/^*ax<+i<]ڻ ~?~  xíVg9i \X-IO=*_Yx|+ڿ?fg>k}o|T-<Ɨ3#\ g?ml4=;⦩aV /۴Wzlx7(fγ <.^kἲ fG *W ڕj'<\xJN1y]*PzjQqSFhr|ѫ K'|!kvX|Aeⶏc~"__$m5$>'xJǀ2; W'~D?d߅^'ey욺'S׋)ykb&5մ kw2źMwş; _[/ 8p5l+s,ye|gΎMS=C+x{}c#Xa9JPSJKuV&o*c[eZ\%,QXXh*~}/o5π&x;Aj$j/ٓß~x{@u[ x__lσtOm>:k ]S~2ɿ hY%'g,ec? ~$lq\꿶We6^SW _-dxJ|i!ŜcW0xeueԣ<3OIa:҇|=<\=)N8C+7?ǯk~$U]C_~&Ex k_0PeԲ<=C8,nEqɳLT(cVaK׭u = pdʥisSYRf+FuiN 0&7:iN5_¯~şً߃/OֿcF|KmL||j|i0[=&] 4ڥuK?\i?K|M k¿?h/|!Vڇ8{KKqu" _9k&6q־ 0 o4J|?Of 썡xs 3O֛peY_k*t~&T+^Ni־8ƹ΍?;Aab*k>ju%Vj*ժNyJu$ܚM#% ?zo[{g c|7W?K|Yeև_S^:?bWÿ*S֝ }PӿhW-g ~1ּ?M'g|cw㿈c>_׊~jwkMŚ͆7Q *Nt*J bW9R`=a ДgJ qrUOFH|~,}RixJĺOyo&~ӿ~/cP>O+-<|"_^ο o~^>#:xS'|qy ࠿ qy>~-cxx3gxǷU_kWw9xPڽƕ>eU?m#x{ί{3ѬVZhg />9W,tC|+sOqiO|I*՝l;׎/a֩,Ej]*\GӔ[ΝJ:8j8[QJ8TiӄT(<:9~_UN焣pKEʊ`~Ja?/Cc²j?g^>?M'H|=<]$6`ѭ?|Kcm_~>j[|n&'+<"_IY+MӦhZﭵHo v yį KҵTQ់>cWZWZo'x2MRNү!('4xERy,Ckw~?gxc'*Ӽ1SoODGf/  aNjP~*J*^ڕJrxT1LTV%1xx8k,3:gI>hWz J<^4yN<㏇~.sp#9k#V5M'ľ{b|=|ul|WңxFq$ |fRi{ _??hkIM1̫cΆ~ ǗPxE_ m*@{=?p}7ڟ gᝦXAkNjc__kŚ_e_|4O xBn~[gJOUڹ?coteR x?gi7Xw<1Ax:?;ڛvNo'|]q?-/0NJd֬4xŸxuYQ4Jko/bIźπ3==^ß!ew xϾee%;-ۯ iZ_% }^m:a)ԫV3TspPUj)[)԰Ʀ+RVUBBp фuyt)œ%jʸOtW͞ g ψ-1¾'|u >mGW ÿ jB1k⎧j Kŧoᯎ |aS kzYOzel/.5oSZ=Y;Tּ;]Vt|G6Zn6ktRsʗ$':|nhVqIJ0&5!(p}4d}18JMe/]*h((((((((((((((kgD4N?$w?gUZ%}MBwWО$˿ |o|ƕ6|_3g9!Cko8i_ѡ3g9!Ck8k__Co)f,ۍ_?ߟ7R?:ORIe֝_g&OZU_I/~ӿ/ ɻ?iq_7쫨^x7֭>j5޹g_פwVӯmWĚdQ ߠ|f]ş x{ū YӅ敩]Ei?9Z͎ +~ztOK_>E꺗υ~s|B 8 흢x'ToE^{6?qěI"+|NFmD?|'[ϩy3¤9i9jGuc6(8Nj#SqѵJ'^LqIO+Χ̜p`Fr|׫R!F52j53jutrYak9|ំ_%L|y3-qxOo~ ?_4/Wռ} Q!?GII%D]^0 MG>(F?j5O6Ikeo Mƞ%s4UƣKxJz:w>|s⟈ ?~YHZ|>~?xo'|-'cg> j 5OS־67>XO[~e>?Zg 4xB-J\:ݏ6_6/GwK]L]~Ʒg xOƚ|'𷀼Wi Nž-֬? Wh&v|1u|:GI&~ K+|\{o/>9]t7Z%į TjS[W&t%Z*R4K - ѡECNu0IaE"|%|.'{~9|BAo xOĞ:f߅յ +RmcO~3 1_.x{>!NxuϹ.C ta' rb~3Մ^.(aR8G4i㬫r)Y"Q\Q%85#[rʓԨUU|MJ?E^"|OKfֹt)~<|5'7_ƫ2/:|E/_CCy/|}gxga4Mx/φ'g9OBRf8G(Fp(Ӎ8%+/cO~8 )f+lo~F{F6~;~E׾2jv>oۯ 5 ִCoY 6x?dY /Hx >}R,5>:5?LV |+tWM޻5D'75_;J"qdrjWk<}KTn_+ Casy>ch?"MդMrtˍRk*!M*JjUqB\Υ$O::OƝիRYU.i1U(87R125NNXN=լQEfQEQEQEQEQEQEQEQEQEQEQEQEQE~M|; Uh7Ə _BzggD4Nޯęwaҷϋ/&g/9~5rWOHwn>4_L*_rkி?/WJM~k+пnM?Sj6-jZ,=6Wz]_^YO՝I=ݥ$60HA<.M#q9Pr#fXLJL1,MHT[JgO gNq0^ΔiF *cj,-|m%9FL3 SSJrʬ)҅)Vnnn*ߛ;|:?jVO?f?6@JڿHծ4c_7xÏ?J~UK}7XuM@9O|"04.>8|Ry럲Ƌߋ> W/:O|-|H4oxg_gk_PO<[i7<{Ɵ߃^Ū\|6$GOSGesx"Y[~b%Ļ |F = >+Zm0>W"}mbYSr8T"iaTT0:Tcs RR#&GNssQw)Optb*JjgGaq*8gF3J\U*|ំ_%L|y3-qxOo~ ?_4/Wռ} Q!?GII%D]^0 MG>(F?j5O6Ikeo Mƞ%s4UƣKxJz:w>|s⟈ ?~YHZ|O?֙C 'Rwc?j-3-Om'ľ,'i %~TjS[W&t%Z*R4K - ѡECNu02,eun:wq=#K׼CoIri6O;Q mOh"O-KwL7aEڏ_,tgbEOem_)v}c~yeLRʱ Pgjaj}~nzt#V5:*1峳ԢC2GǨd\²0$熧(BҋiTw6+Y,c(/5KA[m =ji?Om__ ";p~hk$:)  :/u_~%6xSK6y,o i;A@=䷗0;Gh> .JctjF8hsck*0J3P{j6j2N1~ J |=k h5Orľ9|?kgIou{^گ4Ɏo2A&+@)_޻>#VWC$泧 +RVCx~xOEӯ!ѭeȎ&6B~>-ŏZO.o_YZ\[jڝӿ^ugiΟ[Vm[PNYdЎԬ5:OxlIn.y D wh$8K+2d5zTj`ٌ)bjB؊P:xX:p2tJ5e0YU\Wakhק9)5aR:SUf)N)JssqVwۣ|A?S.x¿g} |sli7%%ž5om&X|$&<) D#? |/Wↁ;|n^~О/-G/ ??i/] > >ӾߢkEo$<-սw fOY4=^*<3۩a>7ÿ>𦛣hJJ/7/߳h_?G3ş xzo4_u|;?d3Ꮛxǿ<m|7>%xw^4o!]_M xZO?7?|kN̿ ?d8ᖱ_|IC)z!~͚ŽZIdxP7~wdhK^+kv ύ?xkzZxm_ڞq}{C{EtV{FyJF{O+dy ^c,OyY0|NrƼXXc^xjRi^n-8BRe2==*1 7'M$MISi2\~6h/{Lז%Ծ)>"ӵ5ä[3XG%Ω_!Oc W5o |-cM7,5'DŽ4١!|SGÝN|Y?x~"O7sw-֥qWź#nyhzΰjpi]48'q5q(pTTaQX6#/P*P[X8paWNXϷzmKԡjWP> s+9_AMǚW~h<-s]D+R׼Wt߉0h xS Ҵu-GIc{[iu>$퟈t ]-']״/ 0xZ/uYtYg]KQ|;{ 뺍zE׉4}Bkyu=.:|Xjj,'x*fY_:Xu񝕏6a}E2-2>0$ex~)|9{P xGជgzO< kڝC#Z"hullLgR3_Y'TUC3t\V_<% chBxiaծT(ZUfK )PqUvJQ%>[Sf?e9TƚkʿiWĺڞ7@Wdt Q4MgN[M׼5&=l.n Bxlu6Gy^M0O"!ZF ^J5c>g/~1Ӽ[Q<~m?G񎙣|:x{_xPV2壂B8ʲka E,DڥRVt=k|"iS˯@K2}^i^ ԗRO CQZ%KN|wׇz.TMRUN'Vs;֡J8έlosL,O |=ZUCIѩO<%NHWR*u)RTqY z%5N+)(NqӞJSj _ٻM|6o#/f,GPg|,*Mi6Zέ+kmJW,4CVPix0~<~ Zg"59u4 |4&k |A_j<k YZ;C*S*a u*SJ#괿yJS(ĵB9BYFe7(pPpƥ*jשN*hXBFj2AVI?(OON?Kֽ;2͌z¯:>Z%%#ڧ#7/|/x76}if{GTӭnq[e9]⛽Jfsយ&/Ə#E#.kᎳx/O~7x7A8F⏂^?5-ѯ  BDMŬt8TRY*t(NF)Q+_xuENtrxF)殢WqSlr9aq`ԍ' ?hRo^.|K>k!B,>=|Co>%ޡ|-O [ u⏇~ zν:Y{ӌ'9{y8FԢ7Rj5'fTj49=Ҋ?ׂࠟ Gw/{{~oUm/xo}szǁ|1g-,77<7[xũ6|l,uz|-Ķ:. |1?FljxG_HFѵoDo4-S\Ӵ;k|9B+9ԌN3v%R8FVr'(ک'i%WԆW($*(AEPEPEPEPEPEPEPEPtZ%Yۭ"m. NN֞usDp[|>8we/_׈emcTy,I?-O#gD4N8,~ W,W/W(' EOgF1ЋyTړ⮖'FsaV5C1FTf+;M+Wz"Ki&;/( H3K}o&Rsu7FdT !Ҵˆ)7[GpW_HgkgWk/&g/9~5sW_HgkgWk;hľ2 p:ݵ~} 8pJxIeMߟ7R?:ORIe֝_gO |=k h5Orľ9|?kgIou{^گ4Ɏo2A&+@)_޻>#VWC$泧 +RVCx~xOEӯ!ѭeȎ&6B~>-ŏZO.o_YZ\[jڝӿ^ugiΟ[Vm[PNYdЎԬ5:OxlIn.y D wh$8K+2d5zTj`ٌ)bjB؊P:xX:p2tJ5e0YU\Wakhק9)5aR:SUf)N)JssqVy7_ᯋU3,Ŧϭi- G:?ږ'9NKA| Bxԯ$/J_ïT,Wz!? N'8Υ\k*9_Vt!F0LU:FtsbT,]:Ѕ*U#MIT#^,'NC*Qrp[_7ge~ |n?g|L\~߃|e">?Ǎ o|`mTx:i~!Rm=Ry|3 vc-eϊO 1 {|&gk6ZSҵxm;>{/P:Sӯ/;hZi,Bj_xxB>5|K[]Νj?4E?Zh? ~"kzGi'ռl:Gx6' |f|G//wu-R:fx:m׉c}#^q^4ǃobWZ|IB50¸|԰0b*`9)Ӧ N&S115V:㈆5J\OױT]8?k_2IQ*G5Δi?)ό~'CH~]OG[W8?4=[H៌?On?495m,~3x I2-d ĚW>h]il<{ž,dr> CWxEyώ>0$ex~)|9{P xGជgzO< kڝC#Z"hullL.ls./6Pb0Xl*R˱x~!uO);ܧNtqtʖ 87 _>jx+FQW<4)`3Jg_j-*ҍ|=\5HFTjД u?|\x7hOٗnᇂ4 gz|Cok}mMož/=O:xXǀ%᷎m-(|3^ {>?7|1s%~2αf?>]  Xk~𧆴O x~'uhAZݽh+֫}s]^g/Ɲ o|φm,.?.eDXx,kd5Uϳl ج_?182UaΌ5zl\F\,WU"P5q~D)j>2o/~$C] _]? [_5'/| *I,m~Xx#)¨Ou;|gQ ?Ǐ^;YxZ_?isuw:ͩcWsxŖ|Q,x7wq 6M{hms{s/?Z._ ~"N=sY8JmQx_zx^O~)h%o g_|d& liWTk߆i>&U$`W_,."Ts\Gս\bq+C.ݫ' =lR+Wi^88֖'F3Kei5 mxWJe瞥WZ?xgĹDž셠͗g>mNf/G j4qxr<./:Xժ*ԡ SURUV Xw,Zs7678{J]Ҏ\N|®3_GJ ^<-gZux#% ?zo[{g BCKO:iu⯇Ud ;W졧~_<9⯊Zϋ>;cxOύ u}Oz:<7m /E֛?5 Joxc&E3)CNn1TMԧ \K*Tj8,J3*%KjuKGBZw8at:8eiNTSUUWAPҭTR^e~ɿ՗>,ΚvVc؋O웨|X2mo^ռ!-Vw|$VYğ'o/7+xr>/~?7|G[/?5ᯃaWXeρoƿo ޓO?:EUb0Nuq>|S&x,'mx^IxKG Z$zerThQ„i֔aRa\Uu#8VI5:{:~3|UJ$u|✠̲l(Μk'f爅NHƟ/-|s~!|E|mZG'o x+J]s3δ/y!Z&t iEw<Ÿo_|+K(h# |+WC>1пgxW |%| ;cE;º?ga_|=jg-k>2i | -׋>\#5"]4w'å5dռM?R7FEFTJ9S悝 y T"ݩc)feZeJ,諉ZZ*3jMV,N6XIU*PGɌ`ۗ'-wTwO>hk>+|NѾ)|5Oq/S|c7|A _\煅Ψk&/sm_x k> t-7CWlhRgXYZT`M?*X,>WZn0yN/*j)cgjj-(½)UYwV>>5|TF.|߳=`o`wgwƺ͆{z:oĿxf1OF1$_Ҽ8-;Z$ޑjʴM֝z*T9t?yiTHa)Jb+ERTeF0RnIIKeZfYG5]5$*? <GxSnLM#Zg/_uoFYxXHONYKw& -xfc>9>&h6>)־|Dᛄu߂)3iSz/OjYӕ)ATw8, \խRҭz18b'RrXN;Ʈ&TTkT΅Zrn Щ7*aTۋ)j|F]sFށ_ :^FUmJ}CYZcō/w4_Og_ڛ.ӼiM_◌|iNں|>׵Y4oК**Iգ_6Cέ5uqpkVRVjB8 $8FӌZ*%dG pY,8zde(Xךw=j6| []j+յ;ç# VD;?Icbڶ1k3e{gYj:uݵm]YD]@Asms4:I0'q5 -$0?῁&>&|=4ŨhFc_xwRy3x~OmO_/Ou㿃P;9xCE;^2|7/hwzbx)hXx/>.ľ,J^eZ= )R.}zTVUC8S(U8֭|U1J6t31kb3-\):ਹp,L_#O¾pdS9Ѭ?t|{">wo |CK2j Z9}Uִ_xBY'ۭCn~&g_4UƧGs R6jeC^jv:5߈4IqW^tMzNԒDtR(QOK<-ox[u9|Oo} j~ FyNJ*x_ͮx?5CķOwo:g>.xV|/_Y|:[WCFoxm|E7u_eCĖZ]xS\;k{hYjuͶ/\8NU¬ft' t< !NS YDYNJ2ԝOc\&\N':}&3 MjF5Y)% ){*jw? R ?q# +nj_\Mjۚitliz$aX~ǖ~M+ 4o ~.6\^|Y=OOy~2xKR!+m?[ p<"ǐSuq>+z_|}_k>WÞ|WPxwS]Dм'aw^#]mt+kc 0̂_b\iex3S,u2V2O-eX|SNTU(feUJܵHc*TƅJ`rcfkX5obp! RQBsߌ u?|\x7hOٗnᇂ4 gz|Cok}mMož/=O:xXǀ%᷎m-(|3^ {>?7|1q-ŝP T#_xvZ/ ٖZچBvZ^w}k72Ec}k^._kxSzxtMM+@5kJUޛjam3\fgAø <3>%"2 8{,˧Ц,wy$N`<~0rѭ_ gĸnl zᆭ:.+խVViԩ7V7WJxXU#ZRo;៊' Cj D__5i? c7+៉h5? 32BͿk r_Jd߂_ xT1m71~?~%x[CNe,k[h"m%EKrI~:Gguߴ~Bubz7 ]SvzG}ck1U0jVg Χ`*K Se.71YNkk!'EOZ\J0ŸN/rK(/?j U|տasZ+G!⨴nݧQ;|jßMƕ=xúO$?e е_'~&$xGXi>ѵ/[-dYz ^ +l>#//j/ߴ6[O~#MQoV''ՓaĪUh4(z'O٧/g|S1gbO ͞>xŖ|Q,x7w]KGU-!z< qhZF oLűx A5oUPk?H5MJ(l.K\uN81T^x p\Oo <پcԣ[b)eX MGR4G>dӣ%p`WJQ'RKtJiPLTkd/&/x>-(~xw~+_ʟ/>(~y5?x5YRh7m#xXFe~%k_Okj MG\O?_Z5j\xSqRt b]?]\𶏨\xM^ ׾񖿡xWWxF/߆5/O-6д}/Za/i4,IzF73I5_WŞ&}Axþ5wи6g+]<5\;oes01D},׌|],˱N&aFR3^|ԣsO 8o^LFg!k`%tˌ0UUUʼ?RRsQ*6,clN]!V8SaP||_o|V^7G.qc!h?eo-x~Sپ+C|KO|5z%/Fw'k>~_[▱⛏3ߴv_ WWŽ/FĿG_ji7to &{nY'F{giIeI$fwbē?g=R= p.e1r3>"?4jTb3l_ X:3oJqts :G8KFqB\ :_WRuӌ+{W:[_č'W:o| Ogïr]PUj0|CF V>Io.Mg6mJ-;[|Y?5Gtg\tgMӵ'QK=KI-5M+Ri8,6++kk'O~<YWOq ?۞ ߳/[_Lςt|a/=z> kkke_ >ſ_ ok=3x]~ x^+֯q u{}ƟY|:~|PmOu~<_|#3^xS[]Wĺ֑eh(٨{Zt;?k EZ?X?+ޤ#E5(MEJt_5/eU9a "UB"-ѫVӜZ|YQ^% / XDŚgτ^ͯc_|L7+ɪA7?w|7?ڔZcᏁ>)N}>*6%zQ<+kԩ%N:tkT5GT(թ9:tMF RUgz ''*PN*ajkiUP5uBV. +ko4k~6m_'sxhLտ~=⫗3|6Mnw5~ ?ە?rY?$mBrJUJtT[WT(TµM.iڭb9e.hVug 4C4p<=xVҔ֌]9IEx*M|Y/WG_+Z6Z$Nq%u;s_49_ ,W<5⟓|~6SA'co Wƥō|Q|pOWߎA⻏ ٟ7ƚŏk_9<7R,{|e{੓T2Si4e^Re4 eJ);׫KcaUTITjTJQl4quSkJB1xiR0,GOj_ᯀ|yugcþ01'Ao>/h==Gt߈4s> ou#xSQmbvOWɪz㏀;<:h -.s%jW$o?:%6hԬ೵_}?MiV)B4pqVu!Q(a15!Iҡԭ nRIUP*ʜ KF.SRc;ʛJ:s:5Bp Ԍߧ_ iR\ѭuu;W埋%7~:ď \Eoqk{/<%ouc|0xo^5|;ֵ>Ѽm/~>+/x4?x_ǚ|0{$|c}7|.D,W IxX z]KĶ:kx BNn-v~+w߆x={Q%oo_1 O^d7#:W>a93Zj <?|UFG,O IƵqzOjؚZJuVZIԧ/iJU+^g4*NySSNJwJN+^ЩYOSWKKZ'R"ߵ_tτ-G4j~!_PYg]sx5ե?~6>1uΥ&O ԗ>Nx|O5, ~߳'Þ7n|kw_tg[B^M ;~(k>_|4um+*s-;HZSNc*IՌ^eOߌ E Nuta**7'SJNcBRu=⣈RrQC."T ?Q_x+Y;_#R:ԼYh~6mv :j MkX<7xGĽo * OڏahHHU<o\xi70j:-ėSJziԥ_ _BT*C(Z`:ҩO J0z)ʄjS 9jJ3xx7t5h֯UXzrBUIEԦ,_O Mŏi~ϊ MtϊtKSk |=^ '&-/?Er+'J~juytEW:>m xΕk߅^~ӧOh*\ƃt}NOhn-TTJաrOi_inJGBpMNU'NJN%x{_iSt}TEa3ucQFT,]:jj*5*MiR~,|(7G/?+_~*|nOox{BM#.o|#֥:K{i}HMBi? ?mo.>i9Gŏ~"᷆tYWOP|sx? k@u冥i ƺ3IBx| U)NKR, n/ះuxľ2g<eYK>*><_xG5 jz@tKwjZپ7!-KFmv+?|5~!V>Դo]v%M^h|)i*OU$qWWNԣ%M8*xT'CUNXT$9d%)Ve^iNkգE UӍjNj*<7K|ԼOO|]~Wsh~6煴+c_5_ xK%_^jOZɢvqZ]{?ˤS񆷧h|~. TY xCԴ;F_485 RӫFTa狥5(RNLU6:KPdgrO׫u QGPoZ!X7 kQW>j:\~)Լsľ᷁c{h}U_<=Oz/4 \O=nuxºy[S@s?hs>еI/4=#NrU$+QHM8>ƞ[V%iPq޲͎*tӯQS%8?i9SU($ےt̗'乯d~(QEQEQE5ROg3zUW?' 埇;!;O_z_e>FicJߛ>/пU]!\^4hпU]!\^4?3yu~m/Jo)?NjW')$QN_ {e' _e Z)Id~^4? :_ ~Uk˻Fi..$GKӔc W ɸIW A$}x7)GüF*NY''0)6ڌvVս?7쫨^x7֭>j5޹g_פwVӯmWĚdQ ߠ|f]ş x{ū YӅ敩]Ei?╏WW_Oa";+Az"旬zu \'/-:/ mi֐h^MhU[{9nkYn.oLg2ye8*ӣFC[Xb(TѣNFڵ㆏!9eay] f3VuhUyiҔ(NsnsӕVӨ( ~۾]|">_[`K9uM4g>0[%<jA-wR|GcŶjo<wSM⯅?>SxS7zl7$>?˨Ig;ҴSм3=M]xQ<'M1jǗG{y?AssIgʂ({ȣH/`Wlkco "%թe>:UװS:ةEі"Լ|~;I`p+{eJuԪS:omN90gVNn0C-ǿt ok!eĖ_~ [߆~'|EI48qK>$]l'|McZZ_&k47/*+p5Ni^2dM3G_pX̏V&/1Ĺ3崹ᇡJ5#9Pe]֩*u)fb' ,c^RL]\q5!*sa :QP:I%Z|Hмy;c˪*hZ ?/a'|V_EM) +e-#5gPOMW5cҧKZ~+x=ӭCy_֡h |ysB͗EPݦ=~>>־0Ǟum?llO_?WӼ=PxV]_ºwiƺ΍~+؛BႼC_???d /g7?R}~ n}w>.:ͳ[?p1neDEhaeS}RJ9FҥoUmvԬ ^>>c/{97y&j)ΡJ/mJK-^=^e&}_g/>1:gC^{w~k Aܗ9> eMoq] )aD|^x[Ko [~|,?g |F|&-fpPc,L8l5,|h\s᱋^Y~#e*50¸PlnEє)`3\?EC29WjS"t%NhW!|*;{/__gi~ xI|?xBŰxⷌ>x{VxbX[p׌<]^/[x ~_W# k 2{x_uƑxU>5xB6:xnu SF|G xSWc ė?_ ?d7/:YC'=_}YgI,w3(6aŴar/3^/+)qRpx׏NXTw5bڤpU5TjF0+e+jqSq*pz0*r~27/~?σ4Ҿ ~^Sϊ_h 1|jέ񾑦|<>!JM~,gxÜy|Ծ/ꟳ!k:,?3?ᎾWo_WrPKoNX%ʩdw3s,8w%ŽalU 8hgUZ\3X5O [ V><ʶKO".Oޣ ӨeJJm"ণ?MCKWxXZ;ֺY5OM^3?ᎾWo_WH9_9v7-E>"UUqW88l[R]W3,,#:zUJ8|E թ}fo9*U&FVfJl7t昊,(C,o< >Έdo=\^\Z7c !JW5/I4:˯ORv |Ao6:l7"Z-QKE$羗7>_C|*&4iU(֔Q)O~$Zqw]]4aeF(FTa SRpZsM5%i=vwKhWKY+ G.xSuK}?MӬme_Rk!Yn%cVyUI5*+|(]kOj/5RGbQվڍq׷Z>xMs[|;Oɧh 3{K|R5_4Q-A[ OABҧyn.5O5o j?sk9Q䄣R\%8n3nnyP۔\e4i4Nmo]oA?S<+c? 5 |?aῆgC)q&"Ndдm졲O`hy[//?Եhp{4OeSm~G jOIo?п:bC)IIsm-խܸBQr╡Y')?}|;¯%?Hi_?e/ |Sǿ4O?9_R׭|s uxM.ᇈ57WuKm[~92uxC|C῁~W$?koG?Ŀ^; ?'^oIJ^ÿ 4>.>Ӿ _JŚx^DyF1UJuq%6$tM Abs+?fo 7(r*WMSr|R_ʟd᧊./ Z|Zm ?doXį~̾|k4Ӽ=/:Dw >!Kuw*=[ڊ^c%1>kU{cď'/¿='Iǀ4_7I7MoZx .x/Oֆ&Zj:~׾ ?o(|4o|i_|)me|6կ?k/8?E WB |#xSľ/_B񖏤IK?y#Um|UW .A9*}~_U/Z\Kgkƾ5|? /Դ(u]&KRt FqxN8)s]_~Ꮛ}>8k M{~.? xOzx~~?>:2оQյb\xL<>SrǾľ5m5Oijrx_X]4_"j߶xdž> :__oڣ6u~c%‹E<yN?τ| {NgҴ;iW7ul*Ҍ\Vjyc&-U],} գK֜PB3cV…/eG*P`jqu*QceN^m8O)JTVp %{{oP _:||>*YWߎ|!A~xS\ |Njem_ 𭖠-c_߂:Ǎ5iD,|Bw>&V?i_|-[B~1CDŽ-3&ψ-$[kKSj>+kD3!#\4Ӥkٞ%˟.{2?izfh[tiƬW 3 6.51+Ό12u׭חji>~ g쇨G_Ρ߀tO|mE sG<O nP>x4լKE?R|~ _ | &4?|>h]ꚋi݆Pou;ie̹GWb?|2>xaD=S'[Ƈw/kǾ%>mEOxf^Ki,r~>;~_<:\i>'f?W1xv5cEѵmsC_9iךֵk.KbV:Uc*i6操^5NhPE¤8>~)[Ӵ??k_Z|?]מ+g\^nn pKjZ_}_Ed.Rռy}EkKe?>.![j_ ntCFh`  2M$hPQCcԧ%*iөX\ BtPi\2F'ďW.^(vcšK7wL~> ?k:_Icvş?|QXx_Go xw{75/z.8k ^>?eG|?wY~k`֭n>%xv /<]plXM\[Ck)W6ݾoMý-?xK<#/k{_k^:վ|3].⧋<?=ĆGi'gn[{6?<:--n¶ O{2_Κ_*ze*/*0֥VTbX}\ey7Ls ƾaBaaIh(eRNqpiCNTkqxxF҆T:qG6V_5oۚ ?#֛3G[|p[ׂ/xOvd44z Zi>#x]?5xo| c=g6Z"|&ܟ|/>*xE<~??4x9W/sNK](OM'Kϥ訍J0ov<֎*UҷqN^(Nc7(Iʝ'BM”(AcM)+'/y?(f;?MQӼ{~Ϟ)/Zg6>);Y/߀~ l |Gg? |Hw. fOسxZ|M|S?Q[6/H?~=x B(n~ xPǧFᬣSZ4NuD$YD_ّid5uψemcy,d~[_٪O̹13~hԣXԧYգ(VU^]'tf*xp~Z9ƦAÚJϞft䷙$/؆_ ) ?xRx⷇ |CDf?R}vo?akxWÞqng--!\t~qqxֿ؊8!~Ҍo'(sy)(1NPn<ьk=|{FEU(ԧ&vmvlߟ7R?:_1/AgH_ͷ٣[?hH/G?a// R~ПiW4%] @ԦRt{)$ɟCơ>|x52mo&5i$wY.7ԵF=#G4H~RsNjȵ^&>;j;>+d]F7#MZҵx'R{MdnŻO}BCD'o$2~7&kVp gAiio!vomUEe8xקK,,\=fu®;%^Jm r+3laxia^:ֽh 7ui]=mϗ$Q >__O?#KAi&_E{<'O`?S'V//I[5QG|e<;g/.3 y\jZj zWϊeI^EME {? ?M/"c iӅ^Tupѩ(:rsʰRN MZ97~h'w&Y.wQ%Vy|){ֵˣE??Tϗ$WǾH3(=G &\<'O`?S'8eU/_og?h_ɬ6Mk\K23owq$ ׆O?#K6_VZj:w/jP@kY^Zʓ]Amsm6 kE~L#s1W(Gc &Q xOC@O-;\̏_O/_?l | W# G_>n,<}I|e 7|ESŦ^6]+nc±hW!~h ^{τ&sqo/foxH*5 "no?_$w/ k`'//aFk}NYNᷱQ? au/fCOkkV>$o>!x|nu+i}w? Kg_x>s_mi5~n/K}jxkR*gNK ]%fN.R1CC8,kRjyvES(R(ӖWVt2VPoLxO[/~|fdc_/?k^/mk>< l|$>5h:Ѵ> jk_sJ㦭I>:t5?7$~ xS}^eӴ$j~n/Ks_Q Ja*QZhXJyN9ŵx0SNk /oVUC5kF$,?.r% 3XԄ凳?;~_j3|Mq_Eevu kV5$+kLJ Z" iƥk4)x&_~^Ӽ c_x[~~x4߄C⿊:7/%x~s'7^ MϋXo|G6\ɪΒNq~n/Ks_ZӭVMTRYʮ!⠱5ܪ{uS2*CMU)Ֆ (JƝ:Xw8zQPK ^U=U._N*| Zbxd|b[^9>x? aZf;^վǥl%۟ j?,_&#VmS)F25%8I]J3t^ KTR/c&>, 8FljTK\/& -xfc>9>&h6>)־|Dᛄu߂)3iSz/O.|@ x: mCZ3ǚ45ob/k+kYknt_1s_G%۟ j*ʝ:s N[Z/ZM+B|v*(ӣ UN88Яgcuur~9\Ju&u'9b'#fU|]/_hٻ޳cecggI,tX|3eߍcoٌn|}xu/MGw^G_؋ǂO~?>:rҼ]~_yWOzց91*.]W6aԾ$j>"qMƞ; g/?4K?i? Ռ:;/s|9HN8.JTac:ԭ~H"K%&`𰓻㫇VU%Kp9P7C'xOëKgg~xr߃|9}oG`.Uy'ƞ.vۚK[i_xg_/,_&#Q g/?4RfZ|V"ʦ'R~E RFϙ뛌nZqN; 0lC}+ⱕ(,G#eV{ g/?4K?i? Չ'{ g/?4K?i? E~^YKM/F_mi5~Q_~n/Ks_@TW%۟ j?,_&#P{ g/?4K?i? E~^YKM/F_mi5~Q_~n/Ks_@TW%۟ j?,_&#P{ g/?4K?i? O/ a'T_{Gxw ;#)ojo'$o gK,OIk7/ jV?oqoR%Ɨ_9'|-/'(B"ѡѴ} % j7}ͨ\Yoa_e{[қNRN6T%S]tXV r\ӕIE%$Kd-Cƿg/W]?!ߵw\^5t^xsN??g/ZsWO߉l6 k[53OZviv:}R[~J 2~UÜ'o:i9%wwS(5JxM&\(Jɵ{^4Fy~|X.Kƶ^?OYuH?Njt\v%|?j%,ukUk%=ϊ?`#_m;ψ<16-kl3¾>Ӽ]i:o{~.ZB>6+I+I,>a{F.8sLiʜ*|MI2TU^9!''4big\gNT_N$w+? 6Qoh~oڝk1+?(~_9Z݅_uk4=Z{Sޛ|K`| _x|S}7 $xkÍgXjZbx3##Ro|3ώuxo;e{-晠kz|9Ji7%aiaIGԅZXQJ"u'(RөZ3W~ʪʜxYQqT])I9QYt)eraJ躑=7É(~]wo־4~՞"MԴc#xÚ捪Y^CizXi:ΝcœkOK=_Jhte,hω kW-͉?uf/_jo?xټ-=ufOUcgPY=ޫG^|]?~M6c_sƷfBx&Ƶx{^ZL g(kYC F\W"fU5*jIbq XL:b( 0}5/Zǝ'w:]SFu-_jc> iOkW^5|7O6$bkWҚ ?ڏGC&co|YÚF:Z߃>!i,&}*о+AO^E׼mru'?_gYx+ | j?:O;-O:QvgK𽎩kn|Mj&H~x[. /S/_׿ 1|K_'ſ o|CmxFú׆~O| /^mW[NLf" zsaQ+b8xP!R',W?oxM+Sp̜m͂q<){ɲ8U˰ԦۭKzX|1ҵ/Gno4]kO~2^2qa*|;{ioɨiqjGDwg[sZ_x[Þ Zh f/mWYt]KQ6V2Ci)|?5ƟgS-ßO>|ߍ?>k_w|O]_x_tO:MR4~ԣVR/ 9+GL|Lk8RfSye:TJ4*ZtTXdC umS5G5Ub*iR 8Z8D-Ù?@?ߴ> ?N ZSxnsF'>xkg'o/^,+ |G_xP|2'.GCZxX5+%~$?>8ßxtmO xQa~h:]cED:Տe_~־'x.խ5Wß n,]#Ƕ> ivUʛ>h%FꛜU¯ Ӕ.HQ3a:XͨC?aRs֝HBJe `%5mW3xgT,zR*4#?N ZSo'-o)ς}{#.sK>tj^χljnej k^7S?j_Vt?OM3O=?xFԾ(hZ?CFWu;<ĻO:˥j&|z:Qz= 5(NH֜%N|S ou*T$HӍ{ю"SNjB(f;L&kA1F\ȪU?N ZS!38$0'iV8<*`,Ox~˪xaoYN$^*uȭN*@ WtOi:OmxWog_B߶E/| ]퍪xVŚMD|׵V!Ɨξ>oֲk}HJbhN~^mNYNMa IJmS bVPUNp:.>U] _me(崰iY(#|l]*¾LӾ&kZ+h>!爴G j&]l,ix|kFKʡU>{p˨WYBoZ kc$EaJjRUv\20 < Ua*ҍNqzL$ ½W>xuI6պmkWM4vDڮ%iZex^t-/Qmx_?o__᷈gߎ`[^W|GDu=njKkk7GF+VV;_~g|O??Ck׌*x^!àxඓsH.\z>û'P'VX-|A> Z-/coVO'oߴׅ"+MW#ߴhŸٗ6 1x_Xռ| GWׄtSW>QiMrBKҥ0SeSI!<ʖ&2.Rʽi%*XYǚY8E*T긩`gj:O̲U,+b18}(Ӗao'-o)ςs7_-/π/ ־!|񟏿g=1tχ|-_}OOos| vi>#mDž<)I΍k-յY5ox:Kſ4ox3σgoݭvé7 94[/Qxk֟14}V/nR|ukNkԓasVS(b#S)(ԯaq15*ª!B4 *e;Q\I'DXEGl,=|<#(ҫ9 D [J?W0m%Jio(k W^bϊ?|a;~"|~7״z_k{O xO@&܏ k-<=Ceϟ|gK"0WM=F']/ 汭ź~\!jؚQ$`0v麎a`=E ԖrR&E{J1QNNE\ ltZQ:8 5ٚMTBgo u9i߈'þ߈u>(\ -_Zt xݭO؃/VCW~7Ne[|+c㟉  o^D𵞛jVtJ<6&C;0!'i V7]毨 'L~nn>5>':|tquxo6Ium _ mRQ:+Ū[Yi֦ȠyUR'(b'FPܢ$Q~ʪ&\hGUZ DSNSѧRJO5U _~~' t7:. <[z5 Ѵ¾uM\u+4-rmb+]S& ~5+'uxXRj?^֙ukz~ZTgssM6m-g㉾CտfٻAykğږYuw>TlC^uޑqyPvM?? >Zτ/iMi/KsJIa8Ϛ>W tA V|LqSN=j8jU3%U #d8nyFJibO !*wN#US*4֝/67n!xkoѤ?/UwG"F՗r8`gRÙ?@?ߴ> 1iOi_|Se,*xPD/χ?ំn?gxFx12A|A.^mcnK~=|(}oj <ؼWNWQOO|ks>Eό|3i2w,֋hxBT1E)hȱY&sQ*o4q֫^Rҝ)^nN0.Qjb1T*N X5<= ~]&G ԟ]~Ϟ2]CMҴfoߵ%wZCa'GWUm] K5 }"[Ӵ9 D [J௕-<y|+4xM=&gc]OZxcF~*gi w6ⳮNgxrYύl&:Jin3?/&@s;g׿f/1j>!,'[>ׅx_Q<GupІ:ZtE KQռ)_bn<> i.4 <2~5#+^hh/?hS[xI-gN/>ïo+P?MrZEn:55|)sj=hy.VXJZuj8BU%5Z49tZNSSTR҅IЄFkIByՍmRtN&(,ּw%x~Զؾ"|!Yihmky_ncԬzs7^+=6_u8͒xoOo/_5|%6~ BO?~"Ma ^׌j 5ux3@=ι{^"?Y^x^_ [jq-({jny0LT%>Iԟ S(֣RUp+Nj%bhc(Ps<73?oէ/e:zf)^ʬT:ml=wNZt:|_џo'-o)ςs7^ u_oK DOmgmxƯ|ymjVĚ4+?hJwC ֺM yk@AGq!+Lo^2׍kĄ|7CxZMM+]]U0ʝJdRI.e*l09RF,} c wO{wJI:oe}<g_]#G}e2X| W)~K5OߴiI~_JѾ|%U;x QMn|cmb |@5߈^ռ)P|%jOwNof~[kY&?T/m#)O~r1ذ|Qwo|'V_>0ִ?kw><%yVx 2~ή'J"ATnqU.fb+G<¤NXEbW͕)) K0~_|]]Fm^+׏u'/Zj-ַWzv]Zޱm{qix?m;|/Kľ"O x .jw΅mQt |Jռ/Y9")_e|e??iKJ.4|)Lh_+y>$?BI@L]?en"kO?|}/nvG|wßn_'N;x\^qڠ!9wLڇk?x>/>hן:5~|9мQ{@՟¾/t{:Ʃig-[7m| O|Y}3nۯus=|k+O'_ 6|>Ox 7v'|-ZW'cFJI8žk GQK]jC֩ZTU—JrjG.̱8xl0 v*QqrUpթ CTVF/w-eR]|5?i(6~֦_x>#mt xV]jڦbS|Ht3Jԯ-{7 -VU i^7ڶ7ֳrw>?_\-Ɵ&iڵ޳k>t /W? gߏ~~?~#X e&f,>#ψkSQğ >Ѿ9 \xFaxN}w)|Iy_rx~H:> i9¿ 3xw5kIlx{<[|,jڤ zCOR;Us u:xt%\MgrV0RŬƄbo~xjSʥIqkݥJz+\gxgGյ[;;)M.|e[Wto>(jaq/w_ >63K{~ C~_ %fmUpѕ|dp(,EL9s*UqG>2uU!jbjү _]Z㓂$ by!'G C Rm*،\*jxL64w]h?jY?<;]GO*ɤej=/|6JK>_4O|yMCw?3+5?gz5?5 i֞OOמut K<77PּI?h[Em~,xZKc_xIt4l"B>xDմ'ǺV{?xO5AW^6~ź iZ]k/Ǐ?M[Sb YռaS׾}7YռsXj:u)R{xƞ+-/:tU9FEakὬS(F.aqxRTW JqRÕe4#K[hS:Sj\63z9 D [J௙?n/wGÏُ<<7Sτ>n*ljtP wSkTo| -/oV&oegIS#:oşC KuwZcl I%(OJUZji9F qp/ G*r~Ҝ(JhS\10R?eSI:u*q/;p#4ֵ?ÿ?S<ټkea~6G#_?_lZq7֕ h >x~+B^|3ϑ5lV:y8tbqx|3֚qܪ'GЊsRzuj*Ul a)KWao$>"鿳h0JuωJiigྑ-۾=oi:-Ɲhj2[D>-|D\_Zm,e?ğ'.|?>?WDƕiVЬZqZMľϋ6God|Y'LKJ٫uo"X|1|u?7͟ .>] ;/=S!+_<U{0>ҴOYGi}xv@4+IƄl&k-eo*qPUS%J (UJx†2>+ R եuk*ΥL$18؊rtR4le:4F4a EsJN~SbG_ǿJ/%/^9]JށS_luBinӴ@>)j wvzFizjF4Ro6T_(>k?WW>0߳G&/I,~+(vuC3_|Aվ |<ş|G YO~)׼OvsZ:Wax6kz_ i:fIa#^O|Eďh^?}e<1x?/We|&'GOImRxOx7H^$^1m^Ӯ{0x-|i7f//h/-t> 4_X#Z9|'~>"Zh uFM]ž9Qv<'wߏiMJl UZ5irXl-NwO2 bEJfktXTiT)UJ 9Sxa)𸔽/)kOğ?}.%I պCrU8$m55+7kJ1٤P??&=Tu?{gHO GAѴֆ/Fh49w[JOx4(w=#½7~5Rž"FӦB]bt)eH 5/牳ʴg<{҄/1}c(Q^-:Ǐ"iIV<o?"gEZ>g_L ExΏHE-G_3/&++eo-5oBV;xO:_Ǐ"iEZ>gOL&df˿|tu݇E[ͼx/~Ɣoÿ7^3?Z>gOL ExΊ*Z>g_L9jq/?b-SM]B+E;)e1E9}~rG$dV*sA2JQ{I4I(㈻ǍqmeҌuQ%i__/ 3~?{x?qe~0xgzt6vztZ4k/eXGkv6vOlO:H;x#ETDO'j*fUTQUw73eZ|csQET+UT;J)6ce%Wڕ?gMepuӼe&Fύ?_|1x#'쑬x1[kƯ)Ƶo 7hQjPwoouW$wC:($e_sOºg~7 ? m%SP:o=iE_jWz鵴_]\Ͼydb_,GHr=i-+.f{x=NKߗ\eK٨P9j0 2RRjͤI."wFHU?<?J(?Fg^Xx/8>+l;K>Ѽ~f"wFHE5f:i{%5g}?6:̯TտϏ!3~Ѽ|@Ċ'APGM?Od?[p|KΩ?wR"wF+tU> ExΊ)ij-.kW͇[?k>Ѽx/U?<?J(GV=+yi\Omt_u_OHU U/7O/O$|#fZ|ee5NJ3?&4.C>o_3jIxmOZ>gOLJ|?_ ;bHnӴc{ssܙ%KxUkU?<?J(}>{%կ#߈׾=|7=sEme4cI?b OKԬOim! E2F^䒌ԣ./UQj)IfM=v8a(Ѽx/QME?f|cQM5 99Iey7%q/ߛt봹lU敻]?*χo?ċAdtwzdž|O/~ǯh:i:]qaz^Z-2C#(ћ(̎Qqe*-YIfi4*<4=gq񎃤 <'GCw~к=ljM&u0|7n̾ԾÖpi%J(ї斞mۋUWnQv]_$QYF-r>sJR="yFHQV|<x$_ (`W~Vo8̯TǏ"iGEY~4f:i{%5ĸ82TU?<?J?*χo?ċAPGM?Od?[p|oEqe|ד6g7EҏǏ"iE/7O/O,%,V#ӣ٫؇Jqk~%>UPG$tp\Qn^jOjW6RgLXA',)?S(lI*BI[3~orGF[C*xh. D#$0yB YRuꚶej$~f Gku923O=~N/>o%ŊG-fWygA8E3$䱩-~Q;2mx]GOO.=B("qFGS9Eߔ5(#6];iI֦)d}cWj]]G4f {wSN Ѥ매r0RY<0x,Wi6-K{/Z!'J>*]nhzNknkX/3mTK1 1隡u!UVݚDX'k&DP(BTS@Ru=*JƷ_kVojH sW5/ 쭌U%iZ vIۺ71 mKs|A_O.>(k絷'Z֞:ZZFNM303?XT<9{#GoĤ4_|Mp@NGoιiپ]yw%Ko?fޖߔ]t1~{+}3ƒFIfڠVukJ; Op( pd'!w(-.>%kts7z[@TZWbʥHw&aS`UCѥkCԭ.wY{uwBZ= 1$ZQ[UZ+F{ #)u8wV/ 4Crr~.t~ +ۯ5$yj@*8%̢ C-~iR('*%ɤRgUH.Xk X1q皓O ffYm9mmYfᶇ9#rSݡ^]ɦ爭>A"oIr2܃LҖřѭp@-9JQx^D5rUCnֿ?Ui/,E^۫rJ9v9T.^ijӛ]1mMʦ\UUH;CP=Jװ.'?VB-=> dD*Vqbׇt>,VeXyƬ@ÐI9~s.S,6,ҷHFcx?O5X*Fӵk."ᙘ*!A#Ývٴ҄cl7L%CiN,U` xG=_ͿƔxSm5J(4stxR?~m4I/?6=>lMAӇ5-X]͑=CzƗ-Cz5)h4 K'޿o޾oQO}A_j4^S}7`=>hm^S} b{gSŸ`hZfjfNiro8jwg[?ƨxik>Z/6kRVWjgExf bįy |DcQJmYnn!Q@Nڳ5e+4+yrcbCwgOi^&utY"g02FчX7?h$?ٿd}tFet22\r?:j:oю)2 `y}EpQ/ o@׾o}zaη62o_)26KdqzbI8dK\.??±u-[,ef {|ZM麓|H9?p \܄%H?0>(ZP5mK^/5{cFt{Xn4\Tֳb ]y-'#ƣ!Ws.NvwS+xD/š[$]~g F3x@ suӿEvtBmxI}Aybh%s";.r RElV: >{mw %"8'{y`>kC_4'O 5/zVJ_CIj+צlF88RvTru𬵟gm?E_ȑ6.Qa\Xy]}baȏ: 5)Za}^X&>QO[g NK⏬L9¶?"|7&u +X%Iyl$~F*z=FjkcLQlyPK:IG&Wa}K V<_A}<)c {y"D* چh x$IaCDywՏM8|<ՇXoפODy+W~lh}͗Mz=}bbGj^liZ/*)}bae}J< ͟Mz0G< yZln1Hf E_ʻ){yşM8x'Qi}?]0q8oBֺem%E"HCSE{4q#Op~?彯MvS?5fW!X#6/={UE/L=N8xJ{_w"o&)bbQ9E/罷M(uQ ޏmm}7R1y= ꨣe8xnkºz(DkͿºZ(DozWAEX{( oo(@Q0Ɖq=a)n?? ۢL^&'5?N0120~g)MH3EX{H3 :_´hĠ,$I®GjOO—j}f{O֝v=}b>_֞!?_֤TaQ_ֳ.tkڔ{DUPg`>ELJ[Rv0ój0A#|;:EIQH" ܢagt( YX`*GS6/- ﭠF 'a$n8֢~O3uoEIVI%wŊר/y\A4|fi \yVӵZ)L_ji>"a%d^DYVHl!zr$ >)G'֟7(? x5#Bm P6'|iOMH yVq3WE M} ?>)@ussڎAyqU%F<=O?oQ M} [.l&n4d_&w`wvPy _WE}_i\-6Fr9HO}i>SB9~waw׷wVWq bD] "1PY= Vw+kKkďYjI'mvq+/O}i>SB:+|ZϔР>)G'֟7(O?oQ M} 먮GO}i>SB:+|ZϔР>)G'֟7(O?oQ M} 먮GO}i>SB:+|ZϔР>)G'֟7(X^^_Ex4 bixdjCWOnflKy'>Ϥj<\y#N fX6S9:4}F\F3k{M|qzC;>[[kZISe+,`\<$= ͎uf]JH)$ U|063Z∬oIm6"sc-jd([ .s\߆j<=}1& n̊"UDfA;3V%>4ε ^YU'*U/PHI/m2XPC8HdV+ʦ4V zWkZ+cX*d"J2n, `WB.4cFWr[*,AXI( \  ??>LO6|_ݜX~^-inl7$&$$6\`'p|@.,t%>y-ү`kf3&K08wt]cK>w4K|٤%@TyNc ^[ 59! xγ6hdp"+ gB W-|kEc&IBt rOSQMcE 4{?i[O$':Jҳԧ 7^;xO.s,/P[$N iX\ =RSӭ-nI}nFd֬QEQEQEQEQEQEQEQEQEr{̞؇.V!9x\=:W5͖;yqo.;7|IݫOt_:zDXx#霊ԴueģȼF#*! N3#jݽ|KSVe=G\\My20.36ܾ]ǎ}B=2_.-VxnluHAr&6/7g^\$5VFky^XAhc>4VԦh-#ymB6*r0XI_l#K'aF{xRO \vU<ھ]306>PRzǤ΍fHi%i&%crƛ"SƼ(Fz:Km_OLFh #!<$|ɼ[ Tv]W2\݄̲;#ǒ2rjPEPEPEPEPEPEPEPEPEPEPEPEPEP\4V<$QGil#UU pI$WS\5 k r^hTg' q>8Ƈmf gs)ܷq| {gwok,}Ij$:ojk{- c]6 )Sźن\IS\ YhaQ6ud$|+\i?p|#qg1c^5ziv_'NO( hw<笓樯sEcn|Mdr8@#^IpppjH5k+oџޤ7pN\^24a_fvx2hǖ7ܶ _ujm|9959oD "~DJU* T$08'jr"e v0A se.{%ZM-A-:ep:'sÆs%[g1ȷR\:"Vprp0Kd R}SطkF[(R<0D!*g i^A[]ioo(!uG|©X܂W*2v qvs%QA<*h:d4-uC^ZTW}DvffDͅы&жaux EYp|$.c*N~`qVz̾} p%̏ɒ!1>x998YUTM2dq<?<2 kw;d+ H8rC¶ڥ7ok8 #FђFuOZMi\M:'FYcZv:Heo#QG'|. AX.]dx}tx'{u%hm*_K WNk[2e,G=kʹߴINi",,v Y4ʎʻߜ+kQEPQEQEQEQEQEȧ:/Ý=F"mvE`jZ:OtV`y LJ[1ר["OQkݯc=3XVvt +}o2F)CV\Ҁ5tݥ2iדieg@/(Y,>h% M2=Zs⁚o\bϻ\m%mkj7ڴ2Kylc% "*8h YFϛjկTk lY>ѹI;o8%IѴm>8mMJʰ? $ff4xo~- #yb]sʙ);r EI:w1MıqaA )W^o1<ۍq}_yCv݀Eۂr2HS]-/Zh.c̶D9% , An-?|gٛ(!n:z`rxrYǧ J}_\x4j RY"U\Hd`~W88u[۝^ i]3ݤq&]n4khmsO v-⹍/p~Q+랴I{~V7ƿ,:ȶhVP1{v2<rUGAė}`d t,6Cp1 6ܛIJrʛv9%w< 2Nd}K$E<v X%kڮ_zfïyaFڵ |;|u8束k-BkxVq"[, ca`Hxh(/]=vO{0i{]{Q:ecK+Qv>vWqH H( rqfQդāb\l' *9$r6z} aK |ZhHM9!/i[;dY^&x**eq!9'f(Jquo.U}ds;'ƟhGKNY>+|<~T_&2##EixpF}"RAO̙'?H>ͲgyטD?.#;y1pP=J {m$O)@CAvA^ң=ٖ?$Fn֦D訡t$O \J$g槯\=KjqBf-LpquϴI:K-؏mĿ-;Ss?w!p n3gm+^g-Qk#p9@]Ăq]xb=N{ C, *36~W7wN&Dȳ8Hd#ip 7cBZ˳ފϮ|;k ݬ!NU g9-ew}$;1fiڤri}bb[f6R~ʰ$` wue$;o>سCp2yB"C:ln6]P6ϕteKm󻷠]^K([}At,";EkrVm!"=Aap,II6W*2Tg: se4m}qsu<֦KFT3 6W&ub#}?n}~o[Wcf18v_CZ od}]KpʗaHdc|af30Pk ťҠ_yR}ˆ>,Fvͥ6lM 5Q sζu{sgugY9 D] m7!;?MfWr@rX@P}2! S~Q':cz͚`Hǿ?ASVXnVV/=;a aPzfI` H'vpwS# 5wQۆY"#zJ|C|dE[E])5ש9y|͎O9tI&g%[/   _>ɹ-<%4%jW6-:D,|BG=ޙɨ}ws4sKpU@_a@g$f{3 Jc׷يtJiޟ/QTl?8G͇+KocS_^lq7Q/QTl?8G͇(KW?6of{h%aj+U7Qa= ?p?05?*͇(ٰ8? {Gf{lq=Oqza= ?l?8G~_Ƨ򿸽EQٰ6oG?c/cS_^lq7Q/QTl?8G͇(KWvG$f{70xG(|)c0eN[dʜ$=V?/kLfo&Jd)Ÿ*}N($.?lF$ yzgҎ1gs2KvON޴}J8ƃʿ/=8_}iQ\oh:Y̫ݓӅO'֏GtW%q' OvTW}(w3*Ŀ7d~SQ4,fU\n@J8ƃʿ/=8_}h>qK;_zp)zeEqgҎ1gs2KvONϥcAe_잜/y>޴Q\oh:Y̫ݓӅO'֏GtW%q' OvTW}(w3*Ŀ7d~SQ4,fU\n@J8ƃʿ/=8_}h>qK;_zp)zeEqgҎ1gs2KvONϥcAe_잜/y>޴Q\oh:Y̫ݓӅO'֏GtW%q' OvTW}(w3*Ŀ7d~SQ4,fU\n@J8ƃʿ/=8_}h>qK;_zp)zeEqgҎ1gs2KvONϥcAe_잜/y>޴Q\oh:Y̫ݓӅO'֏GtW%q' OvTW}(w3*Ŀ7d~SQ4,fU\n@J8ƃʿ/=8_}h>qK;_zp)z"OQkݯc=3\_gX-OomI*2qԐpFzWuy7F/-d#>]^F=:W[8]Fir|P:gG\+~un.|PYp6CfGSAn[{o쿴϶}x&+ϟ>wZCv+Y%M$!c}ēSCZƒj7u|wdGS!v`l%q5~jej)P]=td,(acc),r~\&#1kp2,&|`Fv7;@c*x4kXwx@` &+mJ8GEV0O H,;k=|,4ՙ3x-[kF7F!Yyrce񽰱6=.#};FW$/Gb?~jw7cgc>m H} .Ցur,xQ.+Tf0ݮYGêK,eĄPdy;O9eeXd0T>[ar  _nQo_'oܮ{y`mMb1[O61nff8f* p ?J-^+ګk93^76g漇.vp+ 3v5}z;ZYqw+I$%0PwqoNm15ܟgk[x E (B1q``חpw5WOsG2\s L_ ~VZw~AeYx{أNm_83<9ێM9>cuۯkWVG=̛o xf9 FRÂzؼ4_eד^dN^_7p>߾lwryi>\Cu 5qfH`;Srrげٗw_@|kFUNlbhc1`ܼa s_+7& ,* ' 20 PIq7Y$MS6"5FPafsYsr8 "c_e{uZO5jeWތ} M*-QCI,x RuF $`f[|A`w tH!x+X%X=ܱna%'7 1ĶA' {mI*9yuoh˗,VGJ-S>z\yoXXP"xRY cP +[We~GrWHUYABX0tw%cn*lY[$H*0I3j Zm14>–S"8+ˀrC^+xZkV:|k_UC #Wb͎ |:/i5 UlCMb3<D)%~P y#kGU)9I]4jYgZhwBnpcj2z-wTE/uZ8tLp 0;gԒq8<]pdWOyHCurt$O9)1{f[DDLĂZ=2{Tlzc*n"qx=8V+kB_gq{UU3o|E=ŧy[/IL|(Uh0ѷoO mv\2G A`P]V%䈡b2H&<͠ai|U*LXء +ɰU('MG{|bjTNUXȽ2U^+Sywkh Ku7y\si;߼x}N#ǹ^)Ÿ*Y c}SFONoo1v>|ӹykTFz08&~c;O~c;O)7|X>iܼxrx4Ѡxuo7%;$`uoCuO?L}g/o͟b[B3}=% ;|!wQlCTp,:~%%jZDo1v>VCyO溟\M\De+ 7V+$A\ui; LMcۀĖw'gqmiSlF#b|r= kG߾=Y9<{fWeu٘9Y*9MFbr{g8L+ėzIaMItT6H371;ntVʘ΁|HǢ7+!ܼ}G'sCZDo1v>VCyOmg֬Uⴷ^O{vF Q-U-5ˬ^[RHC[H/9Ȋ \7G]MkG߾=Y9<{ď|z#yrx5OEyu/`_4S\ 9qgßmۏ+n{T왭|HǢ7+!ܼ}G'sCZDo1v>VCyO+m\M̠(& g KRBF(##&1b\<pw0*!I&_#b|r= kG߾=Y9<{/uF+˃ne$ dtnvݸY$ bV~XΊj!39|ya1|HǢ7+!ܼ}G'sCZDo1v>VCyO恨˦#Dn!;#ً9t)QGP"MI"ܻ|,s`=cTw}G9q|HǢ7+!ܼ}G'sCZDo1v>VCyOhZP#Ĩpl&W- )$A9cyTN`nm-_((?w^JNַosE|HǢ7+!ܼ}G'sCZDo1v>VCyO׮fX..$Q;g?#ݐPT2vև[֦t#&i cʩTІ%ͻo$'c:9e|HǢ7+!ܼ}G'sCZDo1v>VCyOj^'eK8RfK( v]}D?wð >S~,İ$7h#;Kx&c ?p٩')/Nrf#b|r= kG߾=Y9<{`ֵ&w٭`G$->gb|Ϝ| ݙeO2GGF쟐W=N2hÜ|HǢ7+!ܼ}G'sCZDo1v>VCyOGԮmWT0Dtb0c9żrm7Zе;鮡GuQMh[p(RI+ rEɭ7]#h#{IY`A9 =߾_)9ܼ~^G'sRkzq&hjbȨM̿3aAqk7˙2ެ eFx `#-litE[]."kkщ #xeFX:R? EaΞ6?^zg"OŪ66H+v#RHy8v|22n.Ԗx€0:(RIja'-;Expkslq7Wh%gj+U7Qa= ?p?05?*͇(ٰ8? {Gf{lq=Oqza= ?l?8G~_Ƨ򿸽EQٰ6oG?c/cS_^lq7Q/QTl?8G͇(KW?6of{h%aj+U7Qa= ?p?05?*͇(ٰ8? {Gf{lq=OqzgGgt2J?l?8\s ׌x_r>0NZҖ3V\EɦL*Mc"_MVj{_dA|)_Q8ҫ|S#o??zU$VtԵ]B5-T`QE <#GW[oOW?6u9޼u]EoGЍ>P&u=!&$+|gf/e6wWM c܋mg’p O$k. W,|΃ZSM^ Q7Ѣ31w:Nc ?1xZ9gXkp!J~sk $J9QiMۢYGVE+)Yp?&֯m4 ֩cyfTfYdt ܖ 68$ի J tlu)# GBku};>/ߴܦs}l8NSqaG%_jnii=bk s,R LѨKH# 5iwkki-A";wcFI,Kֿ=V5滪~{]=-<5ҕB7;p6T-dQ}{@FYXXŸ'8nH>|?,j$d8p1E fcE*d(8t #e@$ko[ӤtvJcΙ}>!>qA. r>oήWʱQEieh+ |s-6bfq&!fR7ls޵ϝRF&Yi\@s遌c_WT}vJmnw j7V 1XYY6"y4iK)UܪrBW>[HlL:Mri3pw<_xcAK{L|r1CHi ڋi (>T9`>U%3Gv 2MbF-U'@W|OaʎNZAR8B8xѣpN99Z[b$w1U3=+Vj͇*9i< f*iGffeqRK7B8b:Qg} ~V#ke0bs8eb۴rzW%<$ݘdi#uAs#}?n}~o[Wcf12R4z;/;{w^+=sy6︹̾ L<6.:׌fGo GjswvK|( $l`F2W s~/%V:k+VUrV ,1lv+gswcvں[?y gb`Yqe*7\EXK׿}/O]wmֺ?-:\]t8wmY3I8VnḸ"MARfb@,2gwD7otQ3^-`G%1ĂvKa-Ń[Xd0Pl O Y["z=/酪_FfD{y-| *8 7']m-Y7y\e)6>wq|5+$vQX\B2I$k^]1RVqWcn1[; ߥ\_TCjR٤nKcC*F:i'PI]mB?[I7cߕC.Qq~Oո%" 2",xvR˱Iq%K,@*A"TUP7NܐqG}:K;]tOzomp)*M }yl0c,JmGSS2w@I/'[RYi0ȡT188D _xBP-^=*FKy;\0 94mBVK{g^6~щq2-56sf"A,^ݩ $?{Yx{أNm_83<9ێM9>c7.'䛅Id˖T۱#x#ˏ x.h˶9Oٯ&LȜn}| ];/l+zcKXHbOY>{y!I 22~Np =뗾"XӼho-e $>v *wqiIYe4e@leڟ3?(瓚Zp)]Aw![엒"q`"06۸V˥)V}~}.K_z"7G.Myqcpfy"2s!Xs|ƅnḸ"MARfb@,2gz4_eד^dN^_7p>߾lwry6)l%k6:0PlO Y[3Ow[ +PԮA0$`%ovw*~7wj>!ax";{1n\,qv_PAnami上3ɳiH -շtMƜ^XMgy""_0.0vMm-),4IdPo"  B[;9ToJ.^ȍ[%ﯽuN{[k;[?O,rNP#em$`d\rˎq[,߆2k k ~M.,hOOkyR?") NrW6EjuhI_m[OT]]}?Rtgq J%Q2ǰĐ,PmE-jKg \ܬP҅?)!ʒ;sM. 1ʋF^r r88={ 6%D 6 n;BpS/z}y}ތ{Ϩ.eW2^Gr0ȱBX`?.TJѯ8WXf@ ghQ,Ncacoiqv$0vdp\_b{R?+oamx`hx\MC,./%[K{U!wd%S#v͠t],mfXu4Q#?2!r82?+44akh\ Y+I, 5]^iuۻy. MnluƌӗBnHQ$3WvDӧ9-;dUEWRQF+ 0y?bgGf&wggxv4-/uwXAaJ]DF7/ɶM)Zw\E+In -WvnbIb; Dӆ-b'U.ęA(vlx I$9zZgFp7 < !%U`%N[pn>cOwMOM.o^CFἕsU2@Dim/PEPEPEPEPEP?#s ]ZS7?0zȣ9b&k9LW)]B-;Q&+$V{+|'1GjEaΞ6?^zg"[mϗ4dX؅*Wi\OA;W.;y4iwE|h]}Wو_}x-HׯdHom ݜ7s4rLTlFWq;C6lgy^sqqɋD^SkɯS$rsPq~GoJU/vʺF.5!YL] S>`67SX}xķחʺSkguȓyU`E8 r7@L)e)]Eڠ'.XNdD[Qo_py[@W=<1O2\\Aq%лI*Z)B2@FOcoiW{ve#32}QH ` VzXg"qz*͇(ٰ~?/QTl?8G͇(KW?6of{h%aj+QEvQ@Q@Q@Q@Q@Q@Q@Q@q`dWFI@ U}7%YEIm}GJ5OUT[?#RVtԵR݀QE*+G?jZQ}l-R׋x;ʾ&MO !iyN fzۻUv^3VY O$k2HIUX S\0tŚiA&֜Vn>kW7~ l, K{B跖>u AeU}&֖&/w7q^4^^<m5Qg4OXՕ&v[nl3e#? {ӆ-L72IN!I"dEێX(ߩĶ^bE\fbq# Jc2ae$@vWucWo \H.! t5QYU)CPYݟJ6׷sip[ߖSk) ƫKM;ijb76szR\,HF'5$$||slkV\yO73n_*%Y9&^XZZ˨7N<, :yg k1ؗlk$-ya=By(5pA,v>cQcG ȅʌtNYԬlju RMI,Ugkk-8K27ݍ2v:$j/AZq?isLrsM4pHPƁE JDI|1\sq>-O*NDrG"HɲC*f&dVEFTaKic-6IF2cY+p;LӂcUu쿧O2;+I[^4LIkky6O3iʳ6y`c-МqUOk]>;V cb^&ԭ$[}Pca,M&0?gobx^ a/LKJŵd1h!^sg2~ vɍ~S_.W2;+3s yyfOy$3I$I'l=HrMvwG?#s ]ZS7?0ځOt_:zDXx#霊SK* HI-7}O[]릩%DK ^,||n$87. 3!IH4W mMb1[O61nff8f* p< _%{v[-v{U}a 8S6%kzŖ1Zºqcu29䣀@e6;z~C$r: 捙#J35./u&)u I`CrH<8#_M5BV_v0nW Gd6x,μlb2s;>j}ƾ~uHxHH8.$r0Hmd7\It.h䌴R?(`W`~<bi!wsiSH!fy ' 4 ^jr_z1p~zAqk wBS#Wr)sS3jifR{Kk0)QL At y#d8rȟ0F< g0xkY}sL/ <ӣ za@ZqϖMЕ.puU׾bi~)V /Ғ~|͛c5"ON%D%X9Xei'PI]_A.hW۷_|&6cjk?eqm0Zl7vUA]5yii?-̄oxZw.,UM:6_'v6gw͌Z>1 zgxR)0[Ǝ11Y@$mijnM2THg޲2 H덮60~Ukm5Qg4OXՕ&v[nl3e#EYmq\VBds#OY"Ȯ2j}X~5[moTפm69|'K2H傭N(iѴD_wK@ev>RHXEڃ qt+};K [M*UH7''q/Zƽu|<s _VEo2xqGg;a|IkO%v)}cݼ9M`cmb 7ˍPj2A!z'E#6cڸfRFW&D\ItG"K#ԒpzW'R/"{˙M`Šز):pǹXm oƿ?k~Vߖ_4*z4*E[ 6;[Dwt>Kv71p: *fzw<h$,B%#}x&_Cos|BeeE%kpǕ 9=z* [rL$4{m Gm(#$,mĜ 5:uIinE/q H,lX(A >iھtzcfX6Ő~|p9V5ΝG2[}i2.`Iy`񡉽+]ߓVk &K>I3!fyݲAPwc$.<*1Ӄ#~³u]CPVtնkkYbhNT|m~g[:v m{W;IlȻ~&`o-$y˙/˧QmhR,bJabA,Wz_iSD-yrAs,R/l'$fkZ64G\d)YCyjP͓:O}㹭$n-ԃcppJz8Otw/~vn޷Ӣ:9t{ 'h1g={tvXXaT#+ss5GKYLМ2g+ָyX]O˶Nl즒YmTN"TGV{'1aPK0r{ O7Ǫ]ޖmN :?.%$;Q@dxO\xI~KWK}Fdh;_ca[ +sQΕoZ}ō ߹k2Ff D|U8M-/iOWjT5vGEXsM׀r1Ȭw>w{0cVȣ9b&k9LVdm^;l=B1y(h(((((((((((((((+vG$ʸgGgt2JZ^*V?/kL03S#o??zUym}GJQTF(Q[?#RVt`Aj[xU4lZ_Vf Mvf3׶.ʨ+=M:[n-uP;ovCEM?f9y;GT~EpOh5S?oZY[vXʱl*7 IxY.kYdqHn"Q!""U*I2'< <;%eX$ +$b0mq\^>Q/]鱛qn-|ݢFD 0La9]W1ԮṒX+ %[c.Hn+4jQ忈uN؍^d zm1vF|pϻroidC>O G\mw6qp̤5+|MEk-cI'2`Jm@2Ry,L+,Si;7W7u 6SaG![za,s5X4hm0`gJMjOEfȂ8Vu%?8l1Hcdc]I]%۩u^ouooxXz* 7{sie9/h;wwvѷ;xI׼KA4fմ|#PEe.e\ yR Bbk2 @;FÝ)Z~mb^h:uFPn]-8g(@Q(~o|,s8_5+&vBnvF}wj}.oMM60 ].iܭ/ņFW £U>.+[C'O_FF\ù]IJM<|Hř؀I$I<溚cEaΞ6?^zg". };:Ny+Ь%916wRc ܷo.,oמּ#KhY3IeXe 7~G5 Iq [NGB*n~RJ L7׿l[K 'WFn⌧hl$CdtҢ&{|닙B*"/ʣHx_KPm#Yj*V̎@ZWTB#@U|P;]g$o|GoS-8;F{}47:Ri $<Иڀnf NIoė*Oqi B9kv㍛r__~&[Oݭ<򀒤G?)嫑píͩuvsڬDlv*8 p@zoM_N%РTk`؋tb.+* &7CAV·k$_8ʖP a4Nmu)Ae>SHaLQvH%ׄl44o/4Ĵ[l4sہFՙ~RAd*X\G7Z? -2Sd׫Ԡc$0H[x9@qkE#O7ap]fG ,07`bGtKEn&/9z^Xʲ6J\2!ڬJ䃹G^.l]`(NH F9dP}ߍK_T㲞-Tv&1 neYVGlf3y^\@ͱ1Ʌ6ȠF02_nQIk܌?t:eN# lOh侻ܻtY ¨I$_~+m#OM4q}G,fK$,*FYRq#mWO6g؍<m\\]jZټO"diU g,>]k-ZXP}LC#B,3̪qU`jYݵvK-517FssyA."g!TGU Bӣ7}II7Ew/m2\x];Qm5[+̏j5ߙ1TAOm.YO! @.<̇?kKS_2_D4_FQk -,r\Bc#|)\`N?_\ ѣOϦyRgUmK |>7Эoc{Z,btXTWS.;ro=^Awwo,7AuC$23J\2‰cCe, eK!uo }GWWmWrG$7R(O2 ݰ, OB>-pj6yo-, p[qebvwgxtx\0814C8>ŶI BBdu`o0 ,S|%wp-7r)\!'r_[g_ͩ4PY-m(P( b6Ğ]5 H;${CC$l8˵9 Z[BirbxpUT*G< ^FNIb@_\i /t}uk,Vh\nXG ;8 ^[in^90`AުQfmd04 FĦ6B @!.GBrMm{;kY, p\9̋#g2+]\s5ܴךWM3[Ӵ`ג yut-F>|;W>G˨^BڃFH<P9RCC{{KHZۥƗ ,rLdmp͝1?H>_#g_v~oN:瞘掝sq>-O*NDrG"HɲC*f&d]Qui_ծ&tp_ڽ{|dTC9V Tl725KxL/(I?3'$$9cËzw[`m嶒6dƲ>VFvS8Ʈ}iz5lgfm[9j*5B^'^BlkY}l yV:jσlgk («}%Kd%c .w4ֺ}Ŝwz'gyd'"xPէmd t7ўYV 8"E8R~jSz+w"ꎞHLwJ&#v6V? #;?ySP𦇩Zzfcf6YTrJpy;_-$7S5I67R-`: B W$^qS 8J -^;hL؛Aӧԅr(N덮񃱘ap W4T#,OLvsi6:ЎЬ)otr,Ř;#8! pYukRٮU:{si5+Oy.w z`U<=i_WKk.PЬu)yv-nfPIl$sc9Len$ E`tP``qX֢$k+ M,o%W%Y.9VePZT3d6oꚯ[hChg#T_噎Cdp&9ӽ:z;i}#ޓga-6[yMs#1v󜜗~o|,s8_5+&vBnvXkAN!mE d!9RfaY@f# *XXxFQ[{4qLd"+\cx6tk-JM>k'ݤ@2ژA I:͸>&aYټHdYIf}Vn#jLw7^}ϒ$6=&fB;e%W^x^[&W2u,Ȱ\TTJb>ؼuQk&RHQ"&~.*8eU\y!rK8k3D\N Ó0\XiS[HBd )xy)^sUgdQ}{@FYXXŸ'8nN:K7Jd<隇#L7?w0sD+ԇ50c-4Bw$2/r;n8f;rFjw$ 0m?#˅4_|{P.9 |/=G>'5%#ίQ'٭yjۙV9޾j!(37>xݒ{کՂo! +Vld?=F W|OJA`G*A@ *Fro 'b,s\6ÿkwiI?E]bL;ЖpXep2!]p,ϳT>U 꺪xUuu+SÐiZwvGY؛0!pUI,)z,.྅a|k,s>tpxe7~o|,s8_5+&vBnvZRY_0e{ϲ }[veyϛ'xsLʚ-*os,27rW8|PTNO7(+{ָg;Zqo P)]_1FOv|˓6fRԛ"hDU\* "N20 .C8>ŶI BAd ><Նݛ^@i'6OncŌhb @Q5qF}s9"Q4V͑!dR>|)ZkR64ۍ>qpLh|%QDžuG7wi]dHPʂ.=d}><`|ϖ[;Al-kw-彧R8=cx2O_Ǩ =]`d)/;c466p5i&LQ y)[ f(@L Jh\^ynn#_%E A(m@TCČbŶ ]]qko<I d^7vn:`.A 0=c_~oFݾn?v5e:ҿ, { n73ΰ9NW TX#g/Vwki(O>1$#i@m8ej}P$$t זq }Wx_ĺᲴ%皮kr#ЕUN KYv6?H%I0kGߞ1[p#pvFk=Zɯ/Fe iYem Ix}?$PyR{H]V9UUVc$`R[p~%@P4I\S8]X< đo1{=Itx5cdA)(̡b ywApxQ-d 2FIbw.F^sشk-g.4xtgbCȪJ8}F+ Ӭom\]yZY`fY1 6@Ƨu- 5W*gN2~%$±$`6w]5Hp_Im c~XJfv qopng/2@S$dJ(rqme _FuK{ ] j5@"ȳ0zndŗJ@-%@:ódx :\. 9Q6FJ[J oZՄ{nAR~]I7g?wI8foII>#-I|+zqkw| Di"J/6 2<_xwLz4ҮgnfEŻ,2od? ef#mu~a}dWrwqqpLh|%Qnl3to^XSI<56 0,#f @V?/kLfo&J)Ÿ*?6SqWR@EoGЍKQ[?#RKvERj+G?iZoCKQM;-QH([t? T*c?uiW$=^?Z@fju=D7Η%6rf 6S.I \^ѯ<%`+Ŀv)Y# #3 arE⋋-di>dS]Kpt Ifadϼ~wZAc[7VJp&/n>Sm,r3owfX䑣utQ .愶Qp: ]Ndcoc>Q,NcgXҧ'Gb {0b|[uc[F=)0ʃG޼rr0{: }3N˵!7'Z\u=oUR|B_;;b7lXWxɠ1 ]~85MCG./we~iZM`XgaTKx<]Mp̈\N .Or[oYvȪ(0W`\_uyon仟KӴx55L 3N^E r!D]mv4-/uwXAaJ]DF7/ɴQ<=&w$.|I#1v;p$[-_7K:BMms%2em J22Ok]qح&-c4K^yډ%6N?WcU[ c{7pY9:-.-^yK=!W7~R"F2@G@fQEQEQEp:S7?0ڥ?#s ]:/Ý=F"mvEsΫj# ǗVcw͏yں4GEXsM׀r1Ȯc|ޡo[oZVOвHp <$cʮ(-v%5^PKQm J pUU2[aR;9ߵ^$ebX(} #oIi:×X\}J;~ ԓSOyZyspo,ș&c4xU@2pB14[)mB#G\a<-ʂ1kbCvim^g Nɵ K#4 ǟ5J(4|)qn؎mB8%y&uhN0@|]9t:QAe}aX.S,.dA- MVmKkKL ^ݭRHA g 0K20|kq>]oTϘIr1+jJjA=ŴuwY ՔS0@"[kImsjh|a"e1@'8ry^ܞ,d%4%LH$ 2HaeB Sw~4zRjP[fG̪Ƭ#r s -uQEQEQEQEQEQEQEQEQEQEQEW:Ir|JM$lyjt:wia0\ٶ2-'s|(BAQ}TPas|fJ6Oɭ)Ğ ]stT;ӀO^^k|)_Q8ҫEoGЍKQ[?#RKvERj+G?iZoCKQM;-QH([t? T?򯉥b>0Zl7vWx:MPxbuX6o|9fD]Լ=j =3If@I **r+3q&KMWM&>o 7~ l, K{B跖>u AeU}&? {ӆ-L72IN!I"dEێX(;𶌚zLW'\N;S~-76\^o[4s{As!Č.@)ɇ3xj<FwK1Or͒yJ7x+?N{,'ؼfͻ޼˥xTk۹-mݵb]UHy%Et}buyM1r@ۗʉVEDf@ɗ5/iyny#YBJJ|16]qopLɌ ^mմu_V`F&T5v7EiP+7wR`ۀ8$gֶ+Qqn/tPGEXsM׀r1ȮsW5m#7I] #p 5p"ZRH0Ln%LHK˸l >KB( C4zNcea @_\څYi.|NaYqWE 0c{;BMw6[`FVWt&ݜm$횅&q$>N8L#nms=BP,9o;p<}^@3?\j Wu->MJ\0V\b`Xr35&m6,R9Wn2ExfbFRn Zn,U!f P 2CZԿMy}=[C(X丄ǶFw$Rف=;-xJ[kE~C2KrL@1NĚ^Kh%Z gHTU--c,@_wj+oi3Gvg*Q𽶥\Iwwo%#)^ ZXeRw8$hM3V-u(; Mд$q&Jș;2<^m~=.=CQ|9e2L[2:i]QVׂ擤3\\\\Ϸ|PUF~Uw'$q< aki&hntI=y12A^v>(m೒7 vL#yĜvƭX6Zn[a1H LN<ؒB9I-!uXUUY0pHLAmj:ŽxY3LA*˵ѵrK7AuSbhҢ-o,3AO'}b$45M%/PUd1$9/&΀1йhK}Am?2\C{m*]˴62rpM}y{}^G,>Ad ><i;x[h$[87]_n18 3<.KKKiTiԯhЃÞx뎏o66x[D\4gqpe=SF[X1Q qj{_d5XȽ2POUU)Ÿ*+G?jZQ[ (EoGЍKQ[?#OSZoC h@QEs-$myAΣ^qk[t? T@34M:C6gy^_ubtHjOa vA<!»cڸfRb`j C#1q+(/d#EdR?bwVW(ڛl͖O𶍥j"˺Xs+ȘB .Uhu dlC^sxX<)k\qKv#f n$w.#(]omdat+};K [M*UH7''q&q FH$3YuxlwW Hؘ?*㗷 'ID_,Kyh'e-6K)6;B.n2ֿjøyrLR,o9#rp@I/ɬ>`"]+E<Ȓ"u$i1^cKҬt[mGwHcTls⹽3Ě^Gb,o5[2_I++18@TN_O>Oxz*h[$Q4G{oY2I}Yۉ9m;y$m³j麅 Jʑ&ٻ w7xUu+k[_,&J/l7#)ٔ7T(:uIinE/q H,lX(A ]ƒIϺDCǸDYGwlT*+BxRocX_h-Is$ͽUpQ( 5x]Ki41m\*MI,GaWoVqv{ʍԳ/Xs4I O(ʌt9<#ņku?-o+K lLJK.?5cxb V k-ݞOr%W";F )WF-SW]&s%532I#1)F݀H0KD+ԇ50e|9KkooM̱KdFێN]k  Yl-1mU1z^ڣO #k;Kۇ/޸wFwfxӃ#[Pjkpqvn-F +8%,{]-7g`(tF39xUmu[P܈H p#$c+?Q1mcgr+RC"+Y܌L);@8<,o.*_ى{ևPe ȖBR A j،qV_ЛU"4) P9F5=%59ٚx$f1m~R08 gXKkiIwǙ ۊwbc~d>"Wd"LpmQj]'8/2Gg{V]K;(G ]ŷ_Az 3LOZTf̻(6XrO;wI@ϰKy}*%M(h㸘ɺEwWPك.BW˙wBcH`,T9X>"S,;)dcA(;H;Xo-_jOi0.{Y 6*#3eBsqݵע."(Z D nJRԂ7$`ݿ/mu 'y!֮ͳikt#m0RrCؓŗ{_ES h ]JaH|NŽTJ?\_^гͽ]$`I`T`<Սwm[To"K% VSA@,h:ƬڜWzخ4k" ϕ>Sq$)%FrziEf3%ަo5iPU98XŒ((((((((((((7Y*u(j{_d5XȽ2POUU)Ÿ*+G?jZQ[ (EoGЍKQ[?#OSZoC h@QEE7?Z[t? TTF20Wxi]6sayku2n#r0!G# kmh ѤM3 Bb֧EڭR6V\HTR8Ȯ5iAkOi}JwkVy۷Dgnd @tt"gFyd.JwJ]6H ,j1W&ŵ<6uJxP.tԟOV{ֶ#O4+}'nYu٭Cek;2'''΅s$j/AZq?isLsx5?F=jiwi'T Τ/m=:?2'dF`C FA=( Xn#Yc au}9QSנm'ٖ?.mHr>Q]FT"MAszuR44+18+H.roidC>O G\mw6qp̤.%z.8d}D.TcGqp|4X.'{P{Y b1uE$HvN[E='Ox-G΁=Q3=&f((@Mhg͉\]|۪CG|Ě'[NZci5Q$v8&|H"^TH\'睼g@Q@YWqtC%}/AU2p nseyi.{K4 €2<=??y ]MGEXsM׀r1ȮCڍ,ZQ' M*ppG^(tF39i~!tˉGynFUZ&B gGNQm^VPlHZxmc`2,>+7dGSc۹/ݬ74m#>SsqۨQ|Ox^XY.Kqi{%6 b7ܤ(Qs šnqH${uв8˕D_|p]^CoU݁ўp&FP|Ybv>(m೒7 vL#yĜvׅ4۫}NDjbioQb|)f O//TUyUUU *hƴɧ bs0s1W>U2sޤEyy}7̺f a yl}!aiVoHYZV {cZ_g\XI{}-C$d '7sdI="@i/5 ̳Fy dE<A[.#nʾfsdX 1KwqN9O]TE} WED &r]);`܏6qkڂ_mLrJ N6YbJw5ͨ㵚oi&(P0\3avgGI[;;K.!t2yb b ImƿϱS:i[;Nf7 PPA߀@mm7Z[D܏$NJ.Ӵ-r/:ŝ]ӺનUPx@Ās^4;K ]A mʊg`(b>%=[%[C4 8,fs"v_]eTiCP'!X>ZACrYH!bs94^]tK>xO,v9!?q=gU])4}. ɯ0 0)-;YT@bWRO ][R{n>$cʮ(-v%I𭎍5]KO>_0q2C g9<]K.{{ {O+$/ʌ|*A;C+U}6I)w  m*rs"x;Ku|ֶT@G|yH" v!^F:lhid4eAFpƨy۸H 'wSHZO]^me r ٝx`Xʱ/.y%WLծnfX4@_h`dp"ZRH0Ln%LHK˸l<سƗcdMȋڸl+rzx}Fk h<ۡGio+!.$%p )GLDb9m^O"1;d˨2 ,<)ubI'hD-31ɚCiN?Yo-_jOi0.{Y 6*#3eYhz&J{鉸F{`h E].0^*-5+o=А aQ˘FInޒkח֫{i;'PT 62{}u\J7#RE@oM~Dj} W`QΑZeڸy%[_RYm5Ku`ѭ#Y Fp}Mo X7Siv |ÄX:2$+qnmagkk )FO'fo&JU}7% O^^k|)_Q8ҩ "TFj)TVtԵ]B4-E7?Z[t? Q(EPSZoCKM*+G?jZ C#1q7VEJ$E `+. 0@y3;Xfi.nB81;ڮ7ܖ9Zyah[%  Uڧ'$rkE젂{xז)nS\[F"F,\{L>d+ )A(b v~͍/JlM!R]; xok ]%gL6Kfb:(*#$,ǪĖ.}mhqHnd+,H*0# "|fV 60hco& GbqQɍ?/s\/DŤhhryV7[~s.2yM;r[#'wVaymͬ%3eF-EVdV>ZԓJy-I,)r~3\}غ÷;2OVFZ$7MB:I.#)!Aa8·IdfI ,AW*cb.vy\6FJ[J oZՄ{nAR~]宂;ZhYcʌn>`=( ( ( ( ( ( ( ( ( ( ( ( u+7Yo&JU}7% O^^k|)_Q8ҩ "TFj)TVtԵ]B4-E7?Z[t? Q(EPSZoCKM*+G?jZ C#1qkº/Lc {Q>dFLi$yIg9Rj_o,2&}<2qN9ڠr]N+ʳ U]H9FQ`*tM&ݡIw/#+$2$(&i􇽂7x-|{XxH-JZ+6:.l׌OŌpOqJg4{eQn_;+jx~wmeqU {=\)o*)LbBYf큁2t O-wwvs^丈h%-(JcR`xb̝GR[t6YheiQ(fE9!M!AcSO$im/,+"@X;g$eoP{E.3S>^wZxV_ xqvl"KR ddc+8"?D.?o>/yw۳Ul91~_菢ZuQyK)U%*%d)K&Ү 2F~;p1Ӏ>^X6Wuw=ŭ '1xٸ1U mm{[KJec1ր#g >~}9||^w|^7Ƴ],Zi8LƲF!`7*FN>[qBJ [rP2 Ƥ##^vlG|NI p['rrH}R֮C<,D6 g¹A.0BzWE3[hjiLNCD<4DPPJdIK OTwѕ&۲7X<7*ӌd/E.uM:nSvȤ>_,7,H\Yk^ k{A%J%|[z1+? 2jXFu#33 PJ ]f>3\}غ÷;2OVF,Wl$R;  7R+T;o_keMK)Xve!bR#mccL%ָ/. 35D @P+b; 練գVVVe;|vrp@<ji4ļmE!{1G)(.#Q|OkW~voY VΊ"Ēbp6?ûH:-Ξ4ٙ%xB lvx$Πחn⼸G$,b#]%odž,(6gwkԖ9u;ղEotZ0B'#x! +Hn[յq/݊AYfeK( 8bk-F)n[|}Ҧ$F]6NdԼ1nQYYċu@ t*y їvUX@ºe֝&ݛۘ&$,x5/iyny#YBJJ|<ۋ3PKC9};-jF#ц b%2H;j_mc2H qrwܩFNw:tM:x+*pC&ETUu Di #4N=:[|vs$UKbIbd'$Okφ--y&UYcW&gg,#[<*ŵrύNM6QEޝ=RCYŻ;X/wiUm=:?2'dF`C FA=+&xY$H&KM6;h-[k.I8C@ĬktjJlvoMJ(h-݄:|@:4.9^mn2! 1sSL<^LoKgN$yŶs%x?VFISWH (6\|B@C5HR}Jm#P.弒ơLea&q FH$3YuxlwW Hؘ?*Rk\:[ 7PՕZdOn,::m# d5zBia;9SFHV7"[3!C \@~5'_#٦P~h׎NF|VƯj7WڴQ̊Fg\tU4t6 gXt4L<Ӟu-{AKlsi70F"@Il]EDdX_xEׯҼ) ReFaQ$OF t>.ϙ7y#J#XCBddsѧ0 <ÜȲ6s"km5Qg4OXՕ&v[nl3e#|=g%Φnm]9ѷ(b\oͷ#,q~z.|gdw3$Mb`!q$(oAԮݺ^ۙ[Iv-HÒ9FOsP?#s ]Vx' Z8啡E#aTV~Q|EZOt_:zDXx#霊Ĺ[hp~3݁qfx^xu=6ߡ鶟(tF39nׇx?wFu=:zdw퇆f[ԵX ڴVRaq|`28̰6Oq=h&r c gc?2'CCvWqv5υ;kE\DPܔ H10oH1 q9[v6"+yp٣G k@F"`p655bOl~dh/eyYn77DcEdž hOIɧb2`)aU*)M CF,.S2YJeG*#㏞(۪"X#},YrҪXӼhڼ4Z~餚;1D-HelfD%21)q|!a s̅2)B2TrC縵$2y7wF0 >Fѯ y#n(qf F _$RiBl{w=q{& $g|6Ncn;t-}ˇd{Scol_BU/t$*ogy>m|Y≮#TD^[p]m8a-y$V.m~E6wdX՘߈{X4&;+o r_1ʏLU@wڐ>z*W_ߝ:=6Iu.R{X]Hd F.%w yo&+kB[41o%@ĩco{c[mLd*DX`81,io:Rԯ.ny$Lf FNP<1f 5t>Mq }Nxr%:d1ͳpӼRڇn4Q ȍWq8$* _FQk -,r\Bc#|)\aa|>ͨ_\G=έ)@ ≴;4%/ l&<G2p;M WsrK ?'o?"f6(I[}/'(s`Aj.BA¾O #'$_OSt禁sbTF?'o?">%e0ߟE9$v;lGAXЭvzd =4'*g|s3 5C9 L<^LoKgN$yŶs%K hچV~d,s޸A,eJK`ګo5Ҭ *Z>t3  Fi^/kqm8#kܮND"0͐C'p+ϳ '"O|y~gv#wwϝ}jH|=[Q EC<(ݳ"*wO]~[rj|{5]d$D^ 3/LԴ?gye5"#;vP\sa4-Ōmi!.݂$0"46O5DŽtqn%pAl̊gVn<>}ioop8*+;~Wad2m#ӮLrmK<<ܭ^%|=i]_]Gn\ƈrJC*A/sZOWwpste[EVt_˗ G|gzFgog/=;Q4Xq9댌uwK%2GXG}ː9#8' v,-RA3(DMk:/Ý=F"mvE`jZ:OtV`y LJ[1ר["OQkݯc=3XVvt +}o2F)CV\Ҁ;'VnJ [h"G!WdC1>Fco'$ /n$W(PY.Ԭm& 䍕 <,BiZ(n..濻/.#{o- @#D\s$l-kw-彧؀B  h4S_jSfILȪ$rKCn  -\#g/Vwki(O>1$#i@m8eh,X:Woa-y#8i6JpTʊO5H|63ZjI/>w,>Z+%c~uSPZ7iʊpW*$EB7 ji*23`M6OFHiKy-n L0]y3^i6e-[ZOv-4ջQPKb]@P 7p ԰𦛧i$ݡK&i2;_/W]r"Ce&o\mX-DŽMH+;~fl. _R4H(L8]T ris_Ќ7 .w9~c@jPEPEPEPEPEPEPEPEPEPEPEP\n#:?%vUkL D[0$d('U}7%;G|So^m&n6FX(`POU77bk gkh) g'ՈpI0zO\_fIR}_({ui_ru$o,#pA I[?*7 Z-ri`sy`ZտId#UUK;X6hCvcX;==XVSM<&Rʤu*"ld1U[b?'ȿ'}jXDێ>ew]wFpQp=C6e5c~O~Osл wVؽO/rZ>2\=ʣ{>2\=ʣ{,kqUm"-w2*z_徵st}e {F8?t}e {F8?CY{c!>E=[Bld1U[b?'ȿ'}j#4ˀp*p>~3G#4ˀp*p>~3Gp)CU/S|{օc~O~OsGuti*U|gޏGuti*U|gޏmfS]팆;l^9o qUm"-.U1.U1̦ wVؽO/rZ{c!>E=[W?GѦ\Tcz?GѦ\Tcz=;Mw2*z_徴.CU/S|{֮;LWo8;LWo8{hw 2ld1U[b?'ȿ'}h]팆;l^9o\w]wFpQp=w]wFpQp=dZo@9#]%ccI;hfU%Ӛ5_?qVjSmO#UQjbIj(Mowa%w{77>R%u]&N屧xiKmh?qInTX33;`G/漕u_ 4WxyVr>. MܥڬM3֠I0^Y-2.1MˈusYjngaٲu.n{rMhU8!@ Řa-tx${/uKL{don?,Hs;C;ŗO}P`͖'pn6ØǍ? nKylB:NʱXTႃg ţ-yI=:s^  7|js5B#Vӱ9pˀk_ph=쮅 ]lTaqZN x{;tZE2(.R,vy-X,ҋ[:bG:PL?pGm:ˮ!tW4v1ύw18 y|WqosgcowavF}DGih@v@Jȋ;='wCgMՕNstOE!>t ~Sܲ!Jeg9ukE\EJZ D nJ5 8zm]iM/YO'2\HcU 7^xW+HwW>tf? DN2Kr܀gk5[s{-儠Ol<)ņ|9u[i2"%!jke4H.-ŹL4'1{/WAuH/uݣJEn2U2(J?Zka[-#5C %U !fPo쇳ԭ!oVIĿv(eq,d3:YC7 'e:pi}k ^5#O,&[J@k, GzoQS&/oZ|RHcSsr8լf߀3%eM7ƭ}u\KDNREM14ش}/#]aߧwF|C-`rx xYMãO4 $ I@6e @S..Q5qF}s9"Q4V͑!dR>|)'pmƸZOs30%eÏiL\[i7:ݙuĂk]:_*i\E°Sd zw[P-Ɣ֊!yj0dAX1!;@c/o<=_Goa k~slʄ#d((u 練f YYY^aYʀiͥ7V^x.,c)kh%:Abv!v<@'_6ş[B5Ue$\+S6gwkԖ9u;ղEotZ0B'#2Xh:M Wq^\Z}&I"XGVWi[ ( bk+XE-ԋsn%LI.q' ~"VEo,VO,1\d q1`IP _Mq[w{qN. |{Tĸ!؟*2vSm7RK57,gyUu#mr.KsUmQ.ĺ ķpY6/ o$R!Ieᘨph,xSl)bLu,LKxL$ˠ rv{ttg{Ǽ9hA +Y-LyabiAjc[K)όo( 16C_\~RdѴ%f((AA X>%Z_k ƞH󑢹G)RM˷0m}F^ⷳtˍV4LWЌd2-Cv-+^YmdkWo/b8vݟqFx#-mn強LrJ N<+7IS•RT?Y>xWg3OҠ2~R Yev,KI?X)6 iF2߹i6 L1?0 Ez >>q1b8o7'#\]5>m?uȴ}B=ٌ!2NFI=-DMihzlI۹!B>]-Q*cQ2NɾwRV ?Z?|.kyǪ?lelaPȮh3!wn* @ڬy3Zh7CMmk&+FEYYH2G,Tsof/V ?Z?|.kyǫֺ5)TdASo5bU/V ?Z?|.kyǪ-MwXmn/'3!!C;x .GmaE7y)+iٽmJ%ǝIf3zV 1oϩڮo&<r8؃ 83*ՆkuR傅6v{T*]7Vվ-M%<\j*Mg_;~zz3zV ɶ5µ]VocGcGP}nKzV _kS"zU$/2S#P gc*O52sjR$Rw w[=G+_υ o?3OԴE& -o} V8 MXVu^xb,efhʴ cRv3V>ƊvoZ'oORkz%5vТE˥[bA#Fd0s/ɽ~F3˼i];Tk䴾iQ dᕇ^{B ~_Mt m//OQZ?|.kyǨkƏƺ~_viµ]Q w[=Y==QA/V ?Z?|.kyǫ7}籣}籣(>_٥ w[=G+_υ o?fo4o4}E;4Z?|.kyǨkƏƏf+_υ o?|>5՛[kz{?{>u_|>5VocEQAmƵ2<^fd7p˛XAkZAzq3lf$lp1a<_GĞ,,W~ռAhs\dMumz>FAa'.zڒRMwhM9AofJ2 xEr1Ĝ܃ׯ SK]N:ΏngQ+n"DY#.vkgh~ |Eb|3TlF2?3׋Ay:1JSކ)sJ-4٫௉;[! ҼW۴|cv3V_?/X.5ouQש6um_&7vx÷i><N⃪6dq'YsCDq xKum>M x{o#kq'Sn 91^!=c:=c:apt|[+Y*sÓ]?Kso|@G_J5I=BFROYI:(vq<;.>!њKKj;AKoHfKxH laA|ĚVz{r#ӧG$UI< ?3׋Ayy~jJuzQMk_{"e]S'}5t7XYxƖ_R}C[:jcm-$_ȤTv)$xC<9÷8wzIskvΒ4Aԣ.NK8'^/_ 'ud_Hp WR *{E|&gY'%WnweuJ8Io[^kAkgAu?Ze˿iʗʷ ^nH7=ڸRy_O{^.ws[}GJX3 EK/8;qVFh82uM%!]Y-$Y$9c\y:ĺ꺃_DC($Q**zkNwH%77|ntʳQj0otQմ{&Լc]Cׇ/ :l!Zwn9p> nSajҾ7x4|֟rmsָS?xn|7/׬5'~1ԬfY4 ЃUQSTJ}mZe~Js[_oh9_xsBCu{}9`_=I++^1ȭ |c4_:0M-+qL<eӧyL ~&\K)q2;>ڪy|S?OLu^'K VRnnJvTRXՄRWEZ:z$KÖ[:f=>KF-";0| @*+3jˍ񖵸U*ѩ<'^/ cŝsN4-ۥPIY[Yi'@eҠ'_uuণgM6믹ץoRޣdz g gׯ}?G3'^/'^/T?g_?dzg)N_ 7G)N_ 7G֨ϟ#S?xnS?xnPA?p?G&:/?&:/?Z?ރ>#lS?OLu^?OLu^>C~/|GަŸD tŸD t}j_z+lQL?3׋AyT?g_}Ok~0箇w_ZBkA_ۛ4[ގL)#b6|7U3?6O xkxV%菋hq=wYFS :Cpc3aW~Q?C˿#=Ğ |潁Mv;0|2WSW٭u?P%W0ȱOiiM n xM^Ow%lUD|~~z[_VGg8UeK?>QMwO8aH6ncv3V"K(6KǙn24x%23_9_x'4njoMt ?Q{hՄr¬pPC oD**֌x-3'ܞ+MVKO)~g_? &h~%gk 5`2>9@?{_oτC.kv1Qif6QR&0@ Ic<þ߈oInOI\Wi}Zv&]i֏iA HĒ{iz8e-tk_gorZxMIT0n6Aʎ3P,[FiWC@#f` + _xOntx ;jS&m_+(ˌsb|{ohvK+d]2c*>ee ئ[ce)읗W_G~Z[nw>~-񦃨a 6u-ZXڐ[$gv4P&gil.xd*v !V.|`I h6elbpzHYB^7,u|coko\71V3lZK2q,NM;-Uv7}ĺ5-.P "ӿj j~oMV O Bhid4M1ʖ8#ú0 ~|x_GޑD=|Kx KTPIkmhS9 7f6֌wǹj+=}Żr7_%/˩޹z-MrTݔ]51ĥ4[S Ȫ5xL5XM+{ĐD$Hrg88ȯ:uwaj~(m5&4ln\"k$iK7"*2d0h_ \w#E.XcޝzSwnw}ށ۽wsn}ޏ{;z>@۽wsn}ޏ{;z>@۽wsn}ޏ{;z>@۽wP߲$RIˎI19]y}+k_앭Zx~n7cO+(DeB~)zG&/\^'MMdxF!P'ˏn$yjg}}?(f{?9^5?'C_xQ6wsMvK ݒD@FN6XM7 >w}.Xd-o4򜴯q%[o+F=}Og}}?(f{?9_4KԮ~5\unmMR6Ҥyv.N{qZDr ZAts\6[b@FUFɗŧl<}k}}?(|{#PdK{M!.mm#.>fqpxlaҵ+ ?Q{IJ V4R) "0 N9>Xy5%uoxC㷊xogcbMKU81@fžo5a~^?z։>s@_ZJXjjw[͍̃c ϺxĖ 𶱯,z]׳$#B8S=zQ6j;woQ {ſqžo5z|e:W/ej(ovDLBy `P[K׆g*&sj0m6QzӖ2[2Vjź.OC)nv$N1glwvaW# KMb?h75LI$vrAAsgEiXҭTX]fP3+ ԯ9ifʭIϏmqȔ}\%ye+? M}3^LEwe=+vb7Dvo0K W5{Mc+Se?9߳K`gv߼1q<vv7~||?kD>/+/qaG|_>>"WaE?ȿW#6J> ? (Er|_>>"QϏmqȕQG/Õ3? ?||?kDŠ=~?GϏmqȔ}\%vQ#08||?kD>/+i_+g\%a]{H"9_??>/(6J)ʐDh(I>saG>/(6Jճ}2E>"QϏmqȕV׷C&m$NHs=jK[~?>Wߗn{j3זIΟt-& RmP۩i~(wM{} o峾MK>_>ND#w펼WTT5M_$gſ>'%h.\|7 {e<.K*dV# }IJ:\wvb_w۟/rqǡQZs| %?0* ( ( ( ( ( ( ( khcKy-W?^m;8=oZ׊|75gk%3I3G]ˀh'i.u=5MFI.,Bs=rFG)Gq=GyEtbiYmj^:yi>$զӮB)IѨ8bR~BG3QEa)[MJ7Ox [úRzan5Xգdra$Y`0zy*K~HP3O7J޽⧏'g)xĶ%ݖ}/)>$jX2pHA^#8[Ck]BQu8egٽ'9#kοcR+Yaa̮l|A޿OXi-rX ΈY$Pln>nß?/^;cxSPG.aWƊ>b fݵ_KS?k!Nm>n<ڈ`4 n-c}+UoK+ =4bЮE,`GpTk99JҲj^Z3*qi.hݧ?<'|j35K{u[l3cVC+e$s%ˋ 7Oy'KD(DmwX8u?xRZ5R4p+nN[9}+<?`,):wnb3]Ʊʤh6䚧STԖϯ[o~vװ(YJ~ZuݞC{P\O oOri%_YR+1Th9PXVū:Vu]MItI ⡃z5maڬuޓ%7[kFCWbWh_CdVquEggat4JZ+^"\.q&&HծQn?/ľ"˯藺i5 K%2ʹgVڿ{d;J^g\klfl4{i+r.Xp@8 ~ecT[u^]\]M0I"Rb8©k<{xC KNg7#dǙM~]38=yz|絎',Z'_o#/>,kόx:Ğ'u*6;p𽬫ityFL3]mD[=C~-6mNvۍ9e kvҵ?6Zw 友%{=MtANx?V҅$;t0-1倠sy,?fO #M𾴚휭4^tJCXaBs?_/۞'|!\j1/#uh͸I";X8iLjt}A;Lb/X*rJ a~hz--\KQÇp&Tdȋaŷ KYAXӵ$/AruV!6BOX/<.'g{5??rS>j:6Z+H"rpM} t WG: :}3yݿw݌v^{ГZX:׿ơy!vfy Gy@z'h&Z?v./Qetr߲sF[~0~]KtX $z;U_ 05 '?OҴoM+ǣ-Ffmζ7rp:q^Zɦ k95QE@((뺠4MCQ14IJp_jSe'HJ0`z=)_P8O ތחVz=Br.,uR2~Kr5*G:i8M/JQzj KYV@R0I}awh-h6fd_z#*92j>+-MIze۶v9]4FKS|AIco,+[m;4G$RHJF7\̷$\Gu+ *#NkN8J1QVk~>⤛mOO SH,W^C7?w_V7e q"> ҷȣ/O8\W§IG]gŝO~&O[}nv.mI~=G.a'm̷ GMebJ '9ݐH+NkZu^3F.YB&CrҺ J>1g6S53_̆ÚKs[ih呀?>Ρh1~=oYh[wyRk?οhXگ[Ou viRQʣiw qYڗ"Ptج#Үl2iL#o<8ƴ[ׯ~ɼ*·m{uwӗ_x>=.t= +[U-,“ldCE)uL[SH%&agx\Ke4Q'̍ͬpJ`v­?Ykɢo(hD 5'հXqѓG}>MCTY-5;Giq}(v'f7_ySR彷EJUY|ݗum{^xz/_%{Pd 2;sy㵆I"5.HU@OAXׇ~0iڬo)͛$7V g$sxOڽ)4D7c|3wwO.,'{c{8R]H$⴫i.cɤcG hrve xQJ̯+DjO^ֶ~-mϠU״ǶuFɆa:F99`sr _xNZQ2_;^wG|<{v:{!XJIɓyuh9{ԵBR#zd>=⋫!g9n1N_JjMO\Ot1{37v91:| }lэj)G@~uȹ}y"Sm>|#u  6삇Q}7=Śt֚Οur 7H8 jו12sJ<,)_sQx[mFlys:>FF'#(u3GHQIյHQ^MTXخoX$>sPo4 x6Vqũ(FdwhwP_և[Ews*M $+)AE>Svtt62d6"~e\p~5gbSQER"E^= )T qRݕJ+,!}vyУLVE.VBXO2W[[{jƷcȍψF2FQKA'ҭmEsIjHGS1S O@q,ųݳWo!?e?Ί>OO /E"!gqo}E-9~돃o(amSNg0QgS_54{v[K4~@Q?{`o D-QYmj wd'i> ?e}~nmZ5ʭJ0[JSrbyxM#j찬rE,T l£`]?z>Aӵ[=*Q1kcCk ~QE׮WYTf #"^>.9GӾizv6/溱yV{UXv -N[dcDŽ+)>ii{;kֻݾy9Q,V^O}VVV>Bկth5Լs9y@["BۏG^\]h7Z΁t̐s̆" cuA+r -w4Q酎sG?z>rO9ȃΔZye>>io3BJx>TJdaFqÅ~[s=m}7ekߡn5h鵽]\|H{×2OHX6"5 *,Ck&/4E$KĿ$keە ەU,ۯx#!7ty_FϳvpqƜe>a6%hnQ^W6.tOh:ե~An'챕P#9v)Ph7-eX2ywQ 48{ַ_hg7bC~uʐBK F]w#"e*ÐMei?< x MyQ_2܁8E)?0Gb0Iq=mw ?~xsYhm[Nf78&猒ؑy> FėcJ-χ-$(]""tT+m to6>~c\<J5f3[ d7dr73Ho, rW.<5uhZ]cjx-o+! m$B7Iy~;0ƱCDAP8J}x.Phm<9Fl/NM@Đ@$2$7šwSm+SA`I3^6+͕vE*0rx5rN7JTW럴|=iZ־&,P{kd̐쑮Fp W]VӮC{K2n`yfE1IJ7 de 4YߗV˿㷁˩+ylϳ}|ݿvxxvo!򠼹I沸;REgcf|n=57VRch0wW~7uǥx?WVrKo ]@Ȟ_7]Zl3C ̲\%ˊhѣ ,L # MY%m+isjO6M>[}\yR?.&?; ܳ<x_iˢmi:F/c]1aB }/Fz%^ '7мU"U[WOf(mhQecA.ʪMjߴoxCn?vPWpH+f*1(BOw12ڳi7o+?|FA{!kYrƷ4GA-+OL.gh''{Ɉلj*_M<:ζ^0[8u{9&#(0 )T? `FT1hmiÿ>]xc]t~ݱΉs]& q:iXb (|Me#cڞ47O+Ml d_ݺ`w);4-o8٣~X4DIVxaa͛ wb~GR/]?7E*@c>VHS ߐ17WהT}N9->]2pw_?C4oNҾ0R]=JTK-Com%Ӽ5vJҮOOkys,VWażcfI@{Snw_?ɏR_Gc|'xBD5;÷Z%Zh$"hveY .SKb׼]kX2ů-صH=J$ $<5{6g  esntFĬDjە(np Ȩk[9]KT-}Ե5Zج#n 1kΙO<2]IA[l" 8ݖ 09}+[{mlf$s<:,n[ܢG"[rU@}/skrȋd4#@`{ xGy['Xgl.Fglx:A#ou'ʃ^j\!MŶoN@Z"s vwYh68,g "y󞝪%j˨믶QH_%=x=cx3F/Eퟝ66%uYpf4?~_ܑ}s.%$"X` b)/?U_Ni~*d~q}5$yv6pI=CYi s%Dk!-tدQ`7\_hY?l]MʁVO4R]Xl8h]H#AkK_=oo?QH(((((( 'o YG )tV~%$D6q"> ҷȣ/O8\W?qo}E-lF>_J82X|6vQExgQEQEy4{mkǾ鮖4u/&b|Drx' {W(z(sι{ៅ04ͨhwVlWH] pARRM')U*8Vȹ._$Q._$W? ?m{3]xZ V.thl%9Ym2z "3]rx~AGM=zKibyDK" ѝ'JXs;m~FVwo_yEEy?? >?Wr6v78{աXŀ+9,|+h~5]gPt|iZ Y$#"0p9 3ݮgQAqEE|o[xחZa:}W0 hvb*]F7wUR3j[ 俁$K8P )Twӯy8k8]+$?ӵHG(HG+ǿAyxh_m:g|Yy~g!O3Mp~+y=GZjF-Rfeap]*TFYZz%N1MK=]#ڿH]#ڿHС|&m,ĺmNne3Ylɷb3.5?!PNt3x7ėZX}FXȍ@Զ'2Ǡ!Z'ntm G?G G?[RHG(HG+~=_xrC0??Q??QߢmWAtj?"Atj?"Ug$;#]#ڿH]#ڿH(HG(HG+~=_xrC0??Q??QߢmWAtj?"Atj?"Ug$;#]#ڿH]#ڿH..4:Ƌ,vpX! ( )3Ò ,!.OO f/ />?~돃o(amSN|E\|o_c|(F_ jpW;O?͝Q^Q@Q@O©xv2𶱠^,VzS< $BT@8c=<Լ{4N->m>lr.2Ag3^+t:qRϻ3 GqvGL$=B!B瑊͚ u/ :5鉤AjW{t$#Dۉ$E{E?naȔ-yCw?Dpyw~ݍI֋ӧq?zM[ivvzUAhBZC rG?x"ן7xJ?͇"RPmi{ۻo79>_qZ kn *Qއax]y~Y@ )h͌T7e Gl5=ogn2KK6Xn+п͇"Q l?Mi]NMwy|$=ε +=W˴{"veLAt ѿuy #hk_is8ԟ^(Z6BR?+kA|%^(qus?V"ן7xJ?͇"Q 7E?naȔ-yCw?DAoX^(Z6G+?ߢ?͇"Q l?g_3WE`-yCw?DkA|%?οg3~Z6G"ן7xJ=~?_fdxG:75|:Vav$rY%KI$j"ן7xJ?͇"Q 5OO ({+C%CϖtGu u~8RpLlΡ V°&h2xϊthVfQҮmB(KsgQU%˽GTe' ֵoþ1滿4kl4xIe[ˉ ̀Y`#4v/m-v=ʹ[Hu`\25i_ _*m~S<8BipkQV0InaT1=^Ȭ#ȑ Nj?z/Eټ/wTyn$vUd`:!Hw5ڂg~?j:>[Z(SU`$d]Y(9 ?ڟšoH]3\x R67Jo2d%G9{w:V9= Jn'DF,`zQcVhoՏ6si.y{Pq/gڡb#3=kh[_w~qߏ-ۼCkƾ+,u;xM+T5\J 𿅿ΟvގerD]Dؐ_ic 1 ŀJǽ+m}=(EPEPEPEPEPEPEPEP^%*?kOi>TZjHg X( Ie*A*Uσ> dž,˧K! 5ԤJ 8Bma :(o!?e?ΊگĽ䈆7?w_V7e q"> ҷȣ/O8\W§IG]Š( ((<=鷖3 'Q/%ݣ\O>ǀ,x9]7? ZK5ާr5fSk+D"A,T/HPXK{ Su;oä_M7?0!kto@4T4J<$)Q<-[q@gT`g^v֛iXΗVWq$OU9vwO'=?ɯO :Ge?|SC6C^{0?|SC6ä_M(Aȼ`f#2mپ)H [Qe}yO :Ge?|SC6˲"فtɴf#2moGe/E7?0!hO :Geߢk._foa?C/&tɵE]ܿ9ä_M7?0!k~=/r/?پ)H Goa?C/&{Yv_r ^{3Gu nji!w#s|72AgE:37J޾Q"?q_?w_V7e sT(˿aQEថQEQEJ`mGJ,*v4MB6+$6H]B1 <>|rE\񆇮]xJ4k}>WVr}xdue+ǐA9x]R8-iIVG^UkH?ӪiZFu$BOcV!&O <c_]T>,5OmNK&&fB|QFK  t}:mhW_X-<7sW<*/x@,5.,牥 C6G8o٣ iz5 S\eb$б2xsb|?kUࢣ}O>cE*x hxWR6O)6sMy%yPUcV~cxAHosI,HX+Q/; uVssrךS;!J9^}/_gʾ!_4/XSG} \Jg+ɟ9i߳?DP)#e/6u4n;%ɅtW@ wWk3o['KKv-/; t}N(=>/; t}N(=>/; t}N(=>/; t}N(=>/; t}N(=>/; t}N(=>/; t}N(=>/; t}N(=>忆SH,~u]kvpZXltDBv 9QYVVD$\53uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cpe/0000755000175000017500000000000011665471326024762 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cpe/image002.jpg0000644000175000017500000010217311665471326026774 0ustar drazzibdrazzibJFIF``PExifII*i,Software: Microsoft OfficeC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222=" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?ŭ1\-(!$!B8&I6ƃ̀s/-l5KIPx 3}y;]7vg/1&$Cm[#%3 y˥M= Mt=Piӿ_VגMB&8a$V$[T GݜR\%Ώ%4 [HUeqO\jZΝB~ΝB~돗wWHӞt\Bӿh0A3 7vy8ftFtYW͵ntx[Q ;{ZU[#J N>8̃SΝB~ΝB~&/$#e#w<ѻt}@Ng3#9//\ R#LLpA|fV! =})~-[kgo— 4/rGX#ؒ008gNOtgNOu)o E6 $vWT>Pr)ڻns\W3K2,(\3 r2B5sпߺ3пߺ;ĕT (Q"TZ2h8s:2b7 2.$힀M?///)M1돓<Tq^jzΩ-}FC_ w``tFtX3x(,ܚ|3ڑ(&d*|wXAn-.ƥYm F(A^=;ttFt\3Gv[]\$j PU_g~arxhce*m-Kpÿ)'O뱩;?ѝ;?LzɥD,q<fyTTI0d c cG2 3ΝB~ΝB~O Y˥$İWF8"F=6৸Ӻyӿ_ӿ_^ z>ކ(NOtgNOu{-h z.;?ѝ;?ﰷ-htFtWކ 9ӿ_ӿ_^ z>ކ(NOtgNOu{-h z.;?ѝ;?ﰷ-htFtWކ 9ӿ_ӿ_^ z>ކ(NOtgNOu{-h z.;?ѝ;?ﰷ-htFtWކ 9ӿ_ӿ_^ z>ކ(NOtgNOu{-h z.;?ѝ;?ﰷ-htFtWކ 9ӿ_ӿ_^ z>ކ+y¶ObʢAGSc v_UIgUVy`|q1ʻs3Rw Z\\/ Y6(+rIR;BF@+̿_GX&uM/LĞ!I.FUԥ—PH?Lila *yRyM !"xNi閈~u=I]%䑋3-2I<}ME,Z[ݬfQ~~x39A$s֩(wa)TFιD>`w8 M`x K9`Ɏp'pF\t# OYlMLM0tpW8woۘKS'6Ժ&iB[{;i.mWYg]\ý&f,*T}syzq[I[.`f}NS*6ݿ,g=h 6<|mqIPsKӞj,}d& ɚ\o x=xǒE,w 6?ˠx]^3F]@,6\'j|?m~W(\/c˙`;XHW[gm>iMhBݻn㞕c>V+X.PO F9D \08C5?i6ye 夼6Yv"8*1+ϱ+oG}[ߕ ,+\Z6XYYd[.B. n:sQ Osuvy#RYAbsI篮j}[ߕ ?Q`Z 2Ln.eqFBJAp+q|55s$Kd_ϱ+oG}[ߕ -6:WtɮmnRћhԱBvO'h4˽wSC!YvRU+gϕ_s1'Iљ9iݹXnթ4O Kzo4Fv]:qg>|?m~W(\C*]*9V+;JQi_o}c>V+X v?أҿO>|?m~W(<+mG*}[ߕ ?Q`.yWb;JU?+gϕ_\v?ت?m~W(ϱ+oEi_o}<+mTQc>V‹sҿyWbgϕ_>|睥(Sϱ+oG}[ߕ ,;JQi_o}c>V+X v?أҿO>|?m~W(\i_o}<+mTQc>V‹˞v?أҿO>|?m~W(\i_o}<+mTQc>V‹˞v?أҿO>|?m~W(\i_o}<+mTQc>V‹˞v?أҿO>|?m~W(\i_o}<+mTQc>V‹SSiN,B*,짇REUOI#"G#B `.~i qZQc>V¯G8VO[r3K2z("UX5P:1]}[ߕ ?Q)g5ݙH,[ mK3gs u'?Z1f!O6E[Iݒ0+?Qc>V²7vuaSO]iXѡInaڶ3q9j~#eM-eElgϕ_NR4l*a@=šМF*U̒o3+p%Vú^:1R70d+d+w6Xy%ۨG͎2/q2'ʓ)"뽳1d+d+]$..z؉n:^Y  [:w?:w?c-I=O(.~IK =]<76q49 J,IQ>Q(m>7;Ž`Ci4m>+L'O ͽ̀o=4H'ʠ҇4[m>Ӵ5K_Y[<{#!"xr@=͆Ԗ&E;34)ŧf[} O;%زF7YlzVN@OMɭЊOi55Ͷg}!4 {Aۢ9&ei+\,P} O:w?WFx"ymYUbRP9Oi5'M}_'M}_(m>CNg# N~R|Z&}gki59n#4h} Rശ{R<-~T$s3>PݷAbh} _?i~W)K`L+s;Oi4ZHo6q$N~'M}_ݷ 6CFiZ}{ig +I ;G 5<+%ޟjby֨-4WH4,>73§,P} O:o?:o?bh} _?i~W(i~W( 6CFjy4kO,[YD%bM(瀣IګwDlU6hp=4Ѵ>U;дŁlΖ;s^sBwm>b-%)-#gGBl``TZ=ݬ76vRC2 #upFAz.CFj͎go-ťPĥPG$4.DWKBBʎ`Ki4m>ei+d+ Ѵ>Q>Q(m>;;Ž`Ci4m>d+d+sOi5'N}_'N}_,P} O:w?:w?bh} _ӿi~W(ӿi~W( 6CFjN@OGN@OG0XoE^>Wx8Ṓ8F}6>P?uj;x+=.ݶh__sE]EDQE(((((*+Mm8T_״ dŕ"6cy=Iⴙc(͝l+bݏL&NGgW5f4NUz=?Q]M1ؘ^5|mŌ1Tʼs,pZT_.8 Nz5:R0-ֺZz4%Nzyk&_*wkkL𜒝~x"y`$U%vQ4h׫NRǙYdR+uo7pj?n1 |mݱ{-'B-im;F]bom#Oum!&THRIcW7`+JzǬMqs @Z`%S>Ѩɇ"<|9-&ڋ1x3Β8@2W<=Hw&|SfEk I K|^E/l*L?fe9h$sk(דr#} V? 4!҂vN>;Eu=W1$HJ-c$8Ty+ʏ*)}ᷖWdTPHzc$-Ԛäl.ZCvTry!J~WrnȗV7a ų9aJH9'mdI≑Eِc kLhdR`69OD.SDŽ/cskfȱRQw99'SS <ԑT\N[~BBqzy!5/ ]kk{{a*шn-f|YSpb6^t2 %*HU`AUзzij}T_kڔq4:Z8)`U.e0lUVΝgm%qq^F)i*<ͼ)4?b[r58㍦% gsOj__[$G6Z2֦?9;CnSDy[Qխ.4S-݆^圳=o>J(.AB!I^Rϰr.)gO4vfd&q!{\ @ʶ܊<-cuv3" $S[tRYIYAEVeQ@Q@Q@Q@Q@Q@y'_EA^^IPUCq3Wz\mWQ\o&RaER(((((:Uѯry \#i5z??OЀ/qFqVPp8Ȧuj}Z*!4Fc 2P0 hc2 z$(70 xĤdF\n?Z ( ( ( ( ( ( ( ( O7n/MggvIJֵ;KӴĴy-·#Pp m^1[2=#*-BiEq3=#*u?l;J+Tkx|vasoϞ}?GH.vW/?|f?H.vW/?TY֊⿵e>zGU2=#*0[ ޝsl+Tkx|,~_֬bgf7nA#>7rkΫ,Qoٶ)u=v2=#*oϞ}?W.e.^_KV5;$WAv'3U9APc|S˞}?GHgu}eOK=Zo"7qo>xg s_SujuX59'n.c zGU2=#*Q9g9NNRݝkx|?e>zGU;2nvW/?TY֊⿵e>zGU2=#*0\WH[_OQf;Z+Tkx|,kEq_2=#*oϞ}?E\h+[_OQ/?⨳ kx|?e>zGUasoϞ}?GH.v9eK]" My_jUV[E=d*YK:߯/?TY̿ YxONH9-dX QC#d`|fʞqzGU2=#*0oO56(-W!H$ޅO\3c?Q楪i663۱4DXOf aX0?.4?|d?GTY[$?uP[퀧ќ%tNC7P=SY,k%DVR0B fuW'9H[_OQf(1 u:Eq,m]6"p<-ֶS"ve-L8`m.92=#*oϞ}?E\hVi%L-7zGU/H.UA($F[h˂F|pN9У!/WS`YH;(^T3|oϞ}?GH.vW/?TY֊⿵e>zGU2=#*0\WH[_OQf;Z+Tkx|,kEq_2=#*oϞ}?E\h+[_OQ/?⨳ kx|?e>zGUas$K_+Mkiܷ@G0oJ|^)>LɪK 9_]:Roζ}k,[[W>HO=>M4eqZ-&I|#+)ķVfyڦip- )g!€\nshx3tӹɨMx!X 9X`8pĘny5;꺣IE&alh5nz'de|ݽޝfZI$TO5A,j3ZƝjB$7: #n(y A㩣'օYZ{B[YF30q)6 oi1\}"I g$,̉~Q{Z=)%y0In$vmh9ր[H^GTQ/,|Z6_oWh`Zh_F- -QUle?ƀ-QUle?ƀ-QUle?ƀ-QUle?ƀ-QUle?ƀ-QUle?ƀ-QUle?ƀ17wF5s3_[,Wmjձ3B0 $xH kČ3JA<ƮZqn-_mqu 20R\~'ҴmY+]\evܰPΌk'ܿ& ۰>k'ܿ& BOi`?RWw7|Kuh=>'!QE!Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@&Q)h`z Z(0=LAFQ)h`z Z(0=LAF 2GBh'tdΒ\Sѓ:J(EQEQEQEQEQEQEQEQEQEȟw`__mȟw`__T~!t'?{|)+>%|:4?J?Γ(Š(((((((((((((((((((((((((((((((((nDX2_r+nDX2_r* >#ݧI]/ i`?RWw7|KtQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEsv'8z|D[v'8z|DU] ?J?θ= ՘NNJWU7tcX-MO1ѣk/M':|;@褮UJrAR{4tR="-+#Ş-O YC>"bݕ42I_jb sY0H!#UhTu!@ 9^Jhcxinc`KpN9(<{MRVռp:Am;؋([ ~jsY-H%(dEb|1Fe'.O\:GH#[1 ([\Gm߰~7wyVbխ٤7J*+!$4q^]}}hJg\2EX1G &[MG-nz,3\Oپ]O~]P 1f+8 A51 H}^W.jq)-#/RrQ&=rJ&K$!]4's<9md[8̒}$6z^k{KKK6[(&4"b^/u}۔ A)7|˹z{/H_[oK4S1?D}WKȐH#Ao:eN>gQRhmj'$'\v}Guw*4BijTh.?&>d _n-^{evW(3(8㪐a t~ Bi^/m RQ9V8@`|1m%İZrMq͘^;c cekNȳ4#HKO9>f2whO_ֹ4ڈ>?Yh.?3ܨo*Ycb1 pCz4QEfXQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEpux?eTg\.]s7oTwRMGO]" o{5h=>v_J[-n@x~j#)}~h5(ٮF]]3̈́ȤӅP/f}ER55Ì4ۇbjAlfCT)e}ER-k?ѫP/]0J&E'ԓZPw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?h@}?Z?~Egghϓ֍'>OZ4Pw|O֏?hz5YD(!d`Q /M:Gy\X7o]1h=>v_^yi`?RWGQ}LhEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEC@wH++/M:Gy\X7o]1h=>v_^yi`?RWGQ}LhEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEC@wH++/M:Gy\X7o]1h=>v_^yi`?RWGQ}LhEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEC@wH++/M:Gy\X7o]1h=>v_^yi`?RWGQ}LhEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEC@wH++/M:Gy\X7o]1h=>v_^yi`?RWXGQ}LhQF=ǵ!cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@cڌ{PEQF=ǵQj1@ V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}g7+ؿ3yBm@g?]kok? /"Яab(A [+YGZ3yB7+ؿ9P_> V}.Яab( /"Tt}G7+ؿ3yB׍5԰v[\20Ob?TK-P  |c }]N@>L>ª:0%Іگ)]nDDGmN[[ÕÐ7O@褮n.%;JkZMޟcXnDd!3ɺL"@V*f/}ӺCDcp[rIԓZJj%Si/Y,{\b9,FwmURx 9+:rZݠX cʥv8#9q>jr>"zBirp Hf#3F\.!pGW!j^ Ԯ I;3omkIw3[9֡%KA%uo2CFvWc5EA/rE'71OHPk^| X97Jv]0y9ƍBŏRaM<`< 7r7ḒJTi!$KKz̈́mmrO#f;"SV?!?"?W'$S5R[4Sm ʲ7`g*2k6PkK!'Q&/r[:`ݕò5EA/rEWuM6++%hWȵxYFdGl;rElC<Kv}Dq-Z}д,4 rI>?7/OH#J?5+cCѯ@ݻ!ƕ?"_W'$U kDjLtb%Jϓ/g8쫂Ojf!ْw '^8H9dO i_+)u*sBSysZƱӖmCf^*J ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( (15.7s?l{/MIi`?RWo} - HY7#Wi`?RW"|\msIZ5uE  rd?羝I]٠KQh?T)\w%d羝I]٠KQh?T{F!Mo{ߔd羝I]٠KQh?T{F4jcK3I$iBHYۗ8S:{̮ Wah?T}俕%65~RQMs{ߔ}俕fy/O09kN[{m5űTHcxKtH%4*9rԷiwg2EajmGﭏ7EajmGﭏ\ +Vj?o}lﶢnQXڷ?Q{c}rսڏ[[VﭏjmEܢo}lﶣVj.{c}ڷ?Qp7(?[[սڋEajmGﭏ\ +Vj?o}lﶢnQXڷ?Q{c}rսڏ[[VﭏjmEܢo}lﶣVj.{c}ڷ?Qp7(?[[սڋEajmGﭏ\ +Vj?o}lﶢnQXڷ?Q{c}rսڏ[[VﭏjmEܢo}lﶣVj.{c}ڷ?Qp7(?[[սڋEajmGﭏ\ +Vj?o}lﶢnQXڷ?Q{c}rսڏ[[VﭏjmEܢo}lﶣVj.{c}ڷ?Qp7(?[[սڋAkVj?o}l廉swt"o* ԑb}:u.I*~_+Jb4t%n56Mϖc'G4e#S7sxnzG4e#3xNW iGG#gV\,f9/UiGZtQp7AҸe9/UiGZ =`LoG4e#3x]>DP) =`G4e#3xWAԟiQpDchIS歔[=yb"@o-Un3+ V*ikcJ-V?oWj@տ4 aj_ZұG[տ4 aj_ZұG[տ4 aj_ZұG[ěFGMe *Wj[YդvcY6dֵ.+m)e1?_CXj4zUn]mVS"QL(((((((*Ҧ? QjL@%l-B2\g]u J:42TE)A<"S?f?ojF{ qI=u'ֶSnȄzVڍsA"Mo:Xr|7r~*LJWI3fo6f_7W<ȵ׬I;cWe#I/o?x>|8S>^H[?ͫIƪb ;p>eV']J;m>u>PrU"TJ~Sc%[3LR),ُO}Հ5f@M8#??߳_/ڼ ,H9r?շQDuE;}8Bg#>/K˺eF~QZ_ p3aտ땷zӬ?uom(((((((((((((+<]zy狿7OΣfvOj}ˬ²7omq}}`K}}`K=V_V_>i>ߥ >i>ߥ V_V_Ee"1Su((((((((J>BeַPDž9Y@js^Y <1DeLm!8 ʫ$wR&jY%K ڮ}YMggVBy|Ȓ]q]t|fcjhl4K6p)`0 EU&A? ΓƑ 7u1~bɬb&A?͟7h*.U=@k??:>ɬbH Hhdf 01MM}/5 Ad1tX zVE*MggG5 A XF[[':aa=Kp#RV,㟽U`QEQEQEQEQEQEQEQEQEQEQEQEQE.X?pScXI"6t FK)5zjwenmV @`([+bQ:mV),*RL 8>Ns:js$>6C*Kf`f*#IkEe{Q[bv6d!€\\|U*h'ML&JbLm.V+_P  f۶VyBo~ŵT#10ON._=G(\'?Ǩ b?_/?sLGb?_/.vW \zLGrڊ1/ Q \zPQ\O&#er?1/ Q;j+._=G&#er9BmEq?Ǩ._=G(\'?Ǩ b?_/?sLGb?_/.vW \zLGrڊ1/ Q \zPQ\O&#er?1/ Q;j+._=G&#er9BmEq?Ǩ._=G(\'?Ǩ b?_/?sLGb?_/.vW \zLGrڊ1/ Q \zPQ\O&#er?1/ Q;j+._=G&#er9BmEq?Ǩ._=G(\'?Ǩ b?_/?sLGb?_/.vW \zLGrڊ1/ Q \zPQ\O&#er?1/ Q;j+._=G&#er9BmEq?Ǩ._=G(\<]]._=\u+`;%Wfc20sqV`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.cpe/image004.jpg0000644000175000017500000011646311665471326027005 0ustar drazzibdrazzibJFIF``PExifII*i,Software: Microsoft OfficeC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222B" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?;آyPH^ @swޗ\ u?AҗR4yS}͘Tˀ$kЬzli5;p쓁 j>װt!tZsLq6|O#<ͧ(ͧ++Y|9zx_^þI$uhdm쓅^$c:1ӥY5 HcVazQ̿P7i@=7 3i@=7 |C}c3ʖxUgKyHhLRrIr\vz[K\Y@RM`w8MWhΏ66nWCC2Ĥ7ņ6|cPo_^Kgd&" n$pv.'6H4s .fzofzo.[kW ҤYo23>i?uW>}JVҞ5DH0Tq&?1 ̀ͧ(ͧ+Z2;HeJx a@_#*׊f̐Z4 2ǃW#9 ocͧ(ͧ+S.NQk33A¬lBɜINqsY֚ 2Ipbi&Ly<79Z9ju9~~AMy}+ 6 nlo7!UĜA׵mfM;\ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5ho.ͧ(ͧ+S5hoҺ/66O٭.ͧ(ͧ+S5Gkv2i@=7 3i@=7 oݢ MM?[fh/66O٭.ͧ(ͧ+S5Gkv2i@=7 3i@=7 oݢ MM?[fh/6mmtv0H$W[wJJڤ@$_4J.'҅± ]wzayV,4^F!sqm0_@rcLی[F V1{61`89?'2Jӗd\u3ƽ[[ɩE|~N0a$潓^EuLHvm^c0A ¬<%%l_˿vwZ|1 $m+Wn|x]cM[ص;xc'`2Gt=;|6^6r}ɷbM|5B BD$dV-ho~s\^^UWgmh/ͿnS& Ifff1oG{>mkU=Lbừm"4} Ԋb)9~E_Ƚ65w{ 5i~3FqⰢ-r,$ lNI`O=1rUpPV)yƏ"|/?5k];7}԰ r'17r؎WVZ燭$7rE8*"v'*:W_"|/^ϛckDh%Ԧ,emFmc8֭Xԋd2 |H04U̍"|/^ϛZZiJCm]]J;Aiv{d{֌.siZjMzr[F J[i` ND^ϛdkƏ"|/?u DCb׶qBc`d+,BB#szW D} sk咭&HToF̊q Q ~E_Ƚ65F] ~a[;7ωD\R@9@W5c}a;(Ccj`V$1F"V?x()`rGg^ϛmk|Dt[Ob/mv\gV"Eq$'=O40.gW1B q֏cSsD/ͿE_sqo/D.; gk%SHtyl$, m콕M/ͿE_񬈼[}{ۭڬ$Vmr`wWF-%!5S6Y>”qONvdt>E_Ƚ653ԏu-F+Xe%]٢Fۢ ``vT0KH.纂Hm),P60à *U̍"|/^ϛ4Tm ЊV&bL6d9Ru;ѧ^ϛmkr9X/ͿE_(acȽ64yƷ(?"|/^ϛܢf0oG{>mkr9X/ͿE_(acȽ64yƷ(?"|/ rjʢlqz/Ŀ*7i;$5_F5 _ğB=#?,1]X nPQE((((((* U[Qw`QIpBTyZ{`d]Z`OT6Z>KoHt =%`%\`u{אX'm ג1[VӹxSC*Jd9;T﵆=Ltin&)lSֺMoֵasm~,!$i#T4>i c]GRIXcnPl?S^撒zyzzhtuUmxO'[= ץZ]hmuX`,dGii7Y$FI<>QR"I}6&jx{H-NXR`p3HWNCu'3Ek.YpxoF:mA${rpn?DZ*ۙ<қzл$ ߽lGѯ7}M|;n^Ԣyw #*? \Gpt 4k(:$qlwW*cqVܿ@3jGE7RoV̻}iJJ&r v}v>Tir0.%ITJE.iw #6-I;V%Z^wR=#u_͹UOa5v9,d?)&S%"v) ԀOՓir e iK,/үQG  ڮX0DZ4e1*c_o6\_k[̷5V[+siGi E8?Lm~쎮##vc/D1Fm 4 |U`"9n7,H55T }xufjF~'ǧdwUxJm>69m.f G1,=u4QEQEQEQEQEQEQEQEQ\o=Ml%t//6iග2AxPr;*+bDZd(h|2Ķ>`ŁW(O\EL//Ymln]0Tv!2ǐFZ+'sc,P?C1 6!-UO^jogK2P6OV1PH +uƪmt{8._RBGȆc t0d+`zL'szj@fY5Sr FORA ;J+PE#[Nh؝ w ؁OfM2DQ ̜1,c,I3"@=tK1VGse$M!20M;r1R ^3>qi<(°ݭ6,UQF@98'FdkhV mi#EA!)/B)P 5K9ne6F!Ԭy oWOJytVr"09! njQEQEQEQEQEQEQE_u@5Y~%WXMnj?#EO[ND+K2Yedr#Rr#zq~Z  :2A< bc&Wcay  qb+vW-l4mZφZ5u[: 2b 88Kd]ߴy\- ||ߟ<><+{_WfNj֣cſ֬O: ]F?/;0n9s.ǜD"pv|ѷG$c%웺wk2ףcſ֬h{(.6YKdRN~aJrF8k" I$qIN6rYzWծҿQҿV5zo%ᴚ_̸P.%;UV:4c?EjM$ 4** ΥE{;Xcſ֣cſ֭lr_ CC'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֦O&Q)40 r_ 4'cſ֣_ſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4'cſ֣cſ֭lr_ 4W{f;o1JwNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJGNjJZٷ 3ohONjJPz7Yit F8oU5ݥ-1Jq?54qzOF!B4VFy?#k'`qdzdƄ) (((((((((*4%x7?GjMYIwwp%60ww`qiqOqcH0%W[y6ȅ>|UpLִhhzΞukwK|[I<ǵd,AŜ9 r7c880zgoaYڋI%N$m)\]Oˏ͞)%M@@b; FԎbfi2> xr[v0:GuTǠ:!U`Ɠ.o?r0 y7UEM}'\Rai$Ҥ6\37,bgtY'!.SIQ]ϔUG [KMH;,+K0*Ss SMF{粗δ/n\,v29kw*?<7?vq.w]ϔTy7UAa)gnssy}]і=8}2-..!٘Ə  CedHFUK"\EI%ʊ2͔UZL#AcU<7˭.RH2_VP=qڗWkҘV&7bUu؃}u_]/ .a"OiWr[F{?1ol:᭜ "FYb^0\Y?0Ϧ7GhޠV5ȶO$y&=;o.sž6Z, 3M@9*}Uxɧo r:;.\Ybp  UuFTB̂[,n+[AbPՆQE!Q@Q@Q@Q@Q@Q@Q@Q@'z?W]L@kb]wA2jh]N/W|I(5_F'`qdzq׌.:SДQE!Q@Q@Q@Q@Q@Q@Q@Q@C|m?N}+ao&[S&ԥIowL\5x(ĀVż1XN `;D(uݜqԏQXtEb K'ǻea}u2]դ1qQp+#ŗ}`b=*+4/2LAY`\`2TmZ_O"Ycw R SԌdphgjO4mI>o&fŬVBF"c\ %rHg8"G$L4Tm0}>W܎hwjO4mI>o&>!ROydkhW$~E9@'^"=]#xO4Dإd(pUHM4'?Q}\;Mk+)4uxYx$ b<|y2mqj@X*BI4um]=Tmf&:LRGTg5.7oYPQ#Q-Qek؂GN;=@ G`tH{~!I좗Hm! #m|2aJ"O #L 2++aâI g=œVȞW$z:=|I*ԃǶWna2Y!l/챜\0ܣf@uԁ@$'$ָkw%Mo ^G)@,yV⧵sZ=qrVHJ8;gTȣ,Ѱj갬:q+n =p U_ϰϤPʔrK X+*=aB[x?t \YEo>qBw4Rg bEt`H?أm<8Zbg?d_`xx:2D1!(R@%$l}} bYϤPm|2CgRgH†' uxfCZƠj0Y61~S8[`H?أ,)!yKGp?J|ex]8\ zq[`H?أqoil`-w#GzT7oR]-x"[(+z}(\w#o}} bYϤP+Zxq&m8Cf]ہۛ>Ko+Ӽm} og,m oi{@2dv 5KSىb<×a4ª*_>C";6gbtTq kƭu'tURFgA&FJ]x= ZWu䶱M/ ɽbQ,Fv NJTʼF}qZ?v_ν_wUF,u;??|?4⪍X z,mg "zQL(((((((((((( @Z&OMVO1j ?54.j$Ѝj?#EjoWG^0=OָZCq{mne K.Tg2[c׿OLw5('h?R<v={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`Ee^?;GX.jQYc׿O={~x? V_}^?;E={~x?c׿O`@Z&OMROPn'bA_7ڝZ\bO#DTGmx )%Cau _ğ_CW'hPm0kriڔq} VyQf]/P!SF4/ kTg';wo@ uɊ(em勰 z`9TAE);!I+aIu;GK$'- }>V)iB0;o3Ղv^et2@ S;aw3|?b 1#UFoy_,T,g;Uaf+y{x XpQ$d $C1I]-J_C,L7SLm_x|4 NssHի{{i38aZ(XR,k{)U혅g(wq'Ԭ-d/a,ʧBj?#V6ٓI$q{wA-QzM-P*v=UA$"mC`cǕsUzۧ_j76_Gs _/ؿԺty]]S,?gɹc Q_j>_[}̛}@ik<7Jqp-3T~W,ڽ2 YJS @/֣G=̞uenlZ?a?'}@/֣{Ok7_6_F} 2z* Q_j>G=̞)@hFA?Ȋ#%$iمQT (((((((((((((((((nO?J+nO?J)OW|I(5_F'`qG-Q4Rit$lU${9_Ox 5=+RmrC*#r2##=+ Gwq[j= >c%em9.,-n緞9e%g\\:[E~lT:O% zjηjvqmVڝV#y*:zLkRZiVqg-͝f#@#Ʋe>k8j=֢žf ے7KQc˸-Gގ}꺆o]Kr|iiO"0(r!UA)*NMf~:Fm/LI&@ Y-XM<ļnN}ޘ|7%/qZ+4F[c̲3[<̪cU$|ʿ a.e\Hʷ6;byY `9啽fJ8#L"U )1xV3Y"vG m\JT;8p>jC}FQK(/.Je3o[ $xCl|!kގ}YMP+ WhT8bP$x<6;jFŕ3]^_EUVI60.[t+z@p/n4o`&Klw+n>g1$HFpL9Qq.$lmU 4.9 z>s@ƉjڑX7?lh'&Z4D@|&-oͻwQ\]Y6J->jp7K,9#>ZyN}ސ^ ۿ]-=ZC%ԫ$FC ͍ǭ6ڃW')9mE8h?zpWswϽ,|s5g[xctd#dH.-I7YaVI&GU2Hrz@aI! -(ot.H8edd6(^>?. E/y@<}G(??Gy@J)|}G^>?._*QtyWʼ|]U(??Gy@J)|}G^>?._*QtyWʼ|]U(??Gy@J)|}G^>?._*QtyWʼ|]U(??Gy@J)|}G^>?._*QtyWʼ|]U(??Gy@J?$xܪX  OR+SO?qL _ğ_CW'hP uտr^׌.:տbƇ`zQKEҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(0=(ҌJZ(f/yğ%}o?Bg%j$Ѝj?#EloWG^0뮋ZVWG^0뮋ZVEP0((((((((((((((((((((((((((((((((({ZżSO?ھa]bыX|I\QD~!35_F5 _ğB7+#?\uE-J|+#?\uE-Jō(QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEZ=uF-b'sIEm_ǰŬ[>$s(?j?#EO[!`񔒰r"8Mn=n[MqUp3V;.somy38iWb FҺúoO5Y4>ؿ]g >ؿ]g w oO5Gvq曟jqgxk Gxk NN.?wMƨ b w(b w)پwMƨ oO5E\oxk Gxk N oO5Fo],~ؿ]g >ؿ]g vo]3}BQd?Q?S}BQtj ߶//tjлTY熻}熻лTf7'.7<5<5f7'7.?Aql_3l_3;7.?wMƨ b w(b w)پwMƨ oO5E\oxk Gxk N oO5Fo],~ؿ]g >ؿ]g vo]3}BQd?Q?S}BQtj ߶//tjлTY熻}熻лTf7'.7<5<5f7'7.?Aql_3l_3;7.?wMƨ b w(b w)پwMƨ oO5E\oxk Gxk N oO5Fo],~ؿ]g >ؿ]g vo]3}BQd?Q?S}BQtj ߶//tjлTY熻}熻лTf7'.7<5<5f7'7.?Aql_3l_3;7.?wMƨ b w(b w)پwMƨ oO5E\oxk Gxk N oO5Fo],~ؿ]g >ؿ]g vo]3}BQd?Q?S}BQtj ߶//tjлTY熻}熻лTf7'.7<5<5f7'7.?Aql_3l_3;7.?wMƨ \DۀCmkW r;zp^K zvxRXgdFP-W}BU{.WKV]ZyJciYj$Ѝj?#Ej!tzhۙ-VA,Qdl/$$Vwy?#j#.Y\˼_<cpn'f4@<1JI䉔aln !%Q$9ӹEh붒d~g5w..Hocܹc Hv4ף{kIauLY]f, Sz:)}~lX%kf5)cR~]0^r*w&4L ыPUOpKd::(UV_p:mfvWvnƽ 8-m9?k%dK'?9?#%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOrC**(]9?ny}𨨠 wA<Q'?¢%F?真 tOsڭѸ۵  sw|I\QN;!B4Qj$Ѝ_Ox㮇]Ht1Ѵ u8`2#{1k'`q߉&H V\FI> /qKHHONJgs+8զ[PhaRTJ^YOB*ԚDFヺ{#H}^n.%apY^//f8>qݭi[&./rE^L&Ko/Zѩh}Wv9X6Kcˎ[ S5ӿS˧Oq$ mo2yHgiCa"G}Uk+|I"+E%Npw~D~tJQn_֡Xi6^M`E{4*:( EjoG6IEfmZ=I+7Hd[bne#?E?R Z,q*r# ;I5ccZZJq ڷ_$Dc?wnwdmFo-RiymN#,tӑ zٞ5 ~T.]-3[[kY$eI#9ƣ-יy,*Da+_"V|kRꚕdpj0(+>l]uv4 Ȇ\\qrm@Pr@Eڇ NZat/S[eq(,^X*dUI8&a+8d Hb!2$]#F'/x PW)}?TE[Kɴ;hd5ϮG5RƮ>TdB w0(1do㨅-u_I47qƶvv`iv$u8c#x?HBͻn%7ͧl}JP?ӿVEl}gГPx mn.B9O˒}fޫi\>nJ yn(#99N6r1EAjDaG|3@m;kU\Zkwzi&mج9rec(`%Iķƃm^nhd1AȂ=c3H>s|_Z^]*6+Tc[{3cBGr%Kkd5,6Y$үUUc݈Hi RK+æ\Kw%Q$~PɂugG=c/ߚ?s6+aN]?,FN5~e1V-w][K$Vg#dwۜ)YPZ0P~:6uiD O}d F#6Vŕ|o< t3VOSI].MRQHaEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP\9WI\9S[!B4Qj$Ѝ_OxOMgy8+GlxWG^0뱷H37O±cG7'>)c[(a{Zq)X@TWh-.Pt v풠qTըTթXei[c%ey$3(``?NJOY–jۄ*Pwo?U~?j>?j,Ҭv8N39^gxwGa Lx_Dy_ٰa38TըTը͠W-%T csonrGzj{G]@ :sm 2@'Hɦ}}X/4dx4u1m\`/ 9.b֖Q p`1P}Tœ hտ QS"oE[TըTը"oE:W#".U}XSQG{3D?nPA84[ozY^6՚k$DpJn;Ws`@lBjQi5+ (gg1p; 瓀122szG"o³gڽ\C,V RDC!@%FT])WV[dG}hۅN`W9 hտ > 4{A=؁y%Xʮ9OA$R4&F"G;kJ0͌pN-/V(D^|7SgeݟFy#FzMw1}X&/'>/Ehտ ͭVwc&t Ke4:Qk %@g FGzG"o¶>7n( W&.U$P| f/V(D^|7VѴj6 y89#sGp1 }/V+F̭-5s$k,7dqveaT[)]Rt@@Xd/V(D^|7VL K̆F؁N?+zG"o¶>7n(dPuYp[oz[c7?Mc7?MzG"o¶>7n(4mڥ|`\.A%`=SD^|7Q[o.uKqxTlI&(zz_%͟"zwd> }/V*ow $a74?˸]"D^|7Q[o~_,?Q߳\u2Ә]]* H<-.'"oE[TըTթTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTD^|7Q[ojzjzTLY 'V9Vtl([?n#E-qU$`d9fIe{K n2AwB!op>nۢ1͕^ ulgL.wm$rN2p;%Mi]UbFF '*Npr8z(|/fۛdž8M:X\R9,8K$q-HGePZ@ kbgaP T-asm=+KM/U~}eCc궚U3YY5ʱȍ R~ Ð1$n=֦(.m))=X̟?o2ƕ_jdD[5ei l`Dj6%aP Zlb$0ouqtC&&[qpjI|,fOљ?En|5Y}ѡq#Ll“/˖xP6WVS؈UdɳlbP'xW!w,g̟?o2Ƌf@ϾYVZ8BB2F< l)#&L sX穌ʊs'O[h̟?ogkP"O?)_1HРf,@l`0:;Y ^XuO%T7̤\Dq$(2),Q2ľW>1m4OE58o6Vm\ mޫ&AxGZg>~m5v!a$%''mQEQ@Q@Q@Q@Q@Q@Q@Q@Xb-9V{ZżSO?# !B4Qj$Ѝ_Ox㮺/k][W#_Ox㮺/k][V,h}Q@Š((((((((((((((((((((((((((((((((( ?_1kO?J+j=uF-b'sIEKW|I(5_F'`q]+'`q]+4>(aEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPk/yğ%}o?Bg%j$Ѝj?#EloWG^0뮋ZVWG^0뮈ַX)p} >E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.QKh4R0} %>C@ E.[/yğ%|هl_1kO?J(&rzOF!B4VF΁8l `.< q[]i$tvzvxfGcŜgDg3/ O&9b5}ohzJ599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WVy󟓏EjsrMho']k6*od8?)O3dO59?9b4y@}7?4y'ƞ@}7_Mug>|?4h1?<>Y<}?F@}7_Mug>|?4h1?<>Y'h59?9b4y@}7-JKQp*; XfD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_599b4y@}7WD,So'G1?7ꏴM=_59:i:r9^G;Pd};\Q a&-GW4P4A 5d_CW'hW|I+T##f$#dmI?Rb㕇e 9AFeG+_]k.|UE+G 1uQE~w@]Owꨢrk.|5ҩcx<$]utq(24g)"Sȧ=#@*0 ( ( ( ( ( ( ( ( rOӓb?,/?Nm:L6Th󗍉'fz㞕7|K:Ṽ0G^lKOxMK|CA1Ey-K]d<8:wUgS0HBX1sq2>Gv(D~I0FGmjW i:'jAFM!1 qԐ?3O-4i 7n*6?_+ŧ=Xykn@&AHcm>iRI%6=OZY?Y+rO p3Ms(۟?W7H$^0G4O ГqkxfT*W g Qֲ|(sMEk> 34C]&ѯZU7zҪ(((((((((((((:yTu?@4-_CW'hW|I+dIh$ur(dg#ݠi?yO_M lOrb~/>.G??VhoG??Gأ4PoG??Gأ4PoG??Gc#{= ufDEBJZ(((((((((d7|K:UBʯ[ՖIA==AuvbfX$nog'ӌ&eǢX%P2.~8dcgq v;Λ:P,#=z+;OO 4C> A\eFpsU1$pNI6*5ğF5ğEO[Yoio+Hҏ>sg'??Ƅh?M^h:|v:v%G3?ZL(((((((((((((/7jQ_oзu _ğ_CW'h%5[-[whk0֑yW8W4^'KKmJ2q<ydQl/6$-! KR5L2q˿Ŏ:g"+INms v 0^@xM[ϣAs;O1+f7ݹ$M?f?AhasO:Ư=+G6p)7 ,zUc'hʌbz_:e4Us=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wtW UUs=?.wuG[S9\%W?Ts[y`[֊T(@2`sТv!B4V}.5Dߜd!uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.packager/0000755000175000017500000000000011665471326026716 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.packager/image001.jpg0000644000175000017500000035050511665471326030733 0ustar drazzibdrazzibJFIFCC"   B%:{@K"YnE[VdUYnE[VdUYnE[VdUYnE[VdUYnE[VdUYnE[VdUYnE[VdUYnE[VdUYnE[VdUYn,ֳMQ]>UM]o,T#'Gv% B[)?w*Sc[Rw񽭭okHQwk(Eġ_2XJQa)EXJQa)EXJQa)E "4BJ *4$ВBJ *4$В_Gfs{\Y;RpoZr;_gUOwοr]OwrǚDZּ rFܲVnuǪ{ǞǸZц Ϥ GBދGB= :͹`盡ny9`盡ny9`盡nyt7'W"udD6+^cdůmφ͡ˊ[8l͏j4秹TL;Eը6qG;%{| r1-wɂrVZͣi;ǗmLoNn3j5&I]ngkRX^y}~ a,.OSʬQyG6Wp#cx9[?׫=k3;CZ\ŤLڗL\?z:s|m}=SnO@~y}sJoٛߎh[:lJ{0M[vxtvy{%>1]K2ߩn2_[7$0>z$ox߲n0,3#L08ov`bqcFgQkd4in l{bu/̦H@#>`ƹ%댌7{{.EGccZo7-\־{Wj:R}-M}u0]~xlOeߙoNy[&ޜ~ZJ&by~lvI_X/qْ7Pn'Jpv#@>$#@>$#Aa=;Ul/B)c5$#@g=p6̮ by.z ~fG#Z>~L^Ϗz2xL'8S UWͽǗimӳs;N.@gvk|ox߲n%Ek2h}Tk 'Z-s۷B횶Sͧ6/m 5|ox߲n<܊or='^YTVʈP3$9D\*foƯ*TERJU*TERJ%@Ek2h􋣾(Y'HrbxճSE%@Ek2hZr2ֿUdŦ6r;j;mP#5`ڧ JHwMߏؿ%@Ek>/d=PJҥJU*TERJU*TE_FɆvU*DRO6|ݴ? אG]o~r)~{EeQZοѷ-7͹}*+{כ B,ޚ'yןzPw%H](Z#_ b} G. ex4O=oĽ"f1]1ݱ a QMVK!#ïim fH} GH} GH0{_-NjMO|K+*eBE99W=#&4H˧U~Z;@0;! yf톼? {_-NjMO|K+*eBѤiNѓq/Nl.??J_[L5GIs/&*ٰP,hFo>^k#. ex4O=oĽ"g2Wj\W؈RѓA7,DU*TERJU*TERJU*TERO7|ݰאG]o~r)~{EeQZ6;zM:/Ӓ `sDO7|אG]o~riz{EeQZϋZ:z<" LHy y~A9e!v[7"\IVUg-XT"PB*T"PB*T"PB*T)ћϛ>r˷B|.M7}%Sw Sqr\7!MSqr\7!MSqr\abj|҄n=B_*hVZ}ʇ2/W\) G Gā|H Gā|H Gār뷼B|zWNҙYͦ-nAVmT&3ʱ0X,< 1gsKhƌf{ҚvpDZ荇bm8lgn:5( y y9%!v[~7p,Bv!;z8Nގ!;z8Nގ!;z8z*sݵ{9:C{9:C{9:C{w*wx멭'oGBvq 'oGBvq 'oGBvs@VUѺF2;^7g>z9Fv'SMÒC(adp进]g |`s|4"gQ,˷ΪY;umfQ5fEfYYdVefEfYYdVefEfYQn -v"fT-V! 84@58 067%P#2!"$&13`O6.8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿqn8[-Cp!Ÿq#RG N)FS煣Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^5Y^*kkkkkkkkkkkkkkkkkkkkjwga&6c" aRTf-CrwyQ D[H#l( {tqYWhw-ȮPsxma2e_7Gvw+7A\BP6XIYpn*a0 3Qzj=5MGGGGGGGGGGGGGGGGGGGGGGGGGGQzj=5MGQzj=5MGQ騁һk"Xr]3d<1bcН ⵾oC 125JКҔ+bŦ ލ6xaݭ$̲Z݈Jо,Q[5:r' jr"m_G3Se*ܛFM&ѓhɴd2- E"`ȰdX2, E"`ȰdX2, E"`ȰdX2, FE"ёhȴdZ2-FE"ёhȴdZ2-FE" )04JitK{3|;EHmg䱓ɓG%8TKBq_vShXPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPXXXXXXXXXXXXXXXXXXXXX/ 焗 @ %zb~ ,\*֘Ňa1w7I:+qPEkB#51F:HQնुC[cyC5uEMcV,&E|hd֢OL%ˊmLF"Noo$ ^Rq]gN/pMڦq'$zBʔ{wW0DM#Bv'WΘrO852iY& s]+1&j1bdKf+U BǂNyi slj*ys|+z9D |V{pPRΎ)Dq-SZ%èZ(R/hL,Xֵ&n.67t*]n4^WDX\ hKfA¬*KtE(l*5cR#l r釰Rm ZL(u};иD`C8UAM) saW6Qk⌎M2".샅PR!Qj]qs_2 A p8d2 A p8d2 A p8d2 A p_e7 Nհ pe֔_Kth8g\sd6@3d6@3d6@3TLyvs #SClm,ayRSKt2@CoqމU?|#ك-NkX#昡4T2-Ra"JLͪKu kKLoRkZK'ye? 65Sv ʙ4NNΕAe՝eǩLWV55J,~wKU1TI^.PM#F,=vXJ/V{h\ϭ)u "()qH܇qJRu]uo֙录5&\ OlLnnoZ6E(̑s1E.755 J=m|Z#rSqIp8@ q8p8@ {}ؠmؠmؠmؠm&Vؠmؠimؠmؠ'RRT+-=vlP6mP6mP6mP6xۏqn^^tH5ݭZMNǛվ֦8D#!BęR3"ΏaTI4}v᭔9(s|tHS6FS:uGUUjUL9T\Y2HIݚu ?nӷ]9Kk(tT'6>tbL.H]RZ-Ko=iU 3\Y8!.=^u? ~7QnGẏu? ~7Qneߦ $Ȩ^:u7+K}F:rUIwoGQ gWY1f:Q3Fcu1f:Q3Fcu1f:Q3Fc[zi<ِ@u1f:Q3FcumWm|u.j,)Z]C$Q7!)hCunoRru%=e(n1#͟Uz~˧?baGgv27mA.#q;!"#0q%nk&Ή]q@c?C,k|U-\DR&ܺ.< _VR=J:K}.-m( ۖc䲲Ri/̋OF(aY vX* ?nލrcLUX(ÈzWAb+/06JDqi &pֶ'G~D(Yq%=[zh76lsOE'oOFh-JKq8 A ac0X ,q8 A ac0Y BI%L$hUP-oolmРGmw.Q9t+=]}Gls;+IeM*c~948ՠ?p62탞qol"cx~|A4<.ںLdaT%Zc΀+F%R3 L o°ӭ\ BK#bs$KqnpЮBhW \4+pЮBhW \4+pЮBhW zG.Q9t+=]yG8AC :\D+SH=5tBϚ <$+1!Yf"zQ+m6O9("mMLELI^d fURTLh䖥~~#;ڪY/Zqwhꄘj쀩%T0v<˗N휺.<_n}[; wFU&1&)2^cN휺.>_n}Ҳ)zB3+v)VkKZ7ߜt}Glwwؕ-sXskmnÅ㫠W;Eطqӣ;g.gO(ۼtC3^k{c5fױ3^k{c5fױ3^k{c5fױ3^k{c5L~rOE'K:O\0U)PZT l\…)ѐsRkӪL.(Ѩ&?9t˧Y?'V{bj݋BYe YgHջhtO Y5ʪD)DjdRHBxRgi]:>rV{h}IP:;]:>rV{h}I^zlKE-H@vWvO3kG6E%i\KrlzJ䓧t1W)uZoۉ~K~rOE'K:O} C3G2dJ?C|b4ڡakE"їZZXЙjd2u~ ]:>rV{h}Hsjuhhhhhhhhhhhhhhh.Q9t+=]yGs\zS#sD?"S<=60!n:Pd&BN#`#R&9Rd-л7qgm79JkT2LX$*Icl,/y×OE'K:O}LzN✨թUYcUy.=L&,j,-kkN$>so}os<^ vcpwwuxibEeg窔)DVBgeEJJ&?w]?m|Q/x>oX %ϲq.FzɪN1)aG9rRLqr&jP5Νl gb ZÞ PI×OE'K:Ncpww榵&hLBd Й4&A2 hLBd Й4&A2 hLBd Й4&A2 hLBd Й&?w]?m|Q/xq$NQr4mx\dHU˜﷘9t+=]yGFƹ@*'ׇAX,\J{;D[=79t+=]yG?w]?m|Q/xȚf^CZ͢vX)k1Ybd9t+=]yG㤚4ʌmĢ ̅jn\ V\)s(m˧Y?!fj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj Ơj ƠL~.<_n &(cpwwBL=J#dkCka,l;=wv,7u~.<1t={7In'Oct={7In'Oct={7In'Du ou8v@ (GeDRDqz%uViM_#X '6rF[un-eQ2F[un-eQ2F[un-eQ JE'7*EgoyҨeԘDnLձ#4ri|Mi)MadDqm`Ƙj\ai5yi&EE]>NZi(nkEѷM{9ϊm(.?X9m6kG5ch汴sX9m6kG5ch汴sX9m6kG5ch汴D|@rNa  a  a  a  a  a  a  a  a  a  a  a  a  a  a \A#ֶkG5ch汴sX9m6kG5ch汴sX9m6kG5ch汴sX9m6]xxq槚+P(s9b1CP(s9b1CP(s9b1CP(s98&De8CUjhtYgD69h2HdQ{{{!kgxܕ< RǶe]gx%ە2,M$M;Y; "nmkLE% a)Q6{Gn@VpwB) Y`1$O9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ñ9Ð8T֗ 0zWDiۦ:O2K%xI◸̪2!(tGB\ !"1#2AQUq05BRTat $4Vw3Cr@v%Ecdu?ͲWfy}5,uUWPIdF"-vw/Z|v˳_zև]Kִ>^g|l;h}>;e/kC.%ZOvw/Z|v˳_zև]Kִ>^g|l;h}>;e/kC.%ZOvw/Z|v˳_zև]Kִ>^g|l;h}>;e/kC.%ZOvw/Z|v˳_zև]Kִ>^g|l;h}>;e/kC.%ZOvw/Z|v˳_zև]Kִ>^g|l;h}>;d/kCw':/O*)Yg&T' F;Rvi6F_SLJ'޿(! ϪJ ad'P ؝~Ü0 !c[j`5rNmUFWZ555\k^+)iY 'q[M,M[B3EH:Ft&e&̽v_ h6cظicj4QH#M4Z\)e; ="UM yVwyqM,R9*3$,BavK3}ޜY.$Q:҇B2SC(sc+*IN_yE yk4ԏ#Y.]=?3Ʈ|qҒp9G?#uy2~dsXBh"+A7/ZFTg*y#zPJ7RdO)/ϫ!BAm4U4` oъUj,jkR+6'1{nL w,%V*CT||%P|reZ3*pwE7m,l'L@)^)كCzdҴ[1H魺ԴzJ$Ak6;[WO4q(%/&JFt(aF-uZe#]b)00Q0l˦AHMP[:L$Eeag}YvAO;elƛ,U<+7oq35N-VF8'BI:(n;rFB7r I4STW[T҆:@Ǘ]>P޷U+jc5*5$F584[x׏&COLϗII%yHy!4qZࡑ*aS% )X`odJn }"rxX)[!|c?)mm=+ S݄^06fUgOG=Gkb=aA+ۿCb=aAͻChP=6ucسn)XP=6ucسn)XP=6ucسn)XP=6ucسn)XP=6ucسn)XP=6ucسn)XP=6~سn)>=6~سn)>=6~سn)>=6~سn)>=6~gt4OaFn_I;=S+z9ґeP>f1~5\*߀z4E.\h1$g;chS*#˖~ib=rlQ-9CvE\)RtS幢Ni;DuO:ʢ5bq+3Tr  x@h''D+=:GLksu%&IVt9K+*: Fʶڡm܋M;tx۠B4 IL{,i[F0kW:0X\sdn"U:iYa1br9nkk@̸W9cwr:I֛@ҝ\h 鉃5l4sY*GtTHIXYQ}JŬ3h2H zA L%wL ¢vzCj*cuiG"&U[9qi#MXo9. k4nC!kad m| RiZf*J1rWWBӭv]F+s6t⦣rV:0P3R=JmD5U!d,}E# \ 6%TEZt^]w8W&M[xYAaAYaI \b. Y]Hta{~hȱ|vN2V,rz%̭ț=& ŏ.66@̶mbUChþ`|@01¡pN@sWN(jaQ-:O (DR 5H)θdX5F:Ƃ bO*NkKI˼U$Jp4X Ox⒛LXntEe3LQ[INyQY3xؘ]D)~zI"G#w]wy#Imr &tuuL.lfEm4jŮw*Yb2Ri V :-qO+O,- Uk<p,u!,ptw'G=9I^p^ 5k_U K ;/)2ֹ"-;[^F~`7HvVe(pD!..T}bwq Z43L9U >7XfQЇAkTyxyHvNmK*8h+L|Ұ#Ujw.${2 ݡ`={]5bKDF8kǻHً)G6x/ۧ2vo8"5x“i*rMSĥtT:V؏j|4xvlYKPQqS/Hk9q2XoʎSfUuj2}R<ÇUXʇTqJ$?]"h*O3PD61G;2>\ı;Fc`*3#J-z29 ؂8mAJή*,$m{UQk86kwR`v]&[w`+ x%3e#1322dӮc $$8ÇcIq$AÚ[j,hkK'8xG]'q-H*1ln F{D4DCUND)X7m%A`ױUb8 ` [@'&=6ko? \{Qܷjg ͲzVS34<UGH$qsųΌNǙ+djNic#F)ѣUYM DwrlN.QA}PyDɺݘʳ8 Ȳyv&%~C"Y&,Mq# C#1ΧeʧEjNJijG#ȱx.MM{6gTD->wz|̛H{A4*|yfaOAJaZq(r$E&PhP&γʤeB(& hZZ P1,Q% d2i+zHE-t4=U2Z @xGXn{e& S]E᪌ DjY))knX:\LF:BS -o^$\FN⚝U܀JO.aC:eP~Pjd:|xO{W}&Ն-ooڏsPL}ߦo?f 6ÆW?><;<}ˎpRO9^C,G8Fn cQ"8A:HceY^[pC`#Xʴ|C*ӭ_jONIEjp'^w6ͻ`Out 7:BMpPxbqu׫ws@Jy{n^ojHZ=-4q [x,d:$D%<-*D1 '| SR_3Ki]X T(V1{ŤLAU*ͻ2vo8? ~Q25|o}'㊭tF [*nJ+ڬ8[2zLz:z&H5Ycvjhjq*v%+!{k[T+NPHq*I G|(Fd%*Nyk.7ru&6ʠ#FtܧbTB'ĕ"Zy)Œn1۶ܠ~Czx*n՛[iSJKLrVo7K2ܔ̱M4骞56i@lE@2@ }1oآ<uZI+,&F[vBDebK a *MWYA"<^F.gff6 s x1}2oY*jjw9zCjU'Pq_q_q_q_q_p8n_|-~Ŵ?@}q>@}qܿݽ[5 hY?ޛ/탤yI4$B P,ɢ72&w,87$6$Dvcnq.v~TNU Ψw-N(!o݄hzTF*U%Q$,KQmT8bXчb/z;.XF&,VrH{]t| ɯ[J%*EƈPSpY rLnⱭs=O!t 'mT7<6Fʭk'rvo8-!dzlY;uԊo:51<&LYLB>n&/C3όpI[\~ 0F>j-j/(%EtPK22Č޵bqs8^<ۗ=~m 'et8&tx>[;OǍ> +wEY@e!x)bYcK8r_exе2S5VI8eZۻo* S2~[=\/N=Lo^ Fct侢nEI&X.^67C^:x[;7\*Ĭ9Jxt_`OȲPۛk:u*EMѬ{@^b Ԥ isJ* hLck9#p η=Q8`\[CO<[H[o?G\- IOG_|-~Ŵ?,M<;J*ܾWRG,3RP{Cض:Gc'Mh(\-̻.to'*RTi_T5DHjfIexyꙒy]-e,Vѷ -}\x-'Ë׆gP\pDI/(T=ȲZQ,,SOYERYC"I t{{n_|-m)et8̀"p 01,Se`P8H˄*%1&$jHq4-#Jʑi , CI=xp]0 a{[Fj4{͗=<. U2r$yUjD;WJx_\nQeY4ȭ*,1G = J(cPPǮ6s2t *N.ѳ*K$J^<ۗ=~?[EC~l#?0qh(e]`8SHPL7urIE _|_=vjM'I^2 HI6;{^FAjDQWaSOx9*7/=]T85$nLxWK 3p42oD{-fS$,#Kw7׊58"ePp@McJcw8y7't-C43Q T .shQ&ۨ)ܿݽ[5)b/S`qv:I\pؐ>BWƷszNv$!T:]6ͬLgCnpI P2,jRG1 qs8\.|g>3όqs8/xomڏsPض:Gb\y!}VF5X MQnRJ" iG6躕 j6_## ZN_`Jy]MyAJܬlllXӣtwqp^Lֽy/oj>{C?bQ`qiM@}q>@}q>@}py/oj>{C*j=5x⚭biBESxU&*w O V)μ:Η9אY::_c^CgKrcَSy u/1s!f9Nu1t)μ:Η9אY::_b*&FdA$}BBݴ-keQV$,!dHVmڔd/-3,+L4Q IC$I@ 2`]jVRЙTQs|:&}+.sY!r" ß) +jBHLd P40w,HL rh(Dʸ@5Pj`8Qf51o'/xomڏsPe+2L5ׁ9AULVR ifs@$imu jeJd~=EXC5sP1ݪP:)[\]HTU!WP( ~&4ܳRE.4F1$ G3oJݽhUubjsլFVF<*SG19QVM3~#YK&H 1[9\.WAh7<ƓV^Or5Ia"0XwŴ$ȎVDZB@@%50 ÿ$rXwa,F1ܲ80U*p[v imn![D8;e^q2CLwT/qrR<`ݫR’vxweg+ݴ\]# fBnߙ"22$@}|{h&a{ GTJ"Jܿݽ[5$Z+e˦]dOl/7PPIcފޭɽKz+:&,v?;ܛԱroRcފέɽKz+:&,v?;ܛԱroRcފέɽKz+:&,v?;ܛԱ pD\񬑴_́xYHdeu u pGF zVC~I[xԁ1BKp z/ڲVz;j><~Y gc՞ڲVz;j><~Y gc՞ڲVz;j><~Y gc՞ڲVz;j><~Yةj&*(xђUK$ncފέɽKz+:&,v?;ܛԱroRcފέɽKz+:&,v?;ܛԱroRcފέɽKz+:&,v?;ܛԱroR]IC%l]Q]$24 Ne:@y{vO**TiRidCύp 2,|x饞UA{j.ʍl(9ҟ?1ӕ}&MtQDZ6ue6]}ȍ=F ڤ†]EJOAO<*ؖlI$ӒII&>$N'ʷA+i/'0QR0*/jTҲW|0$Qe9H} 5N6^IVpcu6:b2&eRxFU̿TޏʼJW2SzB4HVrK3y] ^)f0⾋a9,Wv'9xÊ.݄/?q_E۰g+vRa}nsY8NrK3] ^)f0⾋a9,Wv'9xÊ.݄/?q_E۰g+vRa}nsY8NrK3] ^)f0⾋a9,Wv'9xÊ.݄/?q_E۰g+vRa}nsY8NrK3] ^)f0⾋a9,Wv'9xÊ.݄/?q_E۰g+vRa}nsY8NrK3] ^)f0⾋a9,Wv'9xÊ.݄/?q_E۰g+vRa}n39m[A]=#GUAWRGqq$K#Rb*NO k@m U*nVTTԛHuVsf9m *=Oj!6np*K5P8nMvZ:ez!jH빽zEOj-f f+hOU/rH1POAqPbVD50|/Nx)dIfV0jңx(䧎wb.qsWÍZ4U5T2TM< iRB xbmLff̵uG)#Y$2h@#syh`hJd=jIxV7m*U $,hݙd- Kp mK}qIs$\m~?ks$\~~?kv ?Wnݷ?O}۟'mq_{Is$\~~?kv ?WnOkv~ ?A>ۯ''u$;nm~|_OOI v~ ?A>؛U[Zƥ5ʚ JQ/SY]n|+c4MIzehH%Z(t8:;stwiR*ŝ3ns?2M].1ty~8F A=;] iYQ\B)Dpr\.xfCB [Z+'>JqՈN8+IWIִh.As1;X7s;_RlREG_0 3U7OuD#l!nó.I%CzG6K8gq<}@гǜ{A*8h&l37MO$dd31Ir7Қcv;?A1)Cp5X&eո#SUaA|h=+J*܇buUUY[AIլXnkpjh F&*)jVxfudq!8BB]s>ꊩ26 RXnwvƓx9H&'$p( 鐰$uU&<v2m]ʧ E^0TpVu3.$U6vPg_ 1cIΡ ,fcIх֊ u%|reEzSsGc҉{bS-<+2E5lDӃV;xLffsTׄ&+j v ]ۆ4$473[|x`m@rMCy0|U7`o$`o$`o$`o$`o$`o$`o$`o$`o$`o$`o$`o $`o o9⭾h.Ih0&Ø>*Ƈ`o o9⭾h.Ih0&Ø>*Ƈ`o o9⭫w䖺\ZS 34E,\@އKekRaI5a^8׸7mH#UrɔۧlIQ!ia3i*%BTx,OJS̙ے͕qܯ&pLbG"q|+5.&ԕ-Z0#`ԕH6t*7I4X&ج #,~h},OOiRFd:۶cS(1} VcyK#2x JJBjk]/JF;; QA7- jhMD XAƌwԄ"0]{X5M" $n2VlSi\Е[adFTuLl$G+K.lNWEѝ;x$nKo"LwұiEVp+au $P: dXTqt`NlW| ,]M($V  4ɻN5"FS$sYd)ab t ""Z$n! 9H,5PcJ()6ӬAҫA*Hahjt[̲bQGɫBijhơ=Rw;ArLk҈ŌZBv= bwȄq(H kSs[-=Yh&) "#]Z[ gjgeJYG6P7ekirX=8!v)vR椓yyG[*:/M6$rY%`@):D{ޅ%ztGgԻwVH* Lz9wen/n-H'Io{24unr..ML^^Du":IRlVx.8]y4AqxÎ7́etC4 H JHgQ+ԒJLehYTDW1v$~yT]%Bh:VYbrBou:̎{^eҊaۤv*VmQjҢ QbLI$ q6~ y[o!Kx-;iom-ැC[v y[o!Kx-;iom-ැ/ϒ};r;w'_|8+8vq5)^gLۉZh! `c+0VU$@Dp%& kUuYAPlbb8 N6 u_ûu@u$vP~ktA{nVt,ʼNzC 2 Y6` 66C>us@iq*D:R]V:ZW@!$!QSRҨ!Hq[ٿ}TK$AV(w;XE*]#+hҮ!iaQ se.- G =4O3DqD9$hK4LC4dI Q(4 (IWL}[=GQڒҖJ+u weFѣqjWa\8 孛hy,`SH]II."QEQVUYEvXcXTTXeKnO}ϳq'=~Eu,x,X"3DdQafF!`@au"`a9W T-UQ>rG&P*!0Τ3j:I @f3O-@i5 ti*}-L, =>{S ]xmh `.J܀,: zTTb0;} ui.({27`YHG{%95Ԭ#xY<]y/b]aF,Ib۴I1'cēퟝ̿[>H#jvܝ~i?v€YH uu?ص=MU+TIh 6$J:.Y]5F.UD¦뎝Rߺ+HuDWM1%kpu=Pɤ*7;r?=<q/ WKC_ E]>4dzgª4&V t`%T`Ĥeı*6H4 6!"nq$UjqX)nT2aMՐ2Jb)&tY5Bۥ:*(u$)G2FK>4A" j%Qav\X9-Xm⤱TBmƲ[Q=;f(Pܡt54 柼j~:-s2l!;7ٿ,K2jRW^枚SR$ZjywHYCɥKorEMLQgcɊrzZVPPysU|ի=&?jQOS*Fh6º6 ܞ̥scyc$WZWIQѽ>gNib3c(jS%2:i$AyQA='!V|:1C+.#TpG8-?&>+ٺsM1eɦ+0챕uK!HcFv#]sU f6)g45 .9$E6jGU,B%$ğYTc.O Z6dqъlA7aP$CّNä_ ^ݳ)Kqȑcw;ȿ_?D?Dڏ+[j>m`Ͽݵ* 횢 4uʗ]NiݵJ8D0V^֬B$)bTk$FҐ5v:ʗUm^G^K >Wҥm}<}VMdtkwݳ/ϒڝOo#3i$xDAvk* .xm686llUf \uIMmR׻@i]QM*OE&j7q#4jt,%?5gJg{.9 Kew!I5]LjDu}L!T@u q҄h% ~SKF$j)h!yRO*Έj*z4;3UCD1CEUV}Q-Q+0Lo*Gl)OUSKVKi.5zjZuWhGRYZL/ ơ4\=jJѳh]I7iGe^Ŭx>_ӢB{6(;:"q7Fֹ؟thpf7tB.H{Y׈ae䫆*Yz(LK4STHXJcI zyU`uʰh1/TF!ҝ14)14e6,q=K *,UM,}2ma|ځ&:Cv$3'/eH(j;s$TF&dX#).AjbQAM& ݨ,G21l̼UR$,[:@oݗYwVfNwlahB%4Ndy"{ Qm((gF:@'#_=TLm*eh>, PdԆFKk:]ea:j݈dx@:ts$ջ7]}[kZ}Wm:."/K1m:AfMGK2bPT;xn̿[>H#jvcV=W !9mWk\m k[-RBE>$G %C7IC^ `xv5YG5BTI$1,C[UJ+R;G;nK؂t5-F,tozcS(Ved`t<YE"xFQLSb㦚,DH2 GhXhI!4iNKrHb[&nkTmVБdje-t Qf%7M83cHw+7PNLhs%q$jYexqGS`u)IJ&_*<#2N#iCF7CH&Gc&Y_Lnrg7A0COK+8PBea,*zjjj4bm 4u #34E$ ot&bOIO5CSd4 LawFeGEYA (#7QHk*fcËOǚυ1*ל7p(($hR5hy/4wv ۚ/nk/]v ۚ/nk/]v ۚ/fRT]̿[>H#jv?Ta!v=zY{mORRJjl> *@/!D;zq2YtR0nM>KX4fijjyRZH2hjI,*$}ΥTٹ[ Px[켤w9mFR,udf.2*rō{r90UMtF14҈#UE -|DxHPe p(]i 1Vo=˘cy&m 1@@aMkmXewI6tiIE,}KQK &TH;FIz[4pZh Rm[NiӼ{&(E VTa8z`44-5dEV̬ZbD rjGp K4o{7T{|mL@`,o,*Vwвd^70QĝfӊGN 9DxE֎7JT~ UHK Y[y*O[7<ﶧlAyYop |#` :C1k3[})mMm7㵏߻v<Qr:BIV7k)V lUYa8V(ùVV0'ܹIȿk wc7|&߃߻v~>~o;XMj3/]̿[>H#jv?Ta!}q཭QH3J9ԅǂ$!j0U2*=}ݩ #"EhhX ǬZ`-B@Yɨ9jޢHn.I!c=UO;3Tɰb%Xj M@ S BKUK-U4 Xp ީjW|4@.e6iSk$Naw]*;w2l!;8PrVi[?-՝ 1Mah{5c2o4B PMt:~8t=2BXjqW^ ah᪮[E`?x9ߐw5&35BHb d[U8qj WX8JĒZņyw +dBgޡ1*C}+NqQG2QsP]Q i\҃fSba,nlֹEYz4jKD)i2,feW)@ց! rLƙF7$M/${dd7<ﶧlAyYop )ZGNfVgmީĵ;{hjd2#&Wm]{P: Xn˩20-(1e(;EJB#I#E&: xx>MGv_$?};gO0>{mKYYQ+08ĸ_<:ƋtL]N.wPơd4p :f=KQ\]w\IOXWyg.Ӥk^sm=]+lu 1w$8X,W/rAnL w5/؃nɳ.NF:ڥ+ؤ&YU'NH0*K{2ȶNɸBTDM{bkN2$6!P#:?=ѷWɊy\nFue~~ǗgMAHa݁»Lt8{Anff_$?};gO0>{m_3L"- E:]ՕKцtA A4@a`8v*Ik ȘSKhUj027r9ɧKّN+[;n:MXQL@[fܚ:ZHH-/j:[LtĪ?{D<=`m/ccqj;ۏqCuٗgymNꃓ$>O7rKGM;=rz{|,X)}2ࠐI$ 4jab x@wʓ.H~6fRnZ!ĒLIk#~}T+1֬djhF061S#4"He1IQ=T7H#jv?Ta!}qpJoB]EX Vk8]J}$ d CHgG]6>btԫI XU(RdU`E#E !Vbi_|m+ௐm| AW6Ҿ W_ J+i_|m+ௐm| ;w2l!;8PrVi[?hqb8$R[EY+͟ND&BTTfD44AukɆSYƩԅq9b`C+ahu& wm΂/1R{I4_٪>ۨbfk*btGyGPuf^~|G~9?C+4w--$1:*7FZXS8n]b4nwWjX$^-܄B\JJ3aHWB GMPz8Vbu/'Am4*nB#j-be-mE8 R.eIz6(`Cm:<Ljcuf^~|G~9?C+4w-᳕A "j#@HQ[3$mc7|&߃߻v~>~o;XMk wc7|&߃߻v~>~o;TwgzeCwS{ǹ8V^Dz"iMe HC:q oQm~2k-eی+yn2ߌZm~2k-eی+yn2ߌZm~2k-eی+yM_ainbԚ:#3[YulGc-yt3h(%Px 53M*MԒ5Gii1SV)y\ZFI7Y%ߖ" 9kR[leEsL}j]lM[Q`x16">Dՠ9e`gޱk H;3#+&HvItAbGI \ <WTwgzeCwS,\_M/nk>G{۸mFB$ $qLhm\%W*:+S;նQosI S{q."Cm;ՊdquL wwЏ("M:$ޞjh!SJw$D)#`YDHa7oRAo)+2 ݶZD9w7,9a^e+tbԒ8G~,&#jziBRMH$0qTЩM<ȩ:%db^bʰB=% j$j- QC$uU["bu4HKI}5)#ﲞؗR뿢 Dd%AZܒB"1To&1Z5Z2#Ǭ#q8$`r&{ҫ&*0($R=*JR,NZ샽'TWBf?s/ϒڝSp8'Tf sfs2Q4ù*dH 7쓓Olݒg!;dhmo/&r?|;vKɟ܆6Nݒg!;dhmo/&r?|;vKɟ܆6Nݒg!;dhmo_9=.Ki0ij#\Zui* R&)JnG ;%P,'sy48c:ӤȢ؛mΟjv+amΟjv+amΟjv+amΟjv+amΟjv+amΟjv+amΟjv+amb; 4YlCQRWə5p#lKڅY$;vKɟ܆6Nݒg!;dhmo/&r?|;vKɟ܆6Nݒg!;dhmo/&r?|;vKɟ܆6Nݒg!;dhmo/&r?|;fۇ ?.8N]-neصZc]&a s,jEr뇗3s)FDG7bwh_s_ _25^ #ȳs+fΎn%č!˰}Ye"M[c4 %CNHNWCK) v`Y,=V2M'r0TI4RvHbĘ]5RAH'dn]/ocjvPoŏo=ǷXߋc~,{oŏo=ǷXߋc~,{oŏo2gwƼ?tk׵^?޸'}/.,W2ϸ I7i# 7#毜1ΚiMX!Z P+aX/Y 1AxAoE98Ji[a'6^pW"ueDgSv%ڍc#T%V0hyF&5' DMC(Z4g<9wΟUĈ($L%\d81vKS=-ۤ)O68 8C.9{Zobh쨖d0 -$u:\( h)uGwaxG.iL__V)kI-=BCy@$5p,X3 $4(dBEzZV1Xu㋰Q, irTT.K%++R{;QDXq1ZzOYieRr cͫ9Q:D;v_UUnL߃[=[UtŲ{ԑR,9U\Xč$-E9 May^0D(ՎD9qT!FVfzH|a&1xcȄRę*ajvge"#5`[l,)Қq2]xa 9+G'W;NFSYU$TAAFGKjgٻ2Z8GQa9H sed(0Z{hyEe}Jͯr\VdXG$"{Kt,bj:a"9,A*8#}#j=Pvke-f|cIdG$`mm"vwI͹`I2-Qe31?pP3_ +XSu*|]EWf+hyfƆ{ɘZaEYH4rꈘ׵3KOz.HfRoxT~#@tǑC2@.#1O&u}lœHrˑ!\E}U]խut&N5nz}tS^x  vc08҄ltXXG0#b 4kbZ -e]yUY[*YOˬT, saDfbnR5n99ĬΙw,քE;S4\J$}h6RQ%о>eK" CUiLI3%SNadٲ 8W3'6V1FE^+y_T<{)UsmdƂϒp$Y'̸ ;Ȳ$(C;x/6_U]#"eT NN&Ȑ\$14p 7R.@ʒV,f*Zq>d!DqQrC(E&Rs t=&;y,6elD|Jo rVݱˊCʴQ$*CW0w(l)& MK˵qKѻ8҈Z[sY#@c7޿lYl,4hp7/׶D8pċy4W9 TLFPV *HN@qxhcHp֙ẅ́cce#VKb)b{ԎRd Q۷lskU!t5 h2;GC$!aDr}8dvK $"1AnYm\VJhi>FA611 F#tȢx"*d5?MG.g'͆zIw͆JXH"rV>ӌp`7^;zG|XCeSM,f1dy;v(cZ9UhJ~ݽމ~;);;;v4oz&$lM|'㸒osA6ihJ~ݽމ~;);;;v4oz&k+19ҽk6kkUQ+5hn)ߋ;~/H#|wߋ;~/H#|wߋ;S;g J٪bʿ6>]4jF# D^"dj&}""-‚fIo%LZ:!8mG8c )$=19ةkF½Vc Gq"1(ydV:n^g%#eGł& B̞k  9':1𝉃b )+7ަw=xCE vl)P׵UUNLm窼ck[kR4LMsjȈ<4:H%%;" ]l= f"; E9+ihvqd{mBo^{#]'-UUS>4el6usTf%|;N;%iiT+wS"Sܱc X1cFF|ŝgT9gU$LȰ&ju[c(i*D"KHS)t=!cl ݥZ#Ka;V!p=qK tW#NICϐ$GX{-J鎁tKH鼘P2)Ic\N-"K%L]sGm{{eH*K1$VқU ibʐK6dyPC * A\IؖQLhE)ʌJ0J35cFrx-pJ,vI Qi(CDpē@0#[Ulq B2:{ݵ13"ß8Ynٌ 1tdTPJXs-!OYUHX4j$)RXEV+jVȎj*wq[ɺ)Jq#–N.Es9pBƫe*kCLhjXH.S:LMe4jƛWc`d%B2C,I$18XGxwl1GMn!8!n`9Ն$Lv[|i89;!K0% x$\#H+;h' ]`qBHGJK[$ed Ѫ/xbj+b\mseYfDMPD(0jFG lCkTP 2g&"01Q#CڵjH8szbzs29OU_4QNAk$qJpI(`+bIQG&HeE KFalSD r!bdq sʲH1dK㸻wrG025y1bHxgʹ҉ vQkPkjfWETɀQ/… ߲KتvQSى't).;deZaXdlVJ&۵Qvi:9_[5v rir#m DsV -$5Ѕ!a9rjcʝ k A- idYqun`XP Lr ĉk+ddDDڪ7lDOmWLw3bkYf 5HR5xYu'1j=rAH: XªB7nvq\j\=pLWL2EFv; ܊+F9˵ʬzUUV޾{a8 wQNVl*ik/u#1y#1u9s#ZEW9Wb'ep{:{U5skT좧aS9BLC$f\w,_*IP1&&8#ƯO7 Uֹ`zy$ WoYr6ڒUf!p4L|qK4'aLM)N 5هx $4BJ,H:7z@E,٤'FK9Uو/(cZSD]Ո*~Qt"fODi׺4jfi[6jowr#$FL1hrd1{;؏M 9g!hֱa*CW'M2?jok܉=;;3y'-.-d5jݪ$!s¢QlwHp 'KJA}!)6QbTDprP9Cf5;g5jQ &,@aL)" CXFx qJsJ691Mz>#$qLbw^^{4EnݸNJ_g>;5mk)cĎ㖱6 der$).u2t%4xFGF'lxQܬ p1;M0yX0 $DQ޲E+ۧp~z#1N-,pޤkQwXNT:;C H0Zx/ ]˶ra}zwzՠ_XG|[:Ul١[70_8LIUkݸ]KB.UC*l+#!nf"dG'/5Wg6wvf],ȳZM"D+E#Èf\H+3x1 5@=(`׬9,,I5 @@VN1Ďat(mxd¼)g>D1R[sWS@-Ik„Pa 3șG)m!r&j>Ir.dmuk&UՂ,:(æe [x .'V€TU)D5e# XձhhdS^*IrwkG x"avW'#*~_j/Jٮ'$m_rƐfFMۣ^եݩQUoeQ6mTOMMھ;C.V;JzwZ'OI+! !G#15={5kQ\9Qj0‰(Ɛd ޚ=Z9k;n5nD5{_i"o{p^ouGC{+Uk+Zc݈c5mݝtw@p]~tw{"'q6'a6"lD*~_j/Jٮ/<k GHsG[Ǻ1Fdأ(On )UOD` k bnF7#Umn+Q˵{b#\6m#".Fhj#STL3FI;Bs:D(_tS^Ig.P R5ۨ'{wmzDVc&0@p 9#XƑexaUJW.my& uC&:&#ܛ6N+b&VJjz9өsQSWO$GLrmq'V=!GXE" \5SvmRK؉ ,^4t.ggR֋"vB4F0V7r)kټЊ4~ֵDֳֿ&;ou6Sgm{?ӕpLX1w%&65pȑ(ԓ)@#T\=b!usGXqK;u32K̇ wQO5 .]niKJnahnO(,e{E!H'=-+E`ٔ>圬IA,eRYWf;K>avU Zstyy9 I# mͽ[MTJ%ko@gưe|+9R+Ǹ mf8 0=O7ԐgJROhO&$\(7U;#ݶ2&( eDdv3R/ISehsqLvZ< &B2PX+e EFBpf1<++f@2K8v1ƛ^7;+µȊEEEMT}Ѫ}Tj.ͪ56S׺9Wo"oѤQbHk\H5B#^a 4YA2(gs]U}dE.}ّ8(|408Hۧp-2K0II3o!y/cQ2FRE@T^Tΐ8cHcF656_NA,oQW'rPͭ ݳkVdžXyG͏ da6<2͒>lxe$|6Hlc,<#džXyG͏ da6jO.lД\Br2L~]iD#^MIUX6%WYcl:J4t]ei*aUu9ä,ūh7XX6b]E]&9ä,sMIUXCR;]b`ڮzmv5v"*6%WYcl:J4t]eQ+X xL'+Q҄i#G5\ڭf8+W{Lj8xTF4*?R;}INiOvc;w$TquiyHhEBbI{;.Q7Uk67Q5$+)Lc(& 4*!w3JJ{$N̔naQm%;Q0bvol1zD m-Y6Q"ȑϚggy pUM*ݤ'HcTBEےTewT%Xe{3in ),Ă;ST|0`` 2yvsTY!IXN$Y l)BA J,E]#aƵU=\9#UsG0{+0 %͔(c~LbNn·EHMLGڻSu&UM IpkMe0QPzቩj^)ta+V\lZ4Ju\da'\6+K_^sꗑvq_~q)$>&^#YRׇL7N#9ZنB7Xn6|Sar2 y ١ F+lw!] P*cR.YV( 8k":2@)G3C[*Y*U= .D|yuqmnJ{8fGN)/WE ´M]mFy&7X;/] kG mN$xcbJFDG$G9]ϏN7M/DQ\\B?Fqa`i.B>fGxC4:>3d2:Cw4m8}d $C$ZAK Ѣw>ߟè{RF]DsVpPI#mGؖ2TΞ@XCTSGGŒs4]?-)Uk{\mk*Sy9v w(`%ң{)R2z[˚Bhcƪcd~}qSy͓Ǜ'}O;6Nwl?oϷ<;~ߟo1yw>eu}pJióWcD٩UUxnBmV49n~;]QDĬPN1q6lmv]nڽV[voofFi"0۱(‰7.ֹYɍM>NJ ,vKaa '4L| gPA>/p.k^<ڈٕqgF⸰5DSAxX'-UBXx̶.TWc<HfH|HdͿqH8uа3hLHv%{-ςp4]Xl%e|&Fua !l:4Ș iG4:"Xo(ʴ2xmv\:Fm΃Pnkp}eƛGo.pD8 =PCb>-4Y{p*tyYUg'7%FKd+۔r"װ4IdD|ٔ2L QB3CzL3EPʲŸwpm '/D ːi,hn{b[+ &>Ɯ$џEW*W^+,TvR܄3& X11vAIlgyu<]%9ѪJb3r|[ P*y$2vW*Y5< O- (,\;#Fd1B@HPi5*Twνz6ܡQL dySa YdS5BBKtd[:z6"eFL9AXSbp ceծ=pPRJ̒xy"Xf ^) m.+_5ub ƮFfWx (I8xhtz(VYf*xZ^pZ('<*+D2CDDU]18'9J\@ƈc)3@W>fGI (tkU X>%"ʲaN̨׫uSh$76"XRɕזz|N:*eS%=P#Lb PhV8 os$#afEO$A\dΖS嫴 Nh ߌTV#歌 a3Us7X!Ɓ$P+X!͉a +'jÑɇW? 4ZЉ,{FM#N<`WI.cc!t I5cGgftom;J5彨Mxtdxh٩`PVg aA% XBW+bPƈikVd c^3ZɗA$$jq`%R2b -k^Uۼ1XffpY@\!qHde|gI8g,r! x#SKx^_e|  ~ȗ.SOw.\hT$|+CXj[1VZGZO{fǏُBxx05h f21sOvZR0v $yXlAhP*Z9 ,)TȰ[Y=: 1Bo0s,;) )`U:n#F(M~ {H7.MW\5S&^m)3C7EbWl-w)s-l$$TihnԪF1ta%piBfm!<QӇtYa dͮvqr wi[o)rI jInC2I_dJ $n[McY2f%\Zt PHGpѤJɪh<x˖ck#˕ kW/ 9vG:o8^Q7.u!dLw\q*Z Lc¥.֞qȑ%J.4Y@ toij9 C bA[u+d "z6q+KQLֿtq$lR0DzKX7<,ڌb?#jݍF9ע|sEI^϶'Smz*NnMgj(1IZ1vrƁ{cu8J حZ)U6Tnr^Rl&ݍDj"c-Q8_uN9Sx-GT-Q8_uN9Sx-GT-Q8_uN9Sx-GT-Q8_uN9Sx-GT-Q8_uN9Sx-GT-Q8_uN$CtbB!%"dF"La}\{=*~Uo(c?*T^߳\e/'FFSB$3^6\+faV@ZƮE:Ec4s<&)bD*ɱ+P*+H>OMO>_4Ake ~J.XbD$Rf@#n"IT_agXn t哫_mA%V[ `hŴxp"@[j$Òk榾!^$˹gq3@3n,!K<m1M:=&tqIʱdŘv^O#tEj0fݣfSpDBd,#AJ P9%Ȍ^w&*cb3:@>1&0q杜cۍߥk,IhCрΏ$1 𙢒#"F%6on֨#ڄ+*lBu勲^ lYڲ׼YSıӢG\(Cɳ`*ZEY/*cX\G=jaA~hʹr-vFMesZTȠp GC 567[X>٨Tl72Ol6~h[VX |cD e9أ(xLrN\&ԆLT#$Ǖɼt{0"%E٣s'VLjɮ#\e]f,*= X*LA0&&LB2l0AF%J _^ ;YBlqջ 1sO0?(TPU*~U++f^OZ/;yë*RRn".MM T=ě|EY*.`{fƠyvo-dQ|E_1LBB|ɶyac$жm2c kWsv,w"R@J-TȜgaOY}.6an''YCˑdA0)`1° 'ކ*goiۃnSs6X(3$˖yyv :Q͇%^_qZ)EJL;.H<̾cU(_jF̋lj[DH|e'ИfbG5pw^v`϶ri}|p=d&6Y2mƌ:xi7O8r,g&qQfj2NFy%4TQ(~ ^0M;D& %[I+,՟sԳmmD,$a5 ёZfYr&Nu}=k[e[lY.MY}ej &[VG}{kKLb)ɣm4Y3եir3 R f^6kc7`,YUҡKU1rRvġ:2)"-km*Y 7YC1J[ C2m=(h3Ce8Dupnvv"^| ʊ2x hמE !;Zэs>ծc<0cgW94P.E;H$fqHqʑ-ijhh9:k`sl.@־~ l͹_̮^mn{C XY9@5DZ+Z&um\k ֲ'Wd9H#?˞J BXxJ8S{g&(WvuUo=U8YVyU&Pl 9Xu7V; Gy<MQG;ٮQ K=[_zgN,P+ęvFV0s mMgXџMfWQ HcsG%cHe}?2ARy7款̕&(k(\F=1rexbLmArԛS\@tZNk"UDHO<1/C;oE:|\nlߖ ŧ^)mCEbKWQ^GseIaI:NUe'+ D:ԑ`9*$])gHF$(o+jk#4fp\>A۹c+"5cKdɏ0.CƗf%U"XM c`u`Hd-7a^A|ht3ElK2ɶY\5I"q]r+_-L0U5o+^Ҏ95;+ƨI W_ ;qaMP>5AH¤e{1C-w-d#qys/u"+Gl!%bA&C{vctV7s< 3ɇ(EXpəsծ\ͅw>dҥ(4F1c! d8c\O*+%]Xd^1Y*d$w1D%5LpH a±V158`Xj׵rgtrc x8gqF.G n1`@--V[Imב[GX;R:d{H]z)骲e<*ʪJcDu<S)֌A;xƵDO.DPȍ1xˇSt+vH*&TqlfǢ ,v ;nϷ}ak۾}Xc1m|wﶾ} w_>;nϷ}ak۾}Xc1m|wﶾ} w_>;nϷ}ak۾}Xc1m|wﶾ} w_>;nϷ}ap*~Uo(c?*T^TR}l/*|_ O_2̫ÚXłaVb֗J7nn#8`4ؚ-Ӆ$rS䈏zٳw&#58Uh*;W`&Uv ׸NkܱjMdeXL+k,̦Syxrj& 2+ }[fyd=qFi* 6aEJbp'X<[Z+9<ķxK_u[lfp(GQDHFh"#Yö=laB!K@(9^F+XYNg<:}\$֫).lEzG80^Uۈ7Ys1e;1UH3wP9璟`~PV-?}?(TSQzW?WSK@E~"B]eh5iy:^7ٳW*|r<>P.Ȍcasf].l߾8$ =uQ{g͐&+m%ɫd^!ǣa\Y-Va}amr)\Hxwu'(9r4 ;QmYl"gi>lnFxr#G",+M:İ]s,i-r遱k]ʫ"F!AO+~a%N#dɋXej\'-_2ܔP)+,$R8u{,L'* 'F~YA92u@A6m2mq"GeWp郏Pq` ,ol`-Yg3nRWlYص'6P,iypҦj13E=U]yGfRrVcO"G!RTMj䭎T AKvL~\](&+*0[G.y)& a*Oʰ?/sE1g?d ʴ_-tswZ\\`ӯFѯCui٫Kv `1wmcֵ`ֵb"v; #H1Rɓ(.A1ނ&"k҈؉fZ^.ME7S]c{l{camA1{i"Gحn ~UbQ#ұL+ 3ƏbqZSjCkX_PEgaȎjqTr/s_cCkX?9/?Ʊ5s_cCkX?9/?Ʊ5s_cCkWOXuGT$iyHD{ա]++f? ^Un$ᵤYRZ*zADR= eSceWӡS!ȡ(FK03APR PkG=AX_V9ZWNbbH3cͯZAvrP&KY~-iH2 SDYoJ5q"Kܮouټ#%BA6 35DF)(؊{1ɵEQvF "I<`A#ʬyHEGn1+2"?K+'ݺT >PXUt"V<ȐHAvh,DœIr#31ƞ],*Nnr}-X +\< E\w=ڨjmMTL6LgjUjQȭUEENݩtS\mзÎ1Ǽ*I4f&אFw*],U]bv5v"* jFC3ұHձ{;So$+DRQBsVQ籪\fǪ#wzGpFuvw۽c{z|1[y^{^P% 3I/l%2=4GDʟZҹ"j^OZ/[ Fv݆1]b6cTcu;ț{89#YӊP,d>9dTF#zؤ|rOIMmF \F( n5cǣfkݛf DqZHWv %lUaD7*;Jb.Xݩ_ŕT02IDv^J6P)%Ý0[fY8 I"kbt䟻vM})ĉGALyca.R45]ܨψ-Je92U(o#`ZjI'5vqQs\#9#25VÖ"?bN#bmOjɬj*62S "ĊM4jz5yoF{]^sbT0Z,BcI) ,v#]rh06Q1Z6vw\qY(jnjy)*E ZV pw7;amVP`;G*;xu;pCR{E*y֕;۷kkBױȭs\15{(^¢Qpr^ѫ !1sWWЯ5c 1(JƐE 7{UZ9j*lNjt>gpFlĉ?O00Q#o,c{}K5.27QDQG1r+^"9EEMʟZҹ"j^OZ/<~?ߏ_~>q~ߏ=~?ߏ_~>˂aG5s\cGT{{UP:'GMN`W`Ӱv>#sQCI*BŰ ӺLkj*Fv_ jTNa_jʹ`'dv4#{\'[ZUhx@,U(8'~VG Y3\WW{cfLIHۻ&iQw0c)t5Z3RNY%t}]icMdڨUrѲ#a['xutzIR!͓RC-b[ gXDVFy&De-6}Q!,>,fY/}g#MRrZ2Źs $89RSnn!|ڋ9҉\LA*4$iQ/B0@;%׮f˹RDGBƑE `%[Mp*~U++f^OZ/:Wq{6HxHa1lo{bj!D$hk"4[ls#Ğa]d a4Ac‘Q6=fQvUȲ_*Q2\Ey.+5TBF ^ݖ0I lZ.0^ۨb(׷6f>3k\H q%Gʊٞp.MtpVlbS*+APVˊUĊw$usTۛ'D|mqݞ@$b1z@7̒EJR: *:M{潖Mt*o|ڻ{$#̫'W^f)ZލjO6s-M1! {jsDئ#a6Ww=s_d9W1UGs_d9W1UGs_d9W1UGs_d9W1UGs_d9W1UGs_d9W1UG7F }{ 5Zӫviե6v.2֢)y>6~h[MqE *L4@ qLs6{֢ĞMF:&_7r90VVHۃ Gc=+O`Ld1K:AG76ƪǑڱrbe3`;i]Z!A,!Rdn Jð#1{ &@ck(`5VA0I۔`؊"ai iFRf5qfac,bH{%zDȮ-UG1"\F|!dJc-ZF%|C8jtXBo2!Ynjy5Yo-RǕ646mjH|ei2#e+A#I )Z`pFm$J3EF˦W{ PM2tw (N'1Na `oHp:C#0whZSn"Qk0eZS$WvQV9kхV<)Pe2Q7.y)'G a*~_j/Jٮ2#gyVN*ֶ$NlF4ш7WƹAzשj"W2zpws㊾$)-lYI̕,vtbnÝ3S+GUz IYIB6O5e)L"l!l J)#2e\}ap18ReY/.UF9ыMehHDD̙kP\Q'j8z ýӣz=XXv"lKI-`l@,b.y)'G a*~_j/Jٮ2#gyVҺ*6ljBq ,sF4s^5D7#Z=G1rmkڎkQZ]:@RYBYbH$p<#9DŽ$jo8ZE#6UU6a&*)&4 G# G((GrTsUQq>dZVF!B+߳13jzrgNpҦLaNj,q$ɐg0@+1{܍E_K.y)'G a*~_j/Jٮ2#gyVO:C ,]7v^ɶAA;Gw?Uu]6X-HӖ|5Cŋl藲f;.u*s׶NA<гCȷYK6oak\ghr|i&FVVVv+юg%MxsrűYMp'YtZֺ'ʇ-\kČKDAF# .tPf5Uxh2erVŝ,hVC}a#,Ja"fם1Y溩6AJjY9 Rx8e4f$sIo$I,ۑ+2/\JLܱky:dH79f0vN^˰9\y$V o$N NX"cium|[j-i+(9:a2hPbFyY3wɔ^ot3B*]ecw=_*cWD4Y !V)x ۄiVwQrTY. 1EA1LHsDsUrwgo3%]tmCNM6,@o@7(ZF1Gs %p4I6,Xv-IM5E[~['SeuzA˞J BXxʟZҹ"k? ^UnsO=?(TSQzW?W~qg?d ʴ_-Ƒ[AYM9H-FS5rj#Sj3y'c^oXz7s=W}V9>UUg|O3y'c^oXz7s=W}V9>UUg|O3y'c^oXz7s=W}V9>UUg|O3y'c^oXz7s=W}V2璟{$~PV2֢)y>6~h[OZL JHn2&C8kOS \9o_% P"v̋9tY99]$%KdY9Nq+eJQ1^lp٠k*\`jTޜla>&Xw-!Sf;j+^HNxTFӓu$("@Do}Nɮs!T[-{c,msEZ~cmLGOuzXVkDM8q{H0Fm`<2j Zc D8ٛS q˶ɯQ#쌹p*~U++f? ^UnlTQ ]2r m"h7zLAEt]ZULf2Wɞ$ubȳ ^v]Lpz%ͅ)o2*U[r@H)%S+mg6C9rn-ro&mP%œ4^4"1W]>@2lʐ.M&$|5@s˲f8f Ѫd$P2 :+'H=NaJxzWZn4Vt^Y$ χ,ڨ5ӖW>CV3edW uMuc$*kaƑ) cNN:6{.y)'G a*~_j/Jٮ2#gyVWR 0=)դD.`M$.F:YF@r754=EPRȍUpY)vUSx.ʹ-f KKH$&_1L:HF ػZ3=\E|x4&Fs%Q,p]c^0qY6PM\טS+I-K Jc›~ST\͗fWZ$hW:|OF`k~A]c&5KP$GRxö=E,lTǟ dW,2I8s`|9g9%2voS}6\6{Hdh|}.o &+@Ӽ} ޕ~۳sO=?(TSQzW?WSK@E~UOٰ%Z Zڤ(Ut7Eӵku9ץsKI+^1V-'\czZN1Zqbi:ku9ץsKI+^1V-'\czZN1Zqbi:ku9ץsKI+^1V-'\czZN1Zqbi:ku9ץsKI+^1V-'\c.y)'G a*~_j/Jٮ2#gyVJp!Wiy`5'6DtyP Y&;Ǯk. $m4x'VlsH5EG#XNQ͛~2璟{$~PV2֢"Y]Tq+ j]vOfFݛZEUGO7~ǏycǼd߱f2_3~/xL<{ߦK=o%7~ǏycǼd߱f2_3~/xL<{ߦK=o%7~ǏycǼd߱f2_3~/xL<{ߦKҤf0֫\)d9Ew|5wnzXƯa{(DŽ,BhswZBovF |!I&@~I,95&=.$AF&Z5=r@1Lw m ;Q5 aQ*3؝NaגL<06#$G=6lxedu<2Ͳ:_m ldžWG[c+#m6lxedu<2Ͳ:_m ldžWG[c+#m6lxedu<2Ͳ:_m ldžWG[c+#m 2"(Ij=Eku8HU"cSQzW?WS]F]}ۻkէNԞ:u}t ӫcӳnظ{;\k$:Uac^kNba6lGi`3>IDa" 9qaڑ«uȭn;l+rIs@TnuUHh󏊯d}gg;ZEڭ&E aU[d:7uEJJK<6@^k s'v4er$t(uZsHȯd;en63`V4ώ ;D JTMqTR7nYAn7ȏ@w`G}Q!G/T3 ۖcVHhQO}V'\,@ J5cM+J2ta5g@,4#QihJMsh/Zq]-ULPŌe;:$ k;?,KU%K@Q3e sg W^%6[f*8%H3`$LfTGj%98lEo@"X+d &ɰ]j qB5GuL{bی%9jk^k092^XACңS˗<3%W )tB?\r9PA: tkw*@'Z74VUHv-X5bF-$$+6 ddW=ӵɊٰeG \#ŗÓH k0&DZs;lN65ʈ5mډ F*&TDrw\g4SO:[XR*l!va3,kL9(B6$H$iƪDJUNo+"-qU"`ZEuMjY5}v/UDkZK)H\TJ٣eo㉠ J蔑Յa'˶a 4%&sdF>w8@-ܫdT(k`W%eHUD MR7,>]4hrFuDDlrޅdH=Z $ɬYy>>Mg_W/1S U|[a)RL4Vş+7sЭ+a'YfY2 26xYq2*I5V< D~hJ[|EY̊:: "-$C[Zo-TQkFSY93!Wb,1'˭gQ 2| b?lqe5,r}jY9pcK+1ɋ;P"B4Y o]sjԵLk4#ȝYk Zqb|λymtjP [sDXҴ\\Ǔrū#fH(Ow͋:\0mZ8{_)jAuZ)T5 9 l#|ڪByqƊ+|ƞfdÓocŵqw!%B8M65_RGkz{*I]lBa]s "+oaQk.+M(+M8bUSSJ^Mc KZIN#x 2?%[Ul*sIl}[is6\ O5QkdZ*w:R[ehЁZUC,Fw M 2Y^tȓ̲iͯ ts!0`6ƕr1gNUØÊq5 #dfU!m#|$lS&,T,[ͯ<bC;G$HY(f{ ,a2Jm2-B^\5(l~Sy&6VSjqQ2"ݏj vax6Wdec.zB%k'.ִ"8E.y)'֢EܐoJb2!#i7w/պ_8WuQݩ(_^·mk9Zޭ|wVbw_1]~;կW}_k+zWZޭ|wVbw_1]~;կW}_k+zWZޭ|wVbw_1]~;կW}_k+zWZޭ|wVbw_1]~;կFiA%UM-bi3ol%տe6iyP_|׈dW3KoְeqЦ K=qR5y-ˁF$2CJd 'KN"+ao$1s< ~G{.M@lVT#"OW4Mr#UfMX| AiM#7do _] qT1MdH<CuܺM]j+A)t\G`@3||$#NH UZVVKܝCt EUh65նPG'P+5fKYMp]Φuy%:Vw_@a1% D!pD:@Y1ĩ@.]8rPvLpHZ'= Zʴ_-7¹7/'̑w)Iboy6@{:Sxֆap^{Ck!#FMJqsq*i$F'0DܼFh8z6{u1tk"=,%_+rYZ6,3!N(|<9'2 ۑIa0ȯupA1v Tqe>Hg10$%k\gZ^,S;$ )Tiˏ4b Mk\Wa&ixi59aY EC8-f`K, ?DpHo܃|hѸ:[–[2#3b,7H%ϹV+I:*EBE|(xɎIr=FDDEF @ EfZjIEBnb^4j̮ ]}M$yp!+4upG*|`2A€F^j6+ ٳ.x6,_R,G*ҪT`Spb4h`Ẓ}!oO"t߿HPc=\%܋S lϲj/*|_|l,!1aAQ@q 0P`p?!(h t Fzbn0b*? mƣ߿~߿~߿~߿~߿~߿~߿~߿~߿~QWBlµٸ}vp@6inEhE!O+5[3y @ @ @ @ @ @&L2dɓ&L2dɓ&LYS:T&r ]<>8Q)d㥾*E íC-TB頗l~jQ<ae4HmkC=0RD?:Dyꇲs [a˔G P :ًGЋ=.Q5bhu'AA)~6F%+-.$sFδi F[Θj +~z6qD&vEr[\Z2U kࡱE=,w \oMtWKfҷ!)j˟4ewF5JiMʕOXU,(x,8zf׵+ P&d dGa(&ƻo9JKnT$CJ,[)ƀj!d= xqmxR蓚!$;A끚r3?)+Or55|P{׿m{׿m{׿4enlSe/T{6^MlSe/T{6^MlSe/T{6^M<\;6w̓ls`\;6w̓ls`\;) YiQFP9> c%q(Ќ:0UӺ&`#CB-ȡIʱ)-O ܮmWjJh)@֥$ ïatzZT_߾k-[Xmbŵk-[Xmbŵk-[XmbŵWׯ^zׯ^zׯ^zlg 86plg 86plgɦzÆg:5KBܓKi l$<5HЄ ̚Ҿ!zJF4LR].bl⒑P"ș$X˭Î:{MZ BRf(ʧDXI֨TGA\H  -#$IDr rx4}wLTFv/qPuMhr7Y;(egg 0 CŦT $p.16qID2!k4ʸ< XC<E~J6*BrˈWELI%t~JPs?>E%i [Q';`߸0ݡM4Z E!&Ԁ jpqgjmgW L4uQHZ3 u)rd<5$2Y4d$(QtxUvEc`Y8cta*1%Aw %l. z8d^6n-M9i! V} d"J.9 6F( Xb4L]oB$}` BJw83@3enп))}zEF2=T"D8VDm2[Qg6j0Sq#m[[`Լ+H~xN F %" BdtQ@lzpn+U{7xͻraLJBr :K~ ~usun߶zyƒͻP==7{uO>=:'2Eef (BƁ .\r˗.\FlThnH|M聃Xdz;a1!x~9%Bf>75 >75s~[I"eWg5)}no:ki-UI2K+'aDG3Ĭs-n0MJ2]/9Ӷ3Չ`7 б: jq^9san?u:?qXBYF- \r3X]0ajHx.*I *6ă%' N:Fk<[+6_*5~䴴= 8D|Efo5֩'AXݡ ˽At$hB.4]+%1ΫG /=+^B&qѭđnˡ4N )DT+C8aAr9-O?dyT#g"@>V1yvGDB>#cUԄpilLBuaL-,[_39׶أ uue$N8|' ߡbHFh]ݰkQY3׊X³+V :04,\|&^<+Rl ]YxokWx:W=b$ѻ \!}Sɲ^ZNH` }i%G>NW~teZg5ΌukL}5SWg4y_-ZjիVY@7uLp!'WSșY:XQ'ak]R Ԧ a rPH)#^8T׵)eXJX0]UK5/(2  =f<ޢYKUKRKlj 7%l87Jn14+ܭgANq]i\P霴bXQGD4qaPtG7oHcX1e,4f=L1*mT%d%HT=DѺ>c-ߚ|mPB[huBj0BkEAՑ7#RX3jV8ϫ"|`炻m5 KL3@IJ#89Q@ dB*:pvfr/nq*JP /\qm!h-c|RXN:%"ҋLl<\h3-7SၘH;OTYgH^ l |3x=?̇w < z7r`eU6+oehq?dA^>r㱪 &ð^| @!;=!$H"D$H#GLaNG(HS|i`?GZ?H3PKGOC$~ @$%~|9K?"a>%9-f:y Xbŋ,Xbŋ,Xbŋ* W㗍*c#BykK?AK,>CemA >4K!bQiRaLի{DiH~pHPO05^D 0d&*:.doB[?&I%8 ѪKC226 utnA}O$$MBh@5 Ef)}"]qH5)9ղ™rH*vfCi+U BȠW|c^6ϋM?t R (LMeΤhUoҿ7㗍2>񒣣]^˂Dx3(S3bcP=$I# ~?`6ߎ^6O"@ b~ȗ,/~ \J9)A?GSlZwv~9xۻ/25^?ݻv۷nݻv۷nݻv۷nݻvߎ^6Cxpj$/Jg]L*C򉳀o f4`+(btmT\xԽVrv^zd8 P`'&}7 E}36/;.+0"}|#(\e0"B*|Ɵi<W YɯMoƦ@•G~H6w k1nڬø&`0Imݗ,N7@?&kfZ-p}Af٤DOתw+N4/YVlrir̆W#(Se+AD6FY<]z`5QH[kR$h'6| -Y4Jukyj`6aσ/ߎ^6k(̝{|ϟ>|ϟ>|ߎ^65+'5X;e<իz-VD| p">yvBaD=!=RRs@5&kV͚`[rv^jH9+DA#"xOnv-Q+eԳKm-X<W[D_­j5lׯY*-x|? f樂 mnqX@n*k/ RBS0! Vc,@Z2kBW9s9s2AxJn;p D@BE@SvTR 3遛D䋮lWG7h %~vw:^ET.kJVsrH3"f?ϨSXE2A+O" :^T'%P|@5 drK''AuusH5ߤgs}~(V\l! 6b? rAm5p@`ڢ@Ey`1S#C`RG F$f&lDj@| ^f3S v>yE/7[:KewNsź]Ӭt\nt/7[:KewNsź]Ӭj]ضSKb%o8 Aǎ" hEg&^ ZV B SujSa!9W8@,;4lbǮ(Af[Z-e GNW]~"fuѵY]"N` bX2JOe%V2>;/0p\a!ʜI(DG5MehAQ3ZUeE0X?2LA m%@ SƷot̼ߍဃsV:ԑB|ԟ ;C7\gW ()7P UӛKZc-̽@3 \nWwHx@^({JF } x0hq/*+ #yot)~6O~^@Ynݻv۷nݻv۷nݻv۷nݻv>+/0Kv~o@h* E'Kթ#s]DsX(7OxT|J.a[^cߟYm`.!PI j{d~x %鳪yk.y1c5=KߍotYyȄA 8v\7쌩7WMsF㇙r,LQW'/&>:|V^bViqs4I(bzI0bnv( *1qB>IF.Lnnk, Wv^z4eVϟ>|ϟ>|ϟ>|ϟ;~6OJ P$otnI/Urc"8(ء-Ejbp8lX]} пG$=>nK|-/GsqA/I#~6ЕKe{Xbŋ,Xbŋ,Xbŋ-=H"m fao<@39T+p-]y/U˂`QD%bƥe5BEF |wU3aXVZjիVZjիVZjի ZqR{0rbVյׅCSZ 2(;x(׼-DP]߱A<=`C 4԰8LT[¯ cKLB!j܎X@J"1srh\Ƨ&[m1? eBB{i 0]"Qpy&=8ݢh9K"8h*HESGX?#A>$N@ $91iP Mc2uO hKq>շ5YhlQm)+O|7D X+]uZ V2QPoFD]ܣ^=KI.%i\Bַo^|jpt &ė.: VVr)> <ԊZ7UOaqI ^T{ͭ7TlE0 ¨X&SfRkcS  dy bHQ Lor7lK+|ϟ>|ϟ>|2@mmmmmmӣ<.-|azt$CZ,g%c 4 %uCZ ](, ǍłĢ`{%Ge0-dWiQIq CB$XV @qFoJea&9]O?ß_44(ozќ yHQHy,P!xPI;aL?ZT4TKrBIA-G:N!E1LI6bk12 IDJ}v636-o?A6Oʧ]YLun1a;IJ,,,,,,l `IP je D5=2W\L{|]wK9) eRȊO#0se 0PAAAAAAAAAE,ív}<<<0 0 5 ,$C@ 2 0 0 0<<2E&QN8ٶU0 0 0 0€rC 800 L0I100@8}}$20BǰE14s(EBh,N8Ї@q$!  L/A@-> a-DSݹ^4 0 0 0,(4PG<0 AA  q w AOA 0, N,Ӑ\ 0H,  xq@ TG 8 AA C0"( `AAAA!AAAKC$i 9 8$!  $j 0 0 0 0B   fHJpAAA *!1aAQqѡ 0@P?6qr$Uغj]?_իVZjիVZjիVZjիVZjիV}>jB$މ@SsycEb&: 14r)!ާ uDkFb$TlȀ(rԯ`G"8RGo-43~4* 4Ҏh$AWG1 0 #( kT#seE$Q4 (@]fkM3t"vIuXP EWT1uHTk®Yx] 0F[|BJ"6ऱ[&B2! ;W_g|xЋX.)eAu> %ҤaM*X* r3 ]"K@#Hk S 8y;Opi@9QP+q_)&4R:8@HIBc@7 [% D 1$ገdF$p:@!` F &6aaC(F-b(LvU Qߠ I@IH%5 G *XA2Di~7j \L0 , c/p_ƮL;CmbJ/x"(*/,VQ`J( 'ҞC:*A2ٞ60y/k۟.͟ b%@&15Ū @3XG3F2%g@bp3p+Qh[BLžަVY/@*+* -d@'o CHFJM, ]BЬ4J[yMJPJ։X  3F2jNh3h 3*[DA+J'UF8\ R @][mG^pj:|sKPoQ׻?ڃ~~|79soo:yXHܫ&DwI  P Hq;Hյ'97$x5]t_I9obI$022U# AO➺E.5NCQ.оM%2ZQh4 h0~xEV3N.â`B2~4> m'+cdt3TTav/zM8j3b0mU9,Lб5lEcEIE8DG?sff?H?W(!fQ?x_4w)P1N@hJ ks)ayf"R[YZ8h"|)Q_mLu/RKkBu1)G-&̌ !ȡ௵MV#3T 0Hq=Z3i0vw3i0vw3i0vI'f7J"mx>"ນ͂ @ϠLi%o EP#ЀTG  @Xe~lh`jZE,Y3Qu Q昕+T:JQTt+G `{_hhY?z͊s>@0!&x, X/8ܫ~Mf3T1P @,KI]@T(BCh1$ Jj@d| Qb@%`Ǘh-&B"NƸ3x@X lP12@ ކ `)`[;$p;W9_ |p;W9_ |b!#d @T%!D(000+vsڽCsʒ$l K2 CL^* X6p*YMň7C47)%,C >Vc9e9!uN,K nYBj ")WEB ]~ITKNk1"Q*$JqEVTMBݥ @>ńCL)aF S$T *$W4"t)$":.R\@L RM\mBM6ק?AFSE3>}fC : ӝeLi#IBw?COXQQ2@!LQQj#a|* !arE A(D$g$Xe17ǯY~Aj8vsھAj8vsھAj8vPln*L2R )Un-R-o$U8"B&l`ւK͘z?1̨.I B]o+2NE>1S)R"DP$.k)~ٔo3bX, ="R$$.& yv0c˴I]L`Ǘhp!'R\HBA\:|:|:|:|:|:|:|:|:|:|:|:|:|:rjApb fܽ}6{Y/kj͹{^Vmڳn^׾՛rۗfܽ}6{Y/kj͹{^U 3~e+3;,w~> #3Ċ^w-FSگ (ĽN3:Fh0w81̧P*EUUe,@]97MSoN\r˗.\7gN>_YRdрYg4t1*!1aAQ 0@qP?@1P^] .Bh,jYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYcYBhM:I-L<>Yq"aUEDshZ L}o4uIL"hڴmSI~ԳSb/W%SW) : Kf^ Gpx_GI ;6W`s_a ;6W`s_a ;6W`sEDzs<x~/|<x~/|<v:1LP H&&@6D^ARIaQMSIQ!%?/M@ uE% 20V{@KXb + + ( p\Z;gլ}Z;gլ}Z;gլ}Z;gլ}Z;gլ}Z;gբNX_o6if_o6if_o6if_o6if_o6hJY@A?[کշY[cr*èn<"zZh5ajL B$.IÌI#%-4;X )itfM+B~O`:"b Ow,UXeQ*buId&ݹ6VSX!ܑu&Ȥg@BCyjHмst^.9`@cB"a8ug$ y@TMY"BzzaFRLj`ӀlPE<1% &hd"8C*KJL~€pFVfLKvv/ k2/ k2/ k2/ k2/ k2/ k2/ k2(DdHoאЖH l-yP$@& K"ak~:O r-!Jα`#Q.Н"eU禔'8+D@`R"m,p*[&@uJP8 F@0I"=tApeDḡQRĕPNd+6L $PFqzt$ݪzɤ  h"*#(zGQ-=-šk! vNu(K*>2!D -,+h$(մt >2,Ӄ5a['O窗+bB[F `f^;Vef^;SLhA"K S()ZAOJ$m$Xu*̨n(B*@\2E0# HHbM7Xo1h %Du-X!m"nB薥,[H%T8*<@TLidt(BJ'0V>a:0&p@ޣڠ` GneTt&l(D1*[K3rKBhZD#3DD 'LX% Bd6rœ3~ t%Q(-ۀuYҒ! 4o!s/-S>'[BInt0FhE#LL(MU$.FI 0pZRٙUI @O%K*YXj V ł@1ud I  $u[^l l]a* };GMƸӬ:F|DPš?F;߅a+ceG_d&uqUV AJRG R1PnGMpU)=&fbR@3dHP}.9cU`y\ZDI$I;E G@WbkBܮD2eZ X &Ddk;E5t7(-7/5aԻaKK }Meښ}ti[؋7"ELRlI ,dh8 G% ˆ^ADUܿtSI4 }59j":|#^D$*]-krhzP2ekƆV5+EnkKzrWTG 289wT|V8ÅQDڳ& ""B`kY9(`š* %U2+lRVB$F&F^P6FzVvBH*R,Tc܈XSUʵtd* `X&3߿1gҸÃSBf虈$ &3.(p! cP\IlD,bbo AbmI}'!-56FŽ:Lٱ-Rh DG g. LIAB!͖ɘmBP.1A*7 QF!J@ Cj*luTD" 9!"!h(PH@C&)$Wnh )5'BCҰ#$Ej>H JgaJf'Y#+\< ")նN8(Оj,HͺX*Keh:ZEy{(S IU"NqeSY(lAţc]-=>vld;O|>Y,iϖCg!}>vld;LHdz$ˡiP%8HݴL؁(؀(ad )9}KD# {g>Cs2Qyʁ)qШ2Rx2XE*2&&б 6x=JՂb 0Zq$BQh=x#Ft` r-.H lH Y؀@f}C!t`EabSw)#`HhP%{V^-r50, :7 *P`dpaX .,J#ڲvj=/Wh]ڲvj=/Wh]!t`T©a^p0NAC3 ǘVɓE 2 *p9T bSzgF !R^ y18 ;`E% uHCTTxXt'Dw'%f/*C9jГ(̓$JrgF a HLAxlqYxlqYxlqYxlqY4 R f utSAd @BCYxlqYu3PT\84%;FRR I9#ebVR0Bv *T: ՕZQ65S:0]YLL-K ` AuCPĂP/(ӂ'21%̼68c̼68c̼68c̼68c̼68c̼68oт?UIXrZM'HG T)*T @ 7ո` c;}Όu%*0"sHt8R ڷ dBDt@Oor 1*e ϧS:0] .H2JF}/Wh]ڲvj=/Wh]ڲvj=/Wh]ڲvj=/Wh]!Lzu5ن5ن5ن5ن5ن5ن5ن5ن5ن5ن5ί4wN8fBSq\/ :vR+Gab-> 3 xҀ ؉UR$$+@:(c 0JYmM䏀{$@bXptBciD RQ(} P 1j vz֭/ J\NB)D C)-a0L@g5{v 5|H6gP͵,3-J@R :J\0 Q(J>!L"XC_꟦dɓ&L2d~6 L dG#Id              !CrF>&L2dɓ&LV̯т!D2r ZI+yš5slm.ӱz^KW0PB`D᧣p]H#` I?128UK҅~SǏXI4oN9ÌJoMjpk{B@;e;!<b< പ%IY|KB<=D~IT@\ YF2RPf3ŔZg/s3(cюإ^B-Z3t;'L3tȉt6-Go;|'Q: vNuGo;|'Q: vNuGo;|'Q: vNu  0` 0`;tPBx4UeUgP+cѸF/ar&aWqBWy)hjc]AUS 3"zjT&ʊqtk$cJV2(ٌh08͒Tֆtl8P&A0NV̆%. ᨆ,&`:"PSE J%d-3hlqRJ<>9b(b64^ʌS^VJV-(AWf C$ec4k,xYeY5 {/ŋ,Xbŋ,Xbŋ,XbwW˗.\r˗.\r˗*gD3ٻ bWS8bW VƶqF§貢߶~lF/Kt~ЙC '*MNҰU -1 `W*v3ک .RիVZjիVZjիVZj o#JsԶlٳf͛6lٳf͛6lٳf͛ Bn-q]I&L2dɓ&L2dɓ&L;ƸTd2TϹm۫*x5` Հ [nW+n[u\}d,S*- 1B/,~1V6ڀ&y3 xw 6@`" Cl$/@NH(t-q3vN8t7˝fe:~ CqW7"|0u YiB~GK95*GT֩ Q tzTn0+Obcɸ}'z7GmNG.Ud]٦L%ZL"a+M8`>,^. B@F{3v^"4z&!zN-s[ 0?ŒW7"fU n>w61RL֍n`{ K*f? G O4a;Z Z xFie= ڿ3Q St`4]z'  j'R*&(8] !*t:V)#(DE"BT`9\,(LمC* q,,Z 2zVbtw;rJE|mJg#'>$xKdO!'#_-Ck'PK\!K "mMh5͠5"jLJ2(TFRnp("PI>p⁍c=NQopsmŸ!B'* PK:]㢃q%AQ]2 YXJ*ɚ4Xw%WB\W|AD(RO4zǻrw WE+nZ\!zW۔G P0Df͘UX=ˁ ~yE`. ᜇBU ZG1Uz!hzcAUs>s>s>s>s>s>s>s>s>s$,Xb.֜ 8PQmNeeʼnH/)\7ÿN-mJ]{}+º)W|k˿UV+htW<;?Y;q8:޼W ,wc&+tF{kJ]ڴ{,4-[?oߋu]?tʻ\?e{.B-߽%b9gp:\lgp:\lgp:\lgp:\lxȒЉt2@Jbŋ,XbŋnC>ٱQ_WaG9:1hSC &'t2K~C\[;?$G6$A!sa39  Ecqܫ)D7&{Sb-(#\(gٷ=yo"{nX#a,xiАPc- +F;1<=@[P@=.Ȧ=d A<@x"tM,Q^;왼R*-3/L- S*"×4 G\1 x U! /oNL uj߽GK_\O}n0Y+GmW QmX]".ڪQZqozF hi$o8jؔtC ƍ5j pm|434ާ0)h(/q?i@p4qFaF 2MJ4T֑%xUC]#.T\q&92(T6S i%oqmtu2PUp,mAxMHs:QRj0 @$|Ԯ&QSd T(дuD@Φv*øOx# dVVɼ.P1x][Zc&𺷢@MuoEh :ފ@u7ս2o z+A dVVɼ.P1x][Zc&𺷢@MuoEh :ފ@u7ս\)Y03%*39,8&L4(2h!Ә.Q2dəm$QY'较8pÇ8pÇ8peN`*)FFFULl39 lS1[+H9TVc1U3`䁳Ll39 lS1[+H9TVc1U3`䁳Ll39 lS1[+Ht!HHSve1T;3G[uio<^ NxL[YQ,x2ڥ񨎨aluKӨnL𜨜EVWԯ2BHi)ecp{J-NoHcQ&]Hr#?XM?Ia>ާ^V1!^65}ھHRñ3g+'sw˺Z qQP=YLXDKʉq@2|=#3ؘ OAso; 1<:.1@`M˅Ed F|m:G+)A Ԯ8bHt{2Z8ɣE~ua6ґ@O16l/T>u0^9 0` 0`Њ0& ˆ1T0ǿ_QiPmQR"J2;M,u/k5l >h{!nIɑHJTYR-IɜmV9{OY'Bg'ǁ#?VeXrԔ!QC?>6h>M2L#vU\J[VZA MpFBqRKYbZv.:Nw]1ʏ1sQ m~n&Hr"11_@ u#Ahη16%/s1D*T^9sF8D _=:C߿~߿~߿~FF9!oҢճ׆W"oʝ_nQʭ3*ʾ `o+,La<iaI֨'%8"tx:/h9ki/sS-|I|g?7̓'r~ʋ}l|  Aŵ`</nFV8Jd pV*yvįxAãAM_BS=C uSihBur]v"ݕ}B5|pd|w- g|ʬ TV_$4T}FkAKALY/'JĀq$M&ĬDѣvHJTİL%)iZ{XCiS\s}_J)lcp䆝Jo1Yŋ,Xbŋ,Xbŋ,Xbŋ( rCNI&"̗LN]nd^[7LIzR%M#HI pK sRlUz ;l#өSnXNs D&׹74"$ȄA^R(fC(z"HXpP9,ЂnV>MbaScw{GO.]= [dcu*1$mv ` @21 :8dd.dUlVr{ -F@Z|BH?[-ŀ)LxeUuM];(ߤټ($]ѹ@u ȸQtOmaPK'dܰm%&or21 : +h/%U*Ż+I#-3%C?"&%HE ^WNN( T`NLaD_8{B3`sV\c$rv s%8?U}fcHI p  䆝J{׸o*TRJ*TRJ*TRJ*TR rCNCo`<槇 /«. Zkb;&h L_v fBZmfuh^8c}=c7v:&w45_JguXv}\Of'{ƌdy QR=[D-@3Z +~uxP`i*X6QPgy({JSEJFppөQ&fِBj%ӭVX1}ū2__)ώ^Mz@欻@OBԐǝgjVc{`Og4=#9a0Oxx\ĕs8(d rn݁ qVs)@)0 vod XF|['uQ<}~!y7 PSIIFO AOs &cu`@gM<ӕtiP*alj7@UiԨZ(*-m*Ų%[f0ӷ'%[f0ӷ'%[f0ӷ'%[f0ӷ'%[f0ӷ'%[f0ӷ'%[f0ӷ'A6b@5ǴjAb=,2^/ XEL,ePnaX ɓ&L8:,ZEE5ԨY@H EoGK"1ZPZgzhh,Z.s5IFv"Duo/5VXF#;YVnO՗R}**cnD#- PVkWs{@Ԇ;kґl..b%!蒿EZ^l^_Wy c nNx2a''cV/RJ*TRJ*TRJ*A.4%*T)1Pi нmE~F+Vwc zD8(tl|qPj!Veu{`zQ_il^hS,%UvM:1{ǿ< J)z3Nױ-4LYCiH(}W{ W#V("N!&[͠ "6{B!#p96\xLQ~uʙ[!)R6eMsmC;rB:}3!` 펑` z׍qs̜ S!^[@I0102';M):Pv,15q6=u^Jc \#+UdȆrpHt=%כ$EЕMj=L6÷"WHJT$%*TYF4hѣF4hѣF4hѣF4@dJa}1k)=/$IKWBY~cʠ JοI (TUIR$=?j‘H F o6piDO|65检Ip "ED:u* J]*eGXk6V1b #b6j 0~Toux ˷zT,|PIDw m޷yį8҂zv/fdm__AŪ (zŇu*M^s34*TRJ*TRJ*TRJ*TR2BrnT+gyHHJT.vhIBY+W ƣ_ fѭQҧ9nD-oƗ%4 *\T1yIEXcGjFufwR>ңꐧ@d~}Rj['W@PB (PB (PB nKΡR !\d1A`nJ@5՚= XzZ! uhOA{XesQJ!~@p45/z^<,o8pÇ8pÇ8pr#gEF~hrI~ UuA3f"TQc̺у%| qeh(d+8x_`&}kl,mbj]KfDK=T-ܲ/zT1Fr&һd"^$uUOED(XAqdaH`K /Di4= o,7K$52:\Ԑ-ըGu U:^8A:n_+?fe=3*0]o)2֔iׂm34U tM*|11PH<6,_Q_f!V] 0 0 0 0 0xڸ_#ʕ*TRJ*TRJ*TRJ*T龜`keI(tiaaaaaaI!8KzEv}ɋ&U<8 Ba?fffffffffffffff)l;$;di>Q@hB{٦0ez=5Y"EE'=wKS=# gbgsMD F,b6|OEG.Bl8,Q fh/= T"5O;\WꝏT:qܟDiSZːD&t=}ii ?ʎ 閝 ۅ. :J :_mؒ͋{F)2'I$I$I$I$I$I)$ή6vd`$/yci% ^2"ndt> imta+]4[]lB.dJ5(uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.packager/image010.jpg0000644000175000017500000006060211665471326030727 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;@"R !Q1ARTU"#Sqt2367a5bsru$4BEc%C'F21R!2aq3ArQ"( ?yMY4#X=T.d-6մ!:g8?_q=QVJs|ؓjh?O6]OEO,bGȍI+mhS:Zffc/^]s;峣'_7gGEO¹mj- pwb:w9dYx. ۝@؀nQgaUόo%ZKhqgGEO›3'\ * P!9h n*T4R';9̌F_ZӾ9,ƞwO(o3'MvoKDy3 4>Y.Fsļ]ftR[muufnvg<ҷgGEO›3'\1&|'p=!FH#4:mχlW?'K1i? oΎsAEZKg🹂c6νYxEegm0#뼛k-f~es'C1i? oΎsM a,ܝ #56Ks|DLs"g3'Mv< ),dsҾuF\$C 8F@s巰6?G9ky:6IS|tt]+Z#&`%6gmSRuuѲa+EM:n~gs\<|tt])c::.~gXH$(v SRnbq5rR1i? oΎr۝s^)\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΎr۝s:Ӈe(u-vIW-ڗ;S8yɶ\qrR1i? oΏrNS8y\gGO›3'\RS8yɶ\qrS1i? oΏr˻iKiN&qO|t|])c:>.~..:Ӈe(u=vIW,Nrm\gGO›3'\RS8yɶ\qrS1i? oΏr˻iKiN&qO|t|])c:>.~..:Ӈe(u=vIW,Nrm\gGO›3'\RS8yɶ\qrS1i? oΏr˻iKiN&qO|tt]+?v.Z\G ] 8m SBv8;89xWGΏ9o{b_$cIMeP՚-U5x6:-z- Rs7H]omZ}80I՜\: -޽覙fs}-5)tTLvѳ|UϛQMbRkHqyKGJarg1׵@ӎ nص}Y[tZ:tLS?:hՕ-{f [,?.KV澞<~sXk[>ptGjoUOUūa4EU3?WtWzTDFf'ѩ8NseElN-AcuSMv5@i'maxc~ssM,,E z~-Mjص&N9}1رDZMU;0ɨ*cd6ILNGIZKp ~V-jص7骏btvItz"1P{f474.6y G,2#My6 gު=Sz~-_OO^D}.Xٍ! mJa4W6*EN ʬ״>.-[T5QZSGjMæff'#GyFC #Tq'&`Ml<+e#h#Cs`/{m[T5QZSGj飼~fbLJMޒ18jPgB& 8,-i}hī!}lU dۜY:k_-z~-MjصsDb*O/R9()rm4qSԲ8'`71;λ& uX{kYT_^p۫Z۷骏bު=UOOo;SNZ% Jr]z~-Mjص{)41V y겹qnKUOUũU?MT{|\7$ܗGު=Sz~-N&p_7tijص|ަ-N&pڛں>0tGozoSMT{\.qSqWGަ-M`骏b{N.RlqSMT{0tGozu)6 8FF={z:jط:ӋÜn#jn#jUŽL5Q[ޝoiM77t}`骏bަ-N&pڛں>0tGozoSMT{[qr`smMm]z:jط7={ӭ8I\966L5Q[ޛUŽ\.qSqWGަ-M`骏b{N.Rlq)L7QZAuũ|\v 8Sq]z:nص7=SI\x9⛊AuũD7QZogM7WGޢ-M 麏b{>.Rlq>tGjoQM{[r`s7=Sz:nص:ϋǃn)D7QZAuũ|\.<qMt} 麏bޢ-N&qn+QM{tGju)6 8Sq]z:nص7=SI\x9⛊AuũD7QZogM:I]AI- |-@9/®O좜}VTA [lEM119W}-11\hߦ 夈o6"n"swX׈{6 77'VBLo_;-zJ]if7Lx^^t:4tb';~?V^_S0&mDX]ٱn}G_͡WLĘ\8g l8;֪%i1WPC5]kLhf{/j: ⧡X)ε-9gIZ$f(W+lm68P3 uS 'ocg݁.niAqe˧ыWUpE E-\,-Y%/"UکY )׸7 g-3~}l2JWcul5h7Q54SN=.?Er6X# 4z_h&&}PH"" """ """ """ """ """ """ """ """ """ """ """ "/sX85$}E6QO=-y2Ms[n z (鰪tTώۛDoPx:XF ښexccxWZ^WH-/+wMB_^FEޖ'jDZy0)Qf}]<[Eޖ'j1:x^ɟ3%B׵V; c7+0 jg sXE "G67e'|3A}f&ś{[h ̹/C=KdӐ%ݎtV7O#zaf!pg|($)a Tq+ #;^xtY]SKK$-e;]<#& lI%-dyL)=MeA~{gn 8^鲷Ġi AmHi6lE,qDͷ$!@$mEGPU6zIjbxQ |Zf$xƏ)XjN$qțZrڌ)YUST4I$4s4mv5~ k2 )L;Dq3n 8.5irހ6&69f mi &$t*ҵܠu`7<>rV$91AK$rRUNp#ŵk Jz:XDlsI_7mKEMC +DCCǿ;;8mXr -mc&ۛ.I܂Ae<1F[BX_niWfC=dbŮkg6snHiͼo(sl3ihse 3Q9*J,ؾ" """ """ """ """ """ """ """ """ ,\N)ꢧqlh76VR+ *UQPMM4PHAi.֬UUTQG#G@U'T2ₘG+>9oM_vdV6'+#v!Lͻ^o,T),IlEQIXӗlp'}-|*+@C4Rjдwޑ7 t<+Ky~P3W^FEޖ'jCڶū1Ȉ""" """ """ """ """ """ """ H"" """ """ """ """ """ """ """ "" *ph#F!]l}%+Į6ou5ܥk$ts=cjjZ \x)nVpL|+3I565S]Gx}t& ֒NlѮvXuH!I䥛Ff?^kx8ψaYMD% f6 8AԡG 6-s]n#Ϊ֝niy_#"o͇}!wZWH%8j8x`4;VϧR-V"G?#>VǜSԻSΊ;'SԼቧR(.Kk׏Y ^pөy~uߵia>Ku/8b5'өyN P]]֗~uu/8biԼ k0N M:1AwwZ]]֚ԼቧR(.KkX}:14^pߵiwwZkOR&K.Mc ^pөy~uߵia>Ku/8b5'өyN P]]֗~uu/8biԼ k0N M:1AwwZ]]֚ԼቧR(.KkX}:14^pߵiwwZkOR&K3wZkOR&K)iwwZkOR&K.McZu/8biԼ kX}:14^pߵiwwZkOR&K.Mc ^pөy~uߵia>Ku/8b5'өyN P]]֗~uu/8biԼ k0N M:1AwwZ]]֚ԼቧR(.KkX}:14^pߵiwwZkOR&K.Mc ^pөy~uߵia>Ku/8b5'өyN P]]֗~uu/8bl>Jz,R75vBwwZ]]֚i$l, ϑs֫S6]~ }&ӜS֧Ĝ&JFJYb̘/@OLj0ڇ1L? ɺf6U);cu\ΰcWGWWOΌ&:L.ziݪ墒65鼴ןm7Q(mA xVF[EΊU60UHbcI "qŢd/e6AG졏$p*ZZ6Кj0ܴ;|5)3ՅtHȷzdkX!k𖸛pĭ갬0Kٌ2V.uaY5~S{Dž&XK,u_j竧"kp# skX5Z)a)gc M9Y&O¤7u"hp_k6"X&6#{E:^f;'i'end0>,nrTeUvWڤO'zDU|ݠU;ԑa4%f.-#L V*)RGC!Uw͛19 οAʫRwoCܮ;U_7h9U}NAʫRwTZ&U_7h9U}NAʫRwTLAWU_j>nrTeUvWڤO'zDU|ݠU;*IޭQ1_7h9U}NAʫRwTSU|ݠU;*IޭQ1U_7h9U}NAʫRwTLAWU_j>nrTeUvWڤO'zDU|ݠU;*IޭQ1U_7h9U}NAʫRwTLAWU_j>nrTeUvWڤO'zDU|ݠU;*IޭQ1U_7h9U}NAʫRwTLA{i"C~mɻ\O+S_y!UT ܥw/]~wYw*?K#*;c*?K#*;c*igE|zhvlè-sU49 N 6VѨ?RXtGTMDZX[mq!T2vP>䭒|Bf1ͽ͜krñ9OKS[*yie+s[JKX ,hGf8O#5[6W p 9#(iL~i)_)0b vSԊM37EfN͋?QQ#+A*_OOPC#5 C_}JcdไwgXYVtsDtq+2*}QR?75f9Znd,ic#-h-ՙ{DDAE?2E?2aYD?S῿rJw""""" """ """ """ """ """ """ "" ZnC%rAiK$="_ʻZ_}FTyGU#wUTyؗGU#wU΋t5C ./OA$lM\`mV>[bT9 ][APzc5\[s%NkA mUnZPSV]u M|x};`520 Ei8+,0<'-BO#Ejqu'g6۰fl z@YG^O_´kdyPQrEP[حuchfd h;Ens]7[FqP?WVvt sK ; c5IU0H3T6?>J4^6CH:MV{ER)X xA F9؁,v`wƇh`p}(cg6k6Ʃl?ZAS[Y 1.4fk6o~!^A$LO6s mƻ7MTbWV&ј&6G׬ Q~*f/.)hj` ;qcH9!a?|)TwaB짫Xk&&gY< ֿ;i&e,N,,FYS%s'>׾mmsqsؼ`թzڶS(H=@eI&;L%vQJճTS 40Xj:͸cF*CW,΄o Ym.ǰFS1v, u]ӁRd f 6־1ɢl=sMDH"" """ """ """ "">e*>e'r³ _§"p$DEPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DD?H-7)~䇤KVSrHzDvߊYJ/@\GM/@\GMwߣٝ". z\58Fxm6W#Yqi:ɷ*K8 ZKAb@#Nioh;YȼZJ&TQf Ws<|KcY6-Q٘gv{c -6P#j8ETu4*h!Jj+ki3YqnXn"TU00DGH/={aY,XʜBB!78.;IqLSV&7I<]~hGO4HٮSf;WV'Qc`9ΑupM8kkvgRӘ#OΣapn )Pnŀ FnhKe*>e'r³ _§"p$DEPDDD@DDD@DDD@DDD@DDD@DDD@DDD@DD?H-7)~䇤KVSrHzDvߊYJ/@\GM/@38\8pn3>rE;g4l6:a *pd*!M;g4lkEL6W㏎:/ bVdܑT.Χd͘hjޚC{ԫVV35羝:G2TM2Hf9x!=;g#V#kgφKrsxGYPbM!=eޚC{Z XC{HvzkAZ,M!=;g5-&ޚaHvziMh0E;g4leޚC{Z 2biM!=h4lփ XC{HvzkAH4lhL2SQ(tlip)5BᇆD?WDC42@_*m!=DA0E;g4l Z,M!=;g5-&ޚaHvziMh0E;g4leޚC{Z 2biM!=h4lփ XC{HvzkAZ,M!=;g5-&ޚaHvziMh0E;g4leޚC{Z 2biM!=h4lփ?H-7)~䇤KV ZRHEU5eGzlK];JؕS΋t mν$HyXxpj ;'Z`aC369i,<4#*gHp-8nu`ZQcX4878%K$Q9կ^_\ $69kt5OлUHm6cdx-)? }K+j$i4_Zd?ܞ{RFen 9c]*(4ۤ٧pCx4^m\H|'^/*ON\][xDr6X+/6_p</(ׁlrǝtg7:Sk\\qXk) dt涢WH6.w?<Z].=v(71s4nq֭ʹ_d4wR$`Aػ9qfhx2] [M ol `/rx^QAF$74E;Y>{~ r^{k!e]]L 40${Km7AxO>*c4C9|=M.OScؽ[NDe6ǹ8-ucep7%uC&}4f9S87t-x´+$RbFOhsls8_x{?%t5ՑiET[f4sl ,iuԴa"p\Oh`U~ÿ7 D@DDHzG޳+A*Ak;ߔk:|k;r F*ugzqÄTVwApTVw[>04އ[>00=<53ML=]-n%OzizD}oC{Hb5Ã0F#\R?Vw5S+;r FWSƳ|F*};z B*};OzizD}oC{HM5uX$PKO-9{O*HelR<Z)L.ӊ\;<۞i kj^7fƋNrTޱh 4_Yxn5][T n4Ml.6'p6\惚\m{_ZWM[,kAֆ{꽸xnb .x:WGrsnƀڑuY=Sji9Kދr2/*E~>[w[syoٶVIM8̬ώl5:MdÀ$窹i17cTTM Z[+03ڔ5c$:JVXGNNը&ܳ 58XksW4K@$TU6n`Z/z1^ֵ*fSev6) ,щ^Կv+?bŤzk97)4e{C.\bOTQi ^67PѨur_RΧO$3k|Mx<:Y:Le2E/m }q^I,9IYSQ Y6ÃRQRE[O&̆s!9X,ؐoՂeocw^׷\p0? _bسbcoN /=:AHf,vY{) Z ll0? 1d `$4gMEc԰ &jX l)׸8~q/ ٤ET)$fXZ渻`qߊbE\xkɋM~O Ǫ장7IN$䵤 . p%*de| <2`f#8)l.9 lp0? CMa)#3wWZ[|CdCG|RʆK %fnKx5cV8uѺJ h#kf`q^Q3f9ERTXk\_[M0Sh/zh/zDՃ*mOMOW(eM㜼?㜼?V \s=4\s=\j6rrMX2q^q^rT.9.9Q5`ʛE9xSE9xS&Sh/zh/zDՃ*mOMOW(eM㜼?㜼?V \s=4\s=\j:.9.9QgV*mO_ .8D \;JY!--[dPau`cYM>#J6ӵ壔Fe#ILx5X-k|.679\Ao2dRǽB\טGpa 0WYZ%1M^ƱA!q`uvk{J%ӻŇ/ ՜@)@+L)sdr;LwfV8j:Å ةjj9&&RƳ<;6xUX7:jK<-hImjX%t.|/vN D̉v&dO43"}$)@'aM$*LȟI; ܡD̉v&dMܾ'aP"fDƢon }N D̉/IT>vN D̉v&dO43"}$)@'aM$*LȟI; i'aP"fDISI; 2'NšIT>vN D̉v&dO43"}$)@'aM$*LȟI; ,O<[9cģD̫znsvIcuC䑁J_` J(1j_nSGJcQ=AE*h垈?yϒLgP{G,\U*h|rDϒPVSS=MlVȀxVnC%lZRHUUeGzlK]?Jؖ;1>r"ƭk Bk#7H;5TQ LNQשxݙ()JDb64Rf;™B'4Ø 3u{VvXˢhiIV|zn+<_N+c;D<B?U4x<~g R>u ~Pamkh'kgpc\,;7;^4<B?U4x<~s mR|JgC=lJnchyTk SN [woQRUdQI tkYfM!לBt͇9K&,Bx$Dl[<B?U4x<~(h[WAMM,UO.1L֛~=z5{6{YC3u),x<~hyU:Y_MDOU4UEWIIC;XmxP\hyT5U=d[,Ԩ##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH##T=!<B?UH"ahhj!kK$="_ʶ-ZRH]UeGz_?C~%}#^\36$ċVOO-,,S⯻|"8x-,3 p>-qs3;0$*E]CY=YxsK]qk8AU$5ۆ@`iku\nxC;<~}gw)˓YZ"&QUOy .7lm|Yυsep@kp~}gw's#c9ܳqٹ?#rfy6 ƽ@+*!ո5bv6fg,oYC;r̪<,XW!nl8CCdԘ"*6kpp|ugC;<~}gw(*)mw>>ZcG3!yIb$#J& K4<Ypj[!܂>Zw L7i.8s|AUailٻ+2-`Iqr/mV?d>wr_AUKRf.fG 6߁+*R͗5-l/kZMx#ZxOY |#&qTHvkn_^vmro)qpk2N+YC;;F &x9΅hv59!ܓډGC;<~}gw"E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܂DQOY$E!܁қW_y!U4hO`M&,ε6sG3=kI34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(I34<:w(LYi֦w(sGqT:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYi֦w(sG:LYkV)c.C1u%9ܣֵ<$Gܓ/^O+ɏ?Jؖv%-^wicE|DEv[;Xޤ1^PޥrrllvUtPRELCjө5*kG=5KZl ?J3<1.<iMۋ)kNˑԲdF$ln mhhs/~w73!Ke-tN`7I[gq jY%u{b؝cm]+/sou V)1*z(ϕZ7d%ϓoR\6->HU>ku_|y'6GVK4 zpEQES/1-$0lGZ9 UE4ԔEMGH$A6}k9Aj$v7.~hg~e/ۼ*hϡGnC%i~{Qb^[|rTVIq u#c=qoM5QXr'܋Q#c=N1n{ןcZ8G0ŻMpav3ޛ)mȵpav3ޛg6=? Rۑj;g79-zlz~"w9-zos ['IKnEs ['c=N܋Q'c=N1n{c%-N1n{|#b݌ǧ:J[r-G|#b݌8G0ŻMOtZ8G0ŻMpav3ޛ)mȵpav3ޛg6=? Rۑj;g79-zlz~"w9-zos ['IKnEs ['c=N܋Q'c=N1n{c%-N1n{|#b݌ǧ:J[r-G|#b݌8G0ŻMOtZ8G0ŻMpav3ޛ)mrۓw1fF r9wĨ79-zos [8Ns?`7,cQ|J|#b݌8G0ŻMOt,cQ|Ic;Tg79-zlz~c;M~'c=N1n{c%+XVRg!amjM~'c=N1n{c:J_{1($ܱyG* pav3ޛgt,,cQ|Ic;Tg79-zlz~c;_ 8;owĨw9-zos ['IJگvAOA[ T25Xl47vW,=pav3ޛg6;vW'_cwİ9-zos [8Ng_cwğ'eO'c=N1n{c:JY'eO|?7|K|#b݌8G0ŻM)[dYSiPTTFZKZ-kMܱyG* pav3ޛg6;c;M~'c=N1n{c%+~nX<8G0ŻMpav3ޛ)_X<r9wĨ79-zos ['IJBb܀2k*)~䇤KWpav3ޫ% |˜usK>5|ˢ]Km!Eh ?!jR #8~[Dqq^a~ v[^/g?ypwiQW\{բig14kEJDY)dEJDY)dEJ,&b@.P"@.P"@r;)<Ӭv^& +btG:=3_c+|KATϧko^կ}2)~JQ}Xx*;,njfV~L>pӋej تfhSգ{d~=)ysg#)Ʈz*9~ι3}[Whr}B/RNwEW<'_{?#>EtWڋh5^V_j[~m tY8Q [N&y޿um@$7І~wxܞqZ%"WE]5t!5:y2AɌY?Ԧ*{>5vW]#znMfh>4B D,M4B D,M4B D,M4B D,M4B D,M4B D,M4B D,M4B D,g+S**-l˞NIȮîvs]-K:>baopN4ާ1tΟ軝yyoY9[>=gyȔ}5{|̳NYf$ebFYf$ebFYf$ebFYf$ebFYf$eYYαs}>sO_>>=H&f"mrD\^˵sB#9WZ+Ҋ&2,?T+&RNA[PYfR66@RmjKfd1(R@'-':η1{o4[LZSn7Ej1˸j;qW!PEVM)/QNdc IK0d|)z-`sXyN&.58jpM#ߞC{UNuocB9iK9;Ti/MJ[ܵ;hU@պmkbڑ35nSkmYMiZb':γh^ Y>t}~7gkkuԿRTseR ȋj`+BJE$_]$)]i,dRX9uٍ K9Ώ/F[mpe YXz3P ̙ gVq,IJ%clup,up,up,up,up,up,up,up,up,up,up,w'b8F#yaKX9uٍ K9Ώ|~ȷpx7x(9/ܾPdK(Ű#ۅZI56ѫ2 ?sFuw`mXQ[l# *$ǫ!z5\XacYf4/c},K:>br{k {lRRRRRRRRRRRR%_9LQRJJHpI2²cYf4/c},Kz>,۴:M.t1zhsgʴrrsV}9}=,jjj=;bYae%XbYae%XbYae%XbYae%XbYae%XbYae%XbYae%_HNug[нAt},qʹ':η1{o4[h99>NuocB9ўttkؖY6K,1,IJ K,1,IJ K,1,IJ K,1,IJީG} GEIUUUUY؏GH} Gޘ@D} GWY9GٍKyΏ@{mWFaaYI_~{kΕ74ga<]9C՟=q8d4M ~ި?v0MEϞs띳>sO_9EDEDEDEDFJAvA /n /:f"UTKu nnv4n9γh^46c ;L?36702 6E8@P`"3%1!'5\ZZ/=0av8[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\^b;+N:Os@hWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxWxW^ p p p p p p p p p p pޗc £`iTQ!eKQsb ht.ƣR2iKQN[[ZԱeqEyVW8bAGBQg{CkjNQډϥ<|DY.-)jMZqGzb=1LG#zb=1LG#zb=1LG{qG{qG{qG{qG{qGU8buIY[O\V~A?`ReE 3uC:PΨ|gT>3uC:PΨ|gT>3uC:P̨|fT>3*ʇeC2P̨|fT>3*ʇeC2P̨|fT>3*Uc*Xʬ|eV>2UUc*Xʬ|eV>2UUc*Xʬ|eV>2+:t{j?2MUBPo2VHfZpt6[!զpH ZV4h rfI&2ɳT8lq8NIŇ :Vz_&dOp"S왒3iN} ƦhKJX ZK?7PWR4$0)Eڭx3Z{-QkG.ZύTrvdmvt:Cs΅-[Z #R+L%Ij]Wjg[;nM&q턹S婷GG Sf7Zim+cв"'ͶnD1fn;]vi;ݜ~{~X&MfIjWh/Zq6c"K'Cf h̅4q5կ_] ~7YX$J0]G?葤?8-kCJ[E/&n]rPJn|ݪDGr+f0w)ڗ'G":܊m9 ܤOrNsv*jPDI2j]wWzW)Qزܮei.;`7r92a5r=i6:׋î*fIꋮ&N nK;N$wUzvPrUJMߨOgnCUE+R7YɤXh=:S/3M8}F|h};52 Lrc i]m2e [cpJz^;AڕԐg&1ƍtyД8$-D(.E(Hm1r,]ȸmjdqN$ֳz-Di`)ˍ&QeT[C+Q#R&۸PXөŘNtv kvr(H\xҝ#n[Dqz#-XwNëp:D+!ԙiZ\q;p`HKQJo䨉0+DI#8Qt).%DqFjiv@/NJgx^JݟwGT6,`w)($C$?³ڥE$5QE Mί%@_"(2u/κ%TLl!MJ+:- DA8)SrE'.u>52njc fk Rhq!MKO.3k2;uaXDD~Qc0wm!3)i5BDT ~+nε\=BY`.OxʨwLD-2GfJƝV#I۵Vrxy>;̍jn .nw3{|.L>IWwdf#rPijJ"B3j9%/_RNU4J4hےAY3Z: c1,>TB? x88bXDh (חs`w0n 7s`w0n 7s`w0n 7s`w0n 7s`w0n 7s`w0n 7s`w0n 7s`w0n 7s`w0n /T1v.ne9it+RլQIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %CIPT4 %@k)oݻqcρg:z66S{;;;;;;;;;;;;;;;;;;;;;;;;פtIs"y,]BC%RA8yB4nb5!6a 5KsЍ'2?!u҄&N"j~G !\А # nknʪct yӳ60bO?@̕L4K$;q横Ľ):ktD_vy]>C*۸n$T*Oo!\Yo]R[E36;65 X46#VwG5g*0*4*Z:[uN)%=JEA#{5Wol,7 +)&.-#Di9RIMkіjc쟥s"y,z$Fo~oxߛ77o~oxߛ77o~oxߛ77oⅅ/ 0is0isݻqcρgr&lV?jkcFJ>EGԽ% RjEMΓ-Y- lɍgQk(Pm\0l_-teT+Qfi=mFͥ-!ok,Q5{͗@M6e4ۃWQi鯎Mq1DWVPpU1]-"?r%nEY˛:0Ȱ{ElמYLXUm&35H9Txy,jNF6ʢduZV:V*A:HK`FVZ] m(u6٭1*JBl`֑)i%-b\*_JLJ!:-6?l]k`.lm8S%rJCAKu^-QvD{?r%nEYfQdX`5 aX`5 aX`5 aX`5 aX`5 aX`5 aX`4 OV2x3'2x3'2x3'2x3'Bן| 2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\2 )p\ Nm*>|HqcςuUTDx"4o!DLl< 1J&J $m[¦ۚݶKiUq"NYJe_:nTԚ䴭=UD(zEwk%_HS]'c]NgA C!V1RRd-Z-!Lln{%,Ns"y,d WVQ y2H `.) Ʀe/њmCfɘȖoqoA U%lF:A%hQ'+( ,~s"y,0j 0j 0j 0j 0j 0j 0VeueJSL0TmSL0Tz/w<.ǟ95,wvOxSj;Tڧv56,}|y¥D#҇XsԡUMp+"g:(G9EIdFL_? :eNC(,*/w<.ǟBUN҅f_#ZD^Ǣqz'Ǣqz'Ǣqz'Ǣqz'Ǣqz'Ǣqz'Q_+LWx; w@U=Hs"y,W"p|J7($|J7($|J7($|J7($|J7($|J7($|,PHzǪqzǪq::i?s"y,dDz)].`gU8|Ȇ7\gG3dsRz!KCH& h\Uzuw?;7:n>j'jWj%Z5GaYNu >~K8гyhDd#E[m,dQ1M ̈˶R޴ /IU6'kB7JMhJ9%CіͰDh\W$Ӟ49NxӞ49NxӞ49NxӞ49NxӞ49NxӞ49NxӞ ?HFr3$]^%A_Gܿ}۹v<~?)XXXXXXXXEaoWݻqcϢ6mom{hF6ѷmom{hF6ѷmom{hF6ѷmom{hF6ѷmom{hF6ѷmom{hF6ѷmom{hF6ѷOݻqcϿs"y"y]>]8vNc~ ؟'[ʿOvX_Įre ܮMȽ_C+ʑT$bʲ+!pfUCɝ`$=yb)#F!#WBo mԄ:qܹ֡ڴ[ 55"CS[Q:zpwU$ d ܤL^쭳IOⒸASK[L20#(VbT;BԔJ6Ү֪e*즒j:zj*bSECYLWvb)keuS=S%.!i9Tƥ:jVz}SV&Ьihx16mJ Noh-%MBPKOZ49K_T,6gvT TU{z j?UMUU=.٦j꽜KeojZ)uNԕ9i[fEvjէ 7 *#5UO4q^HٱNFZ]-]\u= F9ٻc{^f*a;hC۔;?jTlF$4׭~ÒFhY S]ZLPE<v}NMɺMX+HmJuIS!Yum?z4hKXUlj!Rfqi(LjHƻ"Q-06gSu*l͇u~ȶ&Ώi`Ψ-VvO&s393}}}}}}}}}}~ u?AG5\#~]pk u?A#O{7hmo$*6Kۃ&̎\d5t.[IQ cxjwۨ- lo5Do iWAv棪6^:p;Ԕr#RA9<^*$hP.ώiYR0@Gw $(cFì2vYڗzuR5}?u\)7RURpsGwȵ.ޢfc <\ IB}a<duSl!{bHY)d&ؔIbi^’nZAOj$oM:j-aViqH M42X۵Iul1XdH胾8~9@#aӐ@ =2 Q{UG}'Gu  /$bEO2C,a4r-F#<+|GurY!:ܐ2SSqrq r7p|o#|·+l(N7c ߔHFF^u|]98>^uj9cF <]y*v=oZuj9cF <]y*v=oZuj9cF <]y:CNӦ ;UF58Xӭ6M[*gMD$UY$Ȣ܁~ظu)O"4U;/FV#UjQI[%h^(RmR*ncjVM`1vY6WvdBXtofaM6Mݙ^IroMۣ,aq~Щ_US1{0 ;.!p]5XUmu2鹨]N&6VDщ,SOJX;-FΦْldwLarInYRr{Ŷ۱0BG 022D:zze'– zhm,YA;5!ydDi3W]- kE[ +8MgW[|@9*enުzOAO3͈nwBՙb8r_[ PEo\0êzKved/d1)i)3O4Ms"IIњSMmy7L0mzM-U"F}pRX B#S皝Ehn`{8i7/#>_xCb²5<ʋm$U,AMFV|G2)|V21EMՖVc"u,kZX W%*&­̐$[8 IX 2Djx Cr6dhiԽ,SYB$BJn 1pM\ŐeY1Nqo&)YȄɅ;DL($WZ#JFBGLFJҙm`v Inx큇w 2P9".21 W-+qޛ+M;TKbEuՌ۷FiH푷7 "8x4:%-J2Q,"⨋9XhbwB۪y$ fbB6HYB}pQEX'.f$eX7$"i+a)P[A apMV!)ɷCz yv&r?Gitnsd9Y#!lF nB[FLԱ2t4,*n o bw$CtɊ­|3o4lo`TÐU`Ҵr#Jb0%NCy9p,& # `q0 K!YR%twp(i}q;(VfHo#]7Z-DΠ ,bm$PMբ |dv #Ƈp6AKyLShZ K $YⱌP=0qs1[k"GOMNqQ]БL+3zO:[v'%zW!{\zGw{pkx7O?~;AQ~cgz*}Ф-1JY#5ŬCDxJDɊ1:$Pq{Hi) e ȌIgރ> 9P+TRIa5lpUX3s@ќ z؟&hEFUyHlg9 *_⊬PٌK޻,0xz$T^Y7~O;/j[*xvmG F˸ AV@iEЉ$U+eD7vc9 NWؖ&uYF2J$VC!;8bD!\Wts`Jծ78njX`Yg[ٚvkHZ-LV: V-d67Y|rfHvr^w51.^nYdѼ:%#'{qabUSDGFYDɝgVߟQI9**zn.3D#E$wet!x{ pRe9g^V(Dx+04m-ACǸ-[|XGNNz8UxuGT+Pi=2tx"]3и搲s1;8ndq" yY pPֈ&g ʮhɋ4ԘCH7όmJ*&,dȷMEzWM3$<[q*Xy8h ahJ2v͊-yy+ zڞ,ts#5]RK!KT$E?TB=ovS M@iY ʤB)wkZt817qGOpe6IWu,%|HW4h[h7 I nT,zshp$ͩzyհG|j搓ceL}C|Kݷu jX,@pkXr2).:8 cqQ~cgz_k}'QN:N:N:N:N:N:N:N:M7=P2^ݟ^_ (lv6oSU15,qKY0Ln8qaӥ$die-d ) 117sE6];Αq"-V 26E,wfKj[ IC>3ƹ{>O^}z׼|^'ׯx>{>O^}z׼|^'׫_~S~MNOO&,`]޴|{ {,E'7&7=:{~O[opzpS#7?ݍnU{Gz^.r3Xǣ7b'W.w-(UPIfY,{ibOp$\I8[!Y2Sk8|@x(eʹ|.1Β5{_҄ +uM"`M2n4]ne-.8/pͻSlNxCTڳ;ed]f'JY"dIX2R#(5c1H|5ٌM$@>Am#%;9bqݺD\ $rR6VȨWmݢf-L7aMRL ,$M3##\z@&gQYBa;%7c!UfN1JV&U Z<ɹt3,2D2*9GU&YrYݢWUD 5pX Y2jY;6]R"dLp<KْgbTTnнِ$ R2G bq8Q #fN7Ikw8@5&P\צE4+F9Vb*X#uшrB\)'8ͼQgbsHaW+ |:åRp% $t^tr>[`Xȸ~nv9cEl;iν&פG=]<,qiP, -F1OLA%}{~?)Elާ'[ ?c/{ͮk6{ͮk6{ͮk6{ͮZ::::&N?)Elާ'[r OLm{G$-Ζ8Un-)!x v G{^~!n\ K ^D,$oe4đMmltΉNWʬaŲRK@2 +KZ_0f;*\R[ 1 R]r6#E#/`mǛ#lnI[w*OxLO*(e e ]|om|omwgzmʟt)?M/n;Sx3^` UP2'3(2:7o yݹ/.s"NX6Ţ b8. uB%fFq2,- HLr#F3زFp WT"cK4p2Gk[ӪQӀ꺑i=UP#1Is2[YA^8F2~lITHyRCOCEr{q;P8XnN4B#@l fc&Q80S([4TLs=_ov?鷩ܩB$ק ڷVj-[ūxoռZVj-[ů|O{_{M.cg69?ە^QcMѰqc~kٱok6:ApuxYXbd4E$29o8-MRǍQά%ゕH69J}|% $Wko" /.WńQbFshq] s93Dt h.%LUrm1lqȶ^ F Q$q|N@)2Xi#zwqJ]11Rk<˛QFn%FoU@!Bc0a^קA~zt^קA~zt^קA~zt^w?tA:~]X X點~S~MNO~_4Ek!G *$\aq!2-2NXhe T72"1 DF|y6KlͲ\H ^TP٬ 48(Rtt0Ug8 L"s034C%KgLnsU3.j]L:>-̪Df"x7!bUb9,oqqn7RX+|vIB_~B~p-뇡o^'~S~MNO~_4EJa,G9ϟ|mr8h2 % Uˤ<,`#dS (V̅0.L xKgla*,'H]Z+ ĩ b][mTp ^hLYZ71T2ٖ5)s48#QQW~GKȿet:8 wCU[*a}XzVO_M.cg69=ߕ~aa Xw;VՇxjü5a Xw;VՇxjü5a Xw;VՇxjü5a Xw;ߏov?鷩BNS~MNOW4r]mr*}У=[[[[[[[[[[[[[[[p'\;_\;_\;_\;_\= BuНp'\= ߢv6tzoʯt(2:S]7ݖ(vsuJy *٤x]hY\y5Z/kǩDLB;ɔ1DȲ䧂Vc3? dhH r8us' ǡ6nΖۤs |;4igGPs<֊qF!gbI/&b/=nO5;?ާ'[r O?)Fcg6*M{3GI#̨ rÇFϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_}ϳ_} ,N!bȎTTVb2xO^  !"1QR#2Aa6BUbv $3VeqCr%045@Tc&DFPS'?>{{tz]/Z()jtu 1@"*-u=YEA5XD*ڲ$<|R t.hiKhi5&Ţ&,O'&>tlx8n?}GwaGw4w{>tlx8n?}GwaGw4w{>tlx8n?}GwaGw4w{>tlx8n?}GwaGw4w{>tlx8n?}GwaGw4w{>tlx8n?}Gwa߹G<|!ףG~>wwo܇^> tkޣr;z;x7C}Gz|?Q߹G<|!ףG~>vom +6.tҔ RjZPVi 9B5$Fd]oK *wo4Zqi)cBz&*habl{>zFW6jUiY =*tX۸amҍԇCM*3]OڢytZ#MU:OR,7YBJJ%AF鶊Z":bꮖz/K=3JI*TU.ZWQXQ(}&t}N5ˣWEUmxTU3QRX,S}$`-&4)JV J`*ՕRJi='6N4.Jx4YvFxituPqF'N@$Iki"襫z =:K]h C+(ak!.xz=O15{ҕP{PC䡮 5JJZ- ^-&k!4U'5L4:^K=4E4]#yi来R"s GAkCfB=<0i#4oMAuγ0 -}U4en%rh!$&QRoE=3I9Evg%+'OMhֽ&XlGT^ !=xǯ>pX^c׎ Kzcy^8,}/1=xǯ>pX~c Oqc8,}?18>pX~cK7qizlԆs)O8QBۃBP&$<6A^7X=8ܭ!iZ=^H@GcztPdS"1ΤM&4]eG.>*̫(UF1'B@|*uk4mf`YSWTueV)ZbVU:6eDKLOZB.ejxI!I$Wn&a"lkYK#l){PVJʊt؆籹eX#͒3#İHGfHd`%ٰ ZRjhACiI%;\d jzyQٔ5+ġ\,iSG03ŧʒK< H34w@Z38354 ƏP VZ>Q]S΁XYLc%.hI+,eEͪqƎ+"Gd *h)h*,M$:e(2E%ԼRdVhT$#n!Fv2X#ojjRlE."A1,PP$hO)>9Zڰt6fR2k;m1$qxm|1^lf2ǻloO}_SIE7otEn \SUC,GaUL d:-K=0ծQMgbe?D#}G`Y 3,6N!$) hllC3 <\M)KYD*@ RH]uI)U.d/hdl3="$?BS4Ld41P`WfՒ"jP23ImPaPT#fDg|,$/U Mg`5}'/TQnرݥvaZepyb*7LɫۓS-VJB!qϪ!)jd3*O E!lN-{%VUeRRe,anL|-4ooV RdQȰӉu$TҭHD$S2K )ɈH^B{yu:J8ΰ4drEP&UP[ Hؽ|t∔XFF|ASh᧗Α%gI%P[!cG.'ms=sOf Q-tO =ˑ̍-l+cվԂE0X)R6 JrxU6gKhXʨ '0* ir?E5jZ2l!T&&bXk4/p]XxoƓMTBQ1K̹21 w2qꎰ-m>ѵ4hZ9CT+Nd1O Ϻk~?nɍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՍbsV5=X'?cXcՄxţDQ}l-ojxJZʚz<4CSk8b!Jƕfj]N@NS_c|}OaZ5ʹ{qFF=c y5k*kιJt#('*he*Zl,w9-,PJtrdh?ɨI9KǑe%pʠjm{$ jk Ue}U=DDnAi=1YɬV#9%x9`Q3fA!~V͘XY5|=H6@3icLr3lv/ $.{`VUY s*RT9c. |e$;3瓣3[5"/m_( 9\VG$Dg<-L$Bv2Uk_$jUXXx\d[)eKaȊ~+Y-FT;Re.H]K$q6,Q6GtFn@x1,힥ch 1dT y͖L!b߈6Kۚ24`K)zhdis6l'WW1m`FLuU;8tErh;FXFYr\S3[1P$t%cFКNkeY \\хR.U`sB87A*,#ll,I4%IVrYV!U-pU'a$*Ar l8>lp?w$\m ~1韩\ޫ| Ι6)"HYmrapEԀE 3FTU)SZZYL-rxΦS"0ekapHl(:h6@f'<ےnW<6*+1U2)ތ/)sM@&4;gx[~D3YM:mRUu9",D[&fV#Gd:8E%C@[#Dh؛ߍ~IU($ĨctDI*(֬,-9MCH u.rۏ3loJXނD+ƿ.vrI(|-Lj5dHDlc9*5j>R<խ.I5Ji:RD.M,flTvf$ZU\VPoY|r0"U\卄BѢ*[WS^E+Y,Kdi2)wէְp#VKtiqz'!i2DY =Tedeͪɒ>n5s%h4efցh D$H7cb#Bۺ:a˹7J*)55V5dhH%=L0Z.E2grb@d%Z5xVřbOyV (7($cjJ"]cݪV9#<&C %*Hα;1c3T5vgdP:+qo,{yxHaf8↴S!L l5qٛ2HHѲR\2@5gEH)IAOdc2UFe^Yjzjk࡬r+j3d)3i OS4d:cCC؊eeL %rS[+8Izs@$5ZXu,"l$4+pm}Mbttol//oO;LM7?_S|QyHy2/^2/^2/^2/^2/^2/^2/^2/^2/^q1N3y:C˜'HxS c2)>2)>2)>2 sr߿Ǧ~kosz~>LE K| [62(- /$U$@H@@H^a"}S&ʌS7&QkfB[V"r8ݛ,E8fVVTl*ꙙ,hɷ#Dϭj':$Ju-1dRQFVUpS- TT@%,S_"FlOcqOgac2ԡ+ |F#DK6Vw *lBk$3C$K26hM&HZ"@7c2)H*ͩ"P dC*Yf<. j^I#pԇtEij!H實eֳedGwo꾧04wfY6Yᔀ]*H$D8V2?##g]GlYŝK`ˌDF%JHd! DZ=2e%C(_[]]C&FcEYFyX 5FMv~[aQܽ;q?vP6~MÐ|f=zzzU0W<^\zsOɁ;Gsu9Eʭb-mjr:#XV홤.͑ʬ;TE ɟ.dj%DD<U iסZJMKRNd]%>y}8\fOlj=8SIx[:\+mlt\vl-B(rXe";q.ghZ%E]fY+f)fDY3DqֻM"B%AT6k ,dʪ3 +3F`"Χ095(l,\I;jh`3Yta@7,/ﳯF,6&^~ }.oU>Oɏ?؟7HN37I'o f73tqM8&fnxN37I'o f73ܽ.9H1ozX=,qy8KnIwo꾧0\+U!"]s#r2]n.0ZBs1{g`^S= *`uw&Kɳ+.w`чR!'jK(4D}@aX!1Lq敢en2,'D\Hdyd7聍eeAk;눜"PHR*hEh{vZYTN,&d-,FuI!( sUP {Z'ZE\RyzidYcQr#!#U-.=%i񗾽ϔ2uO:׌|eSξ2)_z󯌽xy^e*{8ֽ^.|fQ**Lf , |9BÏ }u/Be`e9kIڍ(nG$n,@FeX1HŘܔՓj^6b $k|a01oz7= qy8C^f񇡎/3xac01oz7= qy }{{yΡ/oO;LM7?_S|BG8&fnxN37I'o f73tqM8&fnxN37I'o f73tqM8&fnxN37I'o f73tqM8&fnxN37I'|'Ǧ~kosz~>Oyߌzgn7'7Ǧ~kom>'1zzzzzzzzzzzzzzz @EXq,z8=q?8G~ǣ?CcyG~ǣ?GcXp3E~ǣ?GcXq>'|?k=.oU>OO˷lk<6~߷bBbGVmdAO}~ϱAU9Emr{9tX: ,fXvm}~N&-|6~1韩&Mjmu,PS4]Q ڴY2$c4ZKyoJ!?Wc.ѾC~Ǻ]+ϣ|]tWFAt>v=^}={Ҽ7zKyoJ!?Wc.ѾC~Ǻ]+ϣ|]tWFAt>v=^}={Ҽ7zKyoJ!?Wc.ѾC~Ǻ]+ϣ|]tWFAt>v=^}={Ҽ7zKyoJ!?Wc.ѾC~Ǻ]+ϣ|]tWFAt>v=^}={Ҽ7zKyoJ!?WbudQW*MI 'DSE$L5 Vah  5!"#123467u$ %0AB@Pst&Q`rva'DRSf8GTcdgqw?+n\78?J=kz IIl 7&[|$6komxo?MgIl 7&[|$6komxo?MgIl 7&[|$6komxo?MgIl 7&[|$6komxo?MgIl 7&[|$6komxo?MgIl 7&[|$6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gC6ko1gA[X%N e Ն]Y^,!x1 Gb1&HlZR_XٵsQN\^+FXc q%D3A[C.W F[4i{ qX|9& "8MeNW;z٫ 'YO'㘨>\k^Ha1lO 3`7:stncǵSδ0^ZÌC.qS ̱w9tEIWZvicrM`=D}E$uem4GI+`Җ[#F=5fW}j*4a,9&ake-U+s;bcS`('gRR5MXjhB؟_|%).%2Mi==ihJ%.Ɇo{&&@hZZ3ma &j6։?U-UyZD%Ejk Sp( z"XKY%䢘0ďN`c$iI0ͣIھDz{2ANYC<#;YS Pya/عHVQٰO4tn$$TݏG)b$}Kh*'].9@(k&|J6J1T iz" v*aF^U2}C q*UFy*e\c G Tjq_q-c\JN7i:#, %&F2Wd$y 3˴A\'E20Ms 3&R ҎM8@WR$"i0F.x\%p/[ՅmcWjw6ַ=5=KƽGQW+O\p)&0bԴEJ)emTZTJR .rɋ}jWem"-EW9mI"KUsqFY?O 5}}rPKQr.ggm[?Vo?շm[?Vo?շm[?Wӻi(k5QHN sʸ)!w0c._9<)k&TkpdXpVq,E!x׆E^ҿtXMf9vB6^E&ұZ=9Pė>g4( #?AwG(>O8:z1ӵ}Ì R+5̥ylq7tGNԖ6rYtL ,Gne2:V"8*Ao99Pvʫnɲ%e,VD֢HC &1w(O\ 1szqzǫijhfMikp9Yzx|Q8|=oocy|~÷l~a?0[v;|V?cUo÷l~a?0[v;|V?cUo÷l~a?0[v;|V?\~a|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?L~b|-?HaR6AT PU!oH~`R6AT PU!oH~`R6AT PU!oH~`R6AT PU!oH~`R6AT PU!oH~`R6@T/V5!5&M7_Rw3юz|꿣~lCwU(K3G>eWǩgǷs*I\wԚ*ϙ+px\.7:gD|ڑkwyCj+`ClS ]h \f"Y3lk gb+ir5=H5%u;P ӕ9bM6:EP[Hv~7I[mVJpf3fĄK92Kt_𴔚X%]' VJH2X}Hfϰ$¯aXwuJ_QsVvjż5L|$mp+meo&Lz17q]fs1WkUx}Ha)2@e114󙠺wN~~,aRo{.:+5-Mx-> %Ɂ8UZr$oi]ŸjprsQu!uzʡ!|YoYqz=8Ʀ M5g\ƠAPvM\ לeqqL^;htG=-]cFkJ8Q7l&lUXZx0s /J>leȢM^N*RJ4ԴNlڀ+ 0P2l1]uGS)ꫧy+AŬpMf Lxk!vbO,+)(펷I^ս(SQ+>[(8}'jY: [T0w(L07,L,Li[i* (HK׺1wl x6Ͽ4 !)R2rE#kWt>8dFo18Fi6>*CY^i3KvG@$Za4E,L*.F"tTJ[T޲}S+:SΞ7q!lB{$oybF`YT4FuZIX?5~6c(首Oe$ YDJe6,tRTgcX[Gzb"W#s8mdEn. AqҚ$XEeؚ=6\A*K,cܞB9v'}(&4Z~Jj63iC8uwWrΎUS iX`ٖ*a,A̧=.яjjitHIx;8]P.; "gsK45/5 {Ҏ6nĩCJÅz;8WZjPѦ 6U.OmΤkX"I@"VvDqfEZ]~9S^[FIZk{7sse{Sȹd>Emg[NXhh!V׾grüibձ+De8nEUZ״s2i2Rhj8,KI3Qq,q2Yχ GwMv4JH4}\Gek*n{G7acZKӭyc)M+\k 0צW#D&9XZ 0/Iut' V`ӢZXzП&~&*]hfXg$ﮨ[:d]voVN1=7d~3B#g&h0dL0lOZ{' j>-c[LԐ&}J [bw+\lnf9<`\D/x՗һM?MZRF_xpIX/SQ:lz*+җgGtlkC8ꗭjlY5RN!a{+@Dmm_Wmut m*]JnTw<D({8Y{IntM{q5pP(u+vR.:Jt&pv 4e[sHr\"iZilfkk!]Y$iWcEM6՚OPP{U5? &.ˮ<>y9#=YZI)-2j(p:C)4yX).Mx'ې'sUI*$u ӂ@ӺΝҳn.2`y H R$4Tlѫm9+=m jYpjҞqcO牒q'+wLlʋJrSFy1w8˦WMaj4 0ץwl  "Zkw%֌HV-lۥZG bC )lK8bkVhYO4'~t?Ѷ͞ӊŰx+.Kqn:UV[Vئbc)2yfG}.]6]>S2!VZ2XXM!7h0Nes M|,W8-6K=q]_4ͺ#u_q5OcşNLgaBzU*4U}e]ܮgEfJ_=0}*i4 uf%t\vmbt .-$ SsHwE"dgFKzvy$7gHzq]_4͚'嗡 pp,}sa2 F#؎`"QJP*1e]Җ7բԄN`o4yb`n+a[ZG3Pt|0im.5!5eqOu k'GJ5y&BFE+6ΨzRE,dMj4d)g\ BŖ%!b4[MWޠ _X/]j D h2xV 6twzOBMYIQ%ef{!^j%[9 `vQv{0e"l:Rr˓t% nn'x9t0l]--y}|ECLn K[ NjQ$Kdb4åp|~0%ϕc~{*)&H 0uU}BPYqDVE83UnqF-ߪlɝ6fmd#g0 \f9sTӽuK;q&=p{CMU16'x[5Vjќbvt`8b"g U NGG(:++¥d&}؄yT``JLU`]At ꤴ 0JkƤQwT>P.g ֑ KS+YeWm%${JV:(7sh0xꞍu@_Y+՗ZJ72,s뻹ɑ: .J"a3X#G0g?)Nо{KroRB½rTJ,߁;P=m\q?uFp;DEBĎ!}fGL5dWlLnԴiZtIXJ{>*`fIkr6v ;BOX6Ì0<M3VFz0fJaiw܊j2cR+Ç. &bUf6íEL^(n߹fF+[4΋)H"Z%ܽňfk-}ZCٲxCPw(F 1!OwvWx66s".?| rɉ4fo-F ARMa%ϒ-H Jic6-2L6]ǓٵJ|e^GaE4` ZG*}P;g JvҮEy3 $C0dI+ zMet +8/:q<"󜝞Q⛒f qo\kR#H 4OEر#؈p)M$⭷BZVNsQ[ԳEp$vTiف8,8nYG]K#VV vX͕ťGO֋$B8jq#i)+]>SsRiL;\c^͎ Ŏ-榴 /qIh3er|^0Nal$&$vwc:ځ)7+).;>y&zH+ JZeZ>f;41d)Nu@c2q\r)^g\krY*5A[y,ڭRЂ 5LT9"DEF !+#[4& @H-a,=f,?rZЪhrj;7d\^پ&2bNa~/; 4sycij `4CFZԦq!b #l*#Ű͍Ma$, [_fi,֛pE3YV\LX6[ MXqM(0d;*ֆϦx٥avʋjMEi2T,zY ꂾM:[&Gq⭭B(Д@qrQi&4Qjw OBkDZJLP,$rF|z#0{@lŅt@3cQDPe ?L|'hD7.h jDI U++j5hkSZ!xZͲsE kN(<ZOi֊Nj&uS7UruUnKK؏HQ!fZIhIP^Sͤp{FRVxO]bJ( jdʏO阩E>BJK,Wf2fU, T_ueL޻;smۭ~,na8ĕKUaHOe{ǒKg&ÞW;z:` .Hb9 ` E.+D< D$WfFnVuԛrU;f,g!\j=kw,]:v Yp[|x1]\*%$>*V! K ]CV q9nl! 7c#^#Ee[:-D*"3۞4Zjr 1ޞ1ޜ|w0; k,8:7)+ \z`8p]Hd[ieզeiF`хlZ0[bťMHt+dm+U[u!JufҊvm [ *LfbeyVј63ez~囅l:,V|> #pZχa!a[=IK@|W%wMz}l"BZFp`xbWUxeVv꫆xUu#qb-8'aPZq տOK^2ĜNHHyD rW@cY)WdN8ʚ}H7 [XR-02V1nKxFP10gV3<9a0J'8򲩀x`8 j^*im5WN_[YYX*RDj8Ǹoum-5ŻT:4eIWyrXW, ũsucիD 5[ iNtʙc! .ʙYj:}_һ⮬iZ@㳁̙\[ _,& UrxjZ0M$I(JF+gA:ŌIaVic` J".DaY)Z w`~<֊Yn18E\B1$($qI)- 5A+,Siδ9֙LP3'!)O._ﻡ}_܏C@|٢~XUs38jL҂j< ~^Mo9% Zԥmyt mXOʍRGMڊT6A;-k]wW'T[ R)E6q"}.MӽL֩[3U>,ׁ5"ia%;UV|YlL$89 wcME_U,-Y$ ,;'9H4*ڕ{\;CZ&ICnq\OYbs):u%: fRZY^, ٪@̒.P୦ХCSwWza:wWNjM98+f5e`UxĨH--oY< Y;f)ME§jsZ}?N4VN&#SiYdI.?lt]>(z \$~g2=a}شrxTPjUMiGd_~EZs5tIUcMBӹHpd:ۿ`5&0r]0؇! JPkZ:l:q;떹k-G К[U"[ӓO:+G[٤b}t:T͇cS%N_ORtF"T'R,1X2ۍ7' T[XMޓ~j٫ңܼ'F*1ẕ&X:M0GXNͱ˷'t*llIu:auHʖdv-h*؀dptVtIo_Yrj);emkgjLjձVZ)U1%ERž5y[OB^p%H7p:0d+篔.^ط,m*)VMmAVWXxW"X,T*[)yyC|6uL+njޓ;"3ڶnBin-`]eoU21Q%u-jNHЛF+31LeN%ڹ-.s4ا*kG =ttkq] gQV8-u1;W8JLQQ[U峳Np" ZrU5%4~Ӱu;jh`t [Z9 bkpŨ.]ZY \ӫ-X44/Qƅė~1+aS#,z6ǩ{XV3XWZg"ːa\4@R6O(F213- B8Ca t91Pq(,c1sXϩgqS8t+YT Q4%UqG\18F1Y)Ο'9=3ns%_Ϗ™ǻvQ\\h#f AD&2cs2sŨR,K"C_ eaJGYL($jaVM؃oT@ h({:|T᥍2e!0UI)U=<6i%C}beiM,(Ɉ' c0 @p,' m܏C@|٢~Y"f(sM$ >*@' a z%goCͪom#HyM-$i6v3C)q.j:FAK8f?5O8TX,` -xҴLfehz SJm܏CBOvD*t\q1)<%ʼnKHHCϯcӜuEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[uEh{knMmmI4=TX}&Qa۪,>C[w%2z5Sen{$cb;}V KKZE*u3 8І}]?EbpɐF2$2q ) 3H($Kg9Nͺ-MkOx \"ehp؈ǣrQ5K1"v`z2--5ש&YN-C9z1W9ϩcϝQs!?Jnq96œFo^X~8R?ɾvп\477͟8 rX`r Ղ˗0Qp-ϫѵU+'lC,p(Q<zR1ˋYC<=oX3T`V֙jYT/SAdDQ׻`4{%4RӞLưc=ЖJX=jŮҳż-..=1wRE;USj IxtQtjSUl{MsfMg޹m,Cz Pe`}# ]KFʂ5uyGK鏉+4j=ck>#;Zi^ej٢zlS3#ih^$e+8IGߥؘcɝIxvCmE3@IҴŵX'A,ndg}+ ɒ ٬0ZHU†@JkFOTiS$!!]aZ]Vp[1<([HR'}I;DnNa=N4\/Ȯ$1B3m2$57;umƚ u ck*/[6)d6N{JB;mAF8ʴՂGw+Z eXj$6}~w_'I{u>}~w_'I{u>}~w_'I{u>}~w_'I{u>}~w_'I{u>}~w_'͆S,1,D<1F:aČǽ9? w&Brs3߯6:6oȱUXS.v$H ]UVe`]pe19jJ VdoVHl zE04f@sBYS|YV/!\CF`+PqMq̫5v"w c_zh}ӫ^þQrRkZ'egj HիjJ1dŠ 1b&.GH9*ʶ0n2sy!o 1pX əN6C&:t8’֏Qü2r_7'״ŦoF F.]c񰸙!j8-4&eg{舱Ujs6|.5jm`1yl-/r4`xG%eL"xOl. T&@O-Q0\UHq$\-(+*vVxA_-,*6 F4yDz~-vQi߸lҠ6Ű{Ĕ݌2ͣjf6t]!Ttfk SVC6 nAp&!""=TrIuIXV2KJEJ9‡kq8I64Uɬa*D{.i N:f/c$=6&J#\R#}'ή(Gl;ɡ= ZˋsnL&;FmZmU+6j.,JUF Y+Դ+=V0y0sQ nws9~y_?C0smw-5F(*p+'{\/R)s]rЛulW! OHMEƬWA5``K-25|q3}\c>S8ǩ[CƋ/8/譮]!웛H_Hv7J<=}Y[UZEl,30n "R]16K`mHxXC>(BY|dR<$d*4AO^eP pc+rD'e1g=qbCΟ[\L4t(PR4ܡxoNz75Ki1ߊK|K$ӨEs\4oZHBw. P{իkLY>3@d+!2i\ ai4U^ɥ%qStlQGpԇVFhr^VP׭ç|%Mj`4n0ly9 8dNc%{LP(ZRbmKHiS=9g %b{<ŃDreT^!Mx[;2}0nzzl0;N?b&Z>[;B䴤q[:K{} ALYA4 i 4PޝiC+ݖ ͝]i ddxf4'f2=m}_N^=L[ҋUjW1bjN(gR&#zAi*FZ+ Rp6g3:{0ݒC=k Yq93Ws?!a𱫌/`ڍ._jx^pޟ=tpqwseFONA;msf;dK:Vjuj<[X_lTakXʶE*fP<E>#DM 81J=;rjXǦUh8RGM:28WVcNSs0]ߴ !;Տ7Kd meuv/̘Hzh{jWb i::܈ț G=M Pnzqh劸i7=OH6 c|-+IIYb,Q˦29 pd|x)4U8C1Ckig}B/h$sRct-@a#fvZ7Gi,$.sAHܑ@:Τ0-tqdeYfEެp}I5nkl4˦1Jj j5&$R\)hkƆZvj)* R w응-D8ִ֯Jm]̗W5AUKbtt+F F5rО"rjv*kokcXZݗt/(ֆ]V}8jz!.Lv2vRj5-3 }5AʊyFvk~eEկe|G2 n 㒝Bc73و[]@šbNcucy=5VXekB!<TZ kV:SpצM@3j+OiPC^bpr\C(ƕqu\]Zy.Ri)IERP~ -)qB2fD:zFL:c==T|Jkߧ~Kֶ%dxfӚ¡DPfΡNk "@SohHcۘt]2qTQm= i؏OVԶיu@7#.q_Rs\Qj9ܴ-Q$}<btaZtܩ@,>[a&د(̼2nחJ+aaH`3V?kx`Q*C{UuDӊkmR0u+ **kLu&ddpU(+]UUR*Pjwt吜P. b̖ EDH If}9}0r<k==Nw׋hvV?M硡gѿ^~uGS/aqe+g\ FqˈGPI絏?{Xok?mcgl}?{Xok?mcgl}?{Xok?mcgl}N1>zzwqr}brI)XDp!:7(fq 6>Q콾 |s{|HF&eM#G7=4n{/oi(^o+TgXZKwf0D9t OԞz1jGro/'= >iF1&80$ǎ&Aje8A%avY3ӍO#v3Wy[eL|%DNy`ctoJI{K<ȅ)K67ʍ(cI;)njWhis]W;6žBL8ƚjZ?n_үkR1kd<>UM+H(;\ Mk._H!tS0cg7Q1+൰N1xQ@ ySSjaF=by|$b4&RBB-ŕ^2zyi۹^'tm᪒\ a)סͅEcy0/QieZae]K}Jnęze\F-uIL.-{a~9|dޟEB[LVgZ] xģQ Vt\m1p4r1*6$3Gn¿MɮwM/¹E4WPGܛBb0%At&^{a)& kY-ڢvධV0\)jb++r:ښP]Boף e3:fW Zr7)r j~K(-'RW,ٔ'w4DPjňJA-};Z0p`ZՀJ aj MjrӔUqk+*ԑM]F Gp&oa UV14we(c.SWW$ŝW ar6 pek<}^(=,]7OZmt*}ٮn'u=_ *l1ٗ(`UiG5ViJA<šd_%mKIԺU) 6e ,-5L*}uY('r#5ljZ(s#UzIl*+e Ӆމna7C'TT9%Q%ٽ?S2(3am4OKwg\\EZĂvykmYlhmۧa #{ iR#qT!W@g&Brs3߯6Ul]DG 1FSq=f (1yFLG/_ѷsC=2K8~wv}u68jA;o!e+XMs5LL &usUjG_7% 㔔:F`GMNdNM5Tۏ% b8(HlP u R1]g0ES窰"Μ$rQ5suag.UT(rZ͎х G[j@r4E}E = IצȬ%EzFl/!ӛ⋛[96l3&nnz @1}jX'ŐK,jAN9хZKYjpTQbfﻇm,,88[C$#0Fx`goPG&뙝E_pX붿'\N^S5^re3WmpJԳ_P@x mEmEe 0 ռHRgȩ!e`t &eM]c^L30MU2 1-u:TǮ kBJG5zʨY2UWO֫,0tT~kRzZ9,^'VX6U%1&6Kt{0-Uֹ)ZOFŠ_U\fZZvt|–T ŚHKDR4|( >OOt OȨӉIﱘ wMޠ|tUjD%&E  a4lXMih6gi5mkb彟')12ܣ$F]rI?7듞Fy@?V90P8FETcCHY̺ =BYǜ,tK;ӈJycz:9D}oGONqK=t'y1#?S1KnV f^s:ֈHv1[x2nj ^QV>W;]M҂S("xϾamrnw|WFi`T"V}2 c*k6ri`plο } $%r7E"QRO*QKW9p>`frbr!6ȓP9;Vߜ %]"3dl}]Hip3Je$!8/Ȓ\AfcbRyA M|&q#joCr&  JN.:R;9ahMd˖;򈃒BI@p;4t_ "AcȘT! c,NV}o68|\׃*&R1'H7 a\p4NKd-* UX%lڇ5pR1PJk4/MN+;EKx=k2Ys,\9s@pP#Q1э~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-~W-q ֽ9Ds1Qq1 F&,q!tzqro/'= >i+/>N}\sǩz?)'cjCn&%HBXqgs{x6|$ >nGOۯ|$ >nGOۯ|$ >nGOۯ|$ >nGOۯ|$ >nGOۯ|$ >nGOۯ|$ye &!esog!8[0uֈ,Y&1 )5x"x|R_5X[7듞Fy֗]~E2s$B@!2,s)H̥{RUhdЊ#z6DdG(XU_׎X4b)g0:m2]XKX k:Md&88zw` c;wk8zjۆ򰕉Yb߃YUbG03L,cuV^bMĕKh)9b#a3$|;A-K@YSjw5S&4XNV@ L3cs85KjD&fPZ"E]7; %,il5UIj+nܤ Pf\`Dћm0,F%1˰AYVVT""d`$\Ŭ DsCllu,3U*6Ae<8D̥N9u5ap]ے`]&dY &PH>Qt׼n:_U'Vef"keQǍoctYO >z;aa~rPwwPQn)ɻ˱t=]'NMh_UJf繸aT,K=$]]SV=X@ ]քWJ,_Ldf3e,%&& D%4@ .5Ĝb%IJ"~8B-a)ZscQViLQIkU'>o}5ǙFhJ;<qڇViՉ(K!sEZnE @(~fDK0T80E"D)H qH&qFY:_]Kh9ˁMg2S`62SȍB1IcMȓVe{63L1c X.&>LGJ}%% Fr  b/ BdHgs8=}1qq$<#⛒2c{#:SDž9z8gǫFQe%qHgwa|cn;h_Nz}WZ_tva e~iaSYp4Ud!1Dn(HX7UW{O[i[UAq`]mXZ&D|Eor Z0_)<bn|CJL׳] obSV7 6lBہۘvcH@\c9Z[(iӥCa55 z-ǔBy;1B8!uׂ'b̖u&T2xjk`; 3[3id  CX׺!`KZD3*jX?3QieW^5k63RQWWVUSUˬ XӆDf%68LՓa:[]e5#Rbƺ iZR։#J ;xa򪘴{*5P3N3AqbVk]b,qV;ͅfidB4-,e̐g*//өGDrLY^4E3Rΐ_yhtuz %],SӖye6#5WT(Ob}QL%uvհ^5~n!0>T[hbF8򎪮f`(VzuȌnEuIg'\!Yd1 AbD/_tz7=Lx4Gu w&Brs3߯6:-Ȏ;ߞx"ޜc 0ޜ!c2sB111/GO?*z! 11-#wI8̙ 1>7#_o>r>k܏}7#_o>r>k܏}mu+FIe)44lc> yG0vV?M硡gѿ^m=~uG`NH*&b"1!2$bD1RBgqZJ25(fo >gTo|e s=ԺEU?廓|~9hooכOA_iA W s}'}$A?Ǎ|%.v=*D`cgshlLTQXW?0IһWюt+ݓy՘"`V馭ҵѮj*xh5ct+XRWUPVai*+V86Ba3Hz-%"t`V 0I$01n]C'w'x٦ĦTՆ4#:b*7:5"Yq%%ϜZBi' `t{R UeV~H 3d͖N޽lUՊtΓ h%FBZ d0y+F+"iLN-봫wJv*bf5GJH lҼ}tpMX؁ nMaak|iܿ-Ç_L/={\ia_ҸST\=5Hڣҫǯ=amV1k`{E=&K&Q*>\XaY=N+eX]a4[V[e[Dga2ΥCWh (Ntk+H LԒf)(1|έSSհemiVfZR+MDAz\KV*VK9\5LFO!GZZ~t݂NVqҨ/cӅK&E4^qO'+H`"Z]'@{zVh"T@X^փ|[CЬem*fFFZ-eQ/"0^[QTF(Ṱn}32Xo9byM$NM%Ӗw r8Ioz1s͡f3+6w (]1U%I}#\lqjrX4e`de)AҌd+{c`+ Gۢ? s1ϱ<#:݅U?廓|~9hoo׫?A_iVQc1?gR!SE`&wN!=1$9ttYNgi1- <@| fw=v'"NLEp# {x}.y7m{x}.y7m{x}.y7m{x}.y7m{x}.y7m{x}.y7mBgc[J_݈*5;< ];fU1z72 P$Wyg[uf]͟m:͛?ۨuw6uP6lnlCٳשXh7jFMcJ@JG\}s% w&Brs3߯V~:UvfuH(l+Ռb 1xs<1f;v?ćAݾ$=!-~7oyn|H{tC[nv?ćAݾ$=!-~7oyn|H{tC[nv?ćAݾ$=!-~7oyn|H{tC[nv/#Ӕ%68U o3B#ޞ Qİ\0IĽoroܛC&ɼd>oroܛC&ɼd>m=^ݷr{m`Qa89QHp2DV?M硡gѿ^~uGcu=r(R3JT% nL BL[Zpw0IjҎV r j ٝr:= .I܁ځ*~474yWWZf&[ j dlp%fjQi9k_0;Q&N9UW6(lAJ)jW5xm]IȢUƶ!'_)ŨYJʉS]=FP/Rvm5-S1{rMUjJZl+n 4̅l@Lp\^ wВawnSͅAV x0VRENd# 4 yG^ NT/e%m 'FpH[lΥeװbziky0񝐀tU pRxb EӦ5sw&ni5,q3wqn߆N0@`xwu'Df\R}lL28g ~z!Sc~}+xo7Ai%/S1Kx\A0%bH¿"C K;  1obM0Ó%e "̷1hvV?M硡gѿ^~uGf"I*a0afd2mFDdRDXg6ڢYo5:nuat`5:z&9ONFG3>BK MM<ҵ*ZiD_q0 Aߐ؀Z6ܬ#*'ӱZY6T3d$$W8]T(̪0X<iXfIN:k~ JU1 OI uIk#Z;QFz)^x7Df{ǔY ڗ:@Vj/V.#D:\U6,W,_U?<6%֐IpČS3L)3Ic)J>cf#p!Hi&do%vh^a& nef8-42k3%jHKŶ}qC"ntX'"KYmwu-zgN+&QkS= З*; bɹnɒշ5{.q1)ZYE3mQx 1^-]m桩nUVfh?UƜmvOX( zA\k* WsYwaFSm>_WT_ᵥFG3Qoy|cz Y,' j ː,LS.۷s{yn 4,Sdui5uke%asd3]fEi#-wѱ˸jK'Ur<幢xΰݏl20ЁcctLOC;$y!)LE=~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ G1Lrq>nda1s ,U!p 0cq`t(ǗW<7N1,\w=}|v/-ܛm CC|ϣ~Y K.<ʹ癒}:,b1耄(Bb1Bcyv+]= oOoyv+]= oO`|;{yg&ooo>vl۹7듞Fy`e8`e " 9 ]a 1Mǖ 7j1i:CP7Bm\EcәxY[0 w_,urkS Ջ67fX NfX::I9gv`ccbXxj_CskcNL*;`8t q!"i,rxk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{oj<5cmS熵mQ|ֽ5OױFZ6(>xk^ k|T{m%5FVVF/5# `ur#g?S8C.w=,!a1A 0@PQ`q?!kMJ@,?(qwx~߿~߿~߿~߿~߿~߿~߿~߿~7 ~"ބέ&lJ;*mJ@&k9 ]42pPRA;[ @ @ @ @ @=12dɓ&L2dɓ&L2dɓZu1µ<@EIOAH!C^_9ǰC8N5)cHðCB%2k "0Sb B]Z%- qD lR6gEm<^ț{]Nm:FvUsʰd bO(O^q=ЅÁ5x)+/2B1^nbŢ0P~D*o|!(lU_1/ssBi{/y4旼^Ki{/y4旼^Ki{/y4旼^B5y#W^B5y#W^B5y#W^B5y#W^B5y#W^B)Tݏ?켤 o\ nU dp"Z֞n;}\ث\7yoF1AZRa3{V~6#5H~|\VS* {Kk ʖ$ S:e ~C =%V'+~,ʭōIٿ+W.:,ŃO FZ@&^x.D &XG;Y+!˟g"A8^ ][yykFBJߠ]1Z_?N//>/>/>/>/>/>/>/>/>/>M\9\9\9\9\9\9\9\9\9\9\G(CiۇTyCƖQU05`+# PDoTߛxSW\߸nqIi&MI6m$Ii&MI6m$Ii&M S` 0` 0`89M.]4itKM.]4itKM.]4iT)Ă]ak{dgC j2☌ȓD b"rg0/w1c*"U-Uq!AD`;P7\QR,EM׫S^Oix=ad"I"Kvڨ9 \# `LE:ǏES'ʎn]#aREĎb8JE~cƌ]3JM)'bxR Z q_`:uQPv (f_Hf#JRoi3xfkY[qf 6S`U&M bXB?m̀1zǰlEe^/Ѫ} Y! #$[L;@!@HIPg|Eù1$U12jee_:8x Ef!F7JS&rʍc_,󉪢%ψ8HF LKNCAniU$ WۜF\nHpAt9 *:=nD@̇ ,JCȬDqd8%;cYmU#e9'Y !շ)ධk(D EىDfRYT3U讞tw)@,˸Wm:c띰u_cˣTաeVq$E=PA*YB#*I +^auSBj<5啹$KFb1Ip2͗CMCF[6 C!Fq\Msx٩twQC/2SJrڽ ~ $ [`0^] ªl<ũPclAAt&h C-:'#k#r^ B NkTCQ60:nPa-I&b7/g&L9VW?Am/<4@ɶʣ}SF)ޞ)bMclr*.sibY;/f^w ^8(Rel=g[}P{ m An)Ohh$\9O*iJ#923I1byvkqtMkHpN-%4[(;~I'P`a9edt6]iƌX6?T(c) c,R]ݵ mLd?2ns\*ɧ{N<). !!۱klUp.$2ߵ]kX譜ډ LǨ<8ſ#DKBJ o7xy{5.ÅDw8m\iaMz >x|֠J6]K^Q,SޘC&ա G.jrHvB\R)FTNI{łJ4JQWyɿg},HIQ5QVtjK`9iѩ6 `K6ǽVH ̭NuQblݝLXw5`n6dyMP"؊"?=S*<&+mrxV>P5CQb=16ap =oNryQwHWG?6bK%P%̦؃J&0꠶̐ijݤF?$1P+EFXQ3Y\;&!C>jA:i 6M* Uжg/ S(6;bȥ2,m,R)Ju8rӐɅWuWI@wA0]BLCwM3YePAZ q-_ 9 Կr'A96K2]l'Æ@8KcIERڂ@A+bYO [*YTH4͵eR3,j(0m66[ no8ƠA_ l?P|ϟ>|ϟ>|/h %F.a .6I+bLړq*h9r8‹(hN?DYJ@ :%昙M"mZa$b<&hi HIS i J!5R#˖~aԟkj%Yjs"?3E1Ҥ ~4O8UavJge<-GaV( >BMmCAc5:v$jo ܂LX!(C\hjI ^*S#$ gTegR8 v{ 9}>W0;'^:t,9Rt4!Q:I?b7&r%Y 38ؕ3^hղGPAЯQp7h!Ru*ty2 N F"?":.b}_|#肓'xnVf ŕ Жߣ(x'c0;S´HÇ8pÇ8pÇ8pA({ 9A3gџ?F~S_2TG_FK3 4-`4b6:#8a)nit;r/&a75/Vfx1!P`ael<+H|_F⠏Q$ZsتY a,XI[zxyf#uT" !lI!F K=Q,Ur3p&aù70je3lO0j{4N*S| OHO tF?݆ȿhm#Qzp%t 0k*OD'`> w<".|Fl @(A&|τ?/&1;I'M Y쳣#FA+oRjGI4wb/Rԫ(df&"ozWWߏL l Vչk6P|ijH&`$1U<"ꑂ$|4/є<`謠Ǐm'$%4㹾HW“Z^.wD(C1axvepP#sRA^l$ahfn;padJ#PQ-|͜Hz .D.Pċ'PPO6bZ47H| lR#LCM?d;pXͯR :ux{C'jX3?NȵHx ņM")ݎ=X2m<  16B`04Nҁ bfX.|]ꆽ\¯:v'Nt=լrY%]IDaRjWϔ>*߫[lPeri! ES1 slfrg}sjV@Ln+K˚zk0hMd?})[" F()N(#(.JRUa)po᥏ٺz#W9'0WHhHE^M Fa8!/kuS"yB|ϟ>|ϟ>1=„%wd(EyyyyyyyyBC,BѨy!x2 C p ؓ;t`d`=4r!FF hpe)Ž #C3Yj |lF1r8g~J#,0z|11+mF(1S'G W9.Zn3 6ىR_s?W|ϟ>|ϟ>| S}K ]k;|Mj |Z{;f?aP`M|uEyf sDHifm['@/௝SNmL?P񑼏}|\wspBX%(.sľn߬A%jf=&ƜP#tNejL1oΈB޺jk{"$&,-mJKmQNTי/U\ $19Y5<jqV\x~ &.hޒ##;DOV?db:_F*%욒}4ӡ|t!eDci & i$ԵP[J,ciS EEO:BRmR*G^;VìkcA*'rfzn0Z+ɓ/ ^˲$g>A{wy{;wy{;wy{;[xmʄ 6ҳ)L1!*RUy/x0 9t+ q3&bh[9rI,tmh~qTmI$ӧN:t 7 @sifRLAwP ӧN:t]¢zyI5y-:tӧN#GWFX!iǀ*|:eׯ^zׯ^zׯ^zׯ^zׯ^zׯ^zׯ^zׯ^zׯ^4TBZ"? M4M4M4M4M4L(ԿQ 0 0AAAs1,``  0 0" (O2 ,N( jV[EňLQ  #JP0`(0 0 0 0 0 0 0 0NGJ 0 0 0 0 0@QPMC_95|8>PMC_95|,{l/ |QѳFNFε:|=:dlQѳFNFε:|=:dlQѳFNFε:|=:dlB"h'WюN}ɨMG7~rj9Pz q5CۆLC:‘)HY2((Q"%boL jIa5ɔ!J6#vi!H% h *P*QX)%)'Zc猿maFhL`@& =Lq $ *8H&`II:i PJiZ V *Q73!)F҂ե!\/{ʙђnXN"`m]0@(4ektq0pLHgV9)8$i?+Y&1aj"8cuH8))+8cx-=bXg*NKPmCO9ݣ]9-O-yͩO9<6}<隆ڞ[SsjyomO-yͩO9<6}<9 l 03վ-F4flw֣MЀlpAqy3Ȋ  &$dQ(ʈbL* ." q%)mN** a`I'QT\7<Hd@+ QSBL/䀖r'=2n)x7(b5,[8yYEg3kP_ 3=a⡞ֆ >6gC= }hmPcCj{ZT3ڡֆ >6gC= `K'U?5.[:l8KÎm8cG'sW˭ q8ea &TV@I7*H΃2+p [RAhL+INF_v "@&@ A*AV8";jL?o95&o7MI&Rfyɩ3xԙ~rjL?o95&o7MI&.~j/Q(}XlUo̱ԔyzZ(NIp|_<QY 3y `)2 FKUmjmfySMb0 ZD8$7j ڠD`ݑrHA{DRY @UsЦ}AΤ)rߙ#~^iC:ɝL'P"W6D ϭz U{P ;a  #JweA[P:J*S B,AWJU;{!\ho<t SB[XI4$x&` rۡyU{o MߞPmCO9<8>PmCO9<8>PmCO9< T[򞞛~S}ozzoOOMfVx~7Zo3[gk񾷳|=7ߔ[򞞛~S}n|fqk[򞞛~S}ozzobk6HbϚKHF7ĖKf^I"guswk zClR`%D Mp$lRKH -PL̈1R1J.ppzkl swiQaK|ʩ7=ޢ p4u"J9˛ ~&U&Gu&Gu&Gu&Gu8ػ=q̇z]#wt%'sbg+>ϱY}ϳV}bgج>g+>ϱY}ϳV}bgج>g+>ϱY}ϳV}bgج>g+>ϱY}ϳV}bV(P[#“dr`U,'08'k`pĊF$Tt!AAeGB3fO,5'\a4KIZ(ǘ ;O;O;O;O;O;O;O;O;O;O;O;O;O;O;O;O;O;O;LYA`$Q$)? eM:HBVT #Hx%v@H1["Q{Dfd)aV&RۏJj݊DQ,! t'H0L,Z?i8$D̫AS4*1/GIbj""]rD. " Fc?\AYIb*,OPÐt@`VvJ6iĀ$D%[u/ ^PJIUVĔb $ a&V#@I^ 1 p "eJE`Y0l"Y2 H"q.t0SHxDnYHP$SPlh "dիx&Z+_W>T18iyzkc^H\ oP4s)B' *W,F @L7 OfbZ#Zm1BK4 K@#sEo@ @%}D$<rl1IRi@S%SA C-M$( 'gʋLN#K>goÌRpRM@ScL*5-El~?b;2`@ K7EE(z`ii"kw4ˢOPw=wmǮʹ6{|z|O]im>=w?7椼O/ޣO/ޣO/ޣO/ކH\rlμYPIE5tѬ(EDUkNŘ 8=\ L 78YC1n91M}TU9A#ҭ #]0U.O2'H4*8Ąa<x@rxG1 zdkQ Z`[};9߼i;Nw!syӝvC~;9߼i;Nw!Qf%b=@t\828nC<+"۳dZ{vtOnΕiҲ-=:VEgJȴYݝ+"۳dZ{vtOnΕiҙEdo F)i 0`Cu8C1xQ ߐ%$('!7vyۀrCv87JPBMs@*QIiyaM |dM0ZT 8jݨXꈢ@rE(CEd*gU:X9}n\5;GK~9.;GK~9.;GK~9.ЁRŻb S-:@C%J !foY NK" QA䂇#+"ӻ% 'WBP] PM७5@hQGIϮIS*^ԑ!IJ,eێvڼ5'9qPsC qnTK/sm?`K  vkI&kI&kIID/CkH-$)n @"8@j0wf7O]As寿P]\( a II(A+2a$%(1.t"ȁ`qJX-³,έfYZ̳o:fuk2ͼeyլ6YmV,έfYZ̳o:fuk2ͼeyլ6YmV,έfYZ̳o:fuk2ͼeyլ6YmV,έfYZ̳o:fuk2ͼeyլ6YmV,έfYZd3fI+! 1a0@AP`Qqp?dcR(,_Ef)Q~V(w׆Vz 6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛6lٳf͛1։._զiJR: V5+HrTpN~i% zjt:\ [ h_횵jիVZjիVZjիVZjիVZjիVZj,PзKq{gbW%RcJ܌&&}@jsMt@!):lBңz=H[<*[5@AAFZzUh)]UKzk @ @ @YN<6lٳf͛6lٳf͛6lٳڟ֖w^ʉ$H"D$H"D$H WhtQMi-Y /,o)4m^~,m8CM.U>9Zl] ęDZd Y^ɾ;r2 5+tu,oYcFbથ7|s ZOE CL4BljЧvFr_xKM[Q0\*oȧ%~fbkoȧ%̉w0t%&+݊~t/uBA{hX=pkYgQ(¢AD+beʯMOV<3 ".Wq <^ O46 ,ߡ|$1&*uX9ܤ@ĀUC`t^P7cGtbt:WafK6e~O V Eiky x?CMfM˸P4[oWC4q.~KaGCͣ~ccZH|w*0 LDpE Cf4mĦ'N6#n37jz0x+,ecn%aL[فBZfA dcF&' *<$hR$V &I7H P ?t,@f^ {8h>9sd DGky^5 H#*~?NŅMvwgXB[4E&yt<~5P) bV?FgqɆƕa%l/Ëh˺J!Hb+$`|a>ZeKM%3_2(ƾ!Usآ"&&!~!$K~SL= ^(&Ͽ hܸoO ߭`%HXEѻXK$! -Inh`.7lRVWݩS>/1Cnq޲E'UU_A%=M,JtmEf8*4| _(C(@ t:Q}j)23MMqƯE*XWLqm`ae~Y)+U8;RoW`L2MT[ޓbۇJȆskYG-Y"(Gk퀦6N2%,Lk 6k^O2?&pK*Gq.͜|WD*sw )3A A% rÁ--ף x[-m#btIF6qpBө{Bbf_Y;ƕju]o}hpYǯ;t#kK eDap /S,>mGy7gDx%_'d?Yag)Y3 ͗4DmUߠ9X1%cwOUdz[aHMF /}Pq/4uLOFl4(_\ϟ>|ϟ>|ϟ>|ϟ>|ϟ>cfwDp̓fZED+Kg"ŋ,Xbŋ,Xbŋ,Xb18f] ѱ̸wC4YtB;)z ?  cԪ-mrF=ABq'7v,|x1'z!XfjmC3i){WW[r$sZ2YOELQ&V >?FJ@ :dM4ެD3 [3o!JN$ő̕z <1DK BD?!t'wEK?E^u 嵋(Geig.ZI񩽧in uyGんP; 2%,Lր^v;cL0l"L6{usy#DXGE:f?Cí4{o3XsO9O2ʰ{݆B?dX2Cv 8]Ym ]Q|ҚF3!g? cF 2Hy xtbHc>kDؚgPd >|eI:tӧN:tӧN:tӧNBi T aL2dɓdžw(?բd)uT-HTN:/Z.B_DuQ|c;LR'u`It}'|ِ΋-!}: n+Y!xtrlw2G;<;{$Shmr?@]리Qw;"ï0!ŰѼ9T5[g"g Y 8Wd;pG-Ihl(l -آ( +8QGUiu lyb/+@9dQ#cwmol%:BG 857pڮ?\) ?X*_ }e`3#w؍ \y-fw}MDW1.*G.&Hb xB" jN0vFpLJTYD`l esNތwPP&` H_X$HAU]ĺDV0Q(RAeR&0ܽ XD3W!f-Y~'6ŝ6i6lٳf͛6lٳf͛6lٳf͘ATt@/+BR4hѣF4|2s((c,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,Xbŋ,XbUBo|t 3#/uXS.G/"=e_7鏸t"WSYab S,k#wYNa$ [0C@0dla*U61giFjBRJZ7nȌX o)-4@4T5!)"*I)Y\ ?u}1{ރEp>}sO:@UHK FCPg[5ɫt:f+bYL kTBBZuk%έ%Dw?Ὂ69b zi ӑME%̴4UߋJ熒ihx ^n(qg̴4Ugz QhTԦЩ' s~ > TQp +*c\+ {30!`4gSHbY9J{PKZ% yV~E#.SǑ[o=vJQ] hc#%t(J 8Yn}gV$j-`GLJ(ėՊjZJ)1ܚdshj I:ƎÄ fđ/=,q'jd ?jAR DO 6 3w1bŋ,Xbŋ,Xbŋ,X`l@%Z|jիVZ nr#)e3d.Ea\s޻O%=(сP[A*nI rlvOw堬3k6!O< 7Ir c^ӑ5EQY xEFCȫϭ\(9dZ!w$mn>aoE4(JwQ ^32㮄CnJ { W7ޯpͬ]xB;,M#=\g.xI%Q&B@\DP495G@R(*ȯDžeWd5xKBDLleyи5n5Sh\>䢒5V ޹ϒl)M( ]x",(pB5N;`5cv,^ӳdD5>&r[*~òD>k9}pɓ&L2dɓ&L2dɓ&L2dɑ<@X"c8x"(PB $`[R5{3(جqX AtaTIbC^zׯ^zׯ^zרYRrKt3(-*{Ϯ0DwY}gywY}b N?)G ڕ=-קs`<6.dh`+KjM Q*Q. Lb+"H7ᛥYE;idAxXH!W"@*aRZ#f N}@[:RA 1R֩De9!HIb{3:"տ Wty6죦E~N$%`mخɚp扦[WJ*TRJ*TRJ*TRWKZ6::@X"5>D(PB D#g2հUE_8pÇ8pÇ8pÇ|^ޠhwa`+^pRJ*U{.YGjڽ oͺ]/j23,- :oDDBz䯞{7L%E<kG r{(ߘ}^uha5{ bJM4||y"4 3l:w k@|up}MHcXi{o:*~o,j cg٭VE/ {<,죵l>+;dmjds=4UIwA,+3e@qǭ5`j"/I(+O%Iҩ ;P14xa.tEd]ZʁmENM3jB.u_wmz5RUwI}'ywI}'ywI}'ywI}'ywI}'ywI}'ywH)A-R ev!!jpH5]9V,ϥ?+[\qde`%%GدJI*ec7WҪ<0` $*z, 죵]Tϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|eK #X|ύGk{y?hᣭr.hcR {C|%ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|ϟ>|~B>GZ]} @SG۷nݻvʌA  @JA @5ua'=~$vPo%ub="RM-j@…6Jb^ lRwY}b̠kc}r ȳ3 D40e###&-~}Qj* 9-?(+5ɺ!3G%,EDI&Xj&%$pEEsX_ez%~x ^iH mp_aL؅bLA@*mgrɳت@ԍm@u.E>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;d"W  !1RQU"ASTas26q#47bu3Br$5CEdt%Dc2QR1!2Aq3Bar4S( ?$$664]y+ ^aUvCd`\ܑ:/졎yom*_Κ+]gF8~^W9vqt}`%/h0؇,88[;Z 7ٮuEQZ.5̵xo8¹Ώ78 :>rC#<>'cS5n8¹Ώ78 :>Ꮹ|F6Fasl9G(VpHTOq{a\GޜqshozUVǽlbsEG)Wq8G1pfpڜg8¹Ώ78 :>rV+Oq{a\GޜqshozQUV!lZb?pJ5F=^W9a\G޼'zB>x%:#^v+C{ӎ0s ^=!NQ pJuF=^W9a\G޼'zB>8zzێ0s N8¹Ώ7xO8}G))q{a\GޜqshozQ pHSS5n8¹Ώ78 :><>Ykqshozqt}x}G)=!N Nקݸ :>+C{ׄHSzBgOWqt}W9 8%:#^v+C{ӎ0s ^=!NQ pJuF=^W9a\G޼'zB>8zzێ0s N8¹Ώ7xO8}G))q{a\GޜqshozQ pHSS5n8¹Ώ78 :><>Ykqshozqt}x}G*))q{a\Gޜqshoz0)8%:#^w+C{ӎ0s ^8£|Ykqshozqt}8£|To8zzߎ0s N8¹Ώ7xGTo gOWt}W9 aQSS5~8¹Ώ78 :>aQS*7pJuF=^W9a\G޼#*7qFN Nק :>+C{ׄqFN0))q{a\Gޜqshoz0)8%:#^w+C{ӎ0s ^8£|Ykqshozqt}8£|To8zzߎ0s N9¹Ώ7x9*7x;HR:*$ cXe c^?ҹ?k{H/\'(C;bt(q Y$v2fךT +핚sw_ekOSVG==E%`򁿱|(E67Ү};^OnEuXǁU&ky 6MsD$w/?Jq9K~;e1`Hfֱ݆y |#q$JʱLEǟgV7~̿C6}՝5׳1LybVTN1x? 5JKPmtxHу$S+07[mm]ʞ|ge?S]G>3E7QM5Zc~/UW58csraSxY6)<ԯl6<5|yȟmlt -1{Z\ ;5ϊ|ge$WQό䳾LMFٽc3G?\ee1y籱y`SoeC(*f"wj?m1 v1D6Fj'+w⮣3xv_\/);E= '/b=!+-\/CcՕT "+ $ W]|ge$WQόY.TWÔ?v7vc^{)+мUOό*v_^)s~~y˫t%4%zTI.zOد9uyBU?>3x8_I;.=ЕM ^⪣OOU2q[v+]^{)+мUTs;)⪣ON+s~y UG>3̞*9d=]'W{)+мUTs;)⪣ON+s~y UG>3̞*9d=]'W{)+мUTs;)⪣ON+s~y UG>3̞*9d=]'W{)+мUTs;)⪣ON+s~y UG>3̞*9d=]'W{)+мUTs;)⪣ON+s~y UG>3̞*9d=]'W{)+мUTs;)⪣YON+s~y MG>̞*j9d=}'W{)+мTs;)⦣YON+s~y MG>̞*j9d=}'W{)+мTs;)⦣YON+s~y MG>̞*j9d=}'W{)+мTs;)⦣YON+s~y MG>̞*j9d=}'W{)+мTs;)⦣YON+s~y MG>̞*j9d=}'W{)+мTs;)⦣YON+s~y MG>̞*j9d=}'Wza6[ $5Tcxv_SSS٘ l\BѽoWZh <8v[6ӌG2I;ACTfJX/Ol E1x#-ڥKkysGޱ~+G+]sbly)_)gi]8S1=WV*q<=_Jq'9%9oQv+ Q505s!k).f'[^,j?IQuL;ecqUs;/\#5CQj]I_MI-{s@7'7SUy6_OMI@ژ[ -.G:WH0Qi$xжp7<: êEM< H䛷Y:yvu.1GNKso?+?$J|FEZl|9ITxQ0 P6|U}=T,:9“@l0SGSO<;͎/hqGQm^ cnx2f˶P=06nQ mf#r*&v6`bH/{Q}jwsj*<4K,#xA#-kbp,Bi\q=4tqFI#{,ݷѨ.ݾ̚9ۄщcG[veP=")[@݀<ܤ愹|;eM5e,?L"tNEbޘ5]$5Lֈ.ے1]&JrLMжђnmrVat A jkZ :ls3әX4ߑkY uŤôqi@m;f`|/SPZn@eY SV: 6*+"ĝΟj0ɱ(r9UⵧÚFUedmu3Hӵ-{Q,({C4=4% eO nJ&˓H"kZveSINzhY 16H_ 1ʜ#1=і1\9.:xm xæsU4Ylty5[>A_I TWIبۂMnJ~ruHvyfc@cnWR|<+(*ApDi"fbGr.p~s0,\6 lΘa4bG nA>o8yRy`bp:KU.%*aE 8 yYx}Qbd<g6-`WJpG+z"ۃcvyt6].Hh[f_ج3){Bߤ*)|a˕ƫ:vd8c(榒hCes\K~۫X[$EC8L9"jR4s8nkuy)+O l0U ``9`HgPU_L$$јۯA k[Icč 5a\5}(2@4MC+! Ol!4E17vmlV#? QMbfH}IjxLT43l@:Q7ٚ*6r @>XI; b]K4]s潈ԭ?Hs),5L&(%Kcfl:ƻay~mg 8j<Œnᴅ9رU60Es~DMP qʳ0 *{4-e%G0C3]~ede.\ |}f–<2[-"2D9 Ǒ5qxN+騠8r {u_g^ک+0܈`maq6s뿟s2=%L7HkX xD:YX>쫣qDOa5&m5*e _s|S ~S{D%Me{ׯVGK#A6qԴPj?AQQ2J&wcXZHy$^ܟYSuKKMLwl3;;DQ"0 DZQ<|:sbcΌ\ETeu!,ncd/"WVu]:[)*J: ɝ X\Xp )AfE j5y(iHic#3C,s~p&18.caj ѵHïo7]XxSX"|XkY,lΎGe֣\m>3THbk ÕH'*q`%33Ec&Z |*xj$åCN&<=9r6k'VE?l2zCQ`];ğ$ k>MQ ^x#ib@H RYFjgl4v8'>1"SG3dd.ZǓa7ʉ"*DU6)#p5kqը7j|g:h㑯m{K4]S$K-sy4ŲwncV—WX8LhI+$a!5y'vZfIC#|ld mk{ybxkbdm0IzdsIaUYbhc6A_vW-Y>&SӾI"KPұ0 1%f)5] o)`iNGfHJ״kº]exxFָԗ i!k첬yǑyO s8ˀ,h,/ 0:9_,t{ah.>mk*Ǒ,ya  kCQـ6ڥGI  $4Ѿ1d-jVU"X""u-3.o}6 ac̅m#^nZcȖ+b¥Hass`\] ؏ff9۾Ekip9ijK] r5nZh.uEST1__4oQ>~{E}zgQR5T^]=W<ڭGxaVh%4QĠdI#E k kȦ`mW~=SE*H-#4L5mV ;*b-G:Jh%\7ڍ$ 1%4Q;3##e.}VA{=U{mUqVh%4QDYptG:J@ <ꩈE)ptz&"{=U*"{=Uٛ{f侵TYptG:JB*o>K E)pt~ͪwp67LE(IM{RS##x|kwR Q(IWb,G:Jh%^E)ptz&"{=U蘋4Q(IWb,G:Jh%^E)ptz&"{=U蘋4Q(IWb,G:Jh%^E)ptz&"{=U蘋4Q(IWb,G:Jh%^E)ptz&"{=U蘋4Q(IWb,G:Jh%^E)ptz&"{=U蘋4Q(IWb,G:Jh%^E)ptz&"{"9aPoYnu4fMlעsؠҶHP[ٻca V- 5HlFX8sĒ4-ELQF7 O*"""" """ """ """ """ """ """ """ """ """ """ (?U;T:fNi ~S{E}zgFڭG6ڭGo*?Xb 7g>6-w GRi|-r\-{}iZ5@*tG蝢lk};:幜>kռ ֨+oVFlfiWV2nV7×nc_%4"Мٱ]D[v@j2H#Zh' ݦm}7ԂҲ"èݺʮKCukmJ*JtFd2_ :$ ZֺڞrNAJr y i[UWqθ$2/Qq]NϘE@CvZW5⶘+]myiZ]cO^iJͩըy܊A.]I܏0Hկ#U>M>>PEQٝ >G56m 򋪣cZָ;:b 4X8+)ْJі/RkZ8LM/qky} }@} }@mm#䫧v+N[쾽KsGd616.փ3AA)¢uQzoir >>M>>XU'Eu24bT^[\U CcCcQzoirqT^[\+AA/EuQzoir >>M>>XU'Eu24c +6\mڲOVCcJpNmk$O~J \rX\>h$DDD@DDD@DDD@DDD@DDD@DDG{|GQ"<'GK '/*o7(_YU]"U]"G X޲7V|YW!Bbf{\_ڶaek﷘Oblxݜ3OON꺘LGDPf8(Yb(`8"f2[6ll/7g=̍ |c)ၕ66pd \Xy%_N*Yp)#62F41o8y[r^oFψ{F,n!Jm,>S$Z*7x6$I1&Re9Xϔ9?no7g=y>!A ѲHD"hnVܒ-abIVm0ѾHn9̀]g3[j/7g=y>!WtSht̙vM A -mJC)0> گY7ѳ\z6|Cܠ#OBd~Qq&ir<= Gm|Cܙg=ˊЙzyg=ɚm|C܂L= Gm|Cܙg=$Йzyg=ɚm|C܂L= Gm|Cܙg=10t2aҲI%k 6hր ֶg=ɚm|C܂F)#*y H/tyŎW L^7P;./ ?0u@:[r^oFψ{baxSpx4Ja-[ !AG,tSa%TkdnSck,>jѳ䉮cu^X舀VotR(?U;U$h~S{D%Me4xajÛ \ۿjÛˤYxaDXo*:^bh _fS,5}$T+p1U 9{}Tpc>ZuԂMceP *F+n-p *uco2 *uV͍!vs *43fkm^}za c "#n 붠vYfIc.\@$Ti͐ly+y'^KJHG$l vHٮǡd """ """ """ """ """ """ """ """ """ """ """ """ """ (?U;T:fNi ~S{E}zgFڭG6ڭGo*?Xbt{qh_ Ҳ摯niy Ln';Py1գqsCA{#%s[`rTT~ KOԺ\ԗ]1׮k21x*D U"V{Zlb3D eq@nA`b/P3ĥyXgIS.j]"Ffk^ZZ4]m@9XJpȠ&̂.ϭA[6/N |nyҼl-[4G-iͳ^A9j F%F=ű\ oT&AިZWKXp!.F\ dOx/o~6A7 n7Ihsei u_ثJ)@/4Ti:qPzj$~2<߬\lۯT"_<1ŒF4Ns}wPor BdꅩS#HX̦w7'մ,([2 Bdꅉu8o 7 n7'ad?տ̃/ oT&AިXQ_0V2 qPzbqFN([2 Bdꅉu8o 7 n7'ad?տ̃/ oT&AިXQ_0V2 qPzbqFN([2qPTn_JjJzX &b/_;޿DD@DDD@DDD@DDD@DDD@DDD@Q~7wȩu*y4D`ߌ}~2z<0ߵZ.mߵZ,%K6Ur!\kM {c04󸆛gO? $g -˗X&I;m>;ZۈѰ6t*|Q#NW5>0xu_4|HӇUMGďg" W5>|Q#YȃUMGď8u_4|Hr |Q#NW5>0xu_4|HӇUMGďg"gz9F;[O)ב)TRӉ&R3# fwDku*4<i#k.mu|ˆJX`rB\!%7կkX&4Urxan ۖdA㖎ibpc)$p#m2V$>cecpgPycA@HatZ MfX_ڬ: CU3ha1Hß^ҶuECU/cbSɇT214/{Mˣ69 G&Z- \ӹNm<{êG޴=S+ti5eͶu&';9sb4/Q:O#oêGޜ:j>$}CMcR#d v^L#rZ@9:&ulEHLW4O4yVA0L{ou_4|HӇUMGďAVbh}4saurok{5# $Dxf&@疵Hl|.EJwW5>^VMGďibWu;yhc8;T0ocUUb5X;U,mi$11+uw%ǘY\EêGޜ:j>$}Abؓq6G'Gk9٠Z1j2u]0 ݹmu_4|HӇUMGďs4ΆR[|n\5uM|,- { v+pi暏zTcxTN4"R׷)-϶^_eHFaGav$y"UMGď8u_4|HւLoE#`s`3[csd,;b/n+Ht.\p9u7Z`6\:j>$}êG޵8v3RU)c.t!0<$sun#bB2]b_ںy<2)he}9E G0foKvfr_h״jV_PH :fN"YӾEZyO&7O_ToQ{o_^YGQ90EͻQ90E犏e?Zo{<?d?Zo{, H?ٲҨ  +~K \"" """ """ """ *{+UR"z *WGA`L5hƴX5ET@lֆ9` s@qsʪ<ƌkFswj*.yS1zQESKOY)~[Zzxi"SCp D@׬کM&Q.\nK*;i-:Toy- @TA\=*#aD@yJI%1U&34f lW < ZӴ8\[TD0}G{'}CwVotR(?U;U$h~S{D%Me4xajÛ \ۿjÛ YxaQjfjxݛD@DDD@DDD@DDD@DDD@DDD@DD$D\TDDD@DDD@DDD@DDD@DDDApIxP_S Q4""" """ """ """ """ ""YӾEHVotVpɣ%Me7^ׯno.sno.f,~YG֛ū "O֛ū8hu:Bvw/$S5N3dc$y7ŭNcg;U,0M^.Bp_ב QEcHT1?&漍LBpsi CcHNBnm262(xL{ cHMͦF&E q!8T{ ۄȡQ?*si QEcHNBnkۄ1?*ps^F&E q!TTcBnkۄ5,cHTQ?&漍LBpsi$Qp_Ǻ漓nǺcHMyp<&=1?&#n"G*=dmdPGLL.Bp_s^F%E u!8L{ #nǸ&=dmdP9o.6UTJs8ƔfJVLGqp)PMQ٣'}CwHDzHIemQ_YQGQ"Q~7wȫO8I~2K /m?h7~j?7H~j?7H|Q?wM?ՠmu i* +֛ū m)מνҨ0hp&(ah{\ѷ(#ͫfL.WlL꩘gU۴8ﻛUg򷬖+zkgT}3媳[K?zkgT}3v~Z?zgYmsL}nJ v~X6޲fpq:cSFYK?zkgT}3v~Z/zYmsLꙏwN9&yK?zkgT}3vw_oY,VuMh}; <6USiSv޲i?})ڧ#uj%b<`Gﻥ4wJvFmHcf%_HtN9&3j%e?})~TSv+zg򷬶Gﻥ4wJr] ?dwGﻥ4wJڧ'=嫳wHtN9WgY<-M#ҧjuj'e?})~SNF%޲i?}*woY,-M#ҝr7޲Y[M#ҚGﻥ;Tn-]e[l׶ZHtg~Xj0X ]8Cڹ;; i|Gb3x$wJQo4FQ'a e`K'*(>kUmLqF eDD@DDD@DDD@DDD@DDD@DDG{|GQ"<'GK '/*o7(_YU]"U]"G X޲/7TC֛ūIGH:[xݙtv~TާIPL3Hck,-c}M?K]`Z3sq>eJNʫŽR;ɧ|ŷ7;J`qoTŽN;Z~~&v~Ud0VɊGWS18]\I$86oЭX͈HсfOʣާIPdHX m/Nf}AvrvߡGŽR;oT/klF(v_(]ۺj.-ꔽߕWMz/hwAE`qoSŽN;k +`CUR:hidi d"ַl$D\TDDD@DDD@DDD@DDQ5"z GQ"Q~7wȫO8I~2K /m?h7~j?7H~j?7H|Q?w10,#D>#wMwW 4Mޓ;4Mޓ;^,7zO7zOz D>#ZֱZ NMW"" """ """ """ """ """ (?U;T:fNi ~S{E}zgFڭG6ڭGo*?XbDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DD$D\TDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDG{|GQ"<'GK '/*o7(_YUߘ]"U]"G X޲""?$D\TDDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Q~7wȩu*y4D`ߌ}~2z<0ߵZ.fGJāȺ-<|{xaR"O)zx"O)zz4A"(M<|{H=<|{O)"O)zz4A"(M<|{H=<|{O)"O)zz4A"(M<|{H=<|{O)"O)zz4A"(M<|{H=<|{O)"O)zz4A"(M<|{$Q=CܚxOP.*zxOP&>S=$E>S=ɧr Gri=C܂DQ=CܚxOP zxOP&>S=$E>S=ɧr Gri=C܂DQ=CܚxOP zxOP&>S=$E>S=ɧr Gri=C܂DQ=CܚxOP zxOP&>S=$E>S=ɧr Gri=C܂EG{|i=Cܣ> 6<ح<'OK '/*o7(_YݫVstu[ ڗwk"jNɝc79.Hų҂wZg֞G<~wtHX*\٠ 3Dא2P6A}b?;ӄAޠ/{,} f OR!ffFC5_3lԝia NGz6}+aWHҲPWکQW~E+s5EDv]c.~mnL>a X#X&F4m>jvxK3sH"2Pdp}b?;핯50j-4 PP:tp}<=(w.jj ZI'3(~hwyA-Kڢ55h.wW;J{<҂۞Sҫw{VKI$M+?;JKڙ߼zV x|PRTKrihc\6so9uKڵ -.6qnP>Mدla( \jۯb ڗw`Pb5/],l?J $k`yvw*:x,NH#*ɟIӿ Vpɤ%Me7^ׯno.sn*X_Û г|Q?wz#OB;(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(z#OBb(7IU .H \= 'Q:78$ ?1SV*kQNv8LPnܲ8AeS)ĖJ^n7:"tqicmh#Srmkغrp(=N/;C-L- wv4jqSV88\qT|aE2?V!Mh 3aRyu;I&# >>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|"W !1QSTU"2Aaq#36RVrs7bt45B$CuDc%FWd9QR!3Aq1CDar4"$2S5B( ?{"a|kr3&0g4ms~ N쯍OU C$fylRkq ]h`Ļ>o[WV#nSӳ݆Ot>n\pbS8)IZ{SPz X}ܝdJvƻiQ9yJQ֋os;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*9G'm*9G&o0dJv'VC.3JQJQɢ&s;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*9G'm*9G&o0dJv'VC.3JQJQɢ&s;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*9G'm*9G&o0dJv'VC.3JQJQɢ&s;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*9G'm*9G&o0dJv'VC.3JQJQɢ&s;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*9G'm*9G&o0dJv'VC.3JQJQɢ&s;7v=Ұ;ˌңrvңrhI݆Ot>nN2{a;r=-Rj78ówa+ۓ X}ܸm*yW'mj9W&os;7v=Ұ;ˌ֣rv֣rhI݆Ot>nN2{a;r=\\%Rj78ówa+ۓ X}ܸmj9W'mj9W&o0dJv'VC.3ZUZUɢ[&s;7v=Ұ;ˌ֣rv֣rhI݆Ot>nN2{a;r=\\%Rj78ówa+ۓ X}ܸmj9W'mj9W&o0dJv'VC.3ZUZUɢ[&s;7v=Ұ;ˌ֣rv֣rhI݆Ot>nN2{a;r=\\%Rj78ówa+ۓ X}ܸmj9W'm*9W&o0dJv'VC.1JU f#՘) n{yX8=)b!zie+ۗKCv_WtJ5[uw^2F$\1\Ky!<ilHϥyVÆ9҇>h 1cE/Y* S i -c -s .%hx~.c3ݞQU3. @-3<21`sv!j|J!-U048հ$X4||A3idki Ũ7CHI2Qǘ~1ēmO3glى7݄ h%iᑋ n;\fC-kM-Ln<[b CK xkM8^.cGU?+^Neu,^ָŶ$/TxU3T~UQ1RlJz FBepx|{5Du,TL f#kb ׇpFֿ+l+p,M-Dk\|/aś1&Q;&}@:mn%f]|-}\lAalN1'mi flo e@"䓯PXUkΟbөmo\D_ڈ!c(*iTUpi@ GBɆbM$%6=ZY=Sn~tY`i^b1 sϷYݟ~o6UY`C͋4P܀v_Э)xx-٪` ձW7lkjɺZI Lj_j1J:W0f9n8#6 >nh#_z5e=<ūQ\S?jr2g\@ERsD>Fq"%ַ4D+SBS藆%+xBm4^Tf(ySELhBm4^Tf(ySELhBm4^Tf(ySELhBm4^Tf(ySELhBm4^Tf(ySELhBm4^Tf+y/*h)Y,&2}h*K)ILhAdD$ʙ}h)Y,&2hAdD$fK)ILY,&2hAdD$fK)ILh@Fdks/L5aLK1(*fqaOo6b|]-(aũ_b-Q< DU9pT )RaBj؋laý}/)V#A&IkuN8 uQEzwˏMC*0} c_.U.g꽌v?ue{9v?Ѹ׿+ hm'<32o)[d_WK> LDsj޹T'kz9==]ծ~z?i֧\;ܢ*ޭ;>qEu`mo.QtoVAVkk\;ܢ*ޭ;.qD/mo.QtoVAVk/MwsEUZw;][ծ≮_kyprzw( ][MwsGUZw;][ծ≮_kyprzw( ]\MwsEUZw;}]ծ≭ Z\;ܢ*ޭ;.qD/MwsEUZw;][ծ≮_ \;ܢ*ޭNAVkk\7̢;.rD/mne@uiQt wV&m7̢;.rD/M9]]էsE5ZH0ip2ks(]YD/M9]]էsE5ZH0ip2ks(]\ 6Qt wVe@uk"k{.ӹ̢w$Mr4[osE5Zw9]]ծ䉮_kw s(N2kܑ5`mne@uiQ wV&u w(Nrkܑ5`ӭ8osG5Zw;}]ծ䉮_i{>ӹܣw$Mr4NQ wV@uk"kZprkw(]\ :ӆ;}]էsG5ZH0i֜7ܣ;>rD/N@uiQ wV&u w(Nrkܑ5`ӭ8osG5Zw;}]ծ䉮_i{>ӹܣ w$Mr4NQ wV(0CTJ=nݣf H\bf艉{nqчbzizf( VM뱢iop|,sV`rTӚۛ'Y$}q߲̙?zc=u_FDNh L3/vE 6!YdhjdT$fnȿ?pҫ)1J)hd75j#n^Moo̩؄Y70fFd̐\q܏4lSSQ9@UőP2[V h .η^E%-#L]3ݢņ;>|vh W$\jS[[a,+䩁뾊羏թnI`xL5ZYjJ#X5u> TTxP@3"Qu#gٳ־CŬe#셁ÉWEMV_4f85[ƷE|'ja|Fy6AqJTat@6&A#_[]7O,nH%ë"7Hʈ{,xHT”CEfG@[+6:>3:w3nmI̒DWn54BFU׾:3q'U֥ĘL،fXN1!Iq.}$11ѵƪ\õ\VéW.DdшÁki(W7 ڽD8kʪ B:x+h<4K dNsF<"ŷ( ;+jjQMA^1쑆X57_ng!tC͛5<3HYٷq*r3Ix~6wZA vٯUlE| b.psFFe!쁉?h~H(,pGiv\>ַ7dvֺZG9k/H2C$ B/o;徖W0K%eN^`xLxm%-M<ϕˋmcuNaaīF!-$ұf;ũnخMaX\uj),S'4!Q.Irqk v|79H<OZ+ vA=v9ӽzGoSFv_YL1V把(<\{Goee'<*p!h#5w' #^ _s 8* C˼f+*<>:xnsa}` bp>QE!?L,5݆UapJɌǤw~AqòqJǚMV*`d$ qd+~9e#^諩q'漖X0_βd K~!A~l8H@E bvG/GQjcҿG!6/kuHȼ3Q:CL=yow{ lS=TspS]aφpIԿk^(1r296TDZ杗sO՝46 bxlױ%]#RU8!MQx *OġéQE l2DH,I]lTRI43䩑iqةnEdhj( *6gFq7ˠ*f&gð.HDْlm%~_tأه: )svKkָj2Oj\Xj>1?3굼KOt5sP99dE? 8Ougf[Tt=qMNJ:2Nul[),❲4#it;3Ikg_7;d$8L&: .m+'mlQZض)3j!d~! (6.qH$koG%Gdv!OUNytE,2Kjjya|QH؉vߋ7_{Mx!0P &:Iv@خERTb ѽR \OYr0<؜cgWNKcePƷ3'J*办Ac Mv'iX >G (nWi8PbEG5=$a٣I&bq^o۱f1ORpv`;\f6lC$1#d#=fHS#2Kf+6ЁQ3|X2[)eȸvTm 7Ue7BHχP# aWirѲ8mW%_-Fq#ֵ?#r~JպXsD q`K{82g$794"[!D@DDD@DDD@DDD@DDD@DDD@DDD@DZvXb-5YlrKA0fxRM9n\ƒSTSZVMc*jieh670f>|VêAtѲVD/ulF.k uYkdc?BI#$~54ˈMKK3C$q2YukX`ڠ*[YJʆE4mxlј<:šljhv'QdqI$[$}u\}gkh-]iS+36ZԓX(K3<Ѵ BjIj*:\˝d8E PH%~V3Wi۸vkWt91ak^sS]#ƚ1$BiFqg]WuMty78FYksZ\vr*wE3CHǙhmqʧ:Y`*EX́}сcNgA-S0SI4to~ѝY~ R;t*4L8#[$i:mZ%%UKUKEPҽŎ8g3k[]f!b5`~L5u+7ZS>!іq8cȰ> +"?±Z]S sY-F ؅({dx=NDs ڜb\V,$sihØns z:RX!M=VT@5K!cζ2pڌhGY Ť~!ݧqr ` gx#تJY˭ E~#637NoHı,B6pF:iKKtfWxB ljA-\0K#;F-4\Z5Ab SIEak w %.6Qa>LB\AW ̙>=R;mUx ! Δ D60Mys_jJ-JJխpL; lE^++N⏒ѼTP'';Vc{..QY 42W4q^?TN.!F-T[GGN83ٚEȺ5B79i"Ĵ*ljsj'SR? &WM  rZ&ՕqtJR@U}쎊ɢI#ds =i"vOKbH$Lh {i%Gcc(l;9ęfޅ!poupRGUNnsI*83p.arl>)L`|67b&5Vu;y b|vǐ'-4&*f${h>"紘E1KvE od_WKw-{O52-φR0髃A/l/cKZbR4ә-\o;Ƴuо;g۝W" (æ()NMɨX"Zq6)i-H:P xX)CS ic'5@OGKKME:X,Ah?*btx(K fnuH;-ʬph$BEsakWMưTJFNH-25sڌJLUlhfLA Fe%)]MdL3ZxWRF+bŹff߉i3bsIicp9k}+@9^%sr> 8a;k۬zUˈ2J tٛƵ zLzL&* ّI;V.TQEea8"anњ58kATm=Slinu> Ba)P%iٟGpT1fͅ|&LP4-JgO#,ݚQ[X5┯Y5|J,+(k4" glcwVMuU EQ8np.峯ea s8)kF1k3'UN}Ul066 |Zƒ]+ fSׂ͜ կV]cXϭk"lP_<<6=X̙يVMFBb=>P԰OREGHlcSUbT̩I v>ebMS#_]E yi`tp-9lԳ856pYQ0ၤBA YCՕf/aJF*0͕ܐoZfDLE|]u=CY %Ӻ=tUNgSAZ`m<7.j 'q7(8-4K#eXw J (wm(~fL+:ZVUTVdU21GVDb:<-p5EED+'lVsL"6l/&0u3kW2 (pCE8}C( ʸ#i?JץZԽRT5K#b.6> 1hef4r83sc7x°Ka&yeT@.34_:׽TbTT5#`58.Of&җg#^Is]mˋ,|9#U\χ><{cvxv·LLKrumũ 4. Q0kO,s*:j"w s|G[Q(/hh%kffns{m**_͂&]vp{kmH2re=+ fD/䞶5&mI[ⵜ@sWRGZZ*|A΁4L$ "vmԡ7:JJ´]HaG NxvkmXj\('l5,|F z3s9* 2_ .RDZ'ʼnam< ؂6iEU HCpv^w3s㗅J VSvi J |qG>s؜Kms-*@DDږkG+ v;9ȚN{7:(3B7lXM6Ľ%W_@]oxZƳW=aaxM^!ݦ-?ZyJEQɖ mSV*`p_ *!IAxgaeS}~?c_nPvQ7GS1eGG<vF6(ꮎk_Sz޹do_ms^o̩'2fSzޢ^.vfp)foNe7Cd69OZf9oYӇ?M3z1^e7ß̦D/2fSzޢ^g749M`?M3zp)foP2Hntr2F+zFz⚠&8y&i0_)foNe7$L xs޳72f=snv c9oYӇ?M3zxp)foNe7$L xs޳72f&c9oYӇ?M3z1^e7ß̦D/2fSzޢD`?M3zp)foQ"f0Kß̦8s޳73%Szޜ9oYH)foNe7$L xs޳72f&c9oYӇ?M3z1^e7ß̦D/2fSzޢD`?M3zp)foQ"f0Kß̦8s޳73%Szޜ9oYH)foNe7$L xs޳72f&c9oYӇ?M3z1^e7ß̦D/2fSzޢD`?M3zp)foQ"f0Kß̦8s޳73%Szޜ9oYH)foNe7$L xs޳72f&c9oYӇ?M3z1^e7ß̦D/3fSzޢD`;%Ժ\HƖ>Ŷ* /,wd~c=ˣ:>׿ ]w3?#3[<_k~Yy({csZJ6948U}^}}sZZ}v# Y Vwk}cϚXTNh3[jV;5> ^$H.|`%{H41YDvb=ijafke$e|=|QI*I ftM$nyxsc.-ฃ*SVL20p?*x<M'< h6^Q>r=էCWψLJQcU4cFkcu檞h3KL`%ip,/YA M 04ǫƫ7`ͅDz:sRwԝTQQh9}Iޚ:sRwQZ:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝK=)qz:sRwԝTAԝ飨1'zE1'zh9}IޥDh9}Iޚ:sRwQZ:sRwԝTAԝꉍD146ڴD__\(+?? x>Qhj>fG /,wd~c=˧:}п ]w3?#3[<_k~Yy#$ܽ"or/!sZQ6 GVS+s[N "2޵.X;Ce62tk\i%24f[.+hUոI4pkaΔX1;KAq !%hL;7@:T>36 ApvX*F>Z6jAal٣oʲ*H""" "">e>d|ñ ,T#tD@ w)izX6UIӲ<_%|F" ,C8;aZ#Xa ݡǽ7`5|G44&Q^i Ymbٻ{X#t" sko*W:S<28xkuz j㮤M#^ћy+m`^ׇ%pqN֨06͢UQzFRv`7s|B +n0RKY,2hsZ6_8ZyʘvF{mly8Z׾Ւ+^~8f49<ێ&cIi-%0cssDv86 uU4MJ٘'$\]w)izZ𼤤i{aI,rp2J{n5ya2*wQTI=s [P!L; Ӱ, ( 4gef}¹S޵\)T)mnxڱ曅>,8F#bv0Fܦ߽ͥyܮ߽k8UG%M6TXs 7O.[&IӺdFzZL`s :$ Uܮ߽;{)Nӹ\׿z"a,?r?7~$=ʈ`p.&(X(oB" """ ""#xS+??2|TG}@DDD@DDD@DDDAH?GY?/ܱݒ>fG /./ѿ ]w3?##[<_k~Yy#$ܽ"or? /Q5T>H,R`n+/QX^Èz y(veHIGX |'NS ٗ#*Y#klku\_>S e')}?)9L7N 's*d9sKn^vFִX'e)}2>veHIGX 'NS #'Pi|h{ˇ(TQEESzhQiX |'>S ٗ#' b8&Qoܜ(L7Nf_?%b8&Qoܜ(L7Nf_' oX |'>S ٗ-KPӴ%Gar \lNU%8Ne*8\vxڼUM96Yjgj QU96{y6Yjgj T{‹Hw*] 'i R|TG}@DDD@DDD@DDDAH?GY?/ܱݒ>fG /./ҿ ]w3?#3[<_k~Yy#$ܽbH^M}^1}}sZX,:LRooIU|S{䑏.Ix ^:j˚־Q6 ZϋSfUO; .jbcQkDEmg^5WENg縸,ӝ\x^.to>'G$8In\uxDP4X}#CZRsEp-:d툶)jjYcdGNӜյQ\V\e|Q8 Z=) ITH[Gs{Jd8݄Ǚ|`m;1՘NK$Xc B7g4ZpmZQ&3tT ` z ͩ\Vf4׳uMFNN Q4@[N q-0bTM&y-+mzmdg{]$Ϗs[1#]u+m !ls  D@^̽^̃b².JF%|rL5lrOW:)a{_0l85xl>7ݮq!K`-P|\q2%#)Hns{9Ҥ GR'S0}λ_k1|rjJX夂5)FX^-+XYSHC V>=!8Ù/xҵYο00eN%SIJȢu-DrZӽ.kIqw|5(qܡ _J|=ɟy#7+4U EWfۋl.D2&8fI`x[oȘ=F-c⎉@O#P\í5%v+WՓNĄ-w s{^SautrH K{\ۿV6(ۓ30y8':o1B?6T4dt jx[7k}FPcFT17s<[l sa$vcPnr =[ꤡg5s|CĘ͋pcC:'Uͣk&lmtyձqRijgLculVkɼ;z8H&isL5 qا8jjsD4t΄sIx4P:jZ_ 'lecKoX¶g>{HqpnwV7RL4 nsps{}v IϒXt} ⺳())MP)mQK$ %mƮ1[q7aOg .7hׯRlmS([-n!x i6Nox֘Ȣ*7KAh}[376<\อs*V &y{Z::ZvTʪmMf7 qG>PbO44Wp#Qv8g ;7X#6&iEEU"24bJɤ0|ߐW0e-DE$s"soڛmle[9[H"=C#dfoeR#QCѶy[J饒IB6wj:y{ -F,j)h8e FKH5ylmj-!y$#KAfX⺳Lّk㸤|2 u->i":ٷnǍySUaO}=ߟl'"1-W)"d55g3+568s[Z |Դ6W?q"h)pjdOB2K[ j&8w٭c ǩ06Z>3A_& vbuqHBָgX}*1ʪZ`7PYf |okI齎0튷ZU,~j#s7~j/zܦ'>TSpf͸:Ơ F;-: YQU;n 9h H[ U%nM<:B׺ֹi-'a1_"""" """ """ """ """ """ """ """ """ """ """ """ {$|͟c_nX3g#{[Ot?տ ]w3?#3[<_k~Yy)pinˋ]{BȰ( ,3Ns"ҖIFE~OT9EAdrxkB|1}|<ĤAT5=N[ %Ԕ=%$4Ҿ/G1  nUdkpvmUXj2B+ 3r#WQL'&s//Z-eK^^=OF'cl ҮIJWD]0iw{ԯƗEc^ʫ C|RG#ٍkFB), M41 ̷8vȘ+Sp!ǟisE,X;-sCEi*Ȣ ,7 ║:YL/IߞfOaVpWSHce:KSOYWK"C,[4}׳Z&00'aKsMw~uDǶr_ 5/;A:&'mR40"`AZɢc#rqz }{Ãg憒l5JR2F8D1ADD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDd~c=#l}d{prΟygֿ ]w3?#3[<_k~Yy#6= 8sZy5k첮or? ҄g9`= .|Vci1P ׳_/ .nm(,OcׇX;$=p-\Į\Qc$N1:72ї ʦ[ ]b jX ItM<ݾ= CY+q-j@7h_Xd8Z4jJc#%ͥ^/5\Zn/*b-# $<4v67C##hΙ#9ڭc} 63(mknn ^$,=U;yj'o-S* pv=oR;yj'o-S*ɰ2>Z TUgK(X pv=oUic3)zO[ZXFz4 x;yj'o-SV>QM,|=`Z TUgK(X pv=oUic3)zO[ZXFz4 x;yj'o-SV>QM,|=`Z TUgK(X pv=oUic3)zO[ZXFz4 x;yj'o-SV>QM,|=`Z TUgK(X pv=oUicFM$AOo-SzkK^PAT8;yj)O)Ao-Sz?覉EO[ŸD'pv=oNZ }hPATGQHɪ3k^KȮ&"1 q:P՛Ѽp+(9^ """ """ """ {$|͟c_nX3g#{[Ot?׿ ]w3?#3[<_k~Yy#$ܽ"or/!sZV[^(!L*ΡgMWW jG{Vb}&*XsqM TMQMU]X "v ڂH5j oVS2g ]k\*h`,jHś1G[+fL]U+iꫫ.bF#X<֎eG4R͎F4]?6Gf =Fug[8 ZzFbURWb ZJ]a};ۃ0n#C1vk]3C)sc,6pii Car<>Ę˵mX.Iƽ958׫EE ı&v<-,kagjbڲnGSWYQS$FfHƇj nY#{OUNĩfmP\-R)jhpl6LV$:%%. Xf~*ʎp|Bj x]tNsEq0ljQ$d{Y\δZJM)+êU#f =Y]ut؆<@Z0ؘ$pc.8ihsME\Ca}{e$5Ҽɚ33oPciqGJ!\e'þ6$@*޿Z,|y?Y[]bLJsh ox[ wuG;ܠ>I,m|sjw,K=7#v{,d7#v{,d7#v{,d7#v{,d7#vw,d7#vw,d7#vw,d7#vw,d7#v{,d7#v{,d7#v{,d7#v{,d7#v5 44d=M%^*V{1T*JJؚd$|Hqcbpa{#dui"? EDTmsZ6v |;K)kRh%t{up[ b=0Wh ~#I5msvj:6Gcg\EۯPٷb QP=;F}#^Z fQUWu?o+L`xAs';W>QhPj>fG /,wd~c=˧:}п ]w3?#3[<_k~Yy#$ܽ"or? ү86^g:z_ymkq" 9׽˞4DHH@6I;I(\NQ{uW=.q$ε*{8ߎꗁ#kq scm6&s:@!<BIhԊ9$\1UMS^Y} Owad&\<] #Wۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B|W ۙ ۙ2B6Wb;s?BKKOSR{WWy|󠻞py# $ve]Yv4{xa2w'oU嘼Iv}'e]N̫1x'e]N̫1x'e]N!U嘼Ixkx**zhhsmzwYfjPx^ughsnNWFNfG /./ѿ ]w3?#3[<_k~Yy#$ܽbH^M}^1}.kKEbXMDpٝQiKvgZn)c}n# #FG}a:4Xv;14t/con5kOSIIUGCĜ&C$G<x0W#'bU<"jjfS襦yb?oQf1REG]+񪰌"QK,B"X9? > vURw `?:م7}ҝuyYCհQP3C^pm)J] d :y^ne<=\m59.pp'СɜNΖZ ̲%yB{ִZ6i_EQMD έlX#*%:79L_GƱ~JW))Ghff9𻇡Dlª*C9sqԝSVH*tHֱA&eSQVV|.)(\+E 86 %;2l36Z|+5i(s3hiN>4=^7(pTN*I|Fqp DP̦yTsax7Xdc)qS<4mE9T4ѐn4t|N2 %549=ӭԜISE;3&d nnѨ*H\ϒ~fֵS1)+emE}3a;_}kฬSVphh KlyiNǏjDG/)r UN`&GǣHur,.H.aԚx괒1!uRǁtdT3b1tr;8[cU),lk[k;0VR HC3C-¦PQGQ1վ9'k352)o_SN+o_SN e{- g^ """ """ """ """ """ """ *V*Ut;B? bA T6絷-.>AQI.le{Z^Avd ^&=yqgmffyc%mʩ1}QFҴ45sƖ 4/zv5p=EJ c es!ws{6z)4bFx%D)HtBof0e/#|J PD`f^ݪ̣`xVGW?]?eOw*T(U(5^3g#{[;G?z1e>eҿ ]w3?#3[<_k~Yy#$ܽ"or? ҩ׶@D ,m{ """ ""!mDD@DDD@^".P=Nx\i_=4TTx]'hDM \)WKPeW@X=;?Rf#ӳ-Aҿzi_=b;WKSNԵ_J1 ^#ӳ-N=;?R}+Ǡ&c#xNԵ;WKPeW@X=;?R^#ӳ-Aҿzi_=b;WKSxNԵ_J1 f#ӳ-N=;?R}+Ǡ&c#NԵ;WKPeW@Xb=;?R^#ӳ-Aҿzi_=b;YKSxNԵ_J1 ^#ӳ-N=;?R}+Ǡ&c#xNԵ;WKPeWBv0UFiq ͥAfpǩXp=*ܞ<7IR볁7:aYI[ḉ&ssL`arl'ΤǶH]6lV(qLJ's3Z":^pyVj\'1p؜cfcuwF_ur0Ix^^5r.%oDWz v~xٛY*JB%毬02I$mf 'YrVʷP3N^9 KNNؚ)4z?n)?ejA5]A/zIe8` Z!DzR=+Xbӷ zY 0GABF: rSd@99.nFwڿf`Ya)Ά!%D dp[՜AŇQb2Hj#Dlvv\Jp-u7LG0ma2m;@L``|KUaOGT.׾٤g^(1Zw>VQ:Di V}`/^5'(f1M9%o׌:V>18n`}ݲ{^=ކuS幱͹Ju㦍,pt, P}O;ܮUQjIesmeC +0zg:(AH }MUy})z?o4J`(E^M7Ҙ WSGUy})z?o4J`(E^M7Ҙ WSGUy})z?o4J`(E^M7Ҙ WSGT_*:GXׂ\ƃ'}^0 7sV>Vc ;]9ӈ#[\Xf#ŷޤ5GmL\ ~*4:6ΒF9e_ҤLZ` { "ŀUB^0 8\?* $ 1I7UZޕu m{{fƨ%&49/{aG{v[ ,n !/r[1kUAXwRp>wZe_wSctuL'Pk#S >Qr^" """ """ "" WG?z1e6޲=g_tgO3YԿ ]w3?#3[<_k~Yy#$ܨxt1|t& TGEշr洩GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V)GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V)GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V)GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V)GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V)GGVd|][w&d|][w O-O-YQumܙQum܂<<~M<<~UfGEշrfGEշr t4U%Və%V!QŢ+ k![^Ud|][w&d|][w n (Vkp^iE_fGEշrfGEշr ҋjv^Ud|][w&d|][w n (Vkp^iE_fGEշrfGEշr ҋjv^Ud|][w&d|][w n (Vҽa\fGEշr1E#U';WM """ """ """ {$|͟c_nX3g#{[Ot?տ ]w3?#3[<_k~Yy+ϊr W\NOr W\N^WFr|WPrױc) Ѻ=T nvEOx?K8>SRWEOx?K8>SRLY'?I/Ox?K0dX'?I/ebx>SRVNY>S|cFA`6TU.uR⸜' q9h''q9''q9[lf:30:W8w? ``s q9h''q9h''q9''q9'+(+Le(eNbNMA6޲=g_c$|͟c_n]?eѿ ]w3?#3[<_k~Yy핵-V}*mH,IƯaXe[h wfs5"x+*\nu<9~ JljCZPɯw޶%eɯwސ6'*UCOT(*|m1ť $38`SK?o?wGGdGU7#\6ot-|m@4s^뛀5\JDzi.!їf 5v6Q,&h&i Z܍j7kn>7MΠ[8U7:nױ7XzvzTӅSs:N{ukn>7^%x}}6!P: pAL b-~%nuZMΠ[2W7j =~ryCOcm*Aַzs:LfryAOc;{KhTל*Aַzdc4n;{IܞP}p[G Pu޼T%{vܞP}pN넞?R8U7:n Puޙ+Nc<'ԪB7kn>7MΠ[8U7:nױ7XzvzTל*Aַzt{_tqKaTTOWd͹U Puޜ*Aַzt3g#{[/-Dd|d=X5){[Bbcӎ!ŝDaE MqƵ߁cԈQQLSM] guXc'D^$ѱ8oAqX"'_tw7 I8oA/:tl|?~7 H:6>_?R|~Dd>_?R"}eGNcԟd>#FO}cԈYӣcqX'㾱DOѱ8oAqX"'_t7 I:oA/:tl|?~7 H:6>?R|?~Dd>?R"}eGN}cԟd>#F㾱OcԈYӣcqX'DOѱ8oAqX"'_t7 I:oA/:tl|?~7 H:6>?R|;~Dd>?R"}eGNcԟd>#FOcԈYӣcqX'DOѱ:oAuX"'_t7 I8oA/:tl|?~7 H:6>?R|?~Dd>_?R"}eGNcԟd>#FOcԈYӣcuX'DOѱ8oAuX"'_t7 I8oA/:tl|?~w7 H:6>?R|?~Dd>?R"}eGNÎ"(.0ܝDS )nnuN˛mD_+]+^~uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.packager/image002.jpg0000644000175000017500000010340011665471326030722 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;d"U !1AQT"5RSUaq26st#$7cdr3Bb4%CD񃣴9!QR12q4ASarBb"#3C( ?HF#,]rGßL~oKz;TS3ߵD⪰"_<~v_<~7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~v_<~nZ7=P"_<~}0Ijz$ެBڊAWG IC&}=IMS+ꅽ*Z+i+Cyf&OwU3MIu-ݹ^gЩʼn2i-k/uNցOs-;rI2%|nc7p 0܏2ESbqtQv(1H4?XۀPIdLȞH,, SjJȩ3iIRe-k)Z58sgFtī:Gki5TŒad_VoN-|L}W&5Uܦ*vi@eZ)谭Z16F:O7V 6u5nVe>k Z,xƷ4mMs]Nݦ*jG)w2,{ˇN4wÚ"|ؕ iZ@꘧§i" .QqxO?H_] K~Zhgd692d;-aXGf 8k (\9+l7[}ft i`UM-,SԵQH2qX5jzzm-+US6cߛ!$/a}]+؈bik_ƚG&/f%Áiƚ23Ęiƚ3Ě3Ħ$iƚGa_2q'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#H5!L1'#5!L1'Jҽ2&DĜ +Jșp4M+"dLIҽ4L1'Jҽ2&DĜ +Jșp4M+"dLIҽ4L1'J{ /h}5D3+NW L*3%{sK6&PPe ja?9l1 ب|Ύg bx}^83|Xvjs/uqM1 8Umlr0'XGlms~5~#48,Ұsdd/-N1J j8h] fӬX^zUXZQWO Dw5Y \j6YpAkf|kZ$s yfm&LCģ箨3J+՞=ZIdi };e1Q`UՒOFj!cQg xèIԷݢ[z>̚3[KT&$h b@eD߉K 3NٳTmcܣ/2G!φ7MsrGLE:W_,9.`7|eՆ%TSA KZKEȿ;|:fɅ:<=ﯭF"41kd 4;[+&M%Ax}Z8]oR4=>)%ib21ݙMnZZvՌmtκ{w8|rKE##k-{Y0vK{ވAZ86ćz5ao{8ޞtκܻKgL! G;mƆs|rSF$ v0OOo:i] \.M-<]dL!lWGom; q$siMo:l t"qZ+#,cealadpmNN9!Mo:U3ds2E({ I _>9\b 4茄JvNN1!Mo:돫c}C{<֦ͅfxE1Ys!`LřYc/q''u7uqMJS95Gp&׶e?Ef $4lcůНOc|CΛuA=͢s\.#a,*)8n׹?)s|cy|CκUF T>gHkZaì/Uc)bâm3yw?/w_r=o:oߦcoG! TH.oiխ%$(tq|;A)z'c9/@ޥjmE3:9˓ES7-ԆA%ڭR"ƥ) 5QuPr ^IAK7'ږOQzji,<1؃avdF:){yx b]SoRv:R \5>gr1;\-N+M Rsf5| ~#F(1VVYrƸvbIp$AK7G0UCLB^],hߦ4NbyjڪUF'{|\h{|YhZx?,S<^1%}m%5Mc#A#V̫xar?T2MO3~KKHAVH54cX" i$ XJϘxLZz|{ ގ #bitnHX&1i>F~+5|ϘxLo֧ҾX]NR !n]\O:گ><3V$t.l>59+uZY/'sx[Th쑵~H鲴0֪,))7SK<3\#~ro{kjLJrZ- :bOn5Z`\ahip!]X3}kaAT܄Ե{QTifs1ĵ?ڽZ$1;Zd U0֙>rVg}OByiqqsL`+d/+p09_b<a2Y_of2S@Bf0֠SVt/x ffŁYֽVI04)k3;F汀pzh<a\c h4g:XC;/bOJ)cmE3ȩ_ 7{+Va3}ivcQ89sbmɽ??Jˈ%MiJfÂxLZc6*#6{LlqsNkjukԕ{tTӖ]ϑİ\ kVZf4X YS-s)]G L;7/sab<ζ־T60ִZA0֢Ujh4 าnjJWHم \ n}ix T*jyc*cc'ѝ#lH#_;\iȓ;1{{_%><}}lVE)kAi#osֶa3}j {q)18'nuV1e $8 =WJF(l# k{ JϘxLZ#Dچ40-`jYj]6_jϘxLZT~dm;9I)3;Xݹ7?m L#Y4eه><"pX@ɆofІ-<27%$QCVX\|>b0x&Ff`,b8=6)]I-\TCN$SF pV[,ZfTF UM|ll$66 6:j_hw92Y)&ޭmL3,VZfa3}j0փ/><a3}h>";m: h}H<"HXp |&^7Xx>}boS/O+sFͽWxG^g}W^g}{I?xQ|OTbNU߫Jݿ~'7ŪϟFk=W~H}lSUKd$ER6%?s2|\,~Y@~18tcY+/d+D.f[ my)dTNbnV,Cd4v6f&.D|\(|z ׉Jz,2\8X&nwe8sw8xxi;tn8A^Ǘ,7]FFJc|krd` gm|[|Da 7`'&-Ye@ɩ[P LdKLCYU 摑0ؿoII􄺙N+U[KKз9ܛm[J?+>7A={qi4o:;OАy ipF2b,mrۇlI\6Z,' ]-m\Ƙ8Z/r[ll-Ķ4 Ujy[$nBLemp#n5xc (rw)R""ðD4 Ciq$ƴv#DŽSO^F.ZZjbGl^neq{A;6j ZΥO"kY$PB!4ʷF5x-s\.BgYT9.kS>#=N:fE3"9;@d=nrZ|*@d2?]'`^+Y&8Cisov"_FmcW5M%SZ*)[¶=Kluc^z$榒V5|fz&TDdk+a|BVpy8:8~]D@DDD@DDrC`Jȱ|>\~<6+C4asơbZidbBZ֓kڳWC n9Z mj`mp篞E˓n箩N 9:S y;BSV&lLHK w%dl2Fc#E-v/CYQ* gB2\p]j&'Hy<26=k71@uymWUxe T1>bm{ZVf",\fe.DGT1:ڲ(`S5Yc!YQ99nC7{*[֒,':Y$\Zxv 7B&x1@s˞?S1ymܜa.kuzMEq8-00J4Xi<I- 6 bD}4+_+oо/?TUtӲ79fpCI-"mGsV9jv ${"h塏,}=jφb0┛@8~qO3ţNQa+waT ډs'/EڳLbtx%I,pW\`=zshK !ǭHuL2TnE֞2GP*9XXtqlb#)ُ}D]w1߅ڐ|sjhؾ" M dn+tB[6UGO>Z` v9Vu2bXZ+Y E'i!X-tQ<13OEO]wUYM]+btK'tk wV `La$XP|=| ײLUV"nlUq&E]!3]mq*Y)Y!l {؂@j:nq,ƥk*^BŰ_Y0 8O{sK[QڨDDV1ξ5loeY;]4QLcˣn~k2L{-}W`TDZ@#-|\ֱsY˰zO,k$Ʊ-7\7ZxeuNm˯^\'h7IWIBÇҸ[vkG{Yy? [Vj?ܛg#Eܛg#E_$-NJ75]ֵmuVfjS>Y~Q?WYؗ6۩Bղ4F?XiX4G9,5/t6[ֽ|p=d{E .`-W~ȡiy2-A4N*#anI:XիRbX)H#xd3; =[$' CF. :7Xs[#X%x6`斸\D/";yx$"3lWW11 h`mp5k3ekh7 vD@DD Qs - ,Ȉ`.o$k """ ""Qx1$,uFD 2\zYx}gr/. _ 'i+A;ҳ8gگflYi19 + ٖ&8f\m6WZ]Ūb)D10\Zo7&^/5AW 9;Xp$I^!i#h2f Á WS7S,TT:wKR$KD61,6:x08,ַP ޓUt5ΞTN#21θ}5S2 C lomRr,zCri?US=;1bU2LD7Lp C87KLZյtqRwg Qԋa`͊&1gEsXѹ6mɳ [O$2?[Y1dۢɢGX{Am\p]dPlGu7%F{Yy? [Vj?ܛg#D&Y}-gWo/&(@m&;^ݝ\ֽsuJO5Z1vU[1Bκnc3Of)y`+/hkCF,'m/'vͥd\U&gwQ-mFP{vi|?m/'“Tە]K*Gl_&OKpwj%7=K Zocĩ]i|?m/'wvMRֆ,i|?m/'wvMSHi|?݆<22g.4zq*oڪq,p3Ux}sԼȰp3Ux}sԃ2,9\>L^.\ ̋jztpgtQ㒦H 8./Y\>A^.\/v죻p%X04w.~p읷إe 6%ͳ@N86IP19a=Kjze#èbudtT}NؚKu,3>hP ;sj\>L^.\"Tan4T2Dd\j:\n+F,[{>kΙ\>L^.\ أd}Ú랤UR Ȱp3Ux}sԃ2,9\>L^.\ ̣b=FJkt,p }L"7MJݿ~'7ŪϟFk=W~H|➃MP7|.Kk"nQ}}jû(?jfY-'"4GVRlmYYv~7ֳr'a7Ycq-ioEh& XiAv[Ngw-M_g~WIi^%lN"|xRn~y37FnwmqĶT8o| 'kg5/#Yebm@mk[!kDשO;/uKhL#hUΫ{76nBή500*19 .$ŝRyݤRobq)?~lKx͚'/$}@w`Rx4;K'gssV݊{j^C$tf2's:תj! 7$fg vjרLrHNZkmZ75FY¾zB,l IF+&|ab9 MKB [zSsũ195\lxkgvdt{OWVUbMUHe?<+Ë~۵c?[ur()]$.=Į7,H#& 168Wڸ_S1atRg x:-[POA#7,ЙtYak?khlxSU?6x]oU)6bf@\z/ˏE՝5=NJǼrt\z/7;\j64`:Čڽ!c<^bWWlQOi rS+qُm=.V8G:\ R|G˓|n^1ȹi¶mH;_j np}6#?:&ՓQPx@}5枢1UNyOrNKxNql}|?׆aus1:̾Sη@F#Q*&@ƇGw7]@0KqpZˈx/JQS4S ;?^ic]ֳ"0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu×wZ̈0X9zWu44rm77#JZ3gX($AUOU$A3%|+ZnX^eb 2=qE,u3Sɍ"@\KZHୣ0F7ɧKbbIhu_J7j |FAYdNWecŨ]Vh[Mh!6ܮ-cf5MGbzs &.]a-H K>N׼lUg ),:s)Iwwc]]__:$KE19$a`-9!ɸi:`[] fnWFQ#4rV)%1{WP3OK+BE|efphY6ذv0Jji_16^}^6ژERҵac^ڃmwm=m+*`|6*u>59h*NF6) wF IqԓTֲ".s5ٍ<9o [~+zһ)h4.n8ŏҳ(;?^ic]ֳ" ;?^ic]ֳ" ;?^j, q&H iMl 'ǫ5xJMj{|Zh+q)?buO͇vNJz5Y) eF*X.-Kz5?d9SٶEok2[m^抂 X>0<#ɷ콙zEG,p1>ִ!Gu5f#P)2J CQR&q✋7t;{4s/l⽗n3j߄2ӫR}poTu$\_3MޝK5V/:Y.}aի^QrtXYRMf}t6`O bs0oTu5:GncUTkܰ{td`ps\'wO'Pk@cnѷ*ȹk7TrOض[_Y(CtX6ߵdzHW?7y:|G#HOP$lrx6.w.=|&w.ٱ}8Ł.)Ͳ-upo4t7#uj"Hsbd LY3b|{|AX;? ;[[ O'J|Pfh!͒MŸwAHvlfGڪ7Z\--gqbl9=pmΎ4jBEfxCef 4>A3,)nn &RcMP,sHֳo_?%kM\%릹0OΞ36?H^7Uo_?%ijF87[@YG_xdtRJ$m_Qv|"뭾˝|i/G_eNQi+alԷC6ή#%W#wH޵5KQH֙*FU\#z%W#wH޴ďHn֙*#F$zE%W#wH޴U71#/9*FJHiyU72Ur7tLHJFi;oZbG^rUrGtL\#z="󒫑oZdn֘\#zי DQG85tΘCL /ȩ W{?Ikv^|Zh>~/\m!NJz5Z0u_5xUz)?h9U|}oS|'clbs:3E1ًHͨw:%W`@cLXVlհE: jlflQ( |ږ GTE6s?I+1FD˵L]J#g:F\Z@Vӻy:oRv# u'@ޥި"bG-5-Lfun7AG$t9 C.k:Xڮ!گwܤ({jEr+EBy?noЩ18^O.M&""" """ """ """ """ (]OS 'ǫ5xJMj{|Zh+q)?h9U|}UlxSUUAO"/Vlv)*5fb+oߙMf׿JJ(߯ bTd-|GGe(^Z6ֱScuM>Զ1'DmiA~7^e+gtJtfA7󯍭Jfd|'kF^'}*YQ cy<{ӵ?5=H="j ? e,sbBdpdwJ#|@Kn׸݈<~7O׿J3=Pdy1S֌-|pLjRHcn6I!!<{~7O׿Kf;!%LJܱvG_ ښwd9} i?^) s^.0ni?^)(7}{o߯ Ғ#~7O׿JJ i?^)(7}|v:M~#Ʀ{jEr  ËBy?4UwI?-OP*߉$o*7ŪϟFMjZxߒ(lxSUUAW➃MV?W>z~r,Hc""" """ """ """ ""Yؤ՛)](\VЈQH-lp9OWk0,R|^Jp*kKk@qi6}{`ˣa!.sh E_K IܴFATL*gŵApJǶf[:,[d]Y2Hb]]ŭ/< >ţ4pfӶX&=x~k ^ѩbT E+]+λ:a}9F05 }#RqSz`ۀkZrsIIAXes1Y/>tn5j׭]7܊oYifSzA\ܞUK% ǽDp Q}LX~)tƦ(${aC@o޳:|Ȧ֙MVT94+"T4JMɷO^mbxSR6&tQ⍆k[go2o޳:|Ȧ֙Ks:(0Xju.F7y@wH7/5XMEE;!|qSǯ=CI`OV}7"gZo޳:yhAJ m8qI*R&SzM7"gZeG3r)fuM3M37܊oYiHE|MȦ֛nE7δTQ܊oYifSzDHQ|3r)fuUrL:<лooЩ18^O(ۛ4*L/˓I W{?Ikv^|Zh>~/\m!NJz5Z0U_4xUz)?h9U|}oS*~?rĈ=B" """ """ """ """ (՛)]JY؊5\^ZCs=K& c /buwD|&$/k{X l>b?H"" """ """ %<8mT;!{mwl9NyM^S./t,m֋Nzyf!,Qoxe\k^?F:jH~M;Op\\QjFaq)~jTe:nIDG;U.mWȻEh7hT_/'m&?eɤD@DDD@DDD@DDD@DDD@DDIjzUO$~xf U}ɾ-V|4OroU?{~6Cc=**jah>C?bDEj͔.%FOEa09Ӻ7DxTqNٌ" yJīf jcQ3qkֺ5"*a{ZHm㥌Q2Vf5mí+褦0)=_BOP sG> _Jʨ$+.puE`hhKMNأ,^]C4 C#hP iX49ݔEVK9bodGDAH"" """ ""Jf:G2"03xRCZ\M%F567Jd`\=ͰpkEgd1Fֵ1o hzsjj2F nQ?IQatvtBh)A!F۟e^#d/ p״D@Q|!G;U.UK(, z3[$J.m°n4%gu?mk+],^v^I/;zԭG~ۺxQ6Le4IyֳIOE##FlƺR gRCX350I!q&,^v^I/;z6S\cG -/:^:Q_tIy֚Yy$_7?}wutIy֚Yy$_7?}wutIy֚Yy$_7?}wuş]h>e4IyֱGhwjʈ)n@q$˥K޴%oZfGTK]֥F5i-p9փ֖^I/;zK/$kvQ1 hnwx5 ˥K޴%oZ%ɚ^VNr,ogx%$ _e iy$QC,A6nBR"E1{n߄,vuR:L"<C#]n~'7ŪϟFk=W~H|➃MV?W^NJz5Z0U_4x[!ʟܱ""P 5fbVlv" /ph-x6 TjsSFFI "3j7ln # ?y0ӂ/@hֹDEsTZ1=(<8n86$0F2Ha[]0^ ƌݯ@k4Fq$z)AH"" """ ,bX=FtR:  uĦ"*ToicX%t}wW֌ãl8H,ڭZ4И ks YF;U/~l>(( b4M韈1C .eILstNATѱɑ ; ~-Jpilr qmseIjIi'(? ĜMN?9=Y*7ŪϟFMjZxߒ(lxSUUAW➃MV?W>z~r~zD@DDD@DDD@DDD@DDD@Q6Se?˱ݫ!%F6Wx6UL'v7Sbv=643Wgǩㆹ-Xrx5\:FR2P6quUQ3V_JƦf'qTXekh^y쭸Zjm&:*Jhohk\;o{Zk Me}=[Xnxi_*06jpi?FHjWʭt{8poe n(JiKluXjVd;WKR[=wm^lOy < 7y|XK$Zx<," ""H"" ""X̲AWMrGN5kHiUVslT5 {^dsFQqup6M|okÁQ"z9(i#HY CEU$3MX&TG-q˟7fk{ƨSSEm^He9m`٪0L$RAR w Z Vֽv# crBmжiѫPPOAFʫ Cc=*-|O"/Vlv)*5fb*J""5x0%͎(4mtim}R)[QtSeLsŹLeӫI(jklt:dl"R7qltͬP7#KfkrFl5jHV§tXm+cϨc_#sÁ"J6}1ӆDA=V:qۨq%s&|Nz5:68o^*w)؋(MO x$u?2 lNtg"lAVRTL6c_d-w-PDEH"" *[}ERȬ&%H^M {#=4ۋ\y֎qe ]<.E; |q56(f'Jf㢔dsיD 8ekX׹T/ŋp ܵ$+61C$б΅jҳsQ>8[R yGN曂kߋPa[KWKJ^׶V?6^\>h`lEjI"kH9~a2ށc5)_2g:4X X¨Yzh+ }}D8]#2 7[C_"}}4V>:JEf !گwܒ4[4+j[4+j4""" """ """ """ """ (]OS 'ǫ5xJMj{|Zh+q)?h9U|}UlxSUUAOibDEj͔.%FOEIDDF' \=Tecelv $/ 9_Q5iVjNw?GM$ #ismpxZw骠zaq.[k kt2JSmM :Ն I 8vmmekYQAH"Gj4:S1Tnj#|'}W ]4Ե";.|lIvPOv1SXs6up5XOB3icNuqb6䠭{:qO3/%V儯 gPD潱 \<(2nFX#&n+Q0-SP#[pp֐,M5jڥ ́&Tcc,#y\-6 5+c\H |wZq5XmK(WQJ[8S[e\Zp{rxVUVC3+,clxulMSQh"lylVt7PV(dcf`$[m7з8{jEr>ESӶJ6=y>{;U.Fs}mVs}mW&D@DDD@DDD@DDD@DDD@DDIjzUO$~xf U}ɾ-V|4OroU?{~6Cc=**jah>C>,Hc""" """ """ """ ""Yؤ՛)]OGA5WxtޫשjbhkGs~+Y=:oUijwZQYKI|Y71Vd]zKWxtޫԅk^` Wu:oUk8 pW]zKWxtޫԄA7wM껭HD]zKWxtޫԄA7wM껭HD]zKWxtޫԄAVWu:oUjB(Wu:oUjB jwZZæ]֤"Wu:oUjB jwZV*;W1u8}4[4+j[4+j4""" """ """ """ """ (]OS 'ǫ5xJMj{|Zh+q)?h9U|}UlxSUUAO"/Vlv)*5fb+G]|V9@ kxjJ &;KQ;n;9Zg6VZ uEMrJfy͵ ZP4%+p yi%{"*s&NPZIUFEJKCq%ǘڮD!d1428֍ z 8 S?~:5j}s~. +LbsEu8_l րp/i+.GR x#p$&f7$[][8 `1 !گw܊noЭnoЭЈUwI?-OP*߉$o*7ŪϟFMjZxߒ(lxSUUAW➃MV?W>z~r,Hc""" """ """ """ ""Yؤ՛)]d)7ӷ|xݭiqڹ*(qIO;[;d !C3t3WPC`\𱍎 eh F| N2sTtUT|e\Z9K.uPKS'T(jL2Be`vVkY=/3fR{`&:)S'+1c8U@DDD@DDD@DDDAH"" ({jEr}ȭ ڭV ڮM W{?Ikv^|Zh>~/\m!NJz5Z0U_4xUz)?h9U|}oS*~?rĈ=B" """ """ """ """ (՛)]JY؊*m;&[_(4՚V@./?/GzVrXoM%g%"ED}%g%VrXo^SN2x<` FвJKM+3^Ǘ-6pTDGVrXoM%g%!GVrXoM%g%!GVrXoM%g%!GVrXoM%g%!GVrXoM%g%!,xQ>SIYcHDD}%g%VrXoRZJKM)"+9,}7Unu^&4.W澣 jw]"[4+j[4+j4""" """ """ """ """ (]OS 'ǫ5xJMj{|Zh+q)?au2UNX`nzNJ}?ry SG#8\(h:)q?0)S/bE>Zb+*]=`R^aU;(}Tڵ1s?0)S/bE>mZJJO|?uX"NaU6}L\%{O맾 Tج?CbEV.}`R*]EVȡSX"M_S>^0)S?+Pج?CկD|?tJQ{(}TVȡSjϢW T{O먽>v+Pkb+*]=`R^aU;(}Tڵ1s??ë&d346 bEhx3[boᕈ8Lt| tf r@5k< W[T uQc7{p F0qc k䑿 /tEe&{Ux)A)kjé3/-cf`|WZ~t)i181f8#ŀ-:~K5!گwܤ({jEqQ=̓hu-nvPOA/_*HGÊ:G׭U5ƪ +xƱf1,Lw:,;Aҷ7/*oZrz3ޮwբ&K dOE0sm{³oL[[obeu;I<.#Aқr3ZЉC+Gg2g zz vZSRC{#Ŭ__>e1eҶ Yrƈ&kYssfkj6n -Q@6V#7̲ZωUBb1CH8H y=6 SvP``kF6 3䤍ԴJxn` |׿:lsj*O(᥍fc3Z]fu*s1Bi&}@ s>;_;Yckz JLjU{r:Gı; #IPR:#'[3ln/ MTWyg$1whmf٫> EuZy˾#sXu-ENi S2w2H7scius-*njCRYaҸ;-śwZʙ+? lIL$;\c!n߭gÆ<; I-e}wkֲC5utU>,1U=ɾ-V|4_=ɾ-V|4_CY[Ck{cV'.)[ ,qZX_hQrY""Sn9i/X4~vsG쮊ڞN':3gN8_qhQ7O\Nug !p,+oڞ;+|C?e;L~Z9WEDߵ=rvV9i/84~vsG쮊jzs8_qh3g]~[]p,)g !*&듲λL~Z9SC?etTMS'eovsGi/84~訛N':3kN8_qhQ7O\Nug !`;iq81*Le9G˱fffJź"s&)]F}m`<*V/KCYWP哽[{5KEatbUɴK )U3F&N!Ի'yy X"K)6VjL*Ҷ'Zqf55'yy X%|}ss"k֗0X;a &68Ď%ڃM~kk<vO? `5F@tOgl׵y~ [;ā5~n5#EjZdO/3<aPIZƴX'I>WN-_ekpm&_'Z Xx'`\ ø6wy5nsXI˜34r8ƭ[vN<'dO/3$b6Z:{O? <.9dwu=FW'c Xx'`\rdzN<'dO/3\x'`N^gq%7;dO/3<K'wSourv>^g;'yy,N}<:*LMRr oq+{Y rTOtjf0˃{alu]42rg !>^xjb16sGi/84~訽{\{+|C?e;L~Y9WEDߵ=rvV9i/84~vsG쮊jzs8_qh3k]~[]p-b)g !*&듲λL~Y9SC?etTMS'eovsGi/84~訛N':3gN8_qhQ7O\Nug !p,+oڞ;+|C?e;L~Y9WEDߵ=rvV9i/84~vsG쮊jzW1MQSUO;d].[܀-Uʪ-D" """ """ """ """ ""YbVl؊vE[RH^_0$QV\XO2<+kI#kfB >:Ԣ%mG5Q~Dëϒ<$4\&Kk)&lϊ'6C)dVosneK cuSs3,śSkJz9ђ$yAn *''@x[ ەZ SvX+k<3grԛƟ̝Sc4J ڲ Rn戾91y9걶­_WzR꽕m;"kN^v=- l0JT6A[.Ņhgrԝ_WzFgX;gd*Disc%@.9--WiLa\oWniخex-ngp|wH"" """ """ """ """ """ """ """ """ """ """ (՛)]JY؊*kPQֹghX]}FLj $'Ͻ">F@uմ.sƊmeuus3&` pkQ;NdDVPDEUMjt |5ϣ 2GHh߃Ҭ{Er}Ȩ>ZB "" ?H"" """ """ """ """ uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.pear.packager/image004.jpg0000644000175000017500000003254611665471326030740 0ustar drazzibdrazzibJFIF``Software: Microsoft OfficeC    #%$""!&+7/&)4)!"0A149;>>>%.DIC;C  ;("(;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;/"N  !V16Uu"5AQt2Raq#STs$3B%4Dbr2Q!1ARaq"23#4( ?2k Q3iX%,%/[Um3Q:rַ}s\S4w #ZT%̘!))3KjYD%$fffdV"􀟚9tS 3\S4wO%atS}Y5o֚DzYfmr 1ه[vT/F`'QrK)e]ddfY&IQƲIU[Lum%Y.()w;XbN#sDbҚ+^Jȍ:-c54x-OʒQIE({r2߰BYRC6%:ٴӆ−j<":ۚboZV**l7gkQ[Q$ʵ^B E: 2RAڐe#!%ȃ R[j)7㭕- 9(JVDgwmeiE"u62+kJǏ[\ ')AM ?9JZhluso@loKٟ("/f|H/;>RGT>*ETh[KB٥<昧i& m#TM:6dIʌԈtDmq[uMM|kLx),6gĊ-oKٟ( #B- #@2o XaCV2U(өiNSO8⤲-mV"bXEeH.Xb|1{ ~O{Hb9i)}#x3> eH.Xb|sǻ)}#b9w=;_~oXb|eH.0? ~O{H U3%}NPy"33+ob& Ez_&EW |3Ey:qhEy:qhvfsw]ia IDզO]GewaO]Gewc@?M螺DM螺Dƀ~w~U" ؎C_nLWMdi"$1}?̣ͧ!DiIq4i<5jE:DDE<+k/OzS4LDId!$DcQ n]>)L^RBjFY&Y(0,ѷ&ec+3de MoO@ޞLʾȊΦigWEuWxp쨪 1-LKHS(LrؿgcdAbN2Rƍ+3$J2XoI__9dUTU)o JgW4QzPԖ! m)pM{+^(ǘz|>Χ&Rܖ̈́J^+ ȵӢÇXæVC2INMzb:bsRdN|EAѬ[SзY %)%)Q3+zo&&&:+4cDQ?M;Hjj%7%[Jy6CmDw/(2߶c*J)t*ړs"Q_e7YFzmg$dE;(7w7kk"&[q4WÏөMNT&:#"Bi;Vw?$Pr0~#1s-oe(_V?uZ8\D߯mOǵK.(|p=j]QSa8W@f+M"B,6gĊB#$uHЋB#$uH 0N\9üa] 5@]g ҫaʋmMqI*Et(|@M>9=}ai@W-;/柛5}r{>9=ҀecW?6`? Ujkr#Ay֗RPfGcrǬ"oI^2E{d|5 A\O4ٯ7<ޓoI-;i_Goy''7<ޓ (Zv5q䟓lϻPHFsI61?HϻPnw>䟓lϻPHFsI61?HϻPnw>䟓lϻPHFsI6,6gĊ>~)3q[jmj#24zx|%pޗɳ>$Qbbm% #B- #@Wpz'WH 0N\e&j̵!}:Ӊ4-$FGFBFms -[fŮhn٪G1kjZ솆ms - /遢-Tbdd1HR~lCŕf%)_$c,oۗg`f`M;IBIvEz'嶊K X#̢/ʼnotv90z]i6Hw+|G D'R[dzȉW>M&T$-ȮWRO^{G1"CҖh8YG+ׯ~^NJbm|(%%eC56DgtK+Zڭ鉋Xwu+Bo$̍V2RutUyi\\\T2n6mI֟(GozUtד+4Qn#5YY[sf4R5)= Mԅ%kEXt˜^K䔡fR.ko#ǖFw5)EbCreM)d-h3k" -%8VOv)L2T!s.M'qi,{o+u6]&IW;IYj=/{oD"5jկc䙍)l)琴Uhke5YhJL)+8MJJ&TIlHuf%os eхt6'?k;epޗɳ>$Q}CW |3E|dy:qhEy:qhY+8w?jWpz'WH PTSſ>)1di3",?YO%atS}YtΏ*}/ 3DKx3DKLbx^Lb:?ةD,^A:?ةD4Ώ*}/ 8ZF LjP[2r1K%дۙzŚuF-V&CZI#SjAFDFFFFV21i^ꢨUF/Bx==]>._|G}ыGc<G}ы1}hw1}}UF/ =|UF/BxOX~N*m0Uz}n_%yܚ2և%)yC,NӍrS)pN۾Jf{s;;pJ/f|HЋ+M"(^w|Zh^w|ZÜ;މ5C [bŽ.R"5ӧ|\i]=\i]= ƕޘ ƕޘUҨk[dcV 5%x(St3@JRr|פoFz/{S0lYA2TTf>HHU;-~f&9_閐0Is9bCcH6&JZdWV;ך5+9\gNQof^GP,Sѿ [!ev?$A~+Dp"Orz"teKA]QԛMVySPSz9zV0R\DZ%VRឿ*ɱF{(;)|C2Q%KŤj]Դ'Jm:q6PVAvN[!qW޲osc)LJUuS8y9n>FY[&#Oڵab{Ep}^7:/ e"/f|HЋ+M"PIR8"мIR8-8qjF[p~/WH H8i12Xq&2i?-7/xi1x#6V;k+ShigK#6V;k+ShfJG9lOw6V;&,sXZD9lOw\M*Y汲?։sXZD4TaHRxZ$I̯3@Z,6gĊ-oKٟ( #B- #@2szFa`]^:gHOabp[gZm`7@34:Go8΅w434:Go8΅w/ܯkRK.6(T4Wq3 s6aTr^RWq3 s6aTJ O N,T,zwkS3h g3o ÜALm K$QhEz_&@(^w|Zh^w|Zü5ic{D^pSSqE!؊–[jˎvU1:U8J9v:1XssNa:)jMrBhR' BiRTF-GfC~:1/YKIEffV-fI)J5N[Cٸ2 ~R2mT->YE?GizeuR"JS-"""+m*ÜLlQ:U8J9g4cvheĸۓf) A*It$d4epޗɳ>$QhEz_&@(^w|Zh^w|Zü5i VE;bET o3TBjNG  '57|@?vFFIw #PI C)RhS$"D_VzS@f* "e>(MAWZtұ,QWMEK^a.wˍoċQsjec6mUObw!V61;KC=[jTF'r=EM6quAJn!e*v/;B>xuU8i-˙꽯k꽯ppLUT*qr,v"3"cjf*tNUƤ{!IQI>NJdTS ҈)eK2e+2YL&~#z9WjTF'rcj,8nm+J2/Zi1*mXڪC6mUObw#Z8V\$2B<2Y7TM$̒DWKxXpgzӢEz_&EW |3Ey:qhEy:qhgpLn=,[1isJBˈ댣[& [e}* >3FaPRtؓw+y s"{&8"Y,CpR9]-Tbd[; WpUi .*>Q%D#"=djW#[fŮhn٪G1k6AѸ&CinpӺ+sQ)$"o>#jZ솆ms"|}7 l# 5H-vDg4}_<{|޴>1!ŧDXQ4 Mb-EQ Ez_&EW |3Ey:qhEy:qhgpLnmrIƸV%DcBdCfѬFWL9],-|ht m-#5 2KHvZ+Jj }1ȌynIaN+E~TfTjOhxJChrVİı5:TD0%-Kl%$6&9\ڙQOR:1)*GF;H 2ÛR)*GF;;=pTOR:1)*GF;H W;M>> o֝ M>N8NZԵj3"-cY\7lωZepޗɳ>$P )#GZ)#Gf _͍ bk՛kReƈ|C%2J 3Z['x|q..a$QhEz_&@(^w|Zh^w|Z)^Vhhw{cY PRQ!9/o(#Gy_N>f^|~OLU64 m-#5 2KHv0} m-#5 2KHvr;U15]EnSao$U"u m-#5 2KHv*tf 7-ºS'&=鑟(*1yK&})Qvc-_yz);)ZG>keϚ DG̥8L=N(jٲ/FdFfecad2namsAX[iidFIqDrÚ+%ZQap}^7:/ 7 Ez_&EW |3Ey:qhEy:qh2.7bgaץSRJeVJ<٭~Z~@وbngX|[*5 [*5X~Qp&&1M"dG% XIUjWs y&jhy)3j" #P>1C.%JkS&"r5k/pYcej 汲?։ /\lJdT"@A;q5ݵ%6}{9lOw6V;^UfNkZWRԅU>b|R }DEOz>c c5T񰔭fW3dkLj3Z'|cejk_h۫3 FgV:c@8Z'|cejJvk+Shg5NEV3ixF‘%Cɒ%JI-3I_%Ef,qH,6gĊ-oKٟ( #B- #@ P8I=Ⱦ11>+S3eIa<[6dЃ"?M螺DM螺DhgމL4މL@*)"2r}%;ښ""$z{5~U" ؎C_nLWMdi"_O5\{r$AF#%}Uoz5kS3 Y)*GF;;-&wxʑюOR:1%T1#qn+qVNR[4IuFv(Z*)>gmtԫbAeV+k;RGT-/;>RGT-*7(7XD*7(7XtE:DDE<+k/OzM1h2m!$D#j"!kեƖ/mҸۙ%fQ- -ӽa1U/rr6ECDm=_܋܋>BJIEr2*[*\J3nBʒвQ$ѓd(m⾭Nz r/rZ0:V)af>qJ7I:NJ<+\I/'PTe9VB)9^$QJidI$^Mr/r'#i^ErW{Z$}m٪Oe1bٓJ^JIWQ6ޱr6ECDm=_܋܉ S7yDm=_܋܆z ЍL{|޴8hi"q Dzr֥KQIop"/f|HЋ+M"PIR8"мIR8؛ ؛$+ˍ4s_J#ne FfN\]JyqemFQ ȯukF&ϨCb:42\id#zHLqjEݚY#f*^4FU՚"9ϮKMDjR&dZ̈V"CN-SgHqҹIe(Qƹ\^Wk2+,1ԯem,~/|Y#f*^J{36jJ[ "m_T֤b+q ;q̗!Ra҅NV3QXFJzY#f*^4FU kctQCImm=ddj1{j:Li. )Sǐz%{k,'RFUid{%BMZϒ rP[Qr%^Ye*쌣ebX}X2aA.AFW,Q^JHWeRtFUid{)@p"I)l&G\%}S3ZG{z&LIDhQ_dzթbTjNL֙uRmM!jBL$h8>o֝n$W |3EY\7lω|GHš|GHŠ',;T谤]uJX @SC@SFg ;4 ;h|Ы LGӆ%jI~'z(OR"$ fQn.=FD&j0AWc2&O7mh^1Zdj7I-i:܋%;iW*2ʟPK̪*A$ҲVFFW=gQ_O#gEGt΋s ^:юJٹrf4FZI3b.چCkR5'xw;܋Kev q BTKAY(j׫A#gEGt΋s s+Ԛ-}C3K"$QhEz_&@pBiUBJ!inD6Nj\FZG1ߦX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsAX[iiд"ZG>keϚ @.amsC.6TNܩLw#Z&v1uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/0000755000175000017500000000000011665471336026171 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/StyleView2.png0000644000175000017500000003572211665471336030725 0ustar drazzibdrazzibPNG  IHDRy5?xsRGBbKGD pHYs  tIME  )9\"tEXtCommentCreated with GIMP on a MacwC IDATxu|7v+j41bP'҈"]@PAb9bҌ\g+6:_9sYXX@VBLL Ν!$sr9mڴ*}baa!]tdv=7uWF'99ڶmkdYAAA<|wwwJ.-%W%W%HOHH`h4!0QQQ₝x*U*GK9OHH`߾}eaaa.\@=ի4nXtҥ2d<&_onn ϏFakk+TTHOOȈ+W482cG[uTԔ6m/5 9J"oڴ):on4 -_.Gi%9qeJ~0!ؚS|E6|XJt[neƌL 6?&44VӧOի͛7wͷ&oٲy1ADEaг ZV&~S6=r sm6x^%wq}ݻGΝyزeX6nH-q\pNGXX+Wd޼yxyypBRSSt;UVq ڷot̜9{{{v… t?֮]ҥKtFBB: ЦM_Κ5k;vЏ?fӦM߿ &jժ\{Ӯ];nݺNsxxx0eiذ!:u N/B5 &hZvލ/_rT-[ٳgٳgO"j4lH}γ/#ZE%&9(|Y6xֶfNqϚ~GzMBB=zLJǏK/ܣGzꅱ1+Wҵɓ'SNUFbb"\xRI8p &99٠x~jո|2<}4Gtotr! $u" [lԬY`voQF |}}iذ!nnn;v,LСCM1bD}x SL!00'Nhݺ5[laR3~ѢE !}H{W 3őL3eߧ{VΒF͝Qbg-rmdQxzzryz㱳cΝ IfuVBB3Pդ ҠA\gPjT*t^R$6225+V`ܸq\2dzZ-C ~# 5k#2CBBhذ!}aرRusmZhAJJ?+ӬY3!9 m۴a fOö۵#$.W`ҩIG=#Q>}uM\&sG&+Jr///jժɓ'cҥl߾F}D޲eKx1G}x >}'''F%jZa!,,,G#"""hժUB,#ɝUV\ *ШQ#F#rwy/Bfͤ)qqq899?ӧOsjgTْׅ\HRբT*;[;UfܰZX9wTѳ&SN|ps]v%>>\{6rKڴiC۶mYp!'O܎5Jj{xx3\]][.fB&Mb…k777Νk0c,fM;ҠAz'?~|HժU+WNZI#kZ5jC.˗<3aoϰ.^;̪R gΜ,yY/ܹs9sdd;v޽{'c]sHFCJJ OTXЯ8Gqn߾MTT>>>ݛ3fPD ?~<7nՕ/RJ.x 7oޤVZh0anݚqM׮]ӧׯGVӪU+-[={PR%fΜIÆ E`"(ܹFCPP.\aÆx0|pΞ=˭[DO?akk˹sX"[n-GŅ>vڱ|rh4,Y;;;N8A޽iݺ56mV0Yn:th4ܹsCɓ;wG:Ӌ,~dĉL8-[0h iVZIw.]8z(#Gd0}ta"SLYfL83gΰcis wݻwg̙ܿGHqnhZfϞNK wbuY/Ƚ2~g]e˖d2ٻw/G1kkkd2aaaK͒=[niԨ/^dɒqmaaA=ػw/nޓg/_^ZW^( E%Њ[T\M׮]Q*oߞ@&Nh"oN@/0,, +++LMM177Ԕʕ+cllL\\ٰa9r$27Jkeà &JY P]dWoBapmС,^Z:/ILLdܸqܽ{vB>?ٙ5kbeeΝ;Edĕ7s̡QF2fӴgϞtԉ9sA˖-k׮r92 BA.]~:קADGGsaJ(!K&!!!׎өS'iT.SV-֮]+- vv!GٳgT\`{`eeB:F)oԨRa_|ӧO'66{{{ڵk>|FK*<zx5j՝X"5k|Bo@E٦->slll G6v1uÃ:xi2Ry"VhWd({ "~/*˗/[Z"~kxVѣGy.'˩T/Yٽ{7իWgԨQyk4صkƍ*(r≍NT{TƢsHV aT\tr\]]9s j:ϡǡ-RAZ]02K.7;A|1J.]"J+Vcc^LT&*X=u+ƦF7.-293,5juVȨJ#%#gE|sQ-g0eSz-"$(\r# n0Ә;|5f/f~anL별usp ta0\"{`''0x4Ht ~ IGbb"IIIdP(4P'wC$!||;.3?.lYƲ5`TrƽH".:^_dh iiDrǓL^5>γ!l>gK)[$;>jnP6^D{6 ԃmYw+w_ܼuVݧe7pVmK7 }ɡm'Yg*vaϷ^Cn1~p,Xw+m .zքCN.y֥hغ/-gX&i+?|ג3KBQ6{S{4!we;]sl9Rq^:kq]bQ9ݹ[Y=u+WOK!`r<"593Kcn]By d2Zq izkRQ5)c(>D \d̾(]8\$YƝ++Ug̘J5Yە$n=ZʐJrRlpbrDDKmϼ#Ɯ@?ѯ txa@+r9u:2Q׫ٰ T@x*=N|~;eX[b_ֆ+ane*e 5?lx?Vnݛֽ UJ Z27ccc111sƨTBi\ju+8KH@ѠIWVk^Te J<MUhӫ}?˜y2kF<ϧ<®U{ Gw&y ld͔*9Y7 !.&u(lUT&PT^^7-kmNZ)y^2SӘ{ .HjQ嫕Rm'74ΧGM:V4tMC88 %pJ fffbfffpd=ε{á-[Qe b{ cWiS SiE? XZ/ן:ϭKը ͪSaW1':;? ?.#9!Yc+}>K <66r9:V+eL/^^)jQa񚅑B~3K1x~EǪQGFm`zߥք[h27ߥsBi1R)<=2{ׯӴ}=}<2 ]$16"&)i[ƌ4c0`TĿHO! ؃K1cc9ZS,f$JC&qy4ؐcst?=]113lգ^;)iŸph]iׯ=r9}LAݦ5bR@N[sϱI۶mHKKc4ngg|'ܸqK.W_IVB3UU Of%-%ṱ HRS0kf t`fYFŽ#>&3+S i:T&*Qr#&<k{BSU_DĒ~#o9Rvm@GJɓ'_7x\(\3DDc寊x{cE6Qߒ]U%@? \.ӠA*UDpppc eRD"55oP"V@6<:p;F^H{&w*kd6 m%E7._=yQvލNc -yԭ] j*Pޱ@KJ$26JJ6@"*.8**P~'8*Mt:bciIBoHj"Chڴ)* Rt0yd~bQy/,&>gq4]O#}7r_GE/|%N|]5ǨKIIK3wZ$g]}1Ξu1t-\0%Vf?J={׫tg݁_wR}01x';b׮gx@rj*V]enogJp]r\>P^[7\>ÆL{SRO 1iiiL<(-l2?ө[.\Uu<##q?2vvtvmI#IDAT?nʜ?zJ֬ɨ]<}:"\bmkbJXx<`d޾K\Rܧ~jRg,=AIjxLy$,&o>g>W0YZ,%%I~:qTܻ;& G{Nݸ* }mZ絛 cW}5kPB6˖g,.[Va/^L?Iѣt6]J0}fϦ'n$֓t6ȑxL³}|3_O6~@:_ёCߏ&5kk,Ta֦+s%ﳈ?N0Q0R(xiE.[)g,d7$*_OѠZ5Hn> bTst$M&m,- }чޭZset:ɩ^JV-m?HE~ի]?.͛< fh;pP򛐜,dP\9~c/z*W{|;~K9sR+s3n=~L~rWY{{Vi\ԪXl,-ʱmij_R%ww7Sv5=Dhu:LUƼƧ񑫹h&N4͟Cf_9j5׮̜5OyHc+DŞ}TWZz:ZdLT*Eylb"/k$/Ij<'EcjlJ֋nɒԴteى t:ED p/_VKPh(R|g'26 SE^21)h>y.B9}*yNӦ`]T,=&eѢ~YŬT(d#)m_o+hLF\.z_ +E5BJo.ZtY߀  KJ 6hr[[l!q)_E k*ʚHō WE.v]ĒciƅNy6.SY!ES%];R%ƣ,Wf`YHo ܑj,]Ss &K"_1Hb/ܝ %)ocѢum'-4fw/Ȯ go؈qrhIDɣp|/N͐[S_*l0ף<^JGĠ2/0)SmJ*5F3~i]yJLKse<]I5_ eE8 FѯNhy˺NR)TrtTZDέo(M ecMWN\ު}KjM3=LIb_ќڈiy0Y 1z&.m(ޝF7!W4ە;_py\>m.*7RbTy'q=! ݥN EDj.aN>-NbÆ ]ΆT=.d2£np֎}yJ<3mZ|pIi8ڴttj54ALe66N?L( cZƵ!V3CvDʵrIȌtH_T@y֖{֚[lf"e؛T)GıSn#0,EԮʃEk+-H C f*"3VLk\Yqh ޲7߰תZ&v:A9~2֍aݸ*;\ݪ1Z:.)(Ljۂh4Qєp/p! c1$ 4M-)HzR;~\JDue̫Vگ?iqW$Lۯ|Q|3F!O%7!PիA djU#ds1BPnKM8 ~1\yEB.VUpDusʍ] l;IUaP3E$6qcȧ W`V >N^vk4\ԸmNjS?֏˸;m +AzX%{UZiސJsskt[+MS1T9w3${vO?u!G~k}*1^(VYP)rj2A+6p(,jTn\~h/^dh^pjЭ= [.}&tE@eW" )t:Ajd *[BMt>k"M !-*mj&eKʟN#58 rLΪLՒ$m V@Ӣ_435/,x^NF - OID$tM= 3JŒ j\H>]+!p9K.J7޷ʎ?5 Vc)ͻ쿯X;Haa+%*śu1}Li[8wۻD ) S8#\j>bRt9QMi|۾8nἇﯨ Kְ#sC*sCX~i lš+[njƧ>i_0Tt:1F:%Sq}.g[>HCm Tߘ@Iw͹3 JF|yNUؙ KF*N2acs]H]xչ4ږs{9;0xDZk v|SM*ӡORy=зS%TQ<>f45AAuI:d\ աCKG2|Bj]F0>O<{uirA*Ck+d4+DJ1fP^QǑFC&˼`i 88gV󮓒wT6,W_As9sϦ.jwQj:Ęc)8gfd3#;{(˛fX&0Qd:TA\V}is<´4*UvVZ&g+d$e9KM['d628$qag&@o3MC;q/?YƟL&g}]MRd ]hcof9[nս^gVkG9Q)xiPI [aIzϴ԰Q2+NG}~VwNʨCD7G10_WN>ȌO4'i]p-6r~aΈ#\ -xa#gf3s^MmwM7Uװg5Nh9:HrXT)$"IfYn*><*ޯcĢ5&Rz*fJcYɍ q1$/,kcBPؘkΈ#)P=m)XnN~J-9k+𬵛7hh!:ri!$iQ(3:52ҴHC9e'< MupmB}sF8~wѢF!]܀T] wHH4-@`+FUⰻ@ xmzwQ@P/E+cD(\,ⷸcX@^!p@ .@ B@ B@\  !p@ Q$GQKP+Jp@ .@ @ B@\  B@\  7hQKP+Jp@ .@ @ B@\  B@\  ]T W@\  !p@ .!p@ .@ B@\ jB@\  !p@ . !p@ .@ B@ W#v%@ B@\  !p@\  !p@ .@  jMvo=(%(~ v"TQEooo[-\k${bIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/CasEditor.png0000644000175000017500000022177511665471336030572 0ustar drazzibdrazzibPNG  IHDRL] sRGBbKGD pHYs  tIME ;"tEXtCommentCreated with GIMP on a MacwC IDATxYpWz˭$})-JuK펶q=sfb&<8Gxx~nonnI") ) ľP*y+AIjq"*Tɓ'Ow}x0WyY@k8i=4_5M{Zm8 `EQ|D\*^,N;m2F8/FEA8؆Yȃi *r8(IwLJZq$?,)p~D,+aY a=mki\fe a h [R0(LQ81,$cnAtѨ+kضMFӗ0 Aۀp'{{%ن(xض|>)q֔a& I{0oY,q, Y{mFz>9t_k躎}X6kmmVV[x變mMaئa0u3;NJ|,:'KQW8ɿ>uRȦ O \\F P1K"'/hlK9um΍Cѝߦ9ubP0==iAvI<T4;;˕+WeY$H`Y'N  sNhmm%b~:W^cSir^ʵk8rHݏ+Wd Zw~rƈR 7>>$غu+dny>c~i {_eY\v9AGRpEdYJBEfgguftvv{x|ET*P( cqET*Essz QYdVS\ʐ9u޹i1Og:&FH:E8|2tJ>"=C`XA(tr JO?uǜJj D%,&$BlxEٳ{x<ɓ'Oؾ};XjJP  u4Y?۶pNÈaIT**LW~ r9yy"]-Ww3ghmmEQw|>ύ78|0e{լ>z@.#b6gΜaddW^ynFlWcYERAeb؆x"DQ,˪; ŋ>|rLT0 pkzN}xx?-[*R1z-x yҥK bꢳ˲+Hm i;v젩 YEQo6JqFFFpʓWOY֨NOd*bVQ|89Ṭpnr-ܪ\@x0jLG\@5-*Ҁv5O>3ս4F-MB Yn Z"CPdiaVB"^KϔJ%N> =0Yu>W8=---\t~?=k, 4IR#) ؿ|2hkk̙3E4MCQb1|I2 | bD">J"q4MJ%\Tt${nH&~.\8ypv͖-[(iҚISSDUUdY9sMضmMMMkiJ% CCCe">GRV9}4isNl0W\A$OWW{L&CP,bddp8ѣG3z)H&|\xu瘞!^O?׮]#_<?&uV}]I&\pN8m޽O?>cǎa&lk׮ӃYO8$R~l6˻7ML ΩShiil߾5:ipqؾ};Ǐ'OD(ضeY[LGGgΜnN8AKK mNyI$d2y4!Z[[]uVO?m۵twwc&KKKضiii.,{0mFIRQ'|כMhkkƍX1, X)xj9L*Nq<*B8%H!?mck:>QFLf~? aBaªJX ESW1|F`eq~jFbәg~~)$Z;>L4u,h4JOOxr"T*(Na~?XSVDz,>CmNn_A0 DQAwqVM۶M>ի,--@GG###r9|>Dׯ,ckɭusssb1(LMMիWE˲\k m6Ο?Ooo/9sl6f˖-q5ם`hhN{;vpEN<ɋ/H"`iiD" 333qҥK躎iضZ-ʕ+aYk] ZtwwF)Joӹ\p|>ʕ+,,,000@\wСC\|p8(|>{yxw@mR 뮑H$PUQ}_pEp  lh}GOջ ņF*@Ap#S @(\?hgT( ( 86$T,b3qh<hbL:*1_BDd \LJmGtǃ  Ĺs@UU2t>C҂a8෿-ݻL&GQ"~y$LH$R'NAp ~?m\(0:1‘#G\WI$:8R d~~˲زe Ofjj#G0??ɓ'y'XXXpE< mH$B:X,d2I{{;{4MWDgmJ&DEQHX$N1 z UUy+ Buh44Ji۶{\V n:T*E?>}βuVw,"Q*466=}>S:Dkk+[laǎub@4lȑ#LNN2;;K<wb3g@<grrNz{{9s {#IDss3`p5 J6\.Fo;sKp8};s%d AUq~łf`b>: ].X(8- Y3ԂƚQRDvJˤTAV|=LOK=KFEo;F|tvv( .\@4 `vvQ<>h4Z'kω ~ӟ*۶mӧOs +R X'| VlEגX,bL&T*:$qY"rfgg݅dmŧ~믿iy\r9پ};`е\,m|zT*>|%._L*◿%8pIFFFxG^xw\t`0X k: j 0::A8lٲ";` Jٳg|;flljJkk{Ο?$l߾ߏ8\| .1MN2l_ѣG B[뗜H$hmm yx|ED" Μ99.J8SFVקg?3K$-D,TU2IcYb $}S$%qtX^ hFP,JpDB %oZ1,:/84\. ~BJMyɤ)˲l5Rɵ($IdYdYvCT~Ţ;/ I"qmx<$Is}댌066/(n=jYUU @uWJ%Wr9TUwq-uP(8=D|>V*Wy|٬k9D"5[( a&B-&EQP(V\.Gf|jFVY7J>`0H&qc$GQ2 DAV/~ CWW;YV)HUe2{#jm,//  B+K%W|>|>k57 @ (uGmJUUYmoUd_}],~etEAu*DEn:$WAE ~r6%MEu}OE|K*!(.#aL L:/F‘9 Vν`)T؝‹m˲@uܨ wzuY-''')c-nrֻn-n}s-|l۶{㻵;ۖ<<<\)sI52¿˿&Ww$$1j#IN~ɲf-g~kvQc-v1Ǧ$,{"㾰nq\ O qwxxxxxxxxlZ?/WyQ=<<<<<<<6$I(Fr|uDįs3,V.,$<<q&28af_k8DX,ŋ`q4 :H m/8TU*`M00 M0MsC9=<<<</$۶qiU˾-:xrMY׾Wղn~{t} L&rkqH nB4 poZc,cYp{]ڋhYRﮢOQΏ8hY|>f$y}2==}weO-|D.砊 b<-M7NIhhh nf μ BYw5]8,S,o6e 1M 0ݍWE4äX,J&fu뱑A(n˲ܿ7[N-Iqt]V{xxx|Eq=iEz( ={χWiG'DQ7јcE7y"*͉QambǶXg6`t_C0]BP(DaZ^yAnZ}87Յv@ 6:cdFf)}H5D~$YYwd(˷|˶89y7lsi|< 6}6qN".LK B5neH-XT:K|~k ŷB{SiR.)W~w:$mXײ"jmu ʲ,wVˊ%G0%2[OA0)?[ǟ|`]ݳħqn +{9Z[[µ̒o1hԱmWL__7n@evY 70DΦ ("!EB كc[MAP$۠p[8ثFZ4j"LLf h7-ŵt aS:Dz-$6.߼$)clOgQ D0[>!򪏎]3a(>~'T+x< +{.Ľ(J"IpDQ0 Ξ=Kkk+pA}tb``h4ʉ'K/{7,%ʀ0޺IR}><2X~w]QBu4 aӲV݅iHiYA XqmLàR Kj22U Nۙ++V-I;(򽅊aNOa%Uu~㓌Y(eݯX,- ke ٙKسlow,5>V`怮(J4V+zaY&V[& IRЬ ]+<%IZYgJ' #2cCkb,۶8]׎4FUպcضa|2)b*k~uYѢ +2~M4ηz=<<<<.Nk6h$AEED,r^aX\L`ߏO~Ÿ}۴!Ij_W,//ىa444 ˲W/8y$oyGp&J%>3$I"8SSSevލGeJkLz7AH$HDR ۶h!Mc}M-ԖcL*4Cs$uG)imm8xntaiyF3,iJtE !DL//~۶-UqlIP| aY&(6XY^^ٳd2ٷohtPd 5D*8ZE :uܹs޽{ՐeT2IX$"q'mRYMfE(۶e9\xe) ;wY8李=>ڶm E,ŕgff3g`Y;v젿 ,k$e},@㈅_`-"oJ3g?EaߠkT 21m=}]MM|$ 1??ϥK?]444'|W^abbO?&z)wqm455裏JugEٳgKKKr9r gF4ޣZs=/~ 4McΝ$<W^_رcuF :趈$*OUY4twS,ߚsG ZAdهaDzSW,8w1]ff) 42~qQhnJ1 d,@WKQISC M'q IDATݴ|4@n"UʯO9-X 7}RT*nʶm6u+43@>}QM*f#.PYpG,Ce6rMQTWU5X,F2ZL&?5+qRZ.a:e(+5,:qY6~p,S4뵮n:iba`>Ϊ:B!$J֍86VY)c+?-DXu;O&kV[EqU?(Z;{h#ֵpw(EumQٷs'p F.|F2@3 ,ֵk<͉;[TeVOE:;;yYXX`vv)"D"cOOOsI&''z*/2mmm,--aڵ۷sEz{{9vׯ_gqqK.188ȁ f}9vXn- ["" 7" b"A% @kk+"[,"-b7eYQn:wTEQ$ -&n9) ݢı_x//)Jرc>;+B> EVPYWM}۽_*tAJD0% {kp4 ?XךO)+(H7ʹ'mF dYZ6(!Hoo/ v`EI)U`覍(neD"vڅi466z+|=<<<"57e^q.a6"{immuѣGimmu#:4Z-*(y:;;innRPV<ǫ }w{qnI¸Y "ru|Xv1S'{챻Ӫ-uχ_U**ϵ B±U ,4-Ai]m;6bN۬ebE,A;Ņ,D:H-,4WϠ[&aPP#Q~?ǎ#l.Wcb |9i ;@sbs]k#G,kӑ L$CH2Ϗm[n׻NHۦkmaUqlDtt-k;?U1LQ " V~춳Y}\߿ն 8VEtF۬uJj͂DR%ڶmpl)SB?$sCO/rY~򓟠( vknn78[lann]8766mۮA LOOGpEqHR\vq8w###L&7a K0H9&&&Pe c)TK6"%r N\fYeakZ-膁i:`Q(J+apщE 7Vľ H4nbHGJs371CRF*:;o8HD(b۶m(BTbΝբ(>`0ȁP0룱^zn̗REwDP',$X8')g9Sef6KrRlFc[`. ʹCfZȎrXI>`V_os2Dok c+˕``ou{ ;ဟmBI56# eP(όGj@8vd1pEzj.ںcX7SV$a$ M7QVкm^Be}$ `XMrߑA q%~EX,Oh|>'LDwi=8|; ,hu_ؼF"'ߞ={uw{׾2! web399I&'A`EUpS0;-\bY G_GZ/  ǻZ:+?Z^C jA6gi2>>N>z?IӨ֭[7|k|G_[0L"ƥK,|ǎ}|+3賳wӶm2|%\gHZ p ԉVq3yӲ J"?f)\W{Pam#<<<<<HmΑ+qL{_Ue٘ D0LLAttZhE $000@ɕo(G MQ,t:M\& "k&1Nf BR۾3 6/}jo\eBЦV컋k"V`˲XZZ"1Y; pO@۶)nڽJ>m6Dhhh 0;;K.EQ@ @KK TUBź0(|bvcCֹI^/Ɨ0ƟH3/f}㘦2xY)JضM?~|{A$Pe*+z;in+nܸA2$LnغN~>qbȩS'Ѵ% %-a&LD"j D\r2tu+*,D6L4b>Ç*l##LLjhȑ#RQ_mE UUbaaT*u_Ԅp8& 莊,E0t|eiIvFGƈ$믤q_o0 &ӓ8C[G/ ~t~ZR^(,l2T UUWEoK Յ$I,//iN\ /]?{Oqu>CTٻUoLg(LMep8lzl6$ qlUQ81;9wT*B!o޾rkf6߫/jno :t޹ܛԩSꫮKǝ][ qDQu'L44At;ˁ֩VV8oٹ)Z{6YV],ʅL_Adv=rnw{i'[32b$3OLo8^9 Uî$LDKY=<<<^u"©W$t@8JCć*K끙?l߾+eQ,F|'KKKڵ` xp^gnnn---T*y0FZ[:u~|>*?4D">J].JHos Z[[y'QUEQjrL"\B4M>8P(pi(>={lAkzqla9cK2i N0R\˺pttgݔedxxh$ʾ,,,P,`vv{$a&͌N:봵1001gyH$˗bR)nܸAGGcccE4McTU4i299˗D"۷bB:%FZ:)d(3ij]ҷlf9"]$ۈ7m\zHr 6ǒC1H607NǶ-bf&h#IPMPBTt{MIu 񽗏r'D"y> mL-ϠkSv{a8+nv^u+" /.[L@! 7|08v###444`6M膾y:< L4$j89{|>#϶mۨT*,--͹s~aeIŋ9z(mmmɏ~#8L|>Occ#t={P((Jtvvr ƈF2<<L&YKK sssdY0 \tFn݊$IȲL\ի 011ǎc||qqSSSa&PYv{ejj {?Y8ؖe*LsE4Y1ʶ70>>m>|p8{7VE* JzCQ(/ɮ]XZZP( /PWOMڵkl߾ׯ311AKK m*?ill$333C__T* JMLNN{n'|> )tuu199I:၄M26PW,`p]w6xK]9S'k YXֹr-槮S}L\ؕ3Db  t 47%ЪeF.Ƨv"Og#M Y4Tʺe\@4ހ t"o%lfyaHqfggd2?`nR/"\~qZyI$njIhooGefffH~rr(6eY0 :eB)5&ombߑ?&I&ȥr\vtzrU#hec/#|hC{uy}8C9^$zlYA&y y]$ق'/s^`X^l EAg&˶zX%6a}s_Hs,C[. 9gW_5),oo[_eue_ ĵoڀfD,)TT<ޫ(AJTҚi,y=K$%ʼn%ŏ;yDWOrpEDQء]_ gFD8/:\v/Qoc_==ſsח3ɟk{ya_5μ v 2-hLx5ľ}t:M,Cz='NezzzxMfuFFFBVcH&رYt8Tg}7"O d1ė4Lb1jjjt:Y>XV3=3K:)u!BMZȈ *=.QQ\>8+S Ch$QA,E`v37ч{AQUó0ԂRQI0u^YD5HPhvzKdKA tF"-H c7rOHۓ/8{ #n1ϧiiA"` BX-_mlc Q*X,Yo GvdVYzy=sta**g~~>CCCtwwxػw/S0ڵ9(zшjEJKKF477322:-Z-`0H, RWXrѕ.>`_|y!PՔ011AEE& BgZb;ҡ YJaFqj5ZM*"hPThZb=c4IokZ(tV+JD"rZDaa!fT*%ṙ Ou ƣA *Pv;2Eh ꬣ+{HRPoIz^66O6m0D"{dSAT*mm (b4ؙd"lg2_ӑL&:j5a}Jh4g>`672l @*`0lŲϗx<^lqqAx豺B"MTHt]e}m@ 8$8|㩧rCa$H$Ғl|mP~Z lMYY4Ҍ6g%IP(b46MXJ+5H$ 'DFs yNc2EEEy6Tr0[$FR]|R3o?fZt^lfeeA7dpxo 3O{DbP3wGm||l:rbhTJX,l-'I4P` )XN&ưk=8ʊۋ6mY$@NK|=a/6 *ӸjfɬlԎErVJB8Iw``0`IӲ1sICR6> DIAI 6iL0y~mlc۸7R;o*KeK~#NaV2nn5s.,Z-TJ65$Q@6*n^l7Ɵ,Ӊv#oKt:BQl$Q; $LF.T B!2ݩ;_xi%}}'=>gG)c!.*>1]1? ^'_ }Y=?8&ɰzGAբhPղsE$ tGn&#XP]]Mmm dQ5~K9?{]*29;M Vý`Pb6XZZbjjd2III 8)..LMMQWWP2L0TUUN<)gY[[Tϯj)((`jj!AG֮HӧOs)^~e._=m)O_F9w܆Oy)~'u{Lv<5!27ULbXȜnGEH$T*N'h-%^sl6c4R׹|C= }}}LIIɧ2{={=MaddkxHnyXYY:|:,byƇ').SZlDX$hvn͛7YXXرcJ%8pA8t p~?~:=ɓ!ׯ_gxxx<Α#GhmmKKKtttiiiׯ   ØL&:Daa!W\vSRR¡Ctttt011dȑ#$ 'Nl2t}>.\%Ibnn4 p 6W^o|T*J%\|Y> @OOl62FF(//K}}={<^$111 466Lww7 Fy'daiiiyI8x .˗/N :t eIʇX]]eddC $D[[XXXG!"P#GPSSիWqݔr!4.]9:D<ڵk166$I-F8r~%IܸqN8TX__p}b2E|vS]%x] B,F@GƺJ,-'`@c#:1LPѕamA0q |I(d6ʏD(((b`Zpr,xWDرc$H&$7:>cAd9O8-M8$hQ2 NQ9]\\7ޠ2 DQeO sfen- K25ѤdԠQD012y,y_`qq^Btvv<~QYXX OGG^w{f=rS'Oduu˗byzzw}|b9ϥKd2oM(BVsix pe&&&8y,%߫ݻwcZ BaVl8ލ{=<Ϧ x7h4l6X^^??㬬 O|KBd2ɕ+Wd'O̯~+b$|oZM^^111h䣏>ڵkx^}]8y$h |qRr_FQΞ=Kww7ccc\xI]]?)vAii)Dw}Q)**bxxd2ɵkטԻ_SSõkfV9s ׯ_d2mrߍ"@L$R ȬSiP)_$j5* +DF&NpAjGrm}w|>]믿G}ĥKP*\.qkUt74rM`+++tuua4Cry横Mv… \|^FFFx1ͨT*y |ANckkkb1~?dӧOq\?KGGW^l67y%I"DdAxTD&v>wݭEq'8`T4B,"HňB#"lsލ{^xbz)vݻy饗6}*#NKR4TpaPICDCadmf]&|*TMNwޡgϲ4\pSNmϮO<:Ğ={z9:cǎ Jss3tuuI:&??ÇS]]-{GGG1aZ dVǃ(ٳGހf3ȑ#27PTTTTl8ݪT*׾FAA&C+{m B̐GII z9y$$k.H8Nrz/=+++8pJ*BT?Oee%~99tЖ^޽{ٵkR)JJJ8~89 Yd2ICC*GPPTTDII p)..2N8!?zq8aZ!^* "+++,,,~v;drxy&v풅n=ؚ"Dy|䩧BTʩ]:8 ((Bnźg'Jp)&t^ ]z% 5߮n@ pKZZZػw=#''h(**fh$ Nv9o-$a[Ww2L"\rV~uu5~zϽCSSS8N4 fyK?ш(;w zw,J% 1;;KUU$1::,o>Vl`itRZZRի:ujjjh4X,*a۩vSVVVp`ʞmAfQ[[f7jIhjj`0055޽{X,$f&{t'*LQTDQ L)ȳZ/FA033#SiZ\.z ٘0 VK"Z\.&#{~~Qj5---8NΟ?O:|+geqqp8LQQT*n7tLOOD())l6SVV&UWWo äi Gii!z"5 HX,&&9bO^^=&IfoCTR^^V% 픔 455HUUf 9dzuT*{쑍=Y4'NtnӬ~{kZJJJعs'.FjjjH$,..F^gii*۩d2cΝrH$d;w eee߿4 +++ձsNP(SOQ]]B`mm_]d˅Z# .022jnGaIIXcmkTWO^+'hH?cm9[L< :m S}5iNeG=Օ|RiSYYIMM UUUT*BT2v" !I%%%5k8g=wl[աR$I\.(288H8fǎ۷r~?GZOSSFX,NB b 466$ ,㖔PYY)ݻWΩd2JUU,-- q8[3IAA* ~ÇSWWB?su:??p88 q:R__O,seee9FV+ߝ5tٻ( &GX,|>ySgfuuD"A8311!wb``ew9׵8M!do'kv\㑑&''p8,Vu(Y$IBa۷t@&DI aZ(*P(\/"BvO+<OBh N7Qe޾xWWHXzw&ەUv*35Ay ={V^_|Enܸ ?񏙜7h4k[O,EFauu:Y>mP>5Q6qG6@Ej5kkk<쳲/l8=#ILFް|^lx<ˁUfrxW:g@E{eG>?r]}DQD{ߍpEt:waffsm:}wW-AVR[): P)7<$( BA.G;}wO>KieAVV 3%R^ķ2szJJJra2Njkk^Iĕ+Whiiݵkhll䴼~:TUUjjj69zzz())d-\D?;;+l6-@"~?j(2(I,q\QgIo 1_rVb߾}rE(vx駱lȞCI61Bŝӹ9|P(6 Dv乲^}A mGan'L{;Oq: 9#TGzZ;I(j\sSnOۗ$AG9o~ϭ]{}tf'CEY#[![8z099yϿ{ޜBv笣++ r'mX' >tn/ OOmQAvP(3} P*H;wgJrI\Ɨ摉:"cc4?7b+3 66#gM]]]μ;QPP@^^ަaMum{މy+r???Kv&!JT`t^4#&Sɤ]BLPC>m$gFټm|yL&șR),-Bn7čD" "IuV߸qcX$`0 2Oq:iYFB\.צwyV놅%oEEEAڵ ^,! Q[[>Oh-=(277ba]>ۊ~X]]y^Ȧ|!;/X__n˵++$ >|pNCxl:ض? 6?(v!//ニV0͟8n4q?p8$ %Jt*Zy(G8ID(N $ӹ/kkk|[R)}V$ɇs6/J~! u)^{5_b;o&(""/^ܹstwwx8wy88<Û `0(DQGY3glPibGY/",Ν{}u2>`hhSKY\gΜafff{ƟT*fպXG~8|(_vRn`1jQȠ$MMeYOg,H&ܸq8x d0 X,٨y033͛7t=z͛7l6s14(JA&''d2Igg'mmmmf<$333l6< s(Pjn7fĄ~xbb&jkk9pcccxMcq61jd)n޼ɱcؿ?& I0 B!c6a"|'NTWWSWWs5;;K XZZ5l6fnnN.q:ٳyx< `{QaϞ=2Ɲ@^^^@QQw䕻S[ѰgDQdhhݻwhD3ٳZ㲺<ܹj===r(q hZgƝ hoo'//O BS[[ztRSS$Lۋ르Fػw<+B'"rnÇYZZRĄާOl6P(8rHN]A6e);\$׹qr[g2(//gΝ,..ru:D[[&2 333*7n Lgd~~bX[[㣏>n#Ny8nݻb׮]2wzMM GV|ܳgL)-u:QTTVשnÇ twwchkkۦR6d;7ÕU$ 40Hd:Vo@oGR$qvCOkowyf3?ENVhcc#>@E2b W\a~~Ǐ& ۍ"se.n޼F$IQ, 2g\99``bbBFsQQQAaa!|iJJJ\~]6~,Yr100ĞP(dy虙ynooG.]ʙ.,,_`0o|)L&l660-̦D @"v82_FJrS1$IxhllDqY1L,,,^{M6y饗r2<<,s!TWWCqq&KN<* Ç|2( ;o&t:tgb67|S~ω ^z%N> tZ6~ߐH$AoVvmm>$SSS<ӼFb~~>>($G&''Y\\ J{"!z*h4xY[[QeZMSSSNog*brr)HXV>#fggd2 QRRµk׸y&GiOLL;`QTD"Μ9?N^^N^`jjIhiiAPp)( 9U$8|7?99ɋ/G}*L^ҩ)fggijjB399III 8YV=~dXO<GP(X^^FZZZxeD"$dl\x H&cuugo++F"jٳ`͇~Hqq1Νczz56?(,lMD*QBVlno=>O?sfgg~_G?--- />oTUUo`Xs8TVVrq~ tŲ݆E6fW_}Aֆ[%)J72ak׮188Ȏ;H&ꩧhjj?)>VˡC0ͼ뛾'+pa?I&˿W_Yi x̫9z(3$9אaR/JREt:M,n0_W(V%sd./_y "Xp Lzo+NihhǏ$ 3޽~$hۿ#`Z#J0sN|I1( w2JRΎw'Y&Ivɑ#GhooGR] dF!^xC0ܹs|_n)vy"H|Ɨ՟d`ȅv,#XrYAog+D%FRF"?)oFf'N033EEE8^|-嶱Yׯ G*X,(˲rrQVV&+e)ѣT*2 2 vii)455h6яeURiv;j^lޒnQcXX,hX\\$ bjaCѩT^ytTTTRV_9(ee%x@ {8(kkkT*ַ%477J(//gaaaK22{HFii7+s_,#Ȫjn$dթJKKgL&4 . N7+ڒ0 qyeýYQltEE~A侔$ N' q $ b0tv eahiir.jFGGbJAT*Nge||3gPVVƑ#G[pݎV 7N;vV1L~jmm۷SSSC]]eƍl6w^N8֭[fvE[[, Vb\.ZlܸǏR__xݓd:~3hnnֲ7opR=:2|>x<<F>#>S ~2~mDZ[[tFQfPWWҥK  P?O~Bqq1---| g}Q,Y0\e˖ب=m޼yzNÇSXXȎ;n ,Y,oiiPUUn'iSW6a;֭[Yv-ɓZf VK.`bٴ9n[+G騨BmX~=tuui%F O'|BWW8piVXASS{Ow3yƙK.كbaՔrJ>N]]݂F# ۷oNuu5}.&f?СC\yw@'|*;aӦMt:^/Yn h~veΝ(Bcc/ &e˖ U>l69~8=EEEnt:FIөNQEi#7PYYɾ}2۷D"Auu5Zzǎ7:G `t:-[FII ֭c|رf.]ʑ#GcѢE9r|KKKTNn:N:baj1f꾥66ĭ;h.^ḩ3sUS[dY|>8G810tL.Aj6Y[LYSIv;o&H~+{) IDATUUUf6oL,cݔO_|k/[1NSRR֭[X,3FaZV46\.G4%NcZ1qm:\F@%NVbW^_r9mv3aXX,(rZH2)Zh4ސL-N9==Ȉ0E=H5_u(emZe +WHg2 ҙ ( Sxxx2qɐdLauXnMNNN?WUT*M 8h Ww27H$2R)m7Aܾ&'')((+CѱX MRڵ+W~A:뵩'N111#<ѣG9r&gjFjOû| =ݮ J >YC𳃴?w< >jK ѡ-ĹDii)W\fvlv`{g{޼C_s "Ms{! aÆٝDQf:u=/3t:M__F@ @6ڵkxQQb .PYY3Iy5f3׮]# bd2 L&q\7͉UuAŋYt)f~ &`0-'Nz*\ZL& DG^^dRK>K0 R)z{{p‚r?//Qn``@6hi!c4ϟjhlK8zM0vL6KG:o/Fq<|E(~}@$po# ~ 8Vj#Lu:ɳy}浉 dkdYd*(fy5xr4q&! (pX[STT%%%Fd={PSS--Ng˖-<#r9>:::|[R}]p\ZիWkIܹSK8qcǎrXz5ܹNEa]?ZaSTd}с`裏Exxg(**Gܹs w^|#GH&LLLK/Fٳg矿)s; Df_tY;0b5.70WpOZOƺZ=˅Rl[@8qu`OOro/˫ØV+O_GNb"\v;r,݃xhZ"T,Fxh*͚\|~:}YRncO~rSdY8O<~{+`ԩSva:tH{Q;Fo~(ccc455rx/Dt:MWW׼pg|>(7o{2==ͫU|뭷{!}V+@GyÇsyE͛7oH$(((Rͽ;ww}D^^>(}[l!??wyG}V._(444țoU1_iVv;H+V099[oۿ[٣S^r%= t:͡C(..&K/1==ͮ]MMMx^N֮]KuuٹY", 7o&s TWWSOq 8ӣe7Z[Ǯw-VSt&C0}#8 :ab:LV+9EG:$K™LFˇ*&诩Rill$ oΝ;ٰa###\xe˖155Ŏ;8x`?__*,uttH$2< l2^/L|y~ӧ`Ŋ\pk׮ Q#29j7Zٶf Ξ!<8ȳ7K=ݐa2) ,)+T&Swtd')c$R)g::) y>CCLH \嘚&Pr18:ʇ'NU\y.˗/H$B.#1<\O.\@SSk׮ĉZ Xd X,b444P\\֭[9q;v ī ݻW+}D"vJJJUԲ2x ^{5>|`0}g*++I&?+VٰaüǓF#eeexbEիW_vޭ].\Mnhιs|2z{7xCKAXr #Oy^JJJb4ٷoW^eҥ?^+Ӄapp+Wt;K6X,Ə~#x , ^2>>8I$%%%>P{L^aa!?bh ~h=r?_*V_(//'0391 (f̴f7^ _}d8z(CCC8N6nxGis;~X,:ŋyq\,_ .h)V+UUU_B<n NJ}`^Ɋ+xi\`0 M>(/^رce$x\sjW5i6eڵn9B{{;>,fJJKKlCyyyi75!??_(..f͚5Z1>nc<e]}=G.d4,&3yJ,t: }>|yy)1,*.&Ic/5NmkVƆtQ+}}\\GV FXUSjaQq?bKNcc#.KS3z-qN'۶mŋ=z>^|Ez=׮]A2_ȹv?/nK;ݾg2\Boo/555TTTx'!O1yLc:cI%Gk}199? YV\.D1F#Iss3L^ G-zs8tEEETUUiչ~˯~+L|r~mmz*),,3gݭ%x<[?8pu؈^}Ν;iootRXXș3ghkk Dx<z*7d%/!rb 6o5аXYYə3g~Fss NVo8pOMMMNEEԆBMMQ,C,&۠)\ȅ GQVP#G) ٸt)uF) dkf Ӊ03f6k`BeQmn?Nq:H\wzL*\iv[gQ^^βe˴*jP^x B^ի8p~X Å ظq#mmmpZvBx7z`^-[YYÇ'W\_'Lj````O>m۶b .]DKK nR6lo[TTTuV ÌRQQ(Ge|||zy:::=T+Lww7H*B^W+rktEE}mmm455is}vinn!jkkL$022Bee%WfllL~8N8\rE lEfyXvՇ-F#6lO?*++ TWWkYՊPPPo\.mjڣJϧd29s.fӟDSS_'N388( !| }aAꨨ``p_<ŤΌnb&8=~ :TSO>E&E{{;r9s1Xh?W^d2M6voAp7*9NѨ6|xHRklذZm~j"\.ʼÝlͦծw8x<z=㌎jFFFi:tHYWW7oփt:Mww7:ͦcccZ ispJχ(L&~?\vmvɤwK<' dm#h[ɮ]g۶m L&Coo/d@ Us\i I&ZMח.q }>ƣQ,&fѩ)n789nK$iq|4}׮a(,$34Dp9陝jm*C(M&FFHRxNyyLNO346ziaxlh<(z}MFbr߸<rZl~wd2IWW6Z]ḛHee6W `ZIڱ2߾Lj|7~PRR ѧR)amzNjnEETp8L.ӊNQz2 ===$I|>f$ ~VN=o^/^A<m{(Z[Ϸ/;/gKRٳ6 q8qH$=ޗLNNr|d2i?d#Ja zI&bWtwwL&QB8F<p{RTTēO> oرX,dY:::,}+wbzM0N󶅖 ž|ŸٽDB˿qɥaփfeഛE,AU.R򨬬ߦP[-=88H&2jjjZ[Ml۩^ CꍽQF7 IDAT{]ІgY'T`0PRR,<@yyMvo-S{Xgo`i- 7|_{ֶ]}d2ikVs?k`` Xv-V] >Hm+o~˟Omj6S6'vl\+`MtY,3\?p\xnڗVۥܢI[Rp fobюٟ_{'ZQ^xj_q{KxyfjkkoF NJzwaa Jj9=sM<7wZDc|rϟ;2PVV绡m-Mm=;z06swqde5Bo ;wƍ߳ժyjU<\.\_hQ599y*шj yϋ/E!RB((ja1PH1QOة)x']v?_~yfnػw/X}{؄wnC{\$ w~t?k_d[ntуڗ۵YH+w·޻y}~۷q1/r߭m2ׇնj!}^Ww ͛7p8nߨ(v`*??{&fimmeɒ% ʕ+%\AN# QQQԜZwS2H0<5M]`xd7oD]mzj\gxxX,bh4RTTŋ)..?f*FmܸŋKo~O 9&t}]ZB 9nh_bZyOgg'Z2?hkb28}4hȎ;v"Hj*v;w֮]۹|2HF#/?φ ŋ|>6oΝ#Jxزe,ذa Wg[T^׆6DxQ#LL/ES/ҥK JKKzGaa!O>$pAKURR"yӁB|}t:ͩS" rq~?ӟ(++#(//gΝlٲV-ZĩSPΝ;y呑SO=}/q n7| ?d2(ٳ 6pQ/^|Ӵ)- gL,4zqQY^N2`H͆)axr< ݬj:EQXloI0\uΘW!ccc9rDGss3~ 6000@ggVGˌSO=O>!a6OgϞ%LrNVIQ-=<66F:f۶mڂrIUU;v?9ŷ(9Oj ?ٌHR15>gyLs[}-BoK.ٶmDwygϢ0L7fY[p89sKaa!VKWW>}e˖a2bnᰖtb49vpP(eC;gV{[,X nYvY!^v۷rJNtjz"f p\>|.lقcݺu hŠ$ d26l@$2UUU166ٳg)--e֭k)֭[wWUop<7 ׄB!)z膯:e`㭦l6-\~VLbŊEV:Ge˖-Z)VS !B,vy&5ߩjf_ vᶽ_m X!ߒ92IrĒxJ`!B' 3s{.uEtD"jEiA2d-nV Br } lfvKaQ)!N<3b1>Jaaї S)>;u̲+oQ'᮫ t )\ %AB!9EQ0-LL12ԯpQ\R-6l|% Kõa(&/Eaaϡ.'J$.Z'ff,"c*159 Kؼd;EǕK16abb^5u7 !BsSVQx EQ(,.,S'\aMZ> KgZٽ(ч"bU45 i,|7TUUM}'b۩]LwwOƵ18ϹixUkw q"mg)&''IS  pJJB\O ed!BܟC| 5&2,`IQf4nG0E3i zt:.,2"Hf[e&y1?d;q\<$IK@Z+8r},!qq`f1]ٌ!pL+}|>(-+'NsJ;xnǏPV^I ˗x?l2Kۍd٦:t2X`!Bx7@xIoD2faw8fWbوNM e-nGd"`HXV~yFK( T^xyfڅbjiVq8if3O?=bBnJoo/[4559tH__nW\ JbDl6ۉ e~mĉ\ 6k.gJDAy!BP(OfݺupIQe˖#p8|>t:͑#G0L?>tt.z{{I$ P[[˱cǘdxxl6XH$B*X,Ƈ~`Wʎ{HOB!V\.Lu ۿ[Z[[d2AL&+^'ň㔕|rJJJne˖3ioo'NfTiT NG*"D0 <fyvqpGW\vFzBbBnbp\L3y|=łѣdΞ=KWWgfN'J~~>A~_p)VXAAAp$ ROfppٌgݺusUd=`'X!_+F^z ?O8N~i<6P(ċ/H >Ô+ׇjaO?M&h4R^^Ώ~#O:*F#6 N-›L(W_ N'%B!l6VI@{Xwii)6!//<EvTpht,ZMV{S||>kJmmMCH,Botҙu|e>w?ds9ҙLV`!B܏3ӉYenp =G"$xJ`!B@xn|H$Fozhpv^`_K4B!j!N:J<>@`~%<PQil&N RIe&N#N( F\.K*" u:dRF !R_~]H$0<37k#ryឝt] KmTԲqÜ:y'b6hl^GAa1~@<ǟDvH`!BF*\n/fE8\ox}9tL&Ù3~)}}=$q7Jx^-[AeU5Ǐfb|-VB`!B Vb4UR\RMS0TTVX,XVjjSPX5t:v#ÔWTQVQ(hr֒" n !BqzBUdYEWw;ZH@eLOG)d6@6a:vۃ^gz>ܳx}:yl6(eWQPXO>#沬[ #faCX,Vix!AB!:`fٶCZQQYEYy֛p r9t%![T|CoSzjH Bq?ݙ,^` ͜ پ.X X!%谛2ញfX-nVI,B@uSiIRvPYYqe}eS X!_+L?Ϝ>}d2^ڵk9rIC[ X!_+W\O?_p8oc qi, ?0?)F#.~6l؀jСC$ B^Le!kl6KCC:ژfjj 9vfѣGtΝw%oN8رc <]]]=z\.'-AB!ăAדfIRr9z@ `˖-000իW$011^[vYf \vad2a %B!xpp88x ]]]\p+V`6I$a&''q\8p!<CCCX,z=zٌ^'Ns9xhD73TCA[I,B$@w dX< !Bo B!B!BH,B!B!BH,B!B!B<$OB!:EE޵4B!ͤ`J[+bm[! X!AS+:AHeNB!=HH!B B! X!B B! X!B B! X!BB!]IP 9i{$K*Ʒo+ BqD:WYH!'cZ B!: !B B! X!B B! X!B B! X!BB!]g' &i;k+=$B!Ľ(`3+,ʤQjmE X!/VU^o_i/N !B B! X!B B! X!B B! X!B B!]B&Gr6c1'AB!SMx=O0$ %1*)AB!ln8q4?C|,L$"EуqrRW+UIͪ]{ۭZU+5ĕ$,9,k9H8A3 RCEEŵ$>}\ !BG$B!B`!B!$ B!B`!B!$ B!B`!B!$ B!w"!fB!ə~+W.#1ut0ʒ !>5pd^TݥHoK[q)B!IB!$B!BH,B!$B!BH,B!$B!BH,B!D6B!]W1@:{İʆJojJ,Bql8PXܻ$زaܭcJ,B!#IB!$X!BIB!$X!BIB!$X!BIB!xfB! .jgTe9ۈ*IB!E[!X+yB^V :T$ B!JE^V"B!#IB!$X!BIB!$X!BIB!$X!B,Bv =\ڢ$B!/ Z`>Lp(T*9cU$r0MS!Xu.dl+^m>'y$ƷuQ&I#$ϳ$BqGEA4Tuyڐay`Z2".IBQ88|5EupB!$$B!8!.BqGl4$X I,Y%A6W!לCd$X#W .+1ut0ʒ?2lۖ.!H.2|TK}PIנ_4QX᫚K|B+K"qHf2V/$$k%r%!_,i'{)ʾ% !x@ Wp8,{'$B!?zj[ZfYr^ꕑ,#0 466ǡZDP>%MJ8& iC!I577I'v@Xdlt)lJ<_ p2{V&L/*}>cvv|>i|`u.J3=n"zje]'JR?I_ݮTU|>O>'R(B446r26>'$an.O*B!P($}jQN (5u\.wM8P6yT-(`I7u$ ~8Oƍ9q(oߏX(Ew).M_b]  033|tttsϦM(466ǯI^-رcDT+?P(D6e֭On~r۹HMNgggXH'Xn)җV+ݫԶg`;rNڊ*6LP]U1ՏRUU{O޽{y w|̺x*&Ng/Νرcnz{{ٲe .y>c }}}$ lڴP(D>ŋA*CCCXKKKHQ%^,D;5t!1;aX-mJ;-8)EEW1Mrhj8'bԮ1 p<^M8۟ :zd ɹqGFUU4Mq$:uL&CPZ~x _Ǐ筷ޢZ2>>|@TbqqqfP(fT** 3}j~BFIض-bY&i\jOWg}myr9b˩y - GTTf2L̥]XIJu@C6.8's3֗cZ8Wy^zxkCs/0RHϱ;F'ԇ~ȁ}4M:uRm__,--Տ?r1eqq>#J\gfggjrL2q0 ~J,ciiL&sGW.O)+Ya]?adWmKS,,RRѩ: E&R~Ǻn)mcV\HLFj88E\&5?9\+P(QT@UpkG tuuqEx <.]0 FFFe||ǏMcc#uV/}K;w6JDl6믿iB!4 |>[U+fZ3lʋhQ ~w@wd򚻆apz.E BcIa, )_-؊xC! tAA-ܡMOؖEg)#ˬpP8ε}*Ngg'GwAQT*\xŇ~H\M6i7oO>aǎI2dqq^oMkk+H\pg|_~j#tO)B9.OOto'Fe*ǓiƪPw8e+̺d JK6Wݯ( >۶)/eq]5mOc EBH,$ضm^>*eA&3񩠨:$ z_dT EQؼys}9t]>cdd_|z|ivӧy'333ç~J*0D"*St%ؾr8˅+UbR8j0 y=]EIT1Mlu9sljUmY7v ]Se&D0FwOmJmĉ|(s^ӃZ)lXOiq(eNbai qߤ0 2ea_UoJM0$Xܗ$qB/\ep˲/-Q-QlW.M4D#o}-]8v yCr!a8WڦMx1MRT,t;u_k} ??{npgrشi>EQx顿_|rاmLk ? MؚXmqavEtv:_T3PҾU(9HDaP5۶͞ ^W+7Bk Mi̹9=ʼnؖ]R^;ĩSLXfiOS~ajzݺ\.N>͏~#.ktuu^Ikk+[9<?H{{-'Fkb.KF6rq7[sT یW=6q^/ޅ4A U]~f0`8aTq{zb]*QU&t'_z7crUtfO|FFyY?wwٽ{uT=099~Z[[yinnZZZ[l?TOh|IJhdYn뫸,ε\.GRKz ǵK(NuQRmz_j>rTnOEXeX4*vB`qϒHNC07vፏh UQ0 ?@"^{zzz9666\;)_}Ui6k^}˵ms+xDrR'`41?DliC<ދWLě"|2 פֿ 7Uv}P'cgm( T<>¡.~L0$xeM՚r>iv_QUz?x<lX,FKKK~#MMM\.d=n<>_?c~D"ѭj-iƚq+mh{eAlv 㫯 ,߿B`@$µ,_.m߁b;xP*m-G_f;V]n|'מ gffI~B mmou]w|JmNOW*Bg,7Y|qН[~itvt> \|K. hll$ ʖPjm뢵z @J}g~v[GmpIomK$OV uozܝɺDQHR5WjHi^s~B~?C}jsUUp*"L:HDF,놻>'W RrkE*m:Gq{S'5...2==- C0e:OݏKGgg'mDZ%JQ*;R*N*TL-ۋmrMhll|w`666Lwq_ ڎSypXvwܧd0BU!RDX\aKLnɶm|>n.O]va >]β,BEH,p8L[[]1;;KCCU6VX<+ dYۥq\e~~|>E"UczzzZ\\R& ^'$ 0 \ry}Rhӣې].* j^Y(us+ gΜh4ģTPmQKkOk@B!2K7:W(0B~B mQUUuTM$XH,/۶1 ~ol (Qlٲ塺i6ir)|t??CwG?~~^ZZ⭷^ogtbe[o~p=7n'r̅ ~hn V1 #G066w*?Oٵkׯy~m^ {hێeYҧ$/"3L2NP(D>痿%m60 044(_%w\.uV;F__Ӝ?N8ǎCUUvEgg{Ӳ,LӤ54~46m7$088ȺurdZ255Ů]8x 333s58i {vbZ7=AP`h $ >~?;we6mD:? q 6nٳg$8~8^{$4M"̐dXXXq~S*زe HB@:fllM61==]Nbkd2-S|T*R/|+Fކ5:Rcir~e8s  ^~e|+_~2 'N```~?vDM6qi&&&pK/~NءP~9BKK @a~~ԗ*D"*ohkk?$ 2==M[[ۚO7kCa`N" }v>S.]Zs9|07n^<|1caY\IӸn>#Bttt\#\X>yAUUfff$H8[ZZ@f[ TUI$ز7nqMxzLNN`zzx<۷0dXK/D<ȼ^/=|/_:3Z4\.W}[R6<z>@3gٶm|R)zzz[˲4U1W]v( ϫG}lڴl6什FCTbϞ=$^zvB/2~!/_&?8.GSS7n$NimmEuy0M vIgg'7oT*q%, -~\&q>5q$clrىa[N"fLOO:d&''4HLӬX\JQlFUUǹiA}m}r Hdo+>:٠T*('iriR,e||h4J,[uMڭ fG~R{l-)q|2`ciiښSLJBkkt$ ,baa]oqr, V_}u):B!]a&~Q<e{מ)oc~L&뷷k+$F%۹7S.u`jj 4W}n.? )$2<y>Sܹs {СC,--Q*x㭷"L8SLӤT*aYGqvٳg9{,ٳeB\t9Z[[]YS0\~|"Z!I~)W`!B$)@Z-i. hW=kFy'''?~>3;ȑ#LNNT*EP8q֯_ɓ't qinnO?bHkk+477sQ&''y<<wGX$JgG[ZZ?9qqP{Q>\]XXcjjp?"hvHwmn,bnnݒq<q%,cT^`CAf$X!5YmP YN1DܔNg7cYbffIFGG9{,^ 6{nLӤP(ž={ذatt:M `ݨJ"  Fx<?~L&ql=Au\+|_cll`0Hkk+=a//x^Z[[ql6~h4J$app|>OTZ# FTzdkkAfWG ÚQ~K{&K0;yۉC!&pg{{;n.__ ;|{-y_KR q0'NMyvO2YZZ?ZڊmیsY>LWW^iaÆ 8ip\.zUPT8qD}]Rg### xw?s\.% ۷oMgll|>R|`.sss=r?~.ochw *<ӿ#o~ڵm۶x>}H$SOSO=Ess3`EQf~~ l혦' J:ub޽{$s!2{%0z9BP`dd'`|zzzBUUx 7ɱc' '=SB;6B&L7y ~s Uhz9G#~o+4v$rȕj ue\$xYP6 WXU V %^b@PUÑ>a9&OIv>>3f/:\oD455TX,vO>$8/i'/0<Ulll$'9y ضy5itvv޵ _$wUۜWJERH,B{X,F}"~_R&r %W.fffk9_M`!BU@XI*+|V*}}̿z=v G,'K|T~e&ש+xV !2 0VNT1Y, 48uGa.9G0)OV_kdYeR*x$ sϡip577O~oF^0Uk% B!]8ibmc6aى_ݻwOmBu&'',--fD"`YgϞnݺU~YeZ$ >C}Y:::T*_5lڴP(Dss3Dt:8rɉI줭m/v6(I瑝2j .qK,T $7(]rWu%y^]6Bő>R[)V&c+$ ,@ ! Nss3կHӴrA(\.׿ufff8z(/}Klݺ\jqtx^=J4ŶmN>Mss3G%HꫯOO8;y *HdM4M ~hWZ*xt[|Q(H UcwJmo#]_z%ice( 8qh4J$AuyWȉ'8~8n\.Ï)J*?GG{n4Mȑ#|Gy, .'e&''IRk~$B!oj[I|1i|ݿcttq(\."@X,ݻinn0ƾ6A+ 7|^{+;aطo]]]k>$IB! ˅wԎQv^/ … '?AuqBo6LWW#Z$/IӄB!ٳtttm6=͛q a9z(Xh4Jww| C$ B!]MN4~|*|h4c=FCC@{/xhhh m6l?\..b6@@ Q, B\x'|4Mill\.D"5?8 !ZD6 \;M3 /===x<o x}->5n7ضc=0@[NCCC۶% B!K<4\Xg~‘Fr,|@0\2!N6DT\)% ^lۡjµe?,jH<`9 NJme%^W8 t0-GJmŹUŶgm߰eX9|A/!r<.+=A,c&q{ܬK:!D.S,T|ȇfa.ж~>ӓTJUp{u&π\-=~$y=tkQ pl'g)c1D0oYR n$Brg lwN2vzg@ˣxnz:xdY^>4M!2-FN#hH,;'fq&.̰!FON0qn< M!{vCsi HO=I,x.s**Q>1TUe!a~Kv9L$Tdn*Q6/H,[K4‰Kz8-ds4D|05v?FTIPR6HQ.V-DILӢ\0Db0rbHK#% _ )>8 Y^3x\0y~bfrRJ  i ֵ379϶}[9"Ma^?bɩ4MX'>b(݄UkG!|>1QL87[.T,b :%-1zrdg^CTű̪Q5LP$C(`~o#p8sSiTM%5@\f$3nz6try,TG'5ؖM~iTM/**{VSi\JO0S3g>tNS[ӰXH.ѽu4, d$<*.nSTۼVvރtb08ǥsSlxUSp"\ ةIf'8KamRRȕ*x!{퍫HB!Z-lmۮoiڊ(1|~7f R.Vgr)?%ɳ̀ۅ(q:m.ݣ~{ILΣ.?=8.p8?Cc$ȹԍUUFݟ/ USijms][=i$X!+ |bo\8it B(aSOc3l9;< v[ǩ!fg.K&sxO6d׆ Džٱv-j#م ,rmsdp)Xo|0`E!z/؇_1EUeg?w`#TCGc dzŸrp!fmG;G'O?8G*U'mi'O?K&dX|0{6mTrmrVӋ wbPМR(W?G4RL(.{F>dZ;G.=R:{7oKO"nXĶ,)U*Ak׸2>ο?%Ő 56RLOɓ,kuik]>57ؘNVFA.%z>k%1s}HFbSOF1YuLx5 2Qhqn{Μ>Evlajl ^5\T~%S6Ym:oߎ,w?1tBB.bK_o;ƥQzZl4K cX|4e32m96ofSO7lJuY\dtzsdpS/' 4R{xg]Ô ON2[<>FZ%C. g,P.JIR!Hb&Z$Q 28AȲxzV.`&p)%M 3˫hϖOi9v<͹D4q\N5M4MOA&9g)gxb~b G$:nHddjL<Εq8!ˢ!&H21?TjJH(GPPjWZr4ӄn]UM)ffx1Z[ٱv-FFx!3^ nvX|leQ@)ɥRRcoK4={8q'.J\ŐOϟ1ZmSVQJH*?>L6$ej[G?eߖ-$c16p}j/_%x$¹aDJFRaTH)yrzk'X5(46RLF'i= ?!NBC[7#(o+iٷu+o;Ʊ ^X;$+ǵ7ixׇR09?R%Jh|<4 BEqy N_B"Ӥ1J%(U.-F9zkڈE"54M$ޢPŽ*JD;C+q=&?:9yOb׆ OL~Kbt\l2K'8x$ !BbiHR;;jj䓳oof_t<~cĆIci"rqD$Do.%NBw"6!I,[0$@mTP[-ˋrz$_ A!s$6cIF¥m::M!m3gY<ұωv+L4F$}P[I=S<_*ccƧHz +eOi?ęfݏyzpo'~;30/b4ov?\OQ{w\(; O>w5 U;bvB:UWJ#w~\Ahr3.Nm{3=$B{q3o::1xK2'TCRxpg+ٽ;)⧟# Ķ DۙyC\!m{ڹKx2~Bda1DyWqgy V6E|Zfw@?CTxK0MR;P/P\tvIRw=&gpfhxe?s!)jӳZYaY690 ^܋a۸3;Z0#/H"^9 ΦAc+՛oa/̽Bhgf8X?4M4M/$a$}.lKm~$caBIM"m4F'!D iDtjʓغi[̼<&-xRPK#m03)-2&o'FX:>Hm|KԦf(:ΣS_gRq],`"8ӳ5wnٷLϮbD#W,gbiYHuj{ 5Andէy 0o<>z&X4MӴБt4ȆJ@EX s]6k 75./2+3BT..a&TDz= w`dr}+xKb?zHW. g.zr~|3ˆE1QX܋X<SSx_@CT^'y-¶N83zB7'H'hAYӯW(aeSpoݻ'΢z}qxѵ{kiv_XRaL &v&GwwA%*UyMy\FƢ"Vs,}vf9C$Ѻ<(2)b55{~7G?G>[)HH\ y w~ # ׉D1gJ&(]r\|Hg+4vc%/^%߃0sC`MۚԀݐϰGzR7#mW44Ր%uf"NؙvC?f*/n5$LjGuii! ;͙ 'vt)%MMn]J$ɜDښ 4$|nc+˅ٕB0hw#{!%}Ofz|koX<ח'!}ʿ÷E'i}0y|v9Ϊq"EvYqvIOQq} /Y//X;߰$hIiiRP)|FG|/XjtDOSB13@Sw,Pv~w\+\`w76. @8U;qTP&;pO:%yjXV>T`NP{ʵK \:Ɏ-&|?~dtBZ:_>)o$lsBs>-ٴ`x4`ݚXV<!x1I*(~>AiE,– 'Q;ڽ`[ATHǤUB#wWj/~\Q N8ugP8N3eYg}85M &hk>"`aQy^Us lZw~I, MyA6 K ś=~}HX(}8zJLj ^TI7|vo79}^Ld*xZTl藤yC{?G< ,,!0k"e=[I N)~>UJgo=Fz8M4MϠ\0V(Dܰց3y찍mb/~09[dӒvz\RI\O,yytfW$bz{B)ɹ!D !Iog}yTO|_>$%  5x`z-_q2JGQ"dW߽1&esŵQů p\EV].7]a[#ؾY $gZv~3iR@sʤ1MsF}65'}c>-b)iD\ XXIb7.\V<[i{+ڛGfd-ٳ޹4\qD=mö˄m c>ٽ]o1>B+(W6H\!S4aVAO` O6 6Y,Xf͂dbQ)ł`FAc+`xD_ᅧ%|&g=!ɦ{4d%]y#ӄ$7K\WrU5DLq@220/6<lZT6HcGhN׃BUSj.5t(GBUv=v_k9p@}mWS hJC<#p۾5>6:h:_y㢿4kiiCQ*ttErYA4M{h}Z(e\TUJEgɗT.WVBP*0M}8>5UM4M{q2-㪁thh~2)Lټ^<(MFQhi= tyծp GZk5"Ne.nu^GV4M{ )X\\uoUZpvqj:JcZ# v(anrsX=geud5MӴ˿Kz){zT)mmmw<8,,,ZcݳPӴ< @Kڢ9M f֌"$i@RJqY_αcؽ{7KKK;wbgya͛7388ŋbܹӧOꫯN1M-[pQ~ FT*>Cfgge۶m?~R6mb͚5=Ip~ 8Ro}i@+\z}{:uyسgCCCtttp! ;dYy֬Y8ǎ#LFDQb},"d8{,JIhooСCy~_҂i|tuubMJ@ j { ji.\`ppY&''9vAľ}E(֭c޽055,+Wfttt055EPu]hjjv }._Lss3qFl5xS)IDATm۶133[iW Rʕo])Jqcwq`ݺu+ܚPJ1114|~μι9|'߱m۴u(ji!eMJH*o~Yݻ=J\fvvH$x||rr)i=RTj%״G)grr|>ORa||BM4M~?wQN'&&fT*<#Ny5M4MӴ;A066|Z|)%*^4Mc۶i07.\.y f1y`NK4M}ظҩAӴGOxGSSL Rfikk.cEIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-Token.png0000644000175000017500000000210011665471336031046 0ustar drazzibdrazzibPNG  IHDRAYsRGBbKGD pHYs  tIME  : @"tEXtCommentCreated with GIMP on a MacwCIDATHKHcIt2% 1+`DujQQD ʍ"]p%(Bm_H *AQD4D45E3{hU_ԩ:޿AxB~}ɟCRo)DO5qO~&|{{`~wwool5zjuuu,--VtLOOxX^^&Dݰl|>☘D/..휟#BEE9$''399 jEPA---LMMQ(Htuulb18fCPPPFc0h4T*jT*h4T* _䅘P[[jvsyyIVVVrhnn<ϋLp8h`?33q.3??OYYf@ @UUR9::v388Hoo/&>I`0 lb\x[;p}W5D"Qk cǎ V`0 ƋDEEN< 8p8IT{ lzz:RSSѭ[7m۶"/WTTܹsPT,e0 E~~>н{wj`1K/<}EEΞ=`0  b/-((ѷo_iWhio\'OڵkZm0 `hTTTԩSTkUX* "/^DNND"`_ڵkvg떣/ZmۢgϞ:d6`0  ?}􁩩FpU]]1c Zbqkw н1p@̙3ѣڵkǬ`0 9BBBp) >VR[:b1T*@vdugtu?O===AD077wwwr{/ْ`0/tRŵ55Dvptt899T#]R\v{NR,_[zBz"‘#G0rH;w׮]m۶/,`0 5\+; ^=D"T*TTT֭[:{ɗ^͑ڵk(,,D~xӛ޽{ ˗ Ȁ^-W5t( `0 3Vۚ׺kbkQ7Ϻk I_7J߹sgGP[" NwBHH~GApA,e0 "So:LuR`uu}\pe^ziiiB@@7xAP(ׯ߿ 888 $$Dǣ&&&ٳ'\\\͎^x"={!..:u#Ѯ];ܿT*ŕ+W`jj@.#-- EEEѣqY}0|pܸqy}pqhӗ'e0 3 zO,NNNpvv>...ܧӫcȑ5j+--1l0xyyĉرcD^r7nNU]ܻwHIIH$#g ((Dž P\\ѣG*TVVjL ^,ѹsg6`0 D<(((Ǐ}rrrlTWW j^H$X,3{HOOǏQSSU000G!!Q^^dffC "C,#//+_JRϟǍ7Xu}}||`ii bt bT|U4hbccW#G0zh$$$L_b2 xQ1v+56F[z5JZ۷;mkT]FRARi,cH$xV3zX,I];=_{k=qDn+W&.ƮN:ZצnX`0 ƋXW= ...puuRgggHR.`9::ǏD"GI.71 >|ȭfff* UUU8w \p^0+J_^^D@:h+δ `ݻ011 d2$ R)$ LLL]!"(JT*ܽ{?e0gIlV`Z~[M.`a02mۆCqFt }m͛ڵ+ڶm޽?`&*A׮]Kl=m QW+ߗ!IV(xð Sg&_n>} C a@"++ 3gs?<+} ?D"QP}~̙DYnbcc ӧ<<<[[[lڴ eeeC\\pf]Kd-n; e .3w)))dZ|~mۣFe ]o jJʐz) 'g.> `kp/Qq/_n`ƍl5\|ʾx"~&>{Y(J\۶mCrr2ʊY}3ru$:t(BCCq1X[[#++ nnn7{[ YYO7n ;;?Z e^z _n#~L,ϵM_txJBdd$VZYf5{gϞ͛o0zceeA,666H$S9`/fH9ń¸\+qUdffޞHXqf)EG}THNxy "S<>t/Faa!;y `2dN8"88/իW1w\AAA8zoOgφ+ pݻ{>'G=GJnaSpa#q <9܏X5qy|qN|L6 'ѣGsyܾ}5M5شi>sCpAq G-=jj*Q_B!č78]#==|5?!==NOOB?:x"v؁ٳg_Ǽy0o<6\^+WDrr2?pw!99_|8?<1|L6 !!!ϽtF@ر#FW|гgOdgg7bcc1l0TUUqu<|0'c…HHHԾ1Cʿׯ_O>!!!غu+ ԬY077畯' 47oĊ+fkN竘;v`ƍ#'O777$TJ/^|>ϸqחT*wsδvZ^dddX,oVVVF2-Zd~4yd{'ٳɏ}|__R>"""4\.(!C>}:-[BBBwޡk׮5oL555DDԻwoAoɞfDM'u 量cfOɴ H/.!YSR 綾^JӎeFcٲe믓R$'''߿?YEB:_} Xhd2̤~D";vQPg̘AǏ9 `3ȗ?1}DD7n `?]tҨ7TȠ,ͥ|*..2R(T]]MJԐB .Fb9FkŊAyy9or;wWntӧOΝ;ɓ'cxfpssXXXO>>->c &&&ܹ3/6 ANw^d2o|>>c|CS%hQoDJ%@BCC55ooo`ذalقYf믿j$xm̙3 FPP ]tὯ=!uS>>>vZ"'?ď?plܸ֭K>(,,H?Ө7v08s &M???TWW#>>aaa>]}|!ěo> cǎŦM{K^{5̚5 k׮ůZD"xa@%PU* 6;OEn>}9q.*A{:JoT*ߛO*?;:iQHzΝ;8~8X|9ZE%Cp-s5[k|>>c|CS `FF:w Xx1 q̘13fΝ;1ydL:UEuu5\@a„ ZhTWWC*>s+`O4 .6l؀6m@*b7Nꫯ֮]tA_0`ĉܬɓ'1i$۷o+4'T?ڞt/T ,/_;w}Z}.\o޼W](**2/9s&JJJ>䂟ڔe~̜9̙3abbҠ7~ڷoggg|HMMիe'2t  իb,^%%%4~ ˹7t Dm'?C'D?_BQFaɒ%8q/ZƍC@@@7W㏸t钆m6˗W^AQQ4&?݊6}J8~߳Xe EאM^ Eu4 :t@rr27 .h<_KC:h_}7uoH-,,pab̘1ܯ M1>7Ҿ߁/6fݹsGQ~M؛@OBBȸN:-ޱcd2D4`ˣ>""<==ʊH*ҥK56q XL/͝;5Xr%ڒ=Ѱaܹs'$$P@@D"H$diiI6m2|joP%<<\c'''SϞ=I./D"ڸqcM򃃃$?"ǓL&Ӻ_Hz]|:DrP^(33S&."G r_hoѣL&#R)H~|R?}B)11&_~M\u9y&.TʛW߾} ]vMp}3NSG4 dJ0Qm_Qߌ&..zpa"TB,(z\:Df}ǑӬ)d(q6|JzRߌ{`3K_z!9o>@>俄! _tg|o׌3_~Cх M\|Wo⪽1ޞƏ!g/>>}Wc$HLMMi׮]F&.QNNƢW^6C(g/Bti^^rrrо}{nxEEr9?~zMd.(..g6/?qʪ1kOII zO~~>>hB?III5}3 /2V\7x_PP,#~x{B{/@FMY9dmS]TUe%LUw]y{.~l1ߒo|? Z/++CZZ:tKKfݻwabbk& IDATd2H$HRH$@,kȋT*Rt/\036p Ƌz޽{1}t! @k{)L:.]B۶m`[#K`0քoD"LMMk gիڵ+bbb./g&xe0 &,*++ gnЇbcc  Ѳ\Gׁ9:@(HBg31  ` e1e0a= `0?pٝ;wקZXX48Ƥi,OƝ;wK/=OLL?ݻwwkl۶ Z7`ǎHLLDbb"|P*++y5*B!ɴA888~ORĖ-[{ƍQ]]qT"_m7'-]~kb F"4}Cњ,;ID_X HTHQ"q}!<3111ظq3Ș###666|3Q9s 11Q뽲2!..QQQ8{'"b̘1χ"""4{.H۷oK?{l㭷ނ V\/..Fѭ[7[խ HMM}vݺu6ɯ!Ֆs&,Y?7^d^x?3kOZcWK-gݾ[T*DFFbժU5ks.777@/xwvZ_ظq#222[nEdd$z5? -- Xz5.\H#<<B6m`9:#Yׯ_w\"_m7'-]>WgϞ͛ז?_kKE5liQXX=z0a4;v`ܸq4iLLLSrfl۶Mk x{{0h TUUɓ'(**¾}M6BPpG45 ^J틍/33B \r{E޽oF㹫Wbܹ󃯯/pQ~nn.&O ggg8;;#44{%d]=zP,[Lp)))Xp!ム ĉ5jڶm}ҥKeT*xbtm۶EXX č7gӑA;wJ¢EйsgbΝ ((^{ 39| >sAu߾}; T*5'%%(///^DYY=f̘ռ •+Wp~ݻqqqP(\|6m7;֠ aF|!Cp N/V럙xWsϦ!88FOB_ ?!_Rapuu|}}1|W_绯2#??UUUMOOB?} EƧ!7D>eM?W+D?:>/D>GF'''tuiGMyy99s搗mذ&L@诿""w M<;F"KKK!"BrwwөS())VZE+͘1ƏODDYYYMaaaTYY)(lruu1cБ#Gȑ#Lk֬!"$xbJLLɓ'#Ã~wy&M6lmm)??I.diiI&(ÇD"ӧӰa__UUUO<۵kGv$kkk6myzzҚ5khڵ5tss[j\!sssNj~mz7ʕ+@]v%;;;ݿЭ[݋"XLAw%"7H$RTDͣp޽;o݄ѣGE+VЙ6 ϗ?}ŋ釯|C럫V"LF.\*իM:h؟o>Sjj*aM?W+D??_B瓏Qjj*eddPVVR~~>SYY) &R}jjjHPPEEFGGsgIDD$Hhɒ%DDԯ_? h-ܹ͛GT\\UE#G$BܸqK*߹sgZv- < #XLwUNFFbokeee$hѢEܵ7nʢra@""ݻ7]|!'kkkm޼YPQQzu_~$飏>N"DBD~>Sruu%"͛7S.]J}GM_}otttTW _H5jyzzҌ3SNTZZj4WC _zCOH_`Qnnn藯| >֮]K]tzOK7!᫿ijoo|7~ iӏ/>WV| "mLׯGlɓ'(//ǹs0n8iϜ9AJx{{c޽d?ɓ;v֟J%Ο?bL2SLATT46 PT:t(wM.#88XƮ矹ap|Qb  AUUuعs'<<<"8vLLLa9R璂aĈX|9Nkkk666=c H4věĄ|S!"Z|Ԩ7@ծO<7|}`ӦMx,H6m >>ǏǞ={[x1°pBغu+݋={9999s&ѣGl4BS~U*r?髿EhkFJJ ֬YcΜ9Fѯo}?}C&D?|"|㧐t/DB#}cU?Cg&Mll,ѧO./^EEEСCz; ;;; >EEEڵkEr033Ä 4>]vmhyT*qItҥɕW b1JJJ~)7|ł ˗Ν;2eAmvttģGxę3g4K.!88RX~=0n޼l-MKۧJ&M«UVa޼y믿&]xϗPj0c \r۷oǺu됔,Rk׮i!o}E&T?o|[;B'_>k/$>UP2>laa!J%dDFF>>>† O?ǎrrr;'w͛zF8|0JKK1f( ۷oggg|HMMիepN"##_ĉ7GӼ֭ իW#)) Xx1JJJR;~w>þ} @|Byy9QFaɒ%8q"lll;`HMMEMM PRR^{Mb@II P^^333#:: 00;v,<<<7\}g8-.**9;K~BͿ퓯}~'HOO?aaa0aC>!P__L-J/oHtl$$$ܹ7o ҿƧ}7T>a-? m|+_}b1K4w\M6;v LF" @yyyB3 @"$ YZZҦMB@DtǓRСC.^zQff&yyyillYr%ڒ=Ѱaܹs)?z킴NP0&.TK$W^E|򱶶`SN~zԶ\Ǐ'ؠϛ7ܜb1?.\1bWn?"":q9::)}]nAaa!=yyy\.~MP݄M gõn'? C[_WuP{FWRRҤ1?1 XcVN$Դi7n@Ϟ=c7^yٳ^C> իWѵkW`+O QX333TVV:99!&&gggn!~6i`0->Kf4|X`0  sDI#71a5b`<ttƵ2.(q-5SxzcX %X`0 @:]~[Xw ZU=_ w8|6n܈~ؼy3IIIiP͛buݶmL~:~Xxx6>Mb?5Wni0ZkM$&&⫯BTT=+%K4^ ֭Cll U2!..QQQ8{lm6&ŋ?h7g$&&6I#,'M0wƍz?.\z/)%ۏ5z=D0L{E:ZiW>|Voke_khPbbb UzVxa\~UsssNxVnΞ=͛7sk.\ /p=qQ!,LPXZ |tO>rSBC[W~K'}O񏌌ĪU0k,f0- Zc߇\&td 8ϳ|lGL[R0{l ?>@P ((W\޽{ѻwo899oĉ5jڶm}ҥKܽ!Cĉ8x /R#}JJ .\@h>|8۷׫c 8!'_5/_WXuV011!!!߹sЯ_?T*,Z;w-v[B}O? i.233q N5556m:ѣGsiyܾ}A|JNNEGG딓OmG~JMMҎ;М9sˋ6l@&L _QRRrZx1%&&ɓёˉښMFfZv-/Qvv6Ҙ1cȑ#trvv5kѣGE+V?O| ݝLN$Zj֭[N͛7iڴidkkKӟ!㳟277to6ٳ,--I&X,&KKK>گ,%KK:7M ICІKűd%Ӥ!C1>Nꯨ86k9Z:89ӲiӨ86lcT"!HDrSSNz:d47)n:zc r}4@?.n}^rvSql,5b;8Я/]ش& B(s|m,-iTK;-&)d)]a {2ܳ/C!W|ܽ{lllht1:tYZZr})#_zCϿ={PrrF)SÇI"iذat$Bg#}|\.'$˹iii7hѢEDD4zhDtm"""}2>_u UGdBjj*eddPVVR~~>SYY) &R}jjjHPPEEFGGs 4P{{{$"RH$d""͛7ݩXo=$o宕L&:_|3D~B'""B#" d֮]K]tzO}l޼YPqz:@g1pE^^\ke.6[++Z9[# ر^|>#:z/[ Nߵb1mhܜl,-H$hD:"KL"'NF>m?5 P+>'ks&Ɛ_| ڽ{w9s&wÇ$J/|;|0SMM [ԒOS~O7n YlT*ɉOk֬|rqq1J'QZkk%ӧOH$'Ñ\soz9s U|2T*]v+Oҏ.>n;wBBBf죪J\kt։h?u>2f=t4ttuDU y­(./ǻVU`f 3'Wp>?tմtm_ffKOaC!]Nuq}׿W8wƍ"PWĎ;P\\ qazB(p2 IDAT=X{ x\\"""Zӿ4D?۷oҥKСCqܾ}>>>B7>O!FJJ oߎ 6`˖-5k9iBܾ}śB@EE=3rHtk5ʔH$PTHMMEaa!B7F[SSSoPk5ؠ|>K?<==o>رci&{FqmADWv֐I8׳kj͛֫7}[MbRTW}g;~jEeU%\㺵% KK8L$pJ+.oقcG1cH|&?06 jOJ9oc#B"_!uĉ?"<<7nĺuOZ'6`gK?> OCci?Ν;8~8X|9|K|G]J`ff3f`ƌعs'&OSjURll,ѧOr &LhpoxWk׮EzzQx}7gtɷ{Ftt4!J>~L8VyILu&/--m?j,X???,_w)Sgv5#f=O{XGh %of//ʤUN._k!8:}2^8& b1J+ʸ4J*4g7d25b1NČ/Ĥ!Cбcֿ)fڧ)?u//FQQ)oC#Boc+Ŀwņ ЦMHR?h?}Wg|il mBB/ öm0uT7>jWQ6} /B899A&A[RD||<,YHq?|8q ѣ8}4o۷3{bزe \\\UVflHB~23F9997oիZr(**BYӀ[n4hV^$c())Add鯡ׅ>___5 K,ĉacӰl$$$ܹjee2x:9^z Eee3ֵ'r ׭mJ}?)QݯWOLrK߭W\NMEqy؁Jt'.#_څA.qyykR6FC엯|}) aO?űcc_|  3gDjj*0sLͿvOBS~ i!755EІ… f`o|%S̝ J [65&$+++#TJK.X b1K4w\cʕdkkKdggGÆ sq.ԩ_:իeff$Kxx"奱0_O|$$$P@@D"H$diiI6mKpp0wѣG4x`n Bק?׷ȟ~?N(11Q ϟOԔv%>گXzc ؑۄt4J$Tx{3mR#mv^'XL$JMRű|ʊ쬬ʊv߿J&#+Wj\ޞ;NL t xj_2/"IzPO?ilzwHj@Vr"XL &FyM\Ʋ_]٧;vL&#HD < ߦ_*_>f$ɴnFWÇT*%Ci 'D|)T?g&.9qzQ>WwWn}n8jnPll,zkgg^^rrrо}{n|EEr9?SC )M+ k?ƌl&ߺ磸 T'OK|ӟBII^㏑$[m!-- :te6~K kWYGKsz!< 51Jb%gzU^YR"VrV׭Ոg/!k} f.^z{8yqWoA©GeLjƹ-^b IX ` `@ `@@   ,K㱑`n>*ʲ, < ^m# VUU_fYff/]VN sC@4X8l!iX,$r44_g`. )yDDQ1G(t:u a  ns^ZIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/EditorOneType.png0000644000175000017500000004332511665471336031440 0ustar drazzibdrazzibPNG  IHDR}sRGBbKGD pHYs  tIME  +;;[^ "tEXtCommentCreated with GIMP on a MacwC IDATxy\_38, (&i2kJVZ.]5y2 o]kbK"C ,̜~\G|`My9}g>~?2FC`aalƲaa:G.#$$5>̾+c)Z-[HR0 0 󈢢"?~Я_ HJJB~ҫa>|{Bq0 0 #,ǣsprrr@[ݻ~`aa2FC_1j(^nPǤ_~aa/EEE8yKϞ=~ 2 2QZrr2/^677712 0 T+FҖbĈY\^ښ5kXaaaS.]iӦ,aaQF ɓ'1tP@]v ˑldgg>t,Y#dݻwwޅnnn0`␕eay". 6m WWWYf777TNJ+zAҥ N<'OK.MQs`0 0 c+r9rrr*][ >hp[j]7ޫVq] ..ݻPբaaH*%l kl{=|ג} d-0 0A퓛Þhٲ%}'K// ;tݻwk׮xYf p_RR-[]v8rHm0{lcԩSɓ'#22"##???ر-$'Ԇ"..!!!Ł-0 0A3.|<<<5.{\t =p=!!?._c޼yBZrr2ۇ'O",, Æ Cpp0p)\rxbo;TVu={` /h4 3f@BB_͛ Gl"33Ɓ-0 0LE$}pjdW\JBnC wa "9sPTO?hѢzxzzBѠõk ѳgOT*;w={4hv܉_|M4AllA7@.CTbɒ%___h4* ɓ=z4#\&ٳJOkly-0 0LZ\.xP+d4nܸҴcƌkzKKKQZZ*`ccJ+--'_j VWU ō7Mao+_жm[TllaaY...'<<< !eeeF۷/nܸwsN!mС8s `(Jŋ/(lJIIAFFsHJJhIpQ"<}۷o1?~|SǪԛ[aaJ.FC xIa#1.\7/{`mm +JKK+>pvv~+_0 0̳Htt4BCCMƉ'*M#"$%%!!! hTXd]* #FNiׯIy3 0 ޽{ a᠖ixo2 0 t;vdI< 0 0 >|2`;a0 0 -[b 0 0S@5U.Y>a6utnYެ$a̝;w`ee+++(J( X[[CPJxm9DN^JeP?eaa<|A=c֭ӧZhaV9СzYcm͛7Ѯ];4iصk޷o_<&׮]GvJ=EQ !WZHß>qm/]u,Sj1p@Df'N -- 1cS?4d,6002< $0c ř]W_}isУG`ʔ)prrڵkQPP`̙8sLʮ_p!~:}bѢEy]HsrrBBBB_}[o\_hd2Y5AY~_+Cĭv/> jKp/Pt7_DEE!22'Z 188)))ptt˗k/bƍ5?4d,̙3tX|9n݊ׯy$"׮]3Xb)ݻAaȐ!8rV ///DEEku]]兴G͍7 x3)KǏcРAµ;wZ -.3]bw_íIs%v7lO5=u,C"((AAAضm;նcYlY>"I5~'!!CNdut:,XZB&M;wXD?Amqq14 :u$?YIiM?5m۶!44:xw^aΝ;+={{^ѦM899aǎfםNT}nȊ޿@o|ḷuAZDk\<䯸c& ^ }:^}U̞=gϖ$)) !!!ʕ+|r\~߿7oƷ~ׯ?Gqyl޼sAXXBBB ..]ÇSN_ЪU+B%]"==Dh̙3ùs$o#33߷p5V[M6 NUV5#&F͛XlVZM$?m4l߾EfУGep{%?>@ޕGOc$3-GCiB Js3ٱ`ש-Gݯ6~b {+vڅwwwQU"e"-- ǏoK.ȑ#aÆ*޽{ ͛'iִGon &!C 00HMM_sO?@|HJJ 4LMAhhTF2/^L^^^;88=%$$ל `޽{SHH5'''ڱcs%///ȨVXXHŅRSSÇP(h…DD4`8p'33r9ڵKRٳۛ*m1[B.]hٲe۷ OzyyѦM*\OΝiԩBښ.^()Xb#&QFQ@@z!M6!*7 HTO||<7oΝ;ŋi'?ojI_LӦM3ȟKjN8A2i$ZhoM988O?Dj*"IKl|KM7w~1V)2M1|R*J׿H&ё#GܹsԬY3I}: Yz5ǃpym* )))piƹܺ'r𭴪HOxx8gqƈDnХKI-a?CD8~8MLV_|z`ZFpp|?:cǎ~:Ѯ];QIퟱIя'V}ľ}0rHر>>> 7n>#`ԨQ1K.w}'#Ȟ+{PAA_PB`'b qFn僲<芊74*wWY)`M_膼Jo ?KAСCѣOM/Rǿ)F ///XYYM64h.^X#$$[ƞ={T*%皖QJon,k?5B͚53[P@K6!CaQ:~~~HHHm۰flذ>Koݺ3f@բ 2Im۶??O|]oԨoU^);v,>ClٲSLAdd$+-a?䓘BO<w:f6668}4ƍۣ kbKџ/^u|9r$֮]w}עW^ᅬ \\\ z_}rfdsinKsQz.&7nz=.^zY7oplbPbA۷qQ/.]z"u`Qu {{{-*(|S75⇚3Vo3)))hӦ `͕4?dɘ|N^|M\z-..FnnE簵ԩS=Naa!rssQObS"113gԩSaeeU7~7owww_Xr%6l $:Xr%㑗  ??яjF:bgn_0|p,\cǎרQбcjoڲe .]d`Uaҥիrss%qiCn&??>FӮNܸߐr#']m Apx+N(KImllТE \~]xR .T@AU_nRY컦UokkÇ1bkHUkMϦG)>w Ӆ_oߖ|`M`b۷'>Ν2?(uִzjI oNJd2ۗ233)$$M&)iחٙ?6(r9=s4k,*--5(cD...LgJN?wuؑd2) kZD>o(˔)S [שk׮V) d2EFFVHQ^pppGD4zhR*.Xb#&Z&ԭ[7JMMQ?RD?oP.]R$N'I~b>SR:}i*..R9=¦n{Ǐl-gϞ~7L9Eݮ"NmIf&+_OZo'L9%l@HAFADžM]-V'X+:RKHգ#91ޟ@N)%ԨwWr6/aÆQ~K"%Xb-66MŰiR֧S񠧦h]WQJb7wIIIhѢju4w܁T*P(`mm B+++r9t:z=T*Yhh(dP[SNBOfgu{I;Vzɓ'1qD\t M4i{<<-A-0 7bqL~E#4@틫W]v2fdd?Ǿ}L@0 ÈAcT* !puuEtt4 aZaX00 pP0 1fa4xaai(>Eo6UH=qlmmkN۷s5xî]p-WWn J7dggc툋C\\|ԗTٳgW+VT*+=%99 puu^nN 6SH[%&ȷk>k.QO*e[¾-pP( d=%"˗/ϯ=BdddWbTTGGG\|A{ƌ4111̙3qODƈ#L6;w_~duVӧO7|4{ IDATMxxx`Bz^^:7߄3=*m%%%2e Eꫯ*lV_U[YI]_Xp!~_{{ElܸSCku\\xMm+Vj全('8;w;#믈DJJi&{߷o6n܈$4k +WļyFaʔ)HOOGZZ7nsbذaHMMqڵ Gljɯ*ڤgX8s ֭['tW]ϯug>LNt҅QEoߎQFaܸqBHH&N(bժUغukSRRf͚4nrhZ( :)8XL=/_q۱daZAAAr كݻ _}W^ŬYо}{ ((3220~xC 1?C E$ySNGPPAr1 >M4AϞ=q%2tX`Zj&M 44wSSSq d$''LRgϞE޽1|iNNNرcheee П.& |gھm6B\G>}PXX(Z+.^ht1yd߿?\tVE`` Gkt֮] ???9rJc:AAA ¶m,>ρرc~===_X~s75>SSS /`½IIIFllE?9~%_jڟ1}txzzBR! s̱~M_~tS 99YYY())|orr2ZK*71Hi9-I!6͟b7%_)1U٘/|)1'>4 m޼h4USXXHhƌԲeKZf 3ЯJDDw!GGG?~<9r8@vvvEDD999M 'OR||z ٳgӔ)Ss΢mbS˖-iٲeF˪L~ROcx$onbsŊT*… TRRBݺu'Z?\"2Kvvvo>JLLon1_~tS޽HT\.|oʾ`j~ӏ#ڰb)SSKG~)BiiiAYYYGjt:)++#VKEEEB7o&FC5ԺPjj*=| -\zM!!!rrr;vٳۛ*|yPP˖-iذajtGE6mPDD 0(eff\.]v*&%%r9}7µR*4|ڍ7UY$4`*++#"ݻSDDhRZL>dooO B3[NR5m4sssIVWh)ݻ7r裏JAɓ'IPB0%K'[7oN>?%쿜.]HPk|)iL)럹KÇ'___|h1$~sX~sO;w.yyyQFFFWbKm)"""m۶ߔ}I&E?b7W>5m?LͯO)"_S1UGԚ9Qm50j/.&&/".]Ǐɓ7nt:4i2dffbܹXz5lmm\fUF}T_)KCRϭ[BcÆ +9h2~sW7i$d2bʔ)~+Eb[}Ɛ12̑OM]SJ-ac}G rMm9srrp-tAT bFeee\>3ZnYYY&mc'&&"'' |-pEEEưaÄ͛1tP~ ;:: i@Pķh历 RI)|yLS_ǧ~ Xv-}*@&qƈѣG{nI,XP̛7/6mڄ={`FԩSѻwoׯlkgekGu˗:> QPP"‰',L\"uU?!!!V¹s3fXDR'V%'OLbe Sa|j͟Ro 3VKL͙RX̍tP8(--E=~28809{n8;;cСa#""j:uJ˜1c >ڵ?ɧpqm۶ƕ)Vr9%KR̝;qqqXt)n߾ &f͚?O6pZGFfp%XzDn޼~muM]ۧH:ƍ /+V`_-&+c㇈D/\T*L<W\mW_!>>V'~s״iJ\KUILoRcʧ#bӏFLR#cK/sS@!66 .Dxx8ڷoc͚5HJJ’%KpBp{'\y&^jP-<bĈj7oX~=rJlذ·p|8vM8uh;tcʕG^^,X|׸2퍟YYYOw^j$PXX K0|p,\cǎ2~mڵ (++̙3W^yŠμ<@~~>rssQXXJoool޼YH?t4 :uf͚aȑ駟ذeAvnnѧ'5k>Wŋ7oBCC1fdgg[?~)͵?S>\vM JҷAUGb*3F`` q9۷qMIb_cʧ6쿮"_SCLR#SK/so&6 \N=͚5`#ITL&}Rff&дiӄ{Ν;G;v$LF hڵN? "}6ѣIӉawdn(55ZliyfD...LgJZҀݗNNN (fmm]C666$ɨW^h ¢֭[ի+ld* 2 0 SSp 0 0  0 0 S(>Eo6;Uyu]k.ɑ(--ǎV}v!..ة_:6lgH$[n4iRO U~&IuD\\;ڵ nBPPS3jlBa\.L&pl`eh˗l<]pA૯Btt3վ &&3gę3gm+SLAbbbŋظqci3f@\\\۷o_,Z0o< iNNNHHH\)1?ssd2Y` gօz|׵~RBpp0RRR˗/?U!nvZ>ڧ&%nO8s[Nx%am兴47 xAtf~{F7zXb}6z3Cd{ AZիW *ٌa?ˇ#'']taa< A^ J̙3j+W`Ϟ=޽;_q1 >M4AϞ=q%!m8v~G_|A̛7:u?C"((AAAضm[W V)>S-'##Ǐ;1dɯtX`Zj&M 44wܩR'Tf?۶mChh(t:ӧB c 99YYY())Arrjۇ>*_,-..FANɧ7e?RWk_eee PqQٟ),kПqU̚5 ۷G@@pa_SH#EbT~sk-[Vø8H}gϞE޽1|iNNNرchIL٧)THMMō7]/++XX8_~Yo֭[f#e~s4 m޼h4U<޽{ΎG?ۉЌ3e˖f3f _IVӂ (..ƏO͚5B""rpp0UVQDD/Qzz:yzz҈#СCt!rwwUVÇiԲeKZl=anLɗ(''itI+V?`PmڴBSL!͛FNNN%~1#?1h4ԨQ#2[ok&ZݻΎJ%r>&<]طo5mڔ._L:uw}hӦM4rHI)3>Z?PԾJJJ8q ܦMo\`ZBbΝ;HǏ#GЁNS5͕Gה9s /M0AR֭[''qF?~<}ԹsgZx1M>]Rb#?s_ۓڗ\Juk#F޽)$$ر%#1(J;wS 'kkkKX}ЪU(++<<<,?Gl~4ԇ&ML___L2ׯ_pի7V}z[PEF8˳>?1KOsSoѣGѯ_?K8q%bK|Ǻ#T*&Oɓ'cǎ?~<&NX⢣QZZ=z@VSNPT3fL-f^xdLʯoΝ͛7U_~~;Vyq7NRdqOp5o777(J]@!66 .Dxx8ڷo/_رc7ÇW8н27owww_Xr%6lJ/..Fnn-ٜfɷ|{Fy&^Z[:tcʕG^^,X|KߔcaÇ… 1vX8::V@ܹs۷o͛cjj5Zh!脈oS3b_矑O?{ZllUI񿦂.{{{YIIIXd 9WWWXҿՄ|/#_)SNEαIDATbb"fΜS/oA]t?AJt:MُXiFm۶N?={ d2իi4b_U6U?X~?)1ITL&}Rff&дi,kR>b+_1/gѤT*+ݰc}$kkk7ԅ1SϜbb6l4#t}bʯgϞ~r/v.r=z(effN[nQIIIGG{bRՕ:l_e}LJJJ2))LJHHoJ_ՊG}DC5K>WR~~~ctMWAA WH_s'?#;;ݻgX2?Xbb͑ZKm?bRcNR?bK|G1=x^Z/O?i4FXXGSW)?/W8uzFBBvލ7|(((Y/كI&!&&;vd0L qXYY J P(^"HDtPT-[ 44f6C&ƦqƸqv*,Zիvm=o߾z*ڵk(hcSAJBqqqiiipwwv2uOX h j&fחaa3 0 02 0 0  0 0 A-0 0 A-0 0 pP0 0 02 0 0  0 0  0 0 A-0 0 pP0 0 02 0 02 0 0  0 0 A-0 0 pP0 0 pP0 0 02 0 0  0 0 A-0 0 A-0 0 pP0 0 0u% sKaaeee(++WRY>b0 0 0u 0 0 T*Y 0 0L * 0 0 S%ښ0 0 4젖2 0 0u ocaa80 0 pP0 0 0ՏGY 0 0  0 0 SXd%eaa: ju:KaaiA^gI2 0 0'uuue0 0 05JXYQaaiX@ӦMe0 0 Ӡhڴ)@haaA5H3IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/StyleView.png0000644000175000017500000003761111665471336030642 0ustar drazzibdrazzibPNG  IHDR˻sRGBbKGD pHYs  tIME  **_"tEXtCommentCreated with GIMP on a MacwC IDATxwx?@ Pw * *xb bßR.@B'gsNr (<$gwfvwwߙyWfF nrf`NN{$[)r9zɩn"c+.=zKl6#*#De˖Z@P}v*\xsѦM4hP9L\0m#ٳ$G𷓕ő#Gۻj L֭ 4_\\ݻ}H"ҥ Z3g0`)M*L&ۼynٲðUՍo,~vv6'Ottj_O)..Β; 0;vc;8pSl63p@ ټC0kT)͊/~ e_bzUo~\Err2rl[$ٿ?:uB8H$4&ΎbuThD돯jӧڵc׮]dgg$=vɹh ;uFd2î6899ѫW/*BV=N`ۈKe+׺bÊ7''QQQ>|,Ѻ(~8g3(/HJJ.NE¶'Y,qq~[qmW<?//NWΝ#33ߠA8r{#%%Ћ'ruRJȒ wyv9o20,YTjo IHHfO?ĹsF.]"''o{lR={Շw7n'==wwww@VRLcjmYdnԒqD._\. ]VժUʕIzAXX ߺmۖ3vX1C.[ŋĆ7eGh67'ݳ'&EFYոJ-^UUm ܹ3'11Pf3 b2|25{rك/_&''(0ͤpA twww=JQQ;vߟXvEnn.(9~8EEEl߾:t  88CAA XXf ڵz:wLƍ+jd$''\.GTHbb"\xsA \.`0qF d'"z}/111hZ ؿ?EEE8;;ӯ_?oIddd?m#[p2+P''%Ť\|ŧk*4¢0LĴkG_8N^,'6aeɇEPTù^`ά7L$$$^'880AAAT*quuHJUVxzz`@דL&0^*sT<;PXX5F l6\.Ch4<<<(**KÃIJJråx"""*|28pL1ѣGuswwEBh0of> rj׸k{3pG5dŻ/IGhU W^lvbl+ HOOg֭۷FYg:kzripb#+((`dee<[-ud2 4d[XUX7JENԩSI&\rtJKK&LFQQބI14jԈ˺u0 hz!:O^<ƍmHgСh"Sgjrof3+/W%#F&cVW^:tDѓݑg`6IJJqһZ-rMOO͍T*bJˣ__-7[ W*9<+4k~~~XNÃ=z`0(,,2寰h\h4b00ژUhMdO<6X mvk׮e˼ʫJ2-d;82HHHiӦv=00Hж zm۶eÆ RRRB=͚5c߾}4mڔpN<ɺuS egDEEpY󉉉Nusk6mڄB;b2 c׮]ѭ[7f3M6e޽9۪U+?*={rqRRRjVt4͍͛; _U :J5cf8;;b.\~=]v*ٳg@Ç+/|ǫaBѻDKw찋_ݸM]8 k2thJz=r\H^JU*.\U%%%h4cubd2Z j5ϟ'--]V{ցik<dz?//xڷo/u-w 6DgUگV4z~z RْjNƚ5k{Mo"$Ď2+,uǬ]%LRUw~FpmޏΜ9Clll_񾬦ٷo E-RMڔTݸUhlWn[mIUw75}09)}Ό3DSy Zd(2eiY?cA&Mؽ{4>'+uYݻ?SwQQ@8p 5._y :*2*h޽{|rBBBxyG9{,gΜ!++۷3rH}Y<==),,d͒%K0,_///KHH~m]^111<ۗ~^hdx{{3rHz_-yd[h F#gϞ_%..~W^yE uM*e~fΜ̙3ox$'LݻwbC aӦML4իWj3g0}t(-ٳgӹsgfΜݻ$pÆ ܹs\t8yn՘L&Νlf߾}[T)27AҲuBޭ[7d2;wdʕl,෣4<<}'Jǭ[jj*AAA#FP(D^Gyܲ"SuBZJظq5km۶%00ҟINNvСCQ*׏#G0sZ܄JTViii䄋 NNNhCK+'LId|W(JER̘1?7nYɹp]B;6~xϟ{'2m4eС( {9NJtt4-ZݝQԲkYmذ_~ۓc=& s= 4_~ӭ[7\]]:t$h_PHߏǬx:ZTҼyslWn:BBBhѢEi gXGmzhР]G}N'\nalπD"LMSBmӲ[R"|pk?"2qqqvLKp!WuL}9|04snW`{? uu[Xd .]Y\.'44q SX Md-[FDD'Oh$..K2m4z$\\ШE."c0HIIaܸqjVf3rN:{n Cі5Sc?F2Ȧ73L* e&wo?m­+q lT״aG4umOjvTrN%ф[DQO=D)N`HROq`k(T9_Xz|mN%|HBFG_X̖iTw{\Vr$N"ZiY -vNe&Dӣ`0T)2Ōj\]]LʏqoQEl3a~A&m{|߯Fȗs߯6b"[>¨69܈Q޴k |g<J S 0/KۉLaRهD_H3xn!Y/GOلwTJҳ*}OLA.Н_ͳ :j gG%浧Dj| Z]1XWL ǛdBRτB~ e^~65=SȿtU fVʺg8NfǸ?^'a*QIX+~cml E y4Fq{l5톱yC^M(%S mtFHݼ ?: 19j ?A:}\]DZHRv쓎Uf.= }ťU(LJc'Y{/h+ؚ ~-lھ2|ɷ>Ǩ,/HL&_c"MߗSYTޞ #vs!c Awܷ?; g=m_аg,/r%]Wu6~б T2e|J3SsXM #h:q$VlPVy iط j\]ùe=98{>i+u1u崣M.K4낡3O!SLF1c?o¯g,>[ITZ<1 \)yqjgv+)zv!YG"e{[ȇsDG&B wXkwGĶ;ϲすvkzҨG,.5--2jV3NNN8;;mVnR%78W8vu4$o}ru&ށlCD).CfrOs&Jx¯s[۶1iYv %rDn^ښk8[}݅S]~<0`(.̯ ;d'F]R8#n3ڙv" t{spSM# ;) 2%b"MeqZueR"iJ4r?;^oJJ1t}ǘf Ũ\o(3E`6rRIVM^]~tsAP`1L(E(jch=k5ƖsYAIf6MsO/+ 2<RرcYd ۶mqxܸq7KP8lPJ*24=ӽ|aWߧYfyEdڰHd呝GpC?4MLLHS2\JMK`0BǎQ(JT*O_`2F͝>'ꡇX~vϟI7^}o5 ah>a"'Ld[oQ_16Jԩ;w.,ZDe};W0O>WKnĉL}}&cYv7DL@)|'.}z?{{LR܇ !fך{4CrLЫ|r:KΤ!I9O^QϟMxSzҋ,+Y99|:rrIPm?vY|'2زPUo0WT$ܩ_&$p׬Yݓ_8y9/b2coj}O>s/ KlZPX2S@LL /$++ӧOoS3fHLU>'NАe>> ԉ~Z7_m~ZOD)SgTiG͝K'Y ߼֓&lfXNIWʫzNND?[ի7k&SϿ4ذoXΐ9kx/p`?E%%L}}ZODI~mȗ^"b>ۺb;נ|r]}֭+m,Wld2Vxqٸ_ݮ$0*oB5B&SRU?7&FICs4!'N>;lZ+j ܉?}Z-VWdĈ0w\fϞl歷 5z8s%>4_ 7=g/[|-L25odbƇY}}$sٙx]}=ݺFc&^Ͼ\R >`??V99R{{`ݳt[С?b[IdHվ= HɡT\~).~BJ+ymC6o^[V~g@߾ )NM&oāyp Vl&u^M_Lj'q^JKe; /\>#;!1b\nbTϞ[{ }۵ K`^RBg3gyR5kF#oo (2VWˋ[2~xSkWf8 l.eHl]֯=3]ZR*clcG%Zhūg$geU=g/֭e+,0KiiR )3|enێ_v}XÚ,0oJ>[Dˮ]RvxӶi8..޽[999UvÁ[[:lg)\JIaݜxQfIui&cEݤ SGd`Ѿt:\BdluȢEIȐ`R8S)q"BʭJx­߿^3fW@0c$j?>esҸ+ &~f4 եvI-*)Ak3_RQ+ylkhxx2ݣy(*)a/0(|il9xZ݃ʼ}o]؟vƱwl,}%4᥯K[W328DDP0ZBr?:9ٸ:l V6o=Kv~>aMTdl]==ɓ'h"\=Tgɴk֌[&gf~f;aIbUNN^%K={o?c#%+^}FۦMIp&=DӀtei7ps#$=r0fRv;=ݻݱ/_FR~O e[>u )Ɍ0EkIq 16+|‹֭9tߟwL=dwwwik6o*εzȪ9sxw4uk2T/x??š#>~pz1j V,eӖ'990zrReVd'E zOy|fn`{}T( y}OK ^1\zT>pnVwI.ݺ-VQ#1:\S:T}nJuWP*TBE`0¸qPd2۹zغu+WGR5`FDh8;EM8r<2s͹ !ډE… D6b(WZZTanukYM/((<ل4oʄ.sѪ宲Qa2"ރ/P8 RRRZ7W—VrR>I":o#"Bd{:]2G1)*>S+zI8w?o5Z.Jigd.FoH'8- sD6ۀ2qdc4Hq<1EE'80 /h| M0) 8i2-^:+ϡQirW}fs$\GfPMiWU;\VAic[yיޜFvNyuY8W7(]%¿8}..L(ğɿ:י٥q-wS(MFtCpB,xz &3kI5`O&VOEF"u2CkR*FlYO)%@Q1 >]\:"IMư*?Ka~  \=X1 4h0̕4|9—:& @ii"{iw^de-A 'V}+nh࠷:4id)>NZgBn"8?p_f^O=ULe9<{!)o4 Ný_頞5"(u.' 2b;n /FNG$*[,L4꺥iqZ 9j(]Fr2^mkS Dyo9ۯرcYd ۶maϙqՃCœɤIO)ܺTMMѨ3\zTu7$i۶-$'WϛA c2r////@P_"]`\!r6HvQXyg,,Kqc' Q-j/2V/U<>j.űi"g`AaFR-+ 9^-Y9FM(3R(`>qZmÛ}W)'6ktP_ G. @p%RԐR˯֙7FXNl%$=Daק%c*s ǛՃW_-]hdZ~ W(x 93^[fɺ/*2DP<ޖ?M{rF.}HN31ϼa l2BO:]%2ܬ͢@qF(%;v5etyRsg+p9ȟe ,**M*Ǻ٬/L`,pqVp?3u<~@\= QdCaa!ꏛֿ ke gb}||*8Gt?f)Դ o}VԙWGX>[ʧohI)OgIKEJ`?= 5qq2LZ}`o7qJXg%xUϗK lNӏjy [:'tӰB &aN0qW-2}Évd%E&r,Ngh쫢Mdu9'|L[NznQ Ÿ"cuB6m춐ZzzȨAf*JRywi g 5अ%I4gZGBDEEf 19Jt5!x5[ )-ulM5ob 5ȸ\XN'c"&\A3Z ;ZzCTT]^ebŏoVlBq/*8l^w]z)wawYꝻ_yI-Gbd×_~i7׺`d2a4d #߮dx=^*]J˗T )/;VX,C)JQzM1iкvc-z#`yzj2K6%LbAf}9^Ihbv *u ;kf<3`MՔr!JPRA66ᤖfqaND411:3 )F˞b3&c*͛0|f=ₓVs[2pvv۬d&*Bž5Jig(Lҳ#ZDmrrµ2<fX~9͛X*IkN` UY&zu"F\h5 BL k[@AZm; ƲfZ5 LwJHϔ; =:b=zP|U&M'Aj(ds*z\WYת}P1/}nU(`s.]@Y,tx|)N<4ěoM6̃_7{i49c+圻]Q(LTM }msżpl)q+] G7DmYR9SJJUD($Όdbu,TΔg D&RIr&ANo"ZG³S|3|u҂S-U*MLT5YQ6^;{/uӺKrm %5zW!\=j#[X @P_"Z?E@'rv%([<_#!2@ DF Bd@@ "#@ DF !2@@ Rc}%+CX2@@ "#Bd@ DF !2@@ Bd@@ "#AmՃ^Npz!,@ DF !2@@ "#Bd@ "#!2@ DF Bd.T!\o'ϴ|EyKF Bd@@ rvLKp!WGEO@ %@?]"G %/KKK3. M[13 IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-Bracket.png0000644000175000017500000000213011665471336031344 0ustar drazzibdrazzibPNG  IHDR@TggsRGBbKGD pHYs  tIME  8-,"tEXtCommentCreated with GIMP on a MacwCIDATH]([cHq!DvJ4 %\QNDSi_GHI&BM(+453߶mczZ[zג( _ȓt>տ7C *K.~VGYM!:;;Z6zg&* vJJJX__7jHMME199 %>3K255DP`6x<*lZ@.#"FR~_X0Lj PY8==\@VVˏSSS$^\\HZZ:::0L@?MMM} d2qzz5))) 177 ȐdN'GGG=`0X,hZzzzzpzz tuu loo?ITTTJ__-*bbb{AAAR. r(QQQTVV2??;;;twwL&{4gCCp v?IPVVƧO4@yR~ss ..xX[[777߫W*::Jhq~_O1ļj3'''W1Ӝ022Bqq1!!!z<666p\lmmֆs׍* Ji4iooG"222lH233t:HMMD0To ^9GEQm6zq8ÓnO#4 WsJRdMP{){ <>e>K.K.Xri]KBIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-Underline.png0000644000175000017500000000204411665471336031722 0ustar drazzibdrazzibPNG  IHDRAYsRGBbKGD pHYs  tIME  7+u"tEXtCommentCreated with GIMP on a MacwCvIDATH](Y?C㭹6\ %#4\̝Ҕi.$Wl\Mq'$M͕$B4(ԤLbˈQ3aًgY>ֲ[{;;{9!Wl6AE߭tvvbN.!DYYp}}-x/ZaZR333B!VWWNofxarrw3%R!'$%%155j%###@jmmezz&222to*Nnn.R|v{gnnZ-ہKAVSSS@GGVJ& J.шj[$EKK %%%,//suu&v;&gffx899 􅉉 DP144D__]]]Rp:?P]]&սxss3FDd#"""K$d2^(ƈ`0twwD" nSSjXLTTT]T*27Q dRRR`kk+P{ww"¾?^ (ʠf3$&&jQ. y...\;==eppzZ-;;;x^hkkJ{RDTzg- z EH~JJ ]]]hp8,,,vihhd2N#==4, %%%!8<<|F8_wunotϷeO(e/_ 3]IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Editor.png0000644000175000017500000005716511665471336030143 0ustar drazzibdrazzibPNG  IHDR)5 4iCCPICC Profilex=ha J)QڐN-B*ɉQ`k>L# iIrwMrI,8u⠓f*.bAdWPy z &DX-.\(0G)M|^e}n^ r婣۳uRR\^U@pHu 5@. @@k kHHhw8o|-=j ԅ/+cmxB8v+bs 3 |/n-8pw_$ ]}h'`f@[q5`:TU9UXz']oa`d@xn ٜf':i2 '?Y/y|U[Ώ4džHz|2e.wzCKdz L( 17#; 6ΕS{1;a7juG^i%iLK?H,baGc& IDATx\SߑD`RW;bV[ӵ3Mr[uBi^wfaۢC;9h ֤VB%6Qs0#y9 >~>''9Ku9`0 #L qݡVc`0/.<]]]۶mP qy~߾Gi|r&?*%%eca0jY¢rı h<ϹB~~`X c3ޣ>ylor]pƎu 1Za1 #䌮F{)a[߿?Ao<+`0 #ϖS~Zpǟ0.`\xgFgjUAP @T7]W?~Dj‰׶{;t'e'ͧlnLoDvo8X|;q|%((ۨ?*;>p50_q.|C ^ZO{ q^wͧǻ'{ߚw}#Xr92%G{Ғ/nX0;S\ `(zk0bp~;0xb_ݦ;QYIw_Nf=?0+s|ѮM*kU':BuȠSiq.^Q&>KOOv|{;}뭷SH`= !Ϲ#y#zsGX#GO?9 +L ntJI %Gv}=I^s(cltf~i7=~h*z套`Ÿ?o _M`t̚v)ۿ?g~{^~g7;S.d0  ^=LW#ݩ*OW+j '2D):i@gg4*@g43  }kf0ݱ̛umo<хœ?{#9AgO,-1нwO7ޤ5 \Cs,涹7,/_uuuz+|g/oL_Y={ C6\ՃW:{W=j'\MK?)oC0Ina7)8y.Wx ctc<Ļwe)p޽48ij$3Ό;]0}.-@D-2 #>=Ϲ]4UƼ>peP3Y{Ȥ)z ƫ&LOY1eڳG_^~ rnIIuj}o?:}q7u;_WIU&kySUնn[E5ݠ%%[?T^^z볿(OzߦیQl`0d9+|ի>GϽ3gHQON]R焸(VSHZpK{kO"\pٝڗw⓴?{I1I+س=žE\ UߟY ' =g ԃW3G{{SYwYδy1H{j)z}ꆯ< ήG籕wi%%V}3m7ȋyt}7qf \VldYӿ15*1nяPqz~?ʭA~t [a0 5pW8N7-r3uʾ/%Ϲ>808r J5 J &m->AM3d_C5r:a0 Fh^eJGZs{ C&sc0 Cqü(`a0 a0 CY!hC`0 [6y}X`05[`0 FA̿47*x:^;ΟE29fMqr^FҞ1Aj(cRPAJR*g EEEG{8N UtU5PmJK:EZwV"+hJ5tC54QQ:͖f?E M6ҫF*ȴw87#P-U'G]Yʅy3b?xz W^5ɋewu5B9h$ޞ1v(.^ϝ}`+.l*g/-.uΧx?~@qzNvX #9u.e\qǐNukS=?`F4dO)C|3"CU: JT>Nm⒃ M+mx gHc䪡Z(䲤MeP\u-6mڒe˳z!vjLQ:>X@Iv5DsB7<<@3;Q},v jP nK(;Qi㔂6 fyGɜ6D<[oFéJD* O\2x~# gH:LVGDDL4IRMr߸-`{ j[9sGTFUq;p>kߙ!z ޟY*]h޾uY>mͿY9 Gw{scy8o9l:Cp޹sGt:Jw[[æcͭCwN-T*ܹv;]ug\Nz-*Fө'ĉ$ ^^ܾ-;2U}K3Ufp3Us2v4G{E^!}窂͇T*N3w{sJhFɅ<[% q(knffffVVVi;k|~E׃)Px3rP{1mg(s_:]>2}ζd_T/鶽s"ZU>@|'Ī9XX,uj_{^~A X?p guM), T~臵į?|/@_z8Oܾ(vs@s2ߚ[v{Ik̥w\+6D볦++_o6c[ٴI۰vW\;nR Y5Sw['0.M]g*9xЌ +y$Jjwzn;|8d1:XćHF RM𻪹^5_\]@'\5rg/YV U^۲X4OdPjȷ߻Tw[UVg,YWzl>9o 8wǩcֽ[>nY$zzWD;cEذy]}^Mcxw nSyS759I;uxd?/2m6nxpY' <upJ}p׺W>6Vo@5駍f@8;^l8 d[[Ӵ}s/.&1#ɅiMt=N>\MR@9كĺ.];8sd^S;/>(Ci6i~M~X<U)p 1]F;mz?L_sRXApj\UI†6tzEv>tpCO]`W>pJK'nRr8|DPERw8Am\ %pn97 $ \ppgcP&+ _2{8P4/8}8}YjU͈tɩRLFLj1Q~Dz#?'=Z--N9x6H0/̌өTht=h.3fE%/pǎB"a(]Ted IR{Q:,[89:*t-[{$M7yGrΜ@k?pw zuU?->@McQsܐWc#<` R @#~̐܃zC+Ve w_ioTSݧpQO/P\Y[dwٵ"8&f)J XJZm)[e-*0W} Vw wyn Zs. « 8[C,OKzj(:p(6l2 E9p#GVSΜ9_^|ʕ+./l2מ=_/[vW }bbAxuWPVFL=$SAv4gcezC]m([H)]6As(CFP=ʬ,szh1jn#?^ט z HO#g`Ɂ590~i ҧa&-{.P=$EwEeZw8N;}Ҕm*>]!-[l)---*(:GhQ> Ź9aP=0EwEeJux`v iJSWwjddJ?S6n<6uԚPq.aG(fHH\6&sqʟϠ)Yd8y3{/~6)?jdd0ۍ|(ǞjϲKvNS4H8K6 <.o5n_92wЏivqzbTrJ;BJ)sМ{|Lѝ$2/S_ap\N&I_J<Ȉ [4:NRUY~ĪIo.@<;AaC@KxC[ $:N x}`7bO('nAxzz Nk{P|L'/װp8N;AK Z1eG ޮM34$-@$X6~86mlUM^{.T/Q4%:zBǁB]:)D 52ɕ!^hA$(#W e$%1EwT_?2,G3ӎ e)TG{? `@h5X9{Ug+?&A\@ ;хMkyIzЦ78Q؏~4P qb*!ӛ2CXA ʬ1Ewȼ\yhFd-} LK]*?j FDoW^ΘTrMjMҸiҙ Hp[bCI# F\|>5dPѤKvȈ7Db^$Jk{+{˔kXf$]G3QWH%ޫw &\CV̅yOd>\&y \@\hCv8>m 3,}nq?Uy h<&]"q 5*}g׃_ ke{h#sM,2/O_av84vLK|xQ~LD8w-6FiT*ʘS[CM¸iҙ Hq[`CN6 [ -kgF4O; Yy Mgj<B1.Ah]j?8qC J鍇;C$x=#h]6MF .7mذ^S>#(U%O@yI:(rUŽӛ p z\ԧME&sQYi8l6c{!.F/ m') t[ MoqG&]Y I:o|}՘#3= ;A1zZ|86Q# HsE隥Kd2 UAc8|AOXe<FFQпG CR@͞{* qM\rvMP T~16~"V !1Z}9uŽة?O嶀䳙縠>/b IDATfOp*}R4%}Q\O^rAW NSbH8 <>ߵDIrʒ{XfhcwA֖3MDTqyL6G'ɗZ:W573333++}\ƭ D^=2wC=<`jـoߙU`k(pߙ.ʣib5)<'>Џk߹`{3 f@( e 50€=R4e˓%WkEVC~WCgC <$ԗެR} `)7ZF[*MvA.`5@vIeS[3Z\=XP6t8Mp7-! . ^\05}lݷMRF&07 8\Rn캡CMF.G#[r|6ϞI'l18:B#{lܖ~8\XRVVV '^dzZLlsv1&۴) X2+ONJ#7:* {WZ<'q.IwMR9@鎳daeIK(ڇa@72$(C>$`ָvCCuGtŇW4C)OYOAjMƭ96޽G@0/uDdo=E*Oa8|1e.-fH~ҥtttmN;pFSZFGvҜYZ)AWyR?GaLjΏʆo@Ce+JFS]>DYruP'e5ךs,enܻ|:nX"􆼧pKcÁ L=QW4.*j34#i7xWVJAW^X~{|D K胄cJ(~C.W_,:-xv6Ape ʮ(晇W_?ғ EQm֢bSzzj۰ #q9n T~/17<9IA= 4#L e1vO`e}_ol.oB>(6l21P?rDP1gT!2,P`2JnM^ݞZ2+PP3tڕUN8 mT4ݞvt y]{B"RFR8$9fAa0X+WTJEmTGۛπ1;XuO_*I1k/D;̈#YEC2m2{Fܙ2#?gwʙ,7H&@gDz]GI=7_pwj\yo'98Љ9ٰ s#@1 YC|$GV ;ψǁZE, tO1g^5_\]C{|M F{w:V `nݻ pNrIQhov,u @]Xo%@ƍW7Cnʣu VJNΆ7 wݫ?*mFh^iNZ&+xFv07U\|SSO=U^%yu[yz`uiC@#5~h 2{?zR!"S>m|W摼3rXDIW{0>U0xȼW^ΘTrMji G'v}}p8Xy x{FqˠCEDQ`OWB=x̶:NRː~6eD]x~\Kk!9-}Fh4 2xF6]r, wH|rB !vt=ԓ|'i E8t}wkH MMH0+Ϗ,ӻ1W啷{>+b*xs׶t5mLJl@ew@;&U|l2=e \sc2BO.$$j#MHj=iw?V4&xGh09/]Eos> H!xIm?f0(}+Zvq!5U{,!@ SθK;A1&hy q|}eW晇Weuv~h05p8ݻ5UcDZ N|3ϾѹP# ܽv{0ShY~fH\ Jw-mP1FthM([I:#WC!8uyꇎ޽P{P<2kߧ> G? a]ktk16!H01y|0Fp=!}ńVt(*%q/IMH~.̃:wX+H+NW#oǁPыp٠33DܕgҢҊ݇j6 EY[0i s 2%H+NW#oǁы*}a!Jت#]vo^#Vdծ8Vܿ=wn`,w{RB8(;"Y0 EwqUsu~ú4 28y$Q7&k wr9j ,PckE~cAk{ LM ή6 [r[*\XRVVV {Ӧ Z\4ϝRn캡 &#@Y! ApUxFC=e-#z'ӑ J^Uc~Mr>`lDǨŷ#g]6@n `,k"~Џ{B^m6"3p" c2Š?}6)]'8D ^ # I6\#dT6]rr!UB'!HpQn& =1~1.T-@TTtc*ჟ) F\|#mulf[qk|{dw/2a&t2B,{~^#-޵Fؠ&/댓eUO0z8,G!=77:j.]VygO\E`mGכshtwKǓM%|;Oe``cUlvMzdF꤬BZs,3o6XNG@0fY8:_ a/JZo]6gGp޵; ]X0q XL`^!yqUsI=Q~:Mt%{6'e4EwL%!8`[@¦BڙQ:.zN b^h)=t1tR3~Q{BB4kaEʼnQkMFH(m# FZB;.B d@t3FPPSJޯyHd{b,9}2868 |6j֊C:VgyN [E^d=>$(nA=p82'ڻ߁Zez] DU6Az((?ٛ_ydxH=mڐ"SݧpQO/P\Y[^#9=DKVB )~pLV>-[Kg7Lj&ZxJg@@4@_ Ȱagdy|mSq 72 ;h>q~=֨V):; ~"v y)M`_u!ſPAo: Ͽ##PLLMц>5'&He=Q!?vמ#PLM =~k0`X0 =<C @|:xPR\)GѢ*J|aQZޟvn}( ބM`>PZqst;QMa3enYR2*!IF܂#?h9=KRTUGy=:AI%NOSOɋ7u4n+EBqyy k݁Q [[ܿr~~xNEkwܞeYrj٣3j#M.}nڷ'.<ѴE9ۭ.Qο'|z)u%}T xC?r!ޓ"ԓ `ãg$$-\2?N=˖Lx枊zpӽ/[z5`99Gk?hJ^!z!v*[bP ?ĭ(!zʐ-a4oeO !p9Њ&%A3tviII3ݗ 9zE?.s֌ԖjUC=j:m $vL=C g=c  ᙑ($z5C6wfeUؚ+ h˯$o@d4yB@'~Tu,1}9Vᅞ_x۩nSbG"Xw4f@v~aa~~~ysX -uP/Ӓ `*;; Q\CF0^f(9;Q~S٦l6 8-unw3j)ޓ>SSacǐeTIw5;κApu0ˍPnU`Gܔ0ma5DeIDbSSgc E [v8iJ@v]BSK/aֹ9 &}Jcn~~~~a-v{G#lC!xOZJX(XG=8F9BgYARnseKmơ*IsB3JtZ8N;}vT!ߓ:Ӎ&;,AK}K\Y_m6f7dvt8 m"j2I//8[#Lg]1wēS]$Pn)oX,ʉe.@md_oSaMe>4t mv9vَ23@nKgGy[XR^2&=ʭȒ`>p6E)˖.}k-TOu[u5Vbu'fDIDTmTmܚCT7ך7:ύ&J/:ָvCҥ'aq`aǞ-u/pp_h$yݠz0SSIoX+c^<UO>ty<1Z>+)$J5`Z4`+EKhUWOzyAT3>|т)tO& 1mtLUit?mxm`ZƩZY1{ M+a ʡKm%&N 7|GЦ|HvMM62)`nr 7%#w[v~ʭsBR^KU6zG3"$3@M]#7Hm:r=/k[Nzb0sWD~*v?@ R=q hҗn)f8$A$G{xNZ?'w2>&wum 8=2ou ؛F3 s΅ ܅ذat|bsu$EG7/ѽN>]v6-|{= {Jr1G=yG_ @J)iOZ 0p_vMNwzvD%&F_LN}~ $M?j(#A> }F~ Z:s=֨/a{zU0pX1C\OjļЊUYWF^!a}앨yyD̓CjcC{j0pWq!5u%Dr\SgcgZoHN2zTkmKJJJh;KJjBGwRWZk[RzzB]_^5 #۹sZOԿo_!q/E=asp{}r0ߐM16Fb{0IDAT*t]O($sjKPH7sp:87>F*q`s?<kr|u> CLp=j+=nish[ kw5kr`M__ZZ߇@Kasbˁnzn>PUuȏJ9*.Q^R:%䐨z+/ۡYsTUdsZUm%JHmKA`+\ B6Bq†-x(9vo|Nˮ֋Q5EѥIQJ]c28u:8bפ/jhY(h{A&CN2xo]gᏻzx7=~qZ/: fz_!vj xzIܫ}n3C"s7#yxO{rk7z _<>m8ǚ-95my i_H5H\%"XQdpLjO !1xb=e}͢{rGo=_tf8 V5w|mYReU]Re5#*C"f.GM`\9g,Ni-I_z"`̹wF$wD]YsyY[\ dq॓b@7i#I+@Ll2!hFrP=lc~Y9l.,5$DM "7 t6&0ՕeM7< >hF>x{H|Fۑ `,;'y,NiG-DҔPJ߽PN)eëJg r\0$l8IU:y~Q;lGI+@Dl2!XF2+=njuDIWwRز6bi3g(,ҁX-u.ta8ɭMح1&{|=pwq\V+eGpkB`alhʻp׽zjwkyIzЦ7ˈc[wX.9~Dsq٫:+]f_UVZ=Gt y nqc{=&jN%jfZ+3Zb=U}7<>.,M4-p\K'+M)## !X{6?]1ޣsnC̘y#VWIܻ|Dd~*Q_gSGsU[ve}hR Bk@]:qhsWJa*a683'a(&P0?&A[Q&}!d$;e{F3@WԆ2`:r|(D{q{Z|r.*jKU;&O/ sZ+6G^BP|Tݝe}h B6k9}U^y'0*M`ήp/zx#݂\(NO_i*<_?ROJ4&28<{  ]B:k>xI6<#i 5JhrLRWӲЊ*JKP8JUڸyq.bD~JyMfT Z Huuߊo~#43LH~2oדB3JRhY;3JE4>~p w(1f$F\a}C%{(JRsj~Hzu+fE%&&&&iHKMyvJX ]IzT; G#n6N4M)GK{<[3[J`}FR_vr'zV\/W }"U @4*as^?\n>tftbQ;|&sj_Ris PD'/:]Rg|7FމQ g$J! #G>DmvomoL _!×="/A:N6Ynpe/_ 2U!!֠Lv M$& H'jjKy-MO7"[XhzWw|d~MI5XOv?ڧwpLV>-[5J#))A3w cSSRH֝)חǂ6PG6 G 9"\~j@Oجc={'=c6grXI80\vd' Nk =L8 |zH5ƽw/^(T?te{oX\ϱZPeniWd_GhDNъU]Ttt&kKOP[ҪuoR:LQiաy(0'JۙQ_\u~#xtTd^A`QFB^FG|ϓ5o8ei0]7,"'v&~XfG7j i F(H>l:iJ;)7J:B5Y*tkmITd7FQI@h?\{(ZV6o2d:Ӯz롮[K "2Oj M9z  XHÉ327c!Wo&ct>!*7%G24J=E I>WQ:4HFԽ;i8>;NRT++Z ̓2BGS|8A^p I\Q'aYQ8?+#=YQitk-MP+3 2#W չsܛ5uxv '+&/sʒ!H ӽw:.\BiI t!w@B>wib} 1p_5[8oZ{ TϷb˙grfL=?-)nZQpG}9+J $둫Ƶ Qq8,"+3Az(1yPphㆱ^a7ނd\H598p&@A|{8}GTv JdeY2o _'BgE{|lb)p$G(mA]6\ { ?k`?=LŷH{z!w<9O8 ^7N%ìiMU:U<ȯ$)#c?;38 yԠ{ 0AzOU^!;*zl&F8yt\oz}J1|?u\UۛUTf>-JTsZxPT7xa_QޖU*UVžݥ*UV H`b NSM#qIGh߷eUHYsUysxnQ;.szqb>DD' * 4UpVY}#{!5 ,YoZ}j1|?}.M]g*9r-֪K7h9+W6m zʆGכM}XG}Fn/łA #F[fwlU@XfnˏtٝNgzyZIT|. ' aFPK]q޳`alhʻp׽z bz}z1|TRzGȶ8i]_:%2m]w\ٸ1㽞BLS <7< @uYz5FJ4 6hG'O6.(ߴ\S_ҿwkyIzЦ7@_#I}YYoCQ7ꗚ5]OMN[)LX>u4?xHgD4! # RSuRw[}kM%_䶥<܁fxAd*QaBΜݹDd~MD #b10ڬ' \uoͶj^MVyFSҌ͖O3E`x\I˝x#>=D `e{giiFҬo-O/E ߍ}Xzx[GgZj7n_(9 sԊJ3vF>9C@t'xz m2Ў`0=dG]~Nz\UkÌKtp CAkOHEOt!bXz3[4og{Mw|}{7o$YewsQ6JUղZo\uEnYGKm]]tcL8"oLS)}Wwu{>J 3 lkIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-Squiggles.png0000644000175000017500000000217211665471336031742 0ustar drazzibdrazzibPNG  IHDRAI%sRGBbKGD pHYs  tIME  6' ?"tEXtCommentCreated with GIMP on a MacwCIDATX[(k䬹2VBp1wʞr΅CrE)WwrI"hDhlB E( 3N5Ƽ^_k,^}yW~ !+L0$9==}wwwԄh׷inn~_"''G/qqq!<==xB$hؘBy{3&&&! axՊhl6T*B`0ؙ$#t:ݫ.--R 55E&fILL$..$ VKWW555hZwu.&#I'''\]]/%++Y_e"2Cy. 133^ A~~>*888䄞:::hiihZs1:;;)++{xuu5ń288*v;2V(xyyac````}}Z[[ BP8V'K^^4AEZZګL`_Ʒ\__ZU&xx<^!!!h4ӹ&44E:>>`00I';;___ݔ:6-ny|Mh4h4Y@CCzJ喯Viii!33dL&SSSr~yy, N#**H YYYns^XgZdYZ8o,t?Itt4 6JRrq^n<  zWT?7dh1?ţϏyZL.| I8mOX6jz총 ǁҏׯ4KpQIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-Box.png0000644000175000017500000000206011665471336030523 0ustar drazzibdrazzibPNG  IHDRAI%sRGBbKGD pHYs  tIME  7"tEXtCommentCreated with GIMP on a MacwCIDATX]([cH̅1ދd=\:JQL)WnM%|Do͕HIl_iŔ+f=398_YyZZ2I$~q<,|3EG G) xXJ`?8??144DWW#rX,Ԉ0F[[[P^^ֻ ձLvv6Fin7+++fff!>> Uppyy\.G$DQCDIrr2v4M& FCIIɛsss糶R!''^2#///1jݎ ܌ BLnsvv5YYYA)---~ :.gffrssqp_gaaf PUURduua8;;cpp^V+!/Ąj666룡NfjkkQTل`.Ɉ(԰doon|L& ydBՒ@SSqqqgyAbbbIA 227pxxooozJtt4A흝k++)) Z2xa|X,LLLR^5SDQ|gvv FFF(++#&&&srrzN'>]j= 9,jj(ttt`0P*/XVtloo377h4 @vv6%%%(>,O q/P$I@ JO=SoO96GDDjB@P"z<Jоͽ3L';;{Uxze95m8q[ڶ*I!q$"~mB_"~|]ut)3aW)j5rrJ-VoT͚5x/ _iv9HӖxyykaUEݺL+{{˿`2^o sO=^= 33BT] θ#WΠ%8_… #l<=rʿc*wl&4:CQ!r(H:$zwyiUx[֤E[ MZ_h"\=7_iԬUGѸIK|9 vӖym.Jfk^Tv*T*b^{u% !*5k)&5^'l9?Eq ] &yfy~XlY]Ơ7h).,øGm᪪_uw4DG\AC/ \^?s# 66H@Z j֊3'iҲ=&Hȷzu|WʺMfoMRc*jXz'mGEEןB{v˻~pp(߶Oppad_'vrg6o<pwwg޼yUtZb4E˗l=᪨_͚5^OGs4ouCIIS8:GGGmZ5tt::-ZNG&-8{2 zrsU[l =S\hM&M&Mh0h2%<*e=k5zTf; !xl>8{ꀫ[o存1dR'1zod6Vz Tjkg:4Z b-z說_͚5`).Y zVprjZIgN)"$9 {xns>-Ae<]_8ɆG+A֠T3&CgHKfqhFQ!t1|nDO1uj7Dh ;Ntpp ڴfԩgsJh *~M@SA[AWEo0uLp19z\LNyJ/,mۖ,ڶm[n 42l i`urK!==}b25ʭ5bf Uɀ//6F=^<}ٸd`r2Z"q#(gS'_?˪[9nn\;ޤ8[vY '-- `}-C 5Vc).,Bђr;ƽe6 ԉc%AT4˕vOzz:ռ\L_4m{Tb)2bn~6=_|AL۷ ,7BIՄ9]bzȇlă?SE 6l(k|'+X6LAUI8i Ơk3D\Y\lQUJ +!@WobTD"AXQUM=C:oH׌;oXtحTǐNGook6O*۶jIA~Kܫ6{V-{l@ܳg 2yaVfWPpte+%AX{9 pGucUU{n@ܾset-ʤ}7ucǎݕb|sMZiOaɣ{jǞ\QmvD%p!E9YvQ/d(B B!Tji!BB!X!B B!@,BH B!b!hz*j5U8p@֖B{-VAAv 22ҮlG[hҥ7#J!^ѣGsΑDdd$kז5u~zt:e!=X !wX 길2L>e(Ž;BaRoRPT%"Ν;o!k ծ]CJX!@FDDqqqOyZoX0t2WVy>5{ xzz2qDwBեanunnnzt:!iZ$33k׮qU呑NZэ?f<<fɓO>ԫWh/_NӦMҥ .]`Ŋv'<`2Lj #G{=I0B 6@jhٲTԨQڵkSN<9F}'N\NMFFm[W>PrNjhѢw1cZ͵kה3K'=/Jhh(}/~`00{l WWW~m<<3kFQmeW2~pҦ'p 0@zBQ wl0VԬY֭K@@u:uprrBZGϞ=߹p5k(Ǿ}hݺ5ݺu[n8;;]?ﯜtyҔ 0a]v-ٍ7 +?l߾v3Ti盝Kll \7< Ba#zL^^^4kq-)((رcxxxXҥ ͛77{A:u* 6$**`233+TǗ_~_Ν;ӱcG}]HOOgǎ˓O>|x䄬{֭[޽{o]=`ӞiOSNYSCvv6O[Ę {0q2+w87>> PZ5-(( GDzwh4dgg5iiiԨQ㎾va !9GKwLRT i۶-n8`0ӧyW €prrm^${ƒ,B!,bc56s:wLNN{mgZ:jy(,BΨB5mNjiӦ "&&F9X6%Gak9;;өS'CףVEqS\֯_NmJ ĥmoLǎ$(J Ǐ,GQ?~LjfuB?^&pyLϚ|2۷5#nݺ oSBq.uk...Tf% #<" !gEB!黕S{ B!@<}[^]BdhZ!@,BH B!b!BB!$+??3gp;~G_?yY~MX!8͕OMMe֬Y4nܘ'ORTToy],ݓ@0akVyW*4M6Rh۶mʿK^Y?5jĥKpttoBOФI-[SRRny=BBBXz5M6-3_zꄆX UUg!$$'V?>!BQ];4}Q:ģ>jֻ]6 6={2vXrssXr%:/2m۶eԩʽmM;<#G$,,=z  r =Y_δi8<{wՋ SN1l0V\IXX ҥK1ydBCC9r$ۡtSLaÆ /h?3i$N:>[n7De2tP"""Xp!z=ӦMO>tܙl֭[YhÇܹs 8H.\V5[/}ЩS'‒L`* 6 !$JgϞߟ֭[[ެY3-[Fll,*-[òeܹ3&!!#G;m…tޝ3c /~~~|We|AAAl۶m۶ѷo_(..$%%KYv-֭Cղgy-.gYlP2\dKqq1pA7n?ٹs'ӧO߶X|)ScƌV۷o;[nxyyѷo_"##ygY~=.SNeǎ$$$pQe]Zs6nȂ Xf SLQoBf)KVV/_V 0!CFÆ ͆-M+..f͌5 ZMhh(...$$$rԪUW_}www5kƕ+WرcՕf͚ѨQ#7l0pqqqԯ__?cǎՕ1cVeӦM |M֯_ϡC(,,,3﨨(^x{eZy-[$##ɓ'seCEEElٲݻw3w\.@~ѣԬYӧC`` ,kݵLjHKKȑ#tر7|'N0eׯo6It4MѠjqqqQX Ve..\˫`Ȑ!Y'O2~x?dptt$%%3tP%Z:矧}駟Z-F޽O?(֭[Wf"//|~|}}:t(5kִnn޼|#:vHǎYx1EEEt::e>͛FXXeʹ~:={dٳfyyyyTVW_}eGV^vq)\{{,@|;,Y<:v<@Nku'Mɓ۷/ 6dŊ>}zY`w̝;W9AhҤIL>>Җm?:o<#t:uӓxL@}4hL<(II9aBBB1bqlS>  gaΜ9۾}rYFF#F`ȑq^ŋ~zu+N4kL9K!6*Cy[] >>(bbbK[e呚JÆ ͆TpssCVMjnWWJm\NF2-_ѥKV^Mƍx8|0ׯ_ӳPF!''???dggivzׯiwV]ŞB; xxx׍*#f0U=#شzYlg'''AZ;Z+OV[|c׫W.F!bqo޽;fhт7޲BH 5V'>}I!@\.\HNNUÇkޮO+O[!@\^=BCCiҤ |w\JģGm۶7m\݆o^yj򘶡m~#,,어i}L!?GlSppp^+ʚ4iͫBBB8{]VRq۰UVܹnZBH h޼>8p ̝;Wy CPr=z0p@%aAi+W^cڴimۖW_}1._رcի 0v_бcGvʣ>jsJ{g߿?|w{ƍSү_?40vZ,X<_p!wz?S:;Ԓ%K1x "## O>f=l{C]xcC=T,;TJJ , 66޽{D^^SL{L>]ݘjҥѿy衇h߾=ymh+ۗ64m^zѹsggϞ69ߟnݺ)J)kz*cƌ!88l'L`uBl޼SdZv^z~zv5kd 2  ^z%֬YÚ5kx7)...SVNN0a{ԩS|e{8p ~-Pr̷z/_\Ҟz)bbb裏,ޡ}JӮ];GvIIIY͛7wY75իW//_N^^K.%22RYǏyffΜɳ>^;;Ԋ+hҤ ;wTڴ"١j׮?OϞ=ٶm7fڵT^{*whY ~<<<7n׿裏,ql_իyꩧXxR/c{=/_ξ}ѣvֶ)k?Ν˺uXpyWiժmWiطo|O=4[}HNNfݺu888(;/KO>wAo>ݻw'44hq ___vɓ'6l{w}@ɍ/PdI&$&&w^ef+[d͚5J25۷o[ng1%5"88~vء$|8vlko(;$Xr% 0]ɪUfwvpm󉌌dϞ=7 %%aÆѽ{wcov([le>j*/_Σ>ʋ/ ۳ڻMUƲ!={>/_ĉ̝; 42f)PXXT*e>5j԰XK`0{n%ÑFСC1 J#F 66%d7CсhҤ 'N VN+MRNy%(jk"""ػw/yyy*,)jРA?~O?Gya'NAPPPC5i҄/<%TECkTTGCd*..F0afΜ޽{Rڦ*R#22ݻ3a:u믿Naߟ?I&1p@zmėwrLV{Xӽ{wڶmKN#y[z\]]Gǒ#=_ҫH2 kaˍdc;w6;7((ݻwSzu͆:Pzݕ* J6-8q;uhk׮LQ^[ۦ*4{M[:ӝRf_5oKLi`jqfO"q[''2;ԊlU7*55m۶Z|e* (SNUeתmNh!$ 3?pVEɎx"ݻwWIb e[UB-'hlبnݺURd]aɾ$BH ҂ T~ʝ6wbfSPPpO/ݲx߾}رC/_}0p@V#Fnqŋo:;Uf UF7Br(UĺvJ׮][tZҥK϶HZؼys4k#Kc۶mO>wd]֬YSnYU-++b64iRuիiڴ)PXF VQVI&LUg[ZbjbʕٝKlyg Q.uy ~6nȧ~֭[>9s(F{ť+#޻w/ݺuֲ+YɪUܹ33ت3<áC#GF=n b-Sسk.IIIߟN:1c [_́jM3>>^Kd16TEe2-8EѦM}oqibki&zMhh(kOZ\7*WDGG+Ѹ|ĉӇN:Y*DzuZʮd+Orr2g۶mb[uIMMU,\ݻsA}%(T|{2lݺ}*,X9x C 1ݠN,[L~7rek$;;06TE2I.ÇJbb"...*A`0dOd U(99Yit-[Ott4s%))={Pn]6mڤ<>s7P^1cǏٳ̵ٖIZ&&[u SNtbbbf,^X5Tzz:lڴ#GÞ={o߾DFF*;|y\v]vqF.]6ںwb)KKEck\]]i۶$$$b3㛵u}1h N> dfr PaӦMqww,])oyf6lѣy #>>Z6 'OdGNNVb8p7`֬YÔ)SnaH ĥN޽~Je={2{饗A2p@SsY>cvC=Ă .yׯ=zݝ5k2}t||| :;]xfCOޤWZZ:tP+K~L_llVFV5Baa!6;me9|0l喝zj2d7[Y{2RRYryMZW̎kZf)w2aΝ3;Am<ӼeX"ٝ,G:o[rc+z[KY['{TVVʚZ0LJUV[ Yci- X{n[*3gUfXYnv;6Ø1ca8u[V-e̛7}fy>V!55U.vԥK]MeϏ>777;y[čKMMZjf?0sss)..ty#/.]2;PH]BT[IVFO4YVf7Z-A6B!b!BB!$ !B!X!@,B B!Ľ瞽``0锌'T*W!zٳgYYYU8_ |||hѢTVM !ʤhسg#$$ &Pn]YCL{n-;%Isssx"GaѢE^LB!@qq1?W^e֬Ye2/E4oޜ={rU  W !$LOx-WVr{e˖{n""",U?@IKK 0''WNز*߿ 6{QTTğFMoУqvve qEOӦMV'ggGU;h>>;v}N#)) j5ueӦMUVntt4_5$&&Jȓ FC 4oޜÇӯ_?e @\j^^iiiހAART$W2l0ϟϘ1ҫh4t:z=FLɡCS*}11TӬY3bccdUU<͛G||$pU5dffcѩS'MƥKy{^yŋO8~8dѢEnݚ~ǏhGYuV\ŋy>| &R\\̢Eիaaal۶sNz.Y;p2j(Zn͢ElGqqٺ7~FRV@燻;yyyw!@lBדJ6wΞ=Kdd$NNNJO?D.]HHH !!cǎVy |̘1C̙3Y`DFF`j5ɓl߾C)׮_???OFXr=zl2_~%Cѐ/&((]~)g駟&77ZM޽Y|9j-[FTTEEE{\гgO1cر&MX-[ѐ@aa!ÃqGYyn ƿ|C~~'BH h h4jt:Qwaj`s=h 5"%%V?̘1cpttSNrQ;#]v1cưe4 [&##'x>6mŋ+/U(1_ݻwS~}4iZߟ~wwwƍݻv9h bccIMM4i҄O?ˎ;1b1zhpttTѴζʮSӦMٙ@ƏO˖-iذ!YYYʱym88F#XqLjj5QXXYOJ76mڔ?VkrZ7zV2Ņ"T*뮮hZt:8p?=zi&ڴiCJJ #F <<\Jbooo w}ĉmc===qvvP7fÆ 2UV1g~aVXA^^ ~o'+0~x(`lZR?u,(( ??gggӖBz \z|#<%KILL,3iˋ޽{}vj5鄇ӽ{w^ŋQl۶ooo7 **GVի ҵkW ˲tR}]f^^jqssSzÇ_eѢEL4 Zxǘ3g{AVSzuҔZ+Z{ZnZ͹sغu|\p4K^q~~>f?BT*xzzAqqPQvm֭[Dzeر#{l޼,!i^x͛OϞ=y뭷pvvٙ~={ży={6l߾v1tP222=z4+ҪU+C=Tuʼ޽{w=z4nnnJ=U*}O?eڴifeljmڴ!**}ȑ#qppˋ#GRV-:t考iii0x`V\ɳ>}%33rklr;88sN,~ivmqZ!ijW鉇1-pNݵk3`eZLL 'N --ypqv͓O>IZ`Pvi?==2ZjtZZ5j(tdffRf2Sf~ -tt:m۶eƍ4mDƎɓ'lLK˫INNN:ӭ[7&MdVWWf~fmu3[Tu:iiiDGGӣGڴi]C4h@`` +V`ԩb3[ isvNNNf͔ /ڵkiذ!Z{::RprrF7\ffʼv6oŋ_]TclVnn.˗/'00 "{!RұcG7oSLAJPW{M>}nZ޽{mfQիWZjwe{樾pԪU;+LJou%"">j֬Inhٲ%8:s-.B+]{ HV˗9y$#==6mбcG֭+o3S=u[n~@T*x{{S^=:wL`` +g\F hذ!yyyPTT$ipqq <<x&t";;ǎYٳg3ѣHKK}*q[qv~Rl$/yn `駟t;wAAA $/3(9s&>|HwNʕ+ѧO **Crr2>裺'Z8r39o8vF ƕ+W *ióUVa…tNN k׮Qn^:mIx@~n"zn ::uꄥKںÀ2c2k ܹsسgѬYݟ3T*UѣG_z6mԢE $''(..FBB1` 8jl_y9~dP38w |[n988 40hDŋx뭷аaC4lذY'1gtÆ \}бcGilH*668z(|||'NײeK$''Ν;իnܸDaYfAXc#<<>>>+//Lj#P~}>} Ǐ#++JM h`Q#qꗣ{0wUy9|u94amHIifxgzڸ<" 8tܹ(\r5 ] dgg׸cȑ_>?l۶&Xhϟk׮ڵkRRRwyv½{ၯJTlݺ֭Ê+777DEEI>իWcؼy3lmm0 7x7oDF`Q1fΜ SSSܽ{7odi{jP(Ezz: D|0`I͢"222>˖-Crrq5vүA,YLLWWWQi{6667o6mqa޼yls=R#Dy>C̛7:{~M֭[ Hv?,--QZZ!NNNhbbRѐMܹs8q"vÃP0x`vw}R΁X+V`ܸqزe :w 67߭[SSScY`:uw}{Edd$+Tbmm@^qqql@#vnnn`޽{й9bn_Q\T<4lyhV U4si0 bnCgv0ìtBa86pqV=0H-qc077ȑ#1{lI&:@3dn݂LLL0 {MW˖-Ø1cuVtׯǨQPTTKKKv} uMjJn߾-z]t;;;Bs3l'|?mj5LLLP\\,L1=Rs|nnnףGed2{si"""ܹs%ȑ#qY6Çjٲ% ʊmܹ3d2T* TB@BBݱvZ|ؽ{bDFFbѢE())a٬Y3? Qlڴ Y/={,)$''#88XrL~#q!fa ݎnZgDk ^yM/G^GIIkTYўcNӱcG_'؛lQTT;w`(..-<@ǎf|ؽ{7q9a 00׊ox@,_DRR#ձŋ؊Db 7e1is0GjhӦ ۴Jj֬ƍmۢI&Xr%~ O?۷G6mPTT}UOOO7+Zr/Ə&M 33}>2KJJ X[[#//?{FV`ޏ O>M0{JǴk.Z >>>۸UVhժI;w>Q~}ěsᓷzux回 |/Aa^NĐѳ.m='S_mM]0|ƫ3v;777(J0p@Ʀ͛ݻw}:˾;l߾k׮E߾}%/ꊖ-[bǎ:^ _%%%3f5f-ZwwwnػwoOqN4 4hN: b߾}x7Ѹqc֎߁<<<֭[Ņw\{pp0FVZ ldlZ^`,5q'`Ȑ!hӦ r9?nyBg\I7-rVV7o<55Εs*ST"??5iܞ={ǶmЩS'vڐBYYѺukIz\d'E[JG \ |=%VQZZ 'BW^S^`t;p # ЪU+Q3hW޽{-[ĉhѢE%q_qII&}7=u֋!e:b>7` t кukDDD4k߻woL4 *N6/]c:4uskXaHyZOLjŖI?_WZi "O1ģ:.-KXI^-7LjAdIEEEaŊ/uVlذFʦ|k裏>}L߆lقuV҈!#++ N\ǧ1t VBtt4*iP5IUgLg%r5yk۩jzӧhѢjvrcxָݻRGEѶm[8qK(Pcҝo]~&L`ҲOLsM)MIII+EEEaǎ8~8 UV\\\ѣGW9݅2k"nj5  \~5¢E0 <==-[0|֠=`8pĚ5k0 0zh8::ȑ#ذaVQRRgb֭?tR|dĉN;CPP3g _|]PH-Zh 44Ǐ?Z"$&&#))^l̙'Oɓܹ3j55k'ObĈٗBsm6ܹK,UVRϏob>=LVQZZ &O?օ;7|'NK>&&&x"k:wv*ͧƍ#8u!11 @P\˗/7|Ö1ad2?X[[cԨQXn39Xa`֬Y֭~GOwpp E cN|Ji,XWbȑpXc͛aeeÇcƍx!Ο?{a˖-EZZJ%㑒333,\%%%FFF㑐ϳ&%%qqqquܸqq␔c啶"-- 7o еkWlڴ qqqHMMB`Пѣf͚#Gbȑǹ(++9dO>Aqq1,--8ĎzaXt) ";wݻXnrrrOs,Çٳg1n8},--Ehh(:xvX] s EFFݻS?Vs}>x 8w6n;;;sf.¯ GGGդٻw/ƍ={Vڇ&URdShҝ>}Nf̘ӧI&* '|?kBhҲǡI"eBp~JigjLբE X[[!,POH"_BmH bki(++Cvv6petؑ͛#e\|T EPP/Oϗ[/?n醑#˺tEPPkP*cb8ǧv>>h} u=ԩm۾@ً83(رaZbxڟرRsIaʔ~:<[KJ] mk̹w2zu &MzX_ܹ;FܵS'O(я@Q՜ۺELc Tq 16 Jٟ\.iwnJ"?24kAI!997o։>Mjr}xyy)z=zxS~)q1| }h҅l߾Qvվ%>R{N4Fm{.ϟK"?2m)M$uĸx"K/_~5kVu6mܻwҲ+Waaa-/S{ooolذZV erÌ30`XӑիѮ];O?~qsqXrYXX P/5g1q/XM>kRTZ/i߾=.\!&Z[ap )MAU^0 ׯ^zIM O UTʎ^.^ɺZ+ӛ>dWD랖!eWE"FU]/Kk<@SArWUXP$g͂'o=j)Y=u./,F?$!XpyX`F]yhʅEԽ>s|C~DJ:g$%%|A=zZ _[9:P^Pwk9o1L5y!iejbf xY`xcF'EUOѳ>_li; Ff͞Jȑ#ueFP&gѝ`JP,4UCE /baJÀQ?^G@-}6-}k;*;_h#L,lhlZ$֤hݺḛ-HƣXtGx(3`{ 9Ǯ{869ǮJql\~Rx:0 BN"u <Er6‡ rz(r\A\i~2-}ܞ5;v:x8~+{;0Er"}!z6V@Iu~‚k׮aƌ8|0|}}ѧO\~]GxfϞ]SN:)8=W_}ݺu4"|;1t cΜ9ܹ3 z IDATVItR] ^äIpUjh%&&)8;vcjL>(򌇰p1ZMyv:b\8YyOa f<f4! Mh+NW۫mT%J;/swA7!첒OM"t_2ut?|[mq_鵗-;;#]lxP?Ou GGG|עY8~8vڅN7xCXXnݪcѢEq5\v >>>`F4wȗDiffHs(:a@#fOh4y *9 Pt/ 4(`_P}6HA.h{jH3qFX[[cشiƍAXX*iӦaB(݉QQQ8`ªe#.c~d}^}--!" n \#+!)t9L<+W-Z,a U^ va=g@nkV_eu'rk I@&o pwZ6t*vvD0 &ҝ3̚5 XtWիW/#77ƍ0 :v^z]vpqqʦ())1c`aakkkcW\4i=ڴi\Ǐ-ptssRD9 T)/͚5øqжm[4i+WļyX!ԤPqqqApp0 Pڴi̙ӤWK^^~킃xb 2DpFrjakz'ʴ\Xj\xٰpnP-o3 FYҬ|X4w}] F8GP+(+yCw4]j0jʴ;9wAtt4>Fw2ΰW4ڷoLrϥK7?LLL$r2 yyy_>g:RJ#k1&Hu? &Ehٞ={w^ڵ3ɗ^ IIIhӦM k04ukB˦` v0w2{.F[4X̞uy'2\mYBi|lmmŠ^z:j&ZƤyO!ok޽{͛7ɓ W133{ehNC%џEXL2>9u iJdbbߊ6$E!//[ƭ[tڹ7HSo !̓mZWu2W=|bطPb|V3l=!JL[*X 㯳/_zJ 47d2Hz0^oL@}66{_XOҬS^=Sg`exSN}!ΣDƈ8=#-f8޵yYXyqX~jٓzOpp*WLQEbWEǶvb3[˱hs]%!1do%bR5F;N 7~l:{!/=X.!B!Q\Z/iՀ%}<LOcKKĨr) jl? 5+WCYL^kmHƁ_,l7EޮWx]aLJdz+ `o-]ix;f|1+ዱMaa&ǩۅq"*5`TMRNvpu@LNzbs\T77 oU#s|zV}#Pw 3\p 75r:/ۢ-Fv9{Gv4"oؙbګ am.[ዝ)-caѪ9LdekX\xZtzJ%q/r1iw)v\}h,͍73w `i.GcG383CKxwc& ^RqCe&|?Tج99XD@뙡fmLāX=9"`Էm+^v -*b lM+`&lND_e#H;Y*DKyw9anZq`frxXyC3LXe g{8ژ50Dw@f8alj\\ZÅ0kS"&np7ANa9~ "Ls`c)cn>(Ƣ%IidxJL^` hn,*{8`,@XD!Za:D#6㫯X6c+ >b(Ѧn%VB s=5W<ճ1EWWkL)=uDtne͌o_Yf[vFpsH.Âb{v&腘'EQ0eHw)/nddJh?>n Lb+nJ\-ƞxP! V/n2\gϳafKq8</u1|bńf%jzNS{!>} ^̇(r\[׺;ĭBjZn?BlzP=l3Z64ǒT\WSX%xoX#L_ ;-+un^$ j$ƠaȃgG 'oM*qroJJw[ݫ\,uܭIPB8Lgm.yoD9[b<*#= SLex 8XH2Cf [ eJ1Wl,lRS&/V\EKJۯB!I꼇%$XBO r:oA;Y\I^(<6!Z 겝AEԀq@1u5b!> 9DN 뉽/_Dzz&:7o+ys`YB q ClΘJ Yѯ_/դI#\^VVWC?Kt*f쩊Uo5.Z&VD2 "r{IP7v_W_.csg=zKJ͝66Zc:ƍCt1R/KV-BއIqq ~c5Woto5 [XX` [ "#ѧh|8;wRĽ{m{cpwknCϞ#~׌ u. <͛5[e{!~g(||ã8v  /W1d$V; ه{bkO;v~!..ھOW׫*pOn I?Evv.""̙ظ1D>>,,WDIt芿ފd DÆp7Je)s>l5?W_ %?{^11u(\\cPkh5=ށw@PPXi&߿kQU1\Փwa5ks߆) <)S U'-!o׮ 㓰k>ȐD@/ //wk(,κT*1b4L4 c7o B{!77OWtuWd8q;b&M7 ammww7dE lʐQ"&A& OFv0GIpg-ǎՙvfpuuO8TjĤrfdZ=G`Ӧhvvv:̞./?uhժ,`ט]J;AET(I12C{CU8tAII 7n#0LEqq $XXTNobccW^wmBtt/^bLLHNN͛Xr!ڵkR(%\|-}wzA|x(J(EGG{W#Q#"^`Ətm/]tEf: @`Txx @ˏyټ(e6y9ef8cĈiի*99d~^Fg( 5-;=zm[l4jF H:tR<Z>>CKbtD-RHp#JE•DDR󣢢0mګv>yرVV>̃%,--v? Ξ[RDBB \\qzX|>} cFjUv^~~*RѡZѣ"X[[A.W*> ׯY,&XtzꟷEE$Z3f͚E޽ wR]3$$$C,EGAE^d2ZjAADAAAT7C,_ ?M4\f/?\N5AE<&0G~q:)<4|z{E _89uܹKb "jϖss3u#)Ξ݋w޽X\ Hc?1o L6,ÇyѺu ޽8cӦ}¦JUrir<=`lyM2u|v+Kд&Lx!-._{a s8ܹǛXJwcoaii޽{`P4lX''p*˟Gq1|D[8}/ܺuyy ͻgpB8.] ? HD߾/gnWF ISh׮5\س 1wR\z ǎaNU3"8x/c?͚9 AACuR9AACaeeWז ({P1uu楦f`@JOI񡝪/~ݻwEر5RӔpAEASQllv#G4A^ŋױ`033\E g?@E1cfCPMBQx&}wQ `tYK|ɓE _BCr;`rj,_>ЩSWppEF jbЁR"&ٴ)oG_I RVV7#1pDdd\cۡ azyyJeiNGu;N}011)r9mbbvL&c5 AO/0 _Oi pjz)¡/>f\!QeH,vӗ U#P rd׀}IDATGI< :b!ƌY Ѫ/||4ijO ⻆iLc6:Ein,wPP5/f|ٷZ6X` *qw&dR+NN$t$ZdZ" Jߣ&}xSH^FQUOKHl‚|"& _AEH4f}Ko!?}K#Rڳ"\\egzJ$h$Z,!{Bnҟ%PF:b5%Z|B.oK[,->.D [qZa  yZ$ZDK_,ZU+4:%VB -v8!" -C"|%XOD%zD8^Rzj3M^^坨Nҿ;QyZB/u}گ#H.Kعz jG#R!C}J(4HET<).I(($H!{Xqci{R&&&lP{ ͶQ4W !Kx -BDJK\#^h{V\04B-v|B>O -. yP|4zWb2!!"Xb^WWo.ErWq-/PK_K(!^-)EhIq"R\ ݥ]3_3awg0I-[|#6BJČD΋Hq$v5|D XIJ s/(5ߖ1퉺h mQ\/ H]z Oh!/wן/#AUDhJ[4/ Mj I/.aҟn"@_[/ zDLb.nEamA{?keA#ZB^Pi/!e8'D՘w:g\\BƢB{&6+ip aX XXi{ZRH.%Hw%26-Va>^)Qj*-ђ"DWPAsBj""cȵCxi?OK[F xX )XTGA&-2V#\ڃr7i5%ZBmZ-#`Qb-B@:eH.!(CDKĉċ'Zb"_ΐBEhP apBB ah%&*Rī,-J3.ږJ_D%"jJȤ 7_lD !34|(\ޜ7EEԴ`yZB&e&C$T/u( \߆v_7d&ˉ->0nlkxhpI.mQCILR^cEJl"m 1 Aii)n޼ AAAh׮8T*RSSq}Ξ=45^{5O HHHŋo6ܹŋ#==:gϞZ6{M{Fbb"z Lxgq]յ{ҽ{wDEEAr`W0L4mĦM`iiB&W^?bbbi44i:t@QQƱtR?ؼy3VX̟?cԩ3f ЫW/{nl޼-Z@ƍ/"??l|^zIzׯoiӦؿ?g:Ow‡~N:`2" "22(B(t:dRRRЫW/Gaa!ܤs{ѣQRRA͛?0,A{R`eeeTʂkOKK=T*U_(HKK;rKG􄅅d  rtdFa߂fmll`ccS $ФI nѢE am.+M 0 SwY-Ҽyss+aCgϞطoa[ 0 ð3 0 0 0 ?0 0, 0 ð3 0L|Η"L&2 (B.CEi1cڳas:ihԱyaaXaagaaa~aaXaagaaal(J 8oXYz5{G vvvÖ-[2 ?Sm۶AѣscICrr2|M֪Gozٰa֯_]b̙0,!(غucICbb"BCChjS7Yp!.^ÇcϞ=Ɯ9s+?~<&L> jgϞ0,ׯ#..˗/GNad!33&L@f0yddffVˍ(X|9|}}aoo ;wpU+޽{:d1b'==N:""BVcǎ6n;;;^{ 111fV(x~ag*ɓ'… rd >Xz5>ZncŊ9s&9www֭[hѢBBB+V@XXĂ B|`֏ 8p `Ĉ(**]t2e rrr0gWLSB`ĉRNϼyvZj4۶mlْo64$!" @:Z-ZBˣ̤tJIIhEҪU+z(--r9;={ZvtnرWMII %{NG*̙CDDQQQ̦wdkk+oϞ={H&ADD$i׮]-Gf͢YfwVZIPP%3z*hJIIt̤ˣBRTRRBZt: PkaGÂ>9u\"007oƲeˤ}`̙o'''nIJJZF@@Q7lϞ=Pik.\rqqqϏ%&O,@JJ ?:Fpp0_W8/#<<.\ŋM///t҅o440X=z0Y) xJJJ52:okk<:`ر‰'*KXYYaΜ9Reܹر#?zBƍqa! @<0 ðWFΝ;fL4輏"""jL!!CHcbb0x`#o `Ϟ=͛Mocǎ(((@ӦMk,LQQQ&{i>3(--Ŕ)S ͛cܸqعsRT0m4l߾(**ˑٳgtBJ푗tbƍEf ҥKqi[] ðWp3M\8p E.]ЧO4mV·~={(`0ek7nBBBвeKC~,--qAd2 /s]jdeeaȨ}KDFFE ANLJJ ze4IFV#;;&pvveddiӦdh4(**27(̰nnn\XxzzB2  r\:d2#0L݂5kR*k֬ `a/0 0, 0 ð3 0 0 0 ?0 0,O&jW\1Z6 }a /_Wܿ¹c„ ϠVyHaXloSNF! ~~>+9t9???hZ\LL `oo͛W_5NxpL0SLA\\n޼idh"ԩS 'VXasؿ?V\6mڠgϞ8v옑'OgϞPTС֮]+}رcΜ9???̟?@pǘ1cꊮ]/ :Xl}DQĒ%KWWW|ǜ9kV Jh[aCjj*oj (((sss %{Eطo^xqXhQiŋ1ydL4 2B?55ٳK/aƌXx1O?5o-_t }EqqL8׿_F޽{aaa5k1j(,X@g~!/",, ݻwؽ{7+WDdd$g0o<]j&Ͷm-[0 cH N#VK%%%V(''233)==RRR(::DQt;v?l~Æ (''СC$[ݳg""zI.ӽ{L/)<<¨I&4[Ծ}{ 6r3~xrrrJKKҒ֭[gvA(77&L@nnnFN:\\\g͚E=ٴ:pt¤5 իsC_|󄆆*ѣGW\FGGSJJ Sff&P^^ZjHZ) <:I4i"M KKKUk˗/{v3رcÇѺuJE[lӥ45 oN>g}Vr___eT _L:ʶ IHH@@@@|w04<'OǑh4f&%%AVcӦMR+ƍ Z /2q,^lt7a,fhӦ d2_nƍԩJu:]XZZB&F߾}+ut,[ ˖-3ۼy?*%%%hԨ9>W$"L4 OƬY0vX|7#`F%7n7nÇ#((0 ѣqF,^r_! m6L4 = +ѕSO~@AA @`` ǣUVX)ѿڵY}v?Eܾ}׿{J~뭷PZZ_(**BFF~ ƍ+V`Μ98tɰ gppp023f@VV>\ceܹvkСCٳ R=pܽ{@٢12 ׮]Czz:}]ek%޽;$񷲲믿lݺyyy8wg*] ðW___>}ptt7oׯ4r~?M6uVO3`˖-=Zh!͊/… ꫯbر*ٳ=ztݽF`aaXhoMbf˘6m?3'0C":/Q!t:N2)))ի^[dff͛իq% :ÇLj#T*QRRFS1h"Bjj*7oRDeQ WWWisamm ˃zz:܌LKKN`W.ccc ( ( r(Ɍ 0,OXr%JKKg~1,, DM[nu-|ayxaaXaagaaa~O.^`a;<n*/ɠRݻCU͛(--EnuDDD֭[x7`ggD?WbǎXtx t:· ð3o 0\p}P֝UV5jlll̆c}\\._ A_uǎCRRR)mgӦMhҤ M???9rqqq^Z-FѣGŋvZ~4VX_ڵ+o>$$$߿?7nFaHJJ™3g`3 ?S(**P;\r([{T*X[[e˖hڴC}M777888cܸqR+XP ))ȍ ^z%tݺuCzz:JJJ)aȑpuuE޽Ѿ}{:u ^wwwj HLLOywu^p B@ll,zOOOÇGbb"~W. HzfffB`ӦMRTP]㇈Ν;CڵkÇKiѢ J OK]N+++dee xzzŋ(,,DFǼ<\zwk_UjUݻwJk׮}RRDQD۶m`3 ?cbKBBDpqq0NjNĪa$%%N7GE z$\{^^^{wC!33?Ѿ}{۷Ɛ!CP(pM;wÇJ0,)~( tTkhys<ȽL&vutZnq߿?._AU)Ts5?~;wƠA.\0Lϔ!:sCرc())AVVbcc1l0888pf?APPP<ܺu @LL (u#QQQ((((HOOV5ܻ###UcHii)^.]tEEEXzMУGdggܹs7oĵkЭ[7IM]RD^^4 .^4H_EGy[T seKyiS@0L&t ᷵05,!Y%L~ˋ?3'xu_9:p%yLAf'NHƚA_je=,!΄*WGt8ұdd~O%|]C.C;O9踴1/O lv WWW?k ;L4W,EswNޛHeh_b˾눹V[>Z߶mZ-=;wo_Xf >Jw cǎ @K\ >PqߓZ_ZK)p/&}#:z "=Z({0]TxnU+/AkɌGL'/<<֭[o+11xw,,_3_/y[;~P;8{UNzSH[4N E{AFZ`m6MBr0;{+V G+aH IDATx lYbVjoEz`pШr#Z eEhֻ_8,_:uBDD#GLL0͚5ɓY-7(b=p9e{\+޽{Orɒ%ӧ1b=OΝ~),)]nnn>}R\U>zҧ?֧ocDPdffbAaa!>SO||$ ~:6n܈5kܹsVo(FY<1_W;.,Z@o?9 P{+p(Ne5ok#+Z<V*OJ(L1=.ka?XlHaצ* O>#7:B'p_ĄDt2e d2^z%ۈ'|bvʔ);w.`޽… 䦴V̙3[o"""> aaaԩl(W^hҤu'NľQFfo>#:: 6 'N@>}uL}îO2cr_-)"A do Tv@5=!RYMdQo F鹜,e27\e*Kj"D@"B}ur)$''#88E`` 6oތe˖hgΜ)vrr2 nMRRj$@={"!!4c׮]r huP*77\#So__-Zꅤ?9X3zwQ%D['ry/ԐQz4 :Rʐ[dloFYmu1UEwL"=dMgH&UYboA*5 d ((F)))Z"/|:-- СƎ +++8qq[YYR:gee\RΔuů>fhkM+?$<&JevDewE"'.O+"J-eF鵵:N%Ͽ ܵ8H+ȭ;KB:2?E"P[5 v܉5k}hト~ooorbȐ! <ȭ7{쁵56ol2|2qqqm۶br ֎! . e-3I} 祀%0e%ɰd+ں/>gWg挰D@G ֡=0w%TeSKڻN6H֌Y|c+Ռ{FZ?RL2i޼9ƍ;wJ-GӦM",_YYY={6K.P(8xyyyHOOGll,6nQaOyƌ͛O>Azz:j*i bc7|ummu PYE:ͽШ>;x%/@Zt8x'.)?,0{c ΈV.q1Yd&BV䕥(pS}w\_pRfwd@Ҷ3f +..4m4lذnP̚5 }􁵵5ߢgϞ,XsL۷nnn Cbb"lҏJ1i$n:;wFdd$J%g:75I_OFu Sf(}Z!ANLJJ f~׵NTkKA%/KF2j 4d:PX`w %σg%V,M$MiA":u l\;I{ jdggd PZZ ggg\FF6m LF"#{S~LR GGGΆuyxxx B2r<7#ԱpQ)Pm]P߹-|_osK<% ֯5kR*k֬_?{ 0uW WOFu-<}?]Za"~}%\ŀw?'~"q!c^}߯7ŸQ0@LLV~?2$..|_iXoxP/_ө^,0Ec~D۷!şi>!G0Lu^x ])`)))HKK3z/^ļy </51 Kv,U 22ݺu<==ѨQ#o6 Ÿ R֋P(*_F2rxzzo߾صk6lL&3!Ie޽dOtAVcڴih߾=222PPP/ cm۶Aѣ&W XlY6/INNƛoB .Dǎ9͛NΝáCd`ܸq \9УqVƪi۶-.\B#77!!!hܸ1lmm1exyyչ# (b֭-}._\e ѥK΄5@qq1N>.]鴷GnW_űc0d;?32W8y$p)ܾ}Υ:~z)\nҲeK( ㏕>&Lf͚aF{g˗ ¹sÍ7$o&+OD LquaԩVAΝ~\mڴAϞ=q1ȑ#CffC] :Xlp%KЧO8::bĈ\z wN3J,)]nnn>}:rss۷ocԩpqq+WXn=֯__[@ٖjظqtɓٳ'T*:t耵kEر#lmmѦM޽@>[???Oʇ~-[+n޼YfX`Q(Xd ꊏ?寲ro廹aݺu "lٲ(E!$$NB`` <==b p*+cxM̚5 ;v;̙JӫjL~PCEt:iZ*))!ZMG999I锒B$be^y3۳g=z[oE[l!Zr'Zj9sƏOJÃ֬YCDD P&M%&&ٳgZ4.]HEZj˗/ԭ[78p m߾ @ݻwk9s T*zĉADD ٳ._L}#GQAA'NHQ.Sxx8t:]i׮]SOQ@@@?g2dݸqbbb… 7 fEoU:uA AH Q1bϤ]-hDDtE4}t:w}ǤRhՒ{r9}gtu駟(!!O3f̐ eҎ;J.]h„ tAڵ+uԉiڵ_:}Q#GЎ;HR_WY9 "EQ=C~?|||cǎF|[nUKcLL -YN>MǏ'[[[ԏ>%%%U~JmhPtt4Pzz:effRNNQaa!j*))!VK:N*O,H|@2Zli$ vZرc'"K:T*͙3GX_~!j׮mذ}]4iRkժ{DDFry ?`*--%";vͭk!"rpp0]~=JGEEʪ^ݻPttd@ǏR襗^"A!aJ&<< >+M0܌NJ...DDhƆ `2 ɓkOҒ~ɍ ZJHJ/b˟rp@DDf@kCztrrJKKҒ֭[W2f. 4NZi./zUI? Jdxq)cf̙o'''i$jH ={DBB`8z(t:+Hi&åK*WgӦMر#<<|8Νsb裏)\Vm۶R&g[v܉m"-- G˖-*ʞ)XiҤ uk׮Uɽ7r9bccH/2ty&зo_ܹs9o%hsNYߗ̝;wRjӟ\ P/ᤝo `Ϟ=>}:ڶmk2   f3GN?b X϶ m۶o/B>}|ZCCCammӧKyT;T*&rjJ3fd P ?<$&&͛7Ν;5kU2f3fÇ*ߕ=So… ضmԢ=w;WɿM۷#::EEEX|90{lnů %O/ĨQ̆?SLd7oqaΝƫCU{yyyHOOGll,6nQ..]@Pԛ7oO>HLLĪUЦM 4װqFܾ}(:t\p f|!!ٹΥHIIѣG1gXVBsŵk_Bdd$fϞ \kkkk駟 A/}Y>}ؽ{7̙鶲믿lݺyyyF_<S <<Æ Q?ggWJJBjj*߿ٳgVuAϔ%xriHRB WWWd4i$h4&'ԧO\7nr%'''o+6n({뭷H&Qzzw)@w0Y0988о}(33wN2￧-[t:""z7Ɔ7onrrѹs]vT*I.S׮]UM@@) rpp :uTܷn:RՏTj{r@rhȑt̙ n׬YC5"[[[R(4c *,,싋i֬YP(HPJDDtu#Ծ}{|}yoԤI4xzzҧ~*h7 RIdcc#}PWܿJ%EFF_T****R?~<1( '''*c?  @$)$$ĬS}3Jyr_Q[Ԯa HGt:RRR(AJJ 222кuk4iPΆEE]gddiӦdh4(**2ju-ь (J8::>Tf͚qի|gEpuuR4LL4mڴӥ6yP+FA{R`eeU3;Fll,<==aaa!BB\.KM͓ ?ð?Q0,0 0L~S5*ne0 0L=~S?'V SW20,?ȭ <5` 0,\)P"aZlԚ ð?ΤtYD_͛K|jW\Z 1}C \8 +U/\P뫨瞃J3<JQF!;;BQ+=8Ƣ.'N/[\777"66:ZVXMwʢ(Va;7l=\.p^.?UU!==]v7nܸ///c̘1޽;[' .Dǎk$dY~~5Ø}| pVk$ztF~ʇł4 H{á,=ySWCrr2󉉉ʕ+o֫gp 0YYYZbNxr22ׂ?ÇbhMP=LʆM}6{SwM|yAu0uT#6m`ȑꫯs;w?yI&?CNɓ'%7oĬYбcGcΜ9(((-Z:u Ċ+ӹsgi翘U0SN/Y}􁣣#F8իW+z ???$8 &YfpssӑkTCffndgbQX| Kr""%EDұ\Q^`gJKTٰ JJ oҾ[nDii)J%;[nذapY5 SL֭[q9̟?R87nFC" 'N_vŋ/UVxIt;t耰0)Wb6lQ ,/͛O?=ZhXbʕa  88|$$$` ի1|t .L>Pap Gr;e̝;w^DEE3O{avG}Cw >Ӑ+Z¯/#ZZ!Ћa!7rC5r zvڅ\zB`` |}}PTPEL8ؾ}v•+WFS{Riߐ,>>HgΜ)vrr~^r7lz9* 34DףT~Pe6hӦ d2_nƍpqq0aiiYi<;wĤI0o<kDZcklZZСC;VVV8qD.))ѵYYYA.:LlMVO@*7Y.^~N|ne]/6n܈ŋU0 m6L20l{QQ4Pg IDAT̘?aÆGN={l2lٲO?7|AgX[[c&èL}||PPP˗/Aжm[L^Z/SV L g^(߭/W>˖-C׮]1i$|WGFF^z%( ,]RAa޽5j)T*ٳgѦMN˗1uT̛7#FZ5푗tܽ{7n(@fХK(  ׮];9s'N#\]]q+\\\*߭[7޽_5Ο?>HLL,]*ѿXSN_T;ͻwFaa!֬Y5kү])S`$'' ,@HH}]ܹsBvvvؿ?&M֭[CӡsΈRon^|ohgXv I&^.99k׮EPP49= ¨X1YfokkkX[[٫Tj0Vˋxb< T&,LC}SyްWk""77>>>8}4ڵka{3ͽ ~nxԗ%S_1[j/4///3M(߭ c0?0ob751ˎşi=*{FWY`-fB.;K ä#([ 1JDVrLlMeO8'`/Ol :Ly.޹GQ={˝[Q Q*%$AF[hE~"jm--V@ 1PBB&s9Y&IHH6_}<|?;y4Vn &ֆ@sPs+%mnop`k~nc:V]nσ:ӯw K,`^`/|Zk9M/=='5:b:GuhphrFTSQէpr>ٮ!W>@Y%2!!Kh'o2U ܼJS+{]σFu ׺6(;؝kp~򷃷swA_6Ź w:]WVoGCfCUox|Wjpdt4Z:C}=Q߬< mW=l?l %qvŰN5$<_.==>B ьnc& " )s}ekŽ795su.Wp(f]6Ŏ=BSTy~i#\ݦ24V] nczq  ~>߮wY>MM<AZ~0'ĉK:O.4pKkm] B9;Cҹ]:v#i\jW~~>z1Pre&N e+ ~F%“ȦW^\tt:q8eKzÈ/Bآgڊf7BC_!   epv>y((t{t aoBw+'IP\CX_m[8<8]+UQᐿY3+3\ 0zBEA8#ѷvUڵk>O_hصkWSS ?٦ѣ,^/.x^p8ö~{I|z73\ ?ցt]o4P Xp8 ccvq\x<.gss{pj(Q:bmP6ى0G k*oZ)(.K 谽4MkTUEQp:l$BMB߼vMA7:4>q`1 a%Vj(5Mkdۅh yK\Az~S].W0`/%p Czeha)NSA淆C=~뷆C `}o7_ 햫C:[;TU |hri]64lCfc?TC} xL3Q&yhRO{o'"!޹) % /XCٷK [7C tLmzVfDE"-i4oFDA[L򳊾g~6[Χۉ?(~g釫2- !FҊ)f.i 75Dp>g;nΣ?;"Uĭ*f\ZiNEوmSגp\r3 B&4$omXM7%;%!~9%vBmT|emeAnymHyͅi ؅qk}̫-x;oʨZׅDBsBh#XX w!q1Lws Z cHH>m ?(!-u6(޽$OSF8i`zIT^"BnFہV&W A{h+!b % mpD֮ spQ ЈIƾ><YC5^__V5$_Gb@322j:4TZ]m۶us'"/t@_|>6nرc[ 3m لesƦ-_|Y7A6AYY <&;x 3 /g5[j֬Yi~AhA81c޽{#>o WUU*b")..&''͈#>:O>_|>233yرSNs޽{ْzZM66b"9eBsֲxbV\IYY~-/;VPSSCUUUX%ؘ֗GFi@?<Bh}:l۶ ]׃dhg-o-Vwޝn,222|r B"BpBƌ߿2yϪ^R .?xixiiiu&DEEJfffwɓ= :1VG}t] ??~ee˖MSHKkys;жѤ3alF6fE&Yjr [n%77b àCqh8t.'2 kSíPk$[ߔiĜu~xW?>> Hc_rxV a``4å|bb"G櫯Ln&AhCY_h4СzTTT;zaR@q((11QF B2d`O?~:ӧ80*Ux<<bN8 66*">VȨwsKؿ911gL ^/_^L ];usرIZ?%~ ~>QELK9vXdψ##޽{1cadxGuo?6o̥^JϞ=~z ¸qxuo9^\v-ÇjrF) ,/RSKgu|joE+w5G>ڌ]] : jP]C1% G[g_pׯgҥfeeQSSs=۷on`̝;={7RRRq:|8۶m ',/4Idt$^7>@@ ɄhVp8Ɖ@}8IΝdqZKii)u˃upDCM ҵK,]b\weOzS~a<zڷYTUn~!Cзo30^|0x`P/t(8VGёB""pcN6(?@L>_,Y2hРs򚚚Bkzw}7?wusi ==^{q5oyIOOO>~-Zĸq0a[ne\.4fKHH %%,2I`˓9y%/Q[v.a q o"+"`HEG8P](t`ҤI >5L}9R.fVݻ'RQwKDjwv-ɨEUUUŝv✪*n7۶dSKKKIlMmݱcbȐ!tMn>A8Y_ĉ¯}D| Zt )&ruםWnEUUifpԠViӦ ]QQS_xQ.y!USbp9]hhFN78n\.жF`:\|>>S@smE?uT(>|)KܡйO_̀Fs%/AySϡ{򥥥ܹSBpg EG|4+~vyΡYm۞'$$p矋/"p 55])o_>::ɓ'zٴip8HMMF ӣo.mWF7_>22'( ^Li¿B322,B ۷op݀<.{Va+o6|>_ BQ%OlXn]oQN a' מ={,n# a+au1 u}&F=cr !PO.jiپN{me_g_r /ꪫKJJ saݤpBwaÆt:ٸqc0wC4s*wy'wqcƌ2|prrrp8rz2e PFE%t8o@DDgf|dffk.x V^ ORR999s=̜9_W,_?OM#i5559r$|lg}FNx7֭۶m^7d޼y9s&o6Fi>TA4TU%//UUq:<̞=ɓ'3sLvAJJbK@t8оuFbb"n@ 5kuEa۷oHz͗_~ɖ-[(,, eYgUU1 #***Hy(//gΜ91c?~IDAT#VZŲeP&Ͻyzz?]2m4?SLMhkנlݏc|A^~e:w>++}rw(k׮qWJJJp:K(܇<~xy衇pHOOgɒ%$&&2`Ӟ{EQp8\.)))p3 kطosΕ@lt aa}IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Outline.png0000644000175000017500000003635611665471336030333 0ustar drazzibdrazzibPNG  IHDRHhsRGBbKGD pHYs  tIME  !"50+tEXtCommentCreated with GIMPW IDATx\M-t/aXIbX1>Xlc7-hX3?EDRúu{ST^=}=sd=Q. "QEi)H=DDze+t\P]:?eW;]ph$a쟒| Ȓp'9OD[W Kz!Yܭǫ, ǁhI_;|AI I*i%%Q53$!IR2i s;!C@HȠ$-3G#ԯ ;D> )$+b\k23ԯO$ѻq! On;Y`SglԸ Hb%󕞧\7EoA2BfcdH=qk4$Nr!Y)xdQ$d<{@0Y,._FV>y#D"%vop ko 8%+Y Rr!)q!X.[CJmQxp~G 鎘?j?$_i$ôCgMJx+Y\bqQ&U:(!n(_+7sMmw`o>~6B򴴵xnwcsi~xʪӛPVx --M am˛wƨqp68ʕgg`V bqd,\s֚2Nyѳp<~cf- `"2PۤtH>^qJMp<-%-K@P F߶mZAVSaҀlBSƮ=0~r?GlEnh֬)-P).JvOBXoהe7|q/&>c> FPk1M;[d Ef/ ;#=`6ήވyGZ^XX;`9l4|W#''ҿ#mumHKMdp|bq1uO{tj yyy1m*n"#LԴCgj uv;z°m[@WW߇OUnKuU}EEEX$V6lzoiS7nBqqB-n\˭ [IIݳJ  fU' %""-lB".ͮ\Y1&`uÜ۟7%Cɴ;wα0˔}}Jv}!dBHWoµ[@{pۇɧl@PtFPS\T _U8fV.tMVǓ\z孫:7uZ6ׄZ#\;_;=S>&ԛe\VMMM655ӂ,inص~>ߠUVs3-^iA*t_N'5 rc?/]Fܸ~Ϟ?/W^]JmGӦژz~D;wb݆M6ضeRJZZ k[]O[ˮ'ΜNޭ+w/;/7 |F+W,(ɧ|@ʽRލո ҫ"O^ĤOL}(A7k>,@wk[檶e˖HN/6^V e?߈)T544`dhC&D~>4 ǎ4ՙ|b;9U;Ttnذ z99Ŏ_cþ3tN&~)< iXzyŦBI~(eeM=ޫ^#(;0{J &,Mn<é~-ݭƿ߬@S kܘјBKX7oaCM pfMjݻ2Ӻtu6|>z޾Fzzb<|!^S/Fjj*s( طp1֡tBL>>](*vEMsfgǷ0BW$P]-@OCujMFkk :[`W""XczG:FΓh0hcmSk3uw4Z[2K$w H][?"Zy -IF-Ё9n]z~hںb]ƀ=VN˵q\I{iJ-.<j];rX!h yT !h d*.+kɼMD5ԽxȚx&xB: yV:DTQ"ȚΨ# += wn]GVˇ֙uD}Ț vxq}5.suOK2<;yW܉GQA-r"2]pg6 ШQctjO\Yw_i{jlJDo~$(.5^K?RqrU4*l9,mѱ9͘\;wYv]7LKk 8P;^*v-F  հ$hvQb]IL].TR}Nltbq %z~`B9Y_CԦ }k~X!sx~=+¦5b<#'T[w܅ E"@_^HA x[v&Mď7?'435)H  ;Žd (_~O>gϞ!DT(žu\ PdWMv-%iNbWW@ Q-H$H.6[DTtܬ7'"E""e29"jvTna*O^$zgkXP|>?rI#b)&"bIDv&"bbD"ЩS'!##dLL tttbbb^yJJ RRR555||Gd>}===DEE!33PO>ވ-ZON Dn`ffwwwʴ@׭[=zm۶'O066FϞ=.sANЩS'̝;2mݺ={1 ׯ!b@V7oKbLL \\\y /Jhh(p\zB2\t Gf͂w^\tI:ҥK={)))XlL}ΝCdd$쌹s!b@*5񁃃tZDD/^֭[CKK ǯ*/B?FFFD"e?Zh-[bѢEؿL}hժ4440e!b@*AAA5%i3,]TZ}J籰@zz2֭ӧ1p@ǎè#g׼yskuuu!z)|OIH:9HIIL__QQQhժYXX`͐H$._ y,$"V tHH8Ve„ 3gݻ"$&&ݽeN[nDc…HOOGzz:.\aÆ Hx#6}tbȑ033ôi\2ƤIо}{ 44TZ兖-[000mEDT3]VYTTT0c ̘1C VaP("$$!!! W6^k&Y[~P"AM y 7  [7IDTVJn_R *€$"b@)G9L"b IDĀ$"b@1 DD Țbnn.3'''l޼YfMн{wlڴIn%-&M۷o-/=.wsslݲGD ȷի4i<=="^\\۷cܹرc-x#4k ƍCoUX&N(ӂT7q]UD ȺرcFXXzU|3f `ѕrssqFtImֆ/Aܙ'BBBХKre}:=ʣ]~ `ddUUUaС2?[Z-ӧOWk}pwwǭ[x1 6̝;'ZF T{}999 lj]7B9’. zj̙37Zhggg|Wh֬Y222h"888(_x1 ߾6müy Hpmpss6틥K*rDdxxx >><ڈ@ @Ν;+ollP#yA1QQQHKKX,?%Kںٺuk`߾}<ڈoH$*7={6"##SSS|x֮][cgܸqyACCC᮱=+G{)wtt#6" Xtڕ"Y :t"1 K>="bIDĀ$"䞃!" DD H""$W ="! sb kkk|WСC@ &ڶm {{{@GGVk׮-lsss_"b RFrr2\]]䄓'Oɓprr+kl=vh">_Lf#0`ȑ҂F YF2Xr%`mm OOO)>uuut5=IDATç~UVU-=:Fxx8޽P[u={| ,,,0h ٳGzͱsN 41b"d]ry 2!Crqu޽gΜP(Ċ+^g}V:jj񁗗jtǴi-[իJm۶0`|}}"d]S镛WW&݋ ={6?[lO*<ukcc[[[^Fס4dffuWoooC]]'NDBB?QԠ4͚5CFFegddTxѣGZe/("--M4ޙ3gbܸqpppUcʕXv- ///OzJ?K\(B,E Ⱥ_~)3^.Tgu"??BPں6n={vmY9VZDx{{ԩS5~NM6aΝEnn.vڅM6aʔ)r5j|}}q}b$%%S#!!AAAػw/O.-{i&2]]/aԨQXdI(9s(**D"iY`Æ Xb/_abb"wWWWlذx1LMMVekK @]]ݻ+ .ڵka``WWW=z[رc+ ~eѿ̚5 ߇)jt[;AfCə0<~%?`H˿܊h~Ր" H""$IDĀ$"z YqHD$IDĀ$""$HYoD"R###nnnrPY=dA"b@ʈСC(** }Qj%3ܹs;w CCC;DT7}ATTrCreñ4 cƌ-ܻw...ر#LMM1~x˴BE"5b[n033;rssnQdIHn޼...)tqq͛_+;v,Ξ=+wqqɓ8O" E\\9WB(" 6\@V```'OHǣaooPmmmxyyӕŋu믿&"(ttHN4 ׯp^>ns^.^ٳg~Tjjj*+3:u%"BJBrС}α22899AKK ԩSu#** Z;LD.)))5ϟ?G||<|||!x|AMM ɘ;w̲M6۷eM0s{PTTD& H"жm[tgF&MpQ[|BBB?Lpvv=}tbȑ033ôiw"zqQ5,}%"]l""$DD H"'43D$wIDĀ$"b@1 5\:  )+aoo///G>TUND :->>r! q 8pǾ}[l Ξ=(hiiaΜ9 QըgΜѴiSf̘Ç֭['WCCݻtZUDd%HMKJJpsΡ{.'"d`dgg#;;ҧ#KǧZDĀW''' :mڴN̘1011QRGG}t|߾}ٳ<Ʋe\U[… #ɓ y-[ ʉ-:%KnĘ1c KKK|2]˗>c:cccQe91 봊ÇKoQvYEʉ]l""$1 DD H""$Q{IDD H""$IDĀ$"b@H$ʂڷo]"$$D<::#GDvcƌHOOWuZJJ RRRyyyA]]/^ٳg;vHGL2׮]ӧS*\ND W‰'Yf???L8FDDDHԄ7t"VU9Yo{kbbb9s.'"ddee!++ >Ųe˪UND z%((YYY# [ncĉXf ڵkt91 ]]]_oƕ+Wкuk/`ڴiXn,,,QU95L "'<<>^n?B!N8طo|˖-pqqٳg---̙3Gr"j/9sǏGӦM|N30|pujhh{N؂=5))ϝ;ݻWlWD,]>>>*'"d퍬,899aСhӦ ttt`ƌD4s:::CϞ=e9|0-[Pꨪ؂.\G'ODXXݥ[lAHH֯_/7*'" ?.cƌAvv6,--t/_eꌍFDĀ*.Ge)'"vDDĀ$"b@1 DDOm>GD$1 DD H""$D"t(+++ nnnh߾=v튐 -:u$-H$@ΝѥK} 1 뤔-򂺺:.^g"99;v(lqI˷mۆ .ԩSƹs#Y8q~~~h޼97o???l߾]ظq#&O,k.xyyΝ;y1 ?yDڵ zBVnݺnݺIǻu놛7o!b@NNNGVV/Xfj //qMMM!b@AAAʂahh]]r8pfffСX60Yob}6\֭[޾|V´iMر#qqqxx1 ?OOO<|8|0VXٳgsIƦ9.]GѣGXt)F# jXǒ%}acc7LfPL:UnǏǽ{Я_? 0f9D { `=zt۷2@o| "vIDĀ$"b@1 DDo|233g-H""$IDĀ|ܜ1 ޶k>Q .`ر W;;;- E"_]l;;;CWWQQQ,7DEEAWWWpLAA|||`gg;;;@7n@m6/rJ8882ϒ177Ν;1h XXX`Ĉ>ݐҀ, UV/@LLLYLL ZFxiii8t<"44|O??ؽ{7Μ9P+V,m۶0`|}}yQpC믿.0o<:tHfa͚5߿t޽{`@SSge>1qD$$$ )ttHN<֭p J !3ϖ-[0lذrz=z!CL2͚5 <tH;9p} ȉ'iӦ8qtz˖-}}}DfeC2>>V>Cɓ'x ,36oތ={`ݺuF/߿X$xzz&7Qk3k,hpvv>fΜYn>}}}l޼QQQXv-puu5Ν>0U 3H_^ CƸqQs  "qwt4R[񗠝ͯXIDĀ$""$& ]@DĀ$"b@1 ̙3H$;^E#"dPWÒY'ܹs>+;; @VVVܼyzp\ U"b@ָv;v[O?J1 QF^1c~L/,,͛{;v)Ət.H$@,#00ݺuݑ[eɓ߿?ѳgOK˪S$a֭ٳ'1h \~G+Rq]vq'߿h׮\\\0yd!..fffHGȑ#z*B!ܶYfIIIػw/.]$-Ss!22 pvvܹsy1 oEYFfڵk1m4@tt4! ///>}Z#""xbnZZZ?>~* x1222 Thժ4440eh%zɶ^zAEEΝC޽q)pE >>Ϟ=PqIMME߾}e)urJiӦy(**JĀ^+2,, {i=|||---SN ׭(jJm͛!H \|$"v6p@<|wFFFePSS>7a̙3CQQ^rSNŭ[PTTD"nDĀT@ ԩSQ.hBBB?RuO>9r$0mڴrg4iڷovDEc_'L!zgkXJD.6IDĀ$"b@5PrI=CDlAr1 DD H""d.^>|7YZpp0,X_&"dYIIIppp;ID Ȳ V"b@Ur\O?k׮H SL'OQ Ȓ2 {n\v 0m4L0gϞř3g`bbe˖'J5Ⱦܹs#VSS?ީחr VX<r~%"dW_aܹӧ455;;;DĀ,((@&MФI`ʕ|牨JW -Ze˖'N%y"j-Ȳߠ2ƍw؂$"b@1 DD H""$Q=!6c&"b DD H""$ֈD""b@2H6,%%G ކdsG1 X@t fffpwwGnnyO<={DxxVH$֭[ѳgOcРA~9r$0m48;;˝w4iڷoVks΅&lll+++4jў;wwիCCC}ЧO4k sN!'qԮI&aҤIDlA1 DD* 333g-H""$IDĀ$"b@Xj MMMcǎa"zwظq#Zn,bڵ H"zرꫯ  <7oΓ3g;v,.\ wް… 2gϞ'| 4{쑖vvv/ عs'  1b\'^ /^*RM:ƍٳgqYt &MÇo>DGGCUUW.3|L6 زe ^*- EZZ:Ç~u<66۶m1`-㏸~:vލ3g@(bŊ /OD H|whӦ |||лwo 8AAAΖ={BMM ZZZX` ٳgeԐLnҲC믿.0o<:tHfuuuL8 Ҳ{[^ތQ|.IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/FSView.png0000644000175000017500000005754211665471336030057 0ustar drazzibdrazzibPNG  IHDR# ZL# iIrwMrI,8u⠓f*.bAdWPy z &DX-.\(0G)M|^e}n^ r婣۳uRR\^U@pHu 5@. @@k kHHhw8o|-=j ԅ/+cmxB8v+bs 3 |/n-8pw_$ ]}h'`f@[q5`:TU9UXz']oa`d@xn ٜf':i2 '?Y/y|U[Ώ4džHz|2e.wzCKdz L( 17#; 6ΕS{1;a7juG^i%iLK?H,baGc& IDATx{\Te?g朹UA 0ZM-/P6.6mҴn.h]rZ"Zj-6@/ 0gff˙sgyyC566*7xCՂ@ 8ay>`9s̿v=e!8 w|Hۿh^vlٲM6_9sT{X|ݡP(" vaCCIWc_222xW_}j.m$ O-mW_"hZA,`@4IMVWcts>w/JIDuގQ`YN3h_|<R|xO &OCJ-p#^Wؗ<[ߑWh>SJCՏ@R1w.1GCF@u-+SFUKg;u]A)Gh՘5n֟t+Gd/~e37[--׼xo%[F?먜ƙ6ƒ0/pοOMؙˋ3߻NOrmD0S0ZkkžgѭZ G?_P4x/_g(1P|[ Nbw"tZ y]q$~\Xp??/aԉܥ#g*4q\,/_jכyG&ݥ#vV _ڧοthgd3jPY&uVqڅ}UPm_̊u w疦PGiӸ,"e5g"[Yw.>' l)q]i[w6#ئoܿ70S[gD]ײL 7`\ɽoOw赬4[TsFF?kSgBnorػ{HX?ZcvOXF44B?i31˲"[e9tlΓ?0gTzƘI|;e0T$^g+Z Yb"qAEּg GahCS| jMguʆ>cڟ]7>rQgh 7{'}穃op4Gwg??_>u5fk;Q_@<('>z{W}/[n}hs蚿e>ݜoqPL<4G$G tn2ں6{Q ƽK. ıiÝ:,ҢghG Oa~5pC=Ś.,5ŗhU/?~/M Gk(t\&ɇzeo/o'N).خ64bncc[|UC4,@ykմoh Oz4l/:^Pͣ#xƏ§o%f(  $d>vМi#7PTV yᖧ9E*蒿y>ݝ5&/$VʁEMqg\؜_ <;0Go.~3^h@Ʋ6&{4my; 8 qyf ikD4M"Y Y0q"$"xئ)jf07ЪY(! SMG 2KTvC":uL(e|%%)(BHX1)УLLx ?== *f,ߙO7DlyZTe#w~MOb:N@)Mw̌d՜~κɯo_wb=̞fZi\ 6o8Q)ʻ=[Z$&NaGǧWQʐӺb;-߲48`Eg%vw׶,>|gmP7k2k?_oVMZ5Bx<|Z|]Uohι[F{4gǧ긎y| 3f[WeDOL~،"bioY/>2iW yUB>3IDw<&9+x>֮1C|Ei ]oWYu[=Wii(T@2 i42ͷ}S[kE7]/N70okMV;;rvܺh̷q]č$s̓wnÙ8޳ >-}z:/Upk/^Kͳu+Fbѿ>sܞfN rNq,%Ƕ`[Yxx{\.9,[ƹoo99>]jhA niች>F"74-m5-nkZZڔ:DޣC,󷢇ө[u|H,֯3>՜(F`%tSIDF:tsUԫQ\Cvͧq^xF>2#5԰$ O/9US|7|7iVel AȬ!02ȸLk5ʀOs1v/zdT6k qaǑ73isR^,n=s;iHo\{+=ݫFf,8L>^wE Y`M bG/y͞~qKw~ OR" 푏g*?x 7F{Q Mme* :*CZOZLO.ο2>!+̻/P^S??翖|4 јGg$>3V׶0WZK"nX6mjhn7*ˎ ܰIFDGocMEߒ씟g#4`}n19 Gcb"E`OZuߞccغWz}6-AɶK5Z=W*Zf1 1IJz䎷w ]O%>};a:6в@OS{_ TG(4F!(}ο{Zi g ?|ڼ e9NcY Ҥfħ=}%-826e(k +/ zW'DPWYFM pضC:0aD<7>#/66^d)oJ!X~+K/@\ӟhR7?_llDOّftk~)0V*X?VUёf];`xcӾ8;/>/ @QB}Iƶܙ. iLc4M'irNЌgDFѮfN/ҩe[Y=DGNq76!674x  E P5]]ի]EMqa/xxxTTI@~Su nRP0heK΍ik3*7OnA??`AK_S.QEvQߪom_4; 8.s;lG[[H$m8-;m pssshmE+[ya(=72cx9\e&c|zO; <9ey[}j5M}i}Bc℀P(<ҷv OZ2V`hmɇMW_Vyj-RЂq}*xS%DSi,g,QC0"" rEƦ]J$Trmò,hZD0gw)[9D"bYs;*AKz;!]Oص%+evGӣz/|EV <:d[WbSs\g;&m'< ?W[4MӍ?Z4]9g' ~(xmגo K֏O׊͋VeOiZXoEn*˷'0bXPTJ @Ym)վiZc=KwݿbĞu(SֽtOJ4% CPGw̡(L6bX՞){FVvWxzKJp*aZcҷٖNJR(SyyF)ʖF'lۿoU%G? 9e'LX+kSjˆlSJ)ʺ~ʲU Tª},)t*h.;5޴k;4:y:p^t=ޒw~sM3Ƭۢo[YDž-'{ x6>VcV!ku}93 ?-\*ψ9%UU hnI8kuX\ |{]GdRc'o-Dn}(w[Y|ԑb)55Gr3$VG OUUɋLc(Oˏ\i3&˯tWxJ.K*ZGn@ $ip8SX[Ұ(ww駿y/l}p,` ϸ?KuMչ<9_2$徳l@H~y m$jɲ(Jj)wnv5o{H-{6ɹ=h +s,Q0Pi R++hѹ{7?X6ɞ:u  hC^NtL’J,\#ϔ7[NC( yzoo 8M}?ͺe3" :@b<&ʢ,y@*ƏH 5uҐ(4! &! ^xsi0Eɻ-Jlv҉xx"!Ti?mݼ)>tԜf"*=3Ni1gC'hmE^8j'iazL|2Is*`U²oO\hiiR!qBGG<{0fYOkg}Q4cv5[KWmKf6$&o+,ZY[[YgQZM*kwZ!._8\4' '6-?1EJ+v,~WQx6mե6-,BQigƳljZta^JQe-v/زV,/ܞ*CS3$_BwH2ū_/U(K_X dlFղ4,`mwt< D˟D @$[>iRv^IJU} Ď ۄ}G&46Wn1W3[8фǯ\yj^n(Qxt1$fƭ._ļiS N-oW^Ф X8mdHmӗI+%$4,' d14=<)o9$gO Iy@ZvE>qi4/uffoLX:#,زHN`|ۜ\؎;' d[>H $01817K耑XBm)nK5;kdѶU*B B#k:0HGsJ^QiiiƵg&۹xS#y)h>"tK__y&SNEEEyyy( KzjXBA,o9**YBT(T*9cJ||l oB#Jsm OV.B>=v*vT(96? W`qHyScCՆVTk9ˁM Ǝ=ڞ;K~dׯw4N8f;{xYwٹ'( $>D"˜:s j}s1֧XjЪQtY\u66qcpsP(x\Fy{@4*:iuΑ3;Ǹ7zxëzh z%Ǿ;͍O# ]Anl>A J 0aM},.(>o)F~iN8:MGP( UN v`m{Isu;u܈ֆ߸J]̲dNac)2kXzPؠ3 :QoS0g7eqs($l*XuP笗ZN 7,Gڣ/&}wl*,o@@'5gSy:;R?6%柤s˺ڄa)tRΝ;w\ssskkkKKRTZX1q֪79ZL77[&![9G{N?ܶ`ڸSEbV,rvLz@´ U~6E5H=Xop O?q=%/tj̙3˗ZD"'M4rHSk{ZPHXXXHPc?{ط)x?Hyy)Z`oJNalەMQE-qԘ|9Kw2EQTtʾ.kv..^?뽢K(,]wB&Dр$·!dܮiQQ11111Aƍ&ra^8_loQƜ:yWf|Wg>_켳OuO]& &]//Z'h57C',u ~hqSc|Mq%. YؑA|xf΅a\Ҭ2"}}T͔{<#%mW]<)x^ȱeLm_(7~eɖ]ǫew[ V bD,k1|>a 5{^}Bs;ЈtYR FbʮPj2+[[<~cqñ8˅){XOpJ{V\>&8F;3eٳg: /4vX]P U#~^xx^2c}c>S&Wu"*yC5%%,+UK ZoY[U*Tk=@ Ѓ72="^9?mp{*! 9{OG4 zz(=z= |óO#\ =>% Ex8M@`mO#FWkT\ܬ(@u4Omj(q0xQ`SOSx@p@ 0P:A^ztZtLN5N#4|VcЃ 8NN 4M۹<x<![^::Zm*S/4bah6d#v#u[㉦/~jhtjUlK[[c[c̯b؞ 3q e[g@`K$Ob7Fix;ttZUkjET*u OOρlU5US;n =@U āNU5h dۇ8ryIIII{%( T2c}c>S&G/e_~ =݀تn@{=˅ C2?@/d~0T 2D $N# 3=vÐ:z(Eb7 X2pܿz ݀  tT,Kc'8 2pq د7/FZ0p'$&*#D8uRb*ziaug =cOq.d7.E‹+>i{ Pqa}s\nivIz\%/g/D 3id7_l(jn@Os%$LlX\(j??Fb7 ii7`ݱcI>PB݀0e]R SYĉv"v[ ݀4b7 .d~0T 2i 2D!m7tn@;8 e۬?ĶRa=A5Kqo8r"?/1%vC輧qf5Ns}$!13g&$$$$M_]27Lb7 ؁Uf”q :)߽$(3wIi 3\n`jF,X|9=zǞ4Hwvdb7 8iq%/CٚFn8Wߖ dΌ1hn@p N\n(+ 1F;'NL n2nPUh"mc1].d7Q"b7&gX;W8և 5cYvMbܣ l aϸpaCO# d~_4iB!q0TpnvNS8 V ܸa`7-)oppzy_9b7 8 ingjof݀+ jP"F]i\8b7 8i.l7/X)]<9 %=%6óL݀3ibvsrys'vpn w楝n O7w?ͥa]r8 :hO ١a!3\n0z\@y"i1>4DaKI%@;L8vSc4۸'=`8m 09rc4K\n)k? %z8 vpBv=i9o?.:Fv6*4 H=, XBTY ZOv=?UXozK~dׯqb7I|Dn@{=˅ C2?@/d~0T 2D $N# 3=vPJ뢱ں.[-+ka1p݀ݳe՜L*1I(A}<=҃MGꋒ}ɡ8#JN dWTUTTFNhWm7TMIggjcSv mIyO!5@NqHqtԒ}ۓ̝0#{ :,}M*~+W=1KBTw쌟3)&NYu`Jfplv#*'蠭4!scxFA4:afQӀ5%]c9sܣ+ lF ;j.x._:3oaw/O$8 QLqn l ?I9HQo4>1q @xN~#y܆øm v 8/4E嗍o{usI"feT^!( !qfK s>j\SOG?v6!)A)TܽXA^,ʊ@RѮ1)NsMS)R q|0 ǖHb>9096/t((!IDATO.7F5]] ɹ~ckb77, %qǧCP;e[-!CN8Wt CKVy&Ռ`0?m@(d~0T 2i 2D4׳X%K݀8GwIqvyVb7 1pVUb5 U/ʩ83vj 8ŬYL"V]R$?)+:fh7~&fAБNZ8#2\fϽ/:b7 3psYTWb7 gݠ[݀`=ivn!vBqLf׷#NX (xNh#vBqGnq/FA mˆ-G|&-0/֓a|ǯ1v kUwe$ߨZ2޼HÞJH%k'sX^lH 0 <) Qb7ְ?n05ɴA}VnP%Ȼ/n0gX;W8և 5cYvMbܣ l@N8aCO# d~_4iB!q0Tpnp5Tuwnp2p݀M1b*a8f֪*:)_USUQQi;sѳ donxv}JTZ*'haGn /))9Rd7؞1:31j7=4;GDC2cz;?cj7P{ 74)b7 aOqnP-%t`7`=jU3s݀`Os}[qv/ f Rfi78!]v%`f7]11Ij 0koҞniƕ 2@`H-jE#qnk܄.v9BW sh7pn@ in@\4a@eB!N#Cei.f7XE]]] 1li# S *Mb7 t2pk7-h 줢|m݀'vQQaJft0 pߞMIyiGVh݀Gٟ6,\/;".]T v~0fo;xg*q4ư>n@3NXp298r*T$v`i݀STU8e1V!ad7_:+MH$;iGs:Fv6*4 H=,K 8VT*>f"vaN{~d>1X)Ȳׯ_?]n@$>"ICN8aCO# d~_4iB!q0Tpnp15{vEm3e#vBqLM͖IȯzVNўS;n)fbo7uϖgD,`uSܡd7B,Y0: in'"'˔ _"cah7ܓ1//Tnfy}%vivryw҆`;݀G۟vxչ*er@:®O6?Ns#i7 aἌ-7]n7@0nW8 ,= &Y_lvme7O,o4@3RVԶb,>Id[Moe_I.8sܣǓp{~2Yg >np14iZS {t#&/^֕s*ߨ`&ml|7ߗ!GR{y&t en)D%̎j^B=瑸puJQh7H#vkA6fu] ժ݀w vaå@1ap!F 2?@* 8@\HF HF !1ӆ@\c}inAZzk[ab7 {gF_al7Pcb촨p*Dv4ӆ@4vNJk>(3\ngب1wuRLYa,if$$=IZ՚K|b7 i6@Fʖ9e?LiϤW_== rOvs I6J LQyYc4K$? K+Sp< /eLK]݈*9NQ[YViWהn`nP[W{8M2DS*U&A[[[l]2HG˱غ:%`2z qp'c%?+K74݀`=qZ`jpiGuB[ݠiKzdpiT(XK,7pOva_X&to5^d6mq.m7%>6j+:l@AF 2?@*iBkiP\]mm]np2p\t 3 Ñ݀G [Wt ᔕ'|;%viL3?J ŤHQQPWI8H8ڒ=k/t%mPT)eզ|d"{)v"&;{lI`ce{1}y7B|v>lP42T)F 1΍th7@X~΁v$F np/lX %<-h7ؐݳY2[*yD'&oU 3U w9?|ѥ{ h7@DS(dh7@ROCłi*`,OC'd` B"vi6-  XQv\,Pf˛c H#rd4M&a@Kid4O7=y d+Y +doO{fN}~?vCݠ]6oh<"k7p|7N((7BH 7O {t o4n]jh7@B&OKdݣ @G{@1' IzcmpHvo3 n4 3/CTp{$,C%\O݀K_  mFB4! Jvs7KH Z,N`Jv@A݀T X !4 $U4Y,^OC$4I.!Hy,g7pZy{`B,Pfˉ/v$n@\(ڮ2z۞} Dnp)Pڐ ϵ 6tBP`H$r=vWTPG^9@n@B4ir_Ш-թkV H'O (&07`φ H2po79ipv ԴiKdh7@b&yλME=slv$h'܆I=gd%L1kZN&snr@d7uR Ta676FdskkR=n@2v$H4uBKv$4Y,؟ !bI4y< A i*$qRn@;-f21<\nIJtu _%AɳJevu0n/yvA2*}v$F݀Ia03Ʈ.X^la<;np,GDv | sm Ƨ`U@V4\ H'n@|4 9xT+>qTVVHS'nMȺG #W6.BY/v@V@3]O:x!txc>39IiPv$dn`xtR zn,K{sDn@_9֤O?m&'''''m6f2 >[vczy$On Mrq5AAJ~6ו=ǴoZX2 v! \CCC|0܌FzZn!/8 gq7E߳eT.Zyo7 իWJի% Q0 W~322$H$z67Nj**EdПl>zR=nv={=44&Wy i6$?7Z/I`l#KJhdϞ=˽=wlP %^?1̭fggϟ?KW ;wڵi,J)Ji؟ I$A,hqLC ymWߪϏm깊؝}=\]W_E X4) [*GuK^Vi`||fMLL8N򦧧ٮe˖gddRiB8/TVRT Gv555Z]]FݴiSmm/\UUU^^^XXSOEs2FӨpXi5ME;1vʺ.og70̌F‾aƞMggn`޿kuzZ|4 dwW(d$ 7jL+Exo4ۦ|78G M_^k:5`n=}8C{{%P h`=vd[<wm>s—ԩVje_4M$yv -4\cEsn{vvnK_"i^FsyI)_D$☆<4m4'''!}EQl{:RDIDRJ$"W8.X(dbD<1K_f"@ 3n\xf_|DD%% !"Yn+_ACDF21-Or!=~I "ID4rH"^0R"i$ $$LڇDH%b\ ՟F RL-eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/9%bKGD pHYs  tIME  )VD IDATxw|ef{BKAJ @  w"PzN; 8QQr"MD,H l6ewg~Ih_}<3;>8;9ʥKJ3: z|}|quqƍO!DݻJٲer 7odذaԮ]o[.ݻwnڄB3\r888`Z6 gggʗ/N~+ڵkR\9F#:M!3#S~7oڵkE`@Q22@Cg0rg||=!ѵkWz=-ÄU~.]"<< )\!i4Hӡ:= 995L 8ț^GUU֭[Ei6Q@}`@yBͦ^eddInݨXb5DUo8tɸ1`*W\d/^d/8N TUP3ř7\\\g̛oBw =J5}QL&M++ƒСCm۶L0//"+Brr2۷ocǎ 4?xzzoЦMmۖddd0j(|}}9pȑ#|gDDD[o1~x*Tp|oNݺu5kB<wk{mˋsp}:UU4Eiz}C{9SEK/5rB_??HÆ ڵvիWHV+RzuRSS _~_;ۯC=zRJ(Bbb".\UV\v˓@rr2TV=z`Z e׮]9rʕ+b UUhĉ]{rw2Z03Ptك,پNalj쁠l6f.qttDQ6g3SEkƽSB *VHDDʕՕ \sss#++KK̙3g|rE\f ut:٣WR%n޼5uDa+99f͚i8p 7ndΜ9Ӿ}{:Eq;!a6dQqss+ŅtكCE>WKyb6*4O*R<wۛEl6 rwҧO3͖+pޞ&6ܹ3ի,5!gzLJ .V)_gggy.\yBWw#WLV+6k XVʔ)Sde˖bI4gst, e˖-2O???V+Z5fdd`XdĪV85M6ɓfHJJo}|| a׮]\vtsEiҤ .\~fFjj_1LPL\7BqFs NJJ ~~~w{7)))8::*fdmy{{Z>9W[ooo#' Vв `2X|9...XV|Im$juJlmߟ̙ 8ʕ+?g 6$%%M6uVK5O>!-- '''iܸ\oܹsw|DdJMMWWWtX,f3)))՝LII!==OOOrSg//bi[*p?o߾;nnnwSQrnnnZ-~^rrrrdrX,wLd2 RZ, ==͖oF#NNNL\Ezz:V|ݵ{Ftq! wY8wٓHIIj F嬱+NIIIHR{PڽӾ9,~ !)Gn)κBu_~'gwѱ$ѣB!DiPܻPݦ(Z3f@:>*y !B@n ɺfG%O!BR߿_JA!SzꞬXÇkzB!xXB!rB!B9!B!B!rB!B9!Bq|É'~& BREjB!$۷osh !B6 .IKKc֭(rLJ߸q 63B!xܱc8{,HOODGGo>9B!%PV qqq;wfΜIRRcLrWWW:t֭[o߾$$$HǎԩK,т>>}0~x6mT ʕ+JBB:'x-Z0vXf3111tЁ ZnM~СC Ҙ>\yRRRpwwfaӧf͚رC{?zh{9L&>>>xyyg~$~lذ%K0}tƌop]quue˖-DEE?lٲ|QǏS~}u+xԨQO_;v3d!xJPE\zՊC*'?eEswC#HŊ `/$ 'xF %:{Nk>|,t¥K4iQQQ-[6_~e˖E̥Kr W\њOqttdĉ\rE(B!2eʐxEUwwwI&ZP5دě6vsH*tC|Cq5mڔf͚=?#GpZhbo $$'xwwwbccz*zz_;ƬY ɉ~m۶o2p@nܸAFFl۶@:t5 !#KLLMʥKy u!99:u{I}?ɥf?$-,f̨|A0= ϟgҤIڵk3k,jiQF/xyy7իWFwfh"{=\\\>|8رO?,y(W!Z0 zZjUmɝnaܽҩj!C'DXÇPuӉ˫b!--Mk.|2-[d…tgffr-ʕ+N>W7n4+BSLח.];99Q|"$BQZ0=jArСC !S0W޾r9WWb !A/E B!B!@N!BH 'B!B!@N!BH 'B!B!xȄۥB!ܣhRB!@Q BJ !BH 'B!$B! !BH 'B!$B! !BH 'B!$B! !B B!$B!ȉ"effʴiTU-qaÆs_CQ9B!r۷DLL YYYt[5ܹs%NxbzqcݺurB mk֬wё;wj?aƌԩSQFid'Nd 0zxbmӪU+4iB޽x"s~geƌ3Ν;ӪU+6lPhiӦk..^H>}hҤ -[dڶ[n_|Avh֬}3g}l۶]j-##:`68q"K.{<䓹 ڵ+[fܹXVGEEѪU+Νȑ#B!?.^ر# b͚5ڲ۷orJ5kƑ#G8z(},\_O>sjy'Ndɜ9s|xTf֭[[`К`SSSbMWbb"~~~TRR~~~@$_}UÆ [n\`7oYJJ %0BH 8@ <<Z1vĉi׮/899I (¹sx"nh4ַPno}||<%>...<4l(\xoF#uaڵL2˗/s/^Lll,~)}o&#F?/6lחC+W2qD)p!Jy3WWWΝKpp0 .dٲe,Xs>|.]pqk%\A܁0|N*p->g}O?P9 JR{Ţ?dz|rfCQ"""hР]taΝ1-[̔)SvnbرRBj޽{9q7nbzv~[VxgQU5v8s V(rOףѡctcߟN:yf{4i"_M^iGqAbbbرcGr Nѣ899EERtlΝL2ZjqAt:]~aNcufqiիfӚz:UUto)jbZ ۺez҂:{l6ׯ}NF0 wppȵlРAL0A\v G׮]qppm۶;v?v{!Ds;vЯ_?z… X,o{PCl6ʖ-jCSXq IDATѱ 9y͛7y'ptt,/_ 00PʥK4Z(6p_>`~0:::jCsٳgqwwמ wdmРqqq <{+W2j( ٳgW6m5Xt)Çgƍ4lؐ^xhNZjGƍ8|0O>dI]`QQQTTI[n/NGrr2 .djAR`A7Zׁǫsμ\~OOOΝN  !v xxxₓ...۷IOOׂA1rHt:|AڴiÄ X`An)iii899`'''-9J}b0U'O/QQQxzzjih߾=6l`ԩlܸcDzvZO>4n8WoСCٹs';vd <*UɩSxW[oŸqꫯhѢozF$$$ͪUgΜ9[o5kո${M#طo<))mvϞ=;v2::܎9/ӧO_o XgT6ZRZؘhQ,+V`$$$s^'NuRB(ŋTCwgȅzoШQ#n߾M.]7n=-ɓ':u*m۶ytԉӧpq}Ym9sRn]nݺ͛cǎwB*7o̙3ԬY ~lW RBBh}W ,U-̛>)) www|z*TP`̟?qơ1sڸ}6?3իWN?"#}Ӈ??*ooMr0͔)Sgyc>)ΝkF\\}wJCN<5={Gq 233vOo޵kزe jy#nݺ$kwwR׮]9{,qqq\w}Wk~ >>(K,ߟիW?/_A8݃ 6ms%&&3gjE\r7/Z_|APPPAd.A=OEQ8w6M==sp}|o#g4s5|ٛF#899䄪;wN-޽H֭K.]HMMt҅ O֫WQF1oΝ#<<3sLmve˖1i$ƎK@@FUUmƶmxsդ~W1m4.]nݺFQzu٣DFFl2VJDDW\+<]ƌ3عs'7ٳ ޽:uPjUڶm˯Z~;vv:$sDDD|?e_dN8AVV6JKUU,K^={KӮ]Uڅ `޴ غu+`޼y<|ǼTRzѥK4*T`ҤIziٲ%GgLiҤԬY-[M׮]ٶm bɒ%}7(&O=y…|0d֭[dz>KLL :t`m~7-SU .h-iӦ1azI׮]%<<>C-[ƬY #66nݺѱcGZlɋ/}?{2a>Lfʹ}裏رc7ofܹk׎L7oyXv-Dž  -^{{~z\\\ <.y}~C=k֬!<<ٳg3}tV^]~{?ktΝ;GHH=3b "::[2|_N|DGGP I x7qssr&''윫I0##̦m>`qgZ1LsuQq mŽKtyl6n޼I2e~l6.] %&}J\M@yݯ˹:bA~[9#gpVqɛ./ Aܟ`0q3!(4 !BH 'B!&iZ-eN8! Bb9!B 䄸;ǎcwbŋ|iB<Eʕ+2B`83gO?4sΥG|/̧~zOc*ݛӷo_mbf!(#^:6mK̏?Ȗ-[pqq!++ѣG2y䇲gϾ9._Ltt4c{1i$ٷo|=?En*6 Vj`0`0L SNl޼WWWbccٸq#ŋ`ŊՋ_|%K¬Yصk;vQF̙3UVsNRSS gʔ)kIMMeÆ xxx'|18pz!C0}tn߾ʹih޼9ϟ[fժUԮ]cRj|K/Dڵ͊+8q6#=z^cر899ѫW/kF6mǏ'88XKӮ]BөSwٳDGG YhѢڵcĈL& {b *ό3HJJh4ꫯRvmfΜIRRcᄆ:| g&##x r޽;}eʔaTPANGMrr2bhEQprrۛ5jТE 2TK '8О빙W^e޽X+W2j(fΜر#OFlْ>|x|9sM6k2زe o-[|Gl߾uѼys8~8QQQl߾w}7c.^޽{ٴi'Od,Y$WxfsgR6k ƕ+W ի|lܸwww֯_Off&[n%>>W^y\KJJbҥ,X'''ǠA0$%%i/[ ~*ĠA'6m,[j׮ԩSfƍ@vjc:}tf͚E Xl>YYY|ԫW͛73}t>sF)'#ٳ3F#\|+J=F, _}_55"::@ݵ'DKfa2z*}.-ZE!(W^yWWWiذ!۷@Jp?#ׯ U͛74i'NjzZu4k ~* /AAAڶʔ)CϞ=ѣ zok.TUe޼yʱcɩX@&_~Y{={ٳ'...T\9ʢs==5##䐕رcK.Z 8|0ΝU9~84lݻӵkWr?~<UVr34iR\4oooݵUGFFzj޽;ZJ1Tɦ( fƍTT)cre˖-ҧOΜ9sun8'^"!!@:vHNXdI?j˗Օo&`0\dffx{snSN% ѣGk۷LՋufsFl6wDWZ5EX, yLX,<۷9r$eʔƕ>r9G)+Wg}͊+HKKjj5}`4o9Pn̖eϐF[UUܥ3l5k ȉ:t(#Fӓnݺx*T@DDݻwߟ 0w\֮]ʕ+qpp`Μ9\ +彛*t= A_D޾p=!!!\R zs.-TU%-- WWWrNZ{쓩NCkՕ4$@Njժ?u:vȓO>IBBժU+rȿ9v[ͭ6jnĉyfZn͘1chٲ6El6퍳6Ѯ%(ʹ?ooof3H?9 DQA!5wܹs-[֭[y&<.rq3g6aEq!0TPKLRJ~e]Vf{@J)fhhʢ ̙@@Q!s>r,{csf?]PvI`6WXNus(,,mU(pqqA^^,K8GP/}u&Ƕ|t;G:x 'N%g߾}8|0 V 0nNÛo1cȑ#9r$pq^,*|gx@9sXb M6w޸r +OWkw8|;T'c!@vfhĶmлwozݡGO>7fd2Uk̆>Ç`[ r?~<-Z8s J Oظq#֬Ys]vuG?2tZjUr_AA*5z՝vv!55/_ƤI`0*lo^^]OOO9:~PPPO>5BTTxibS$M6mS, 2DSNXf ЦMdddॗ^|7o^zexƎnݺ!00PPg?srBn۷˭]# #GT o6ڶmA!33z;uϣF<ڵk &K}x1rH0k,m۶EJJ̙3gxa2>͛c ?#bbbqqq`T^G6m* !?n Vၰ0hZ$''ԩSq4iOexap)$''C",,  q rtN:%1Lpk7;w|6l@jj*0x` 'ODzz::ݻqA,Yϟݻw%[g h"$&&رcXz5O 裏m޿?<<|\wZ ٌVヨ(ifom۶ܹsfP`Պsa۶mx1k,iQQQ)79/#;@ףuֈҥK@dee!##J): ''#Gy}@~M4믿nZ^7pmq6g+[f $I?H={Tzcyx &`РA睝s!;;xCEtt48p ̙#[bb"-Z[W]Z4 |}}YYYHII5k`ZE˾BJ|}}ѳgOÃ!A?aev;~?p7nÇcƌܹ3v܉~U3$Ipuuy… hժ~a#lΟ6m&LP#G /g֭?>z Ǐh,V \'эnZ,trZ ///UV00(--fۧT*j ^^V˩ rt'`0Arrl:twFQQDQAУG`0}9~ *?{+pYa۶m01a,X{7nDHHڴiS:SLHMz)H;wbHLLĈ#PRRV-[`< w;v@ll,6oތp_ pvv<==a`Mch~Qeϣo߾>]vh֬~̙3hb |ט2e a1j(T[oѣƖ-[*?x`L4 ZB.]ݻw?8}]""߿VO*u߇VE^^^(og>77r%iGAhh(L.],"b+ر#~ZY'ֶ K.,\~-pqdgg#>>]vExx8233޽{ŋ>wׯN<)DGG??~Q㏈SASNɗJKKSNaÆ HMMERR^zɓHOOǡCؽ{7<%KG 5jN>W_}+WѣG_ڶmBM\ke q*>Oa0o޼Jݱ\ x''G1m4>݋Ǐ_~A˖-|rtS j5f3~w1Kyzn6l4 |||p%@`` N:+V@T";;/ѧOt%%%ꫯpe9XFGGc>}:JJJ*]fAA6mڄA| rSNEǎ$~ƍ}r]z5bbbNDZQFرc>\ֳ}ARB1ca6mdt:k׮ҐLT$7.'"bGoie0툈ܹsT['' O2IIIhժz߾}#GSNrKZY˖- XdeeaʕedG˄|^wI{eh4NV \>mڴ ݺuC~~>:vXr~6 (VCvb@ӡu,"k3wq!޽EEEEQnMȀ ѣ ^ ggg5 N8XVT*^K,A1w\yYW^EPPVZf͚̙3(> _~%z%o_vrJ<㷵1bJJJje?_F~nn:jz IvndŊh׮BCCYwFA\|Zڶm͛Y7 %"G@@<=jRZ ]s?׷)##zӧO/%K둙Y_n~zY6 qX,E^^ ¾}G6ET hDNN]$Y"ju98ZMZ%n;ڜjBaʕxW˵trcT RXQr88 HIIhsc5 AT*XV&G(Xrϫjs>ՊPXVݻ(0hڴǏDΝm۶AEL0))}QPPǣGxgpJ1֞(ضm ^x衇p߿":XHNNl(xgG!&&N7;v((,,Dhhu#oΝ8bΜ9uZՙbTzL)  ' NшA '''9ĕ=:NӤP(0l0] `ڵHLL,3gDdd$ۇ>/" z+Vu0`֭[OOOݻ[~r `,]iii۶mC.]ᅦ شi3f`صk8B/Ă +TXgNNZ6MK>ZV<&&֭î]0f/bذapmL~9Y6M6 ɓ'>zh III(,,DDD._b hҤ^:+ r Cn`6a2hl䈈A9N|LralhA%~o6.]Zؾ};F3g 77rz`2xbdff_a|ڵ+.\AЪU+tǏO? APdee_r){wy;kwٿ?}A`2W.g B^˫7DVm3f O8& 99Ctt4~mh4(Jʕ+1bZ-J%^{5899]v2dF]Obܸqӧd?~JcǎENNN,Xk׮Enп̜92++qCXX#G"44 WvTe|Q:zj^DDEwrUٌÇ#-- O=@ I|-{z+le2_NN ,$ɷxzV*dܹ .|w0~@ HHHQ`4Z26 999;w.z*oYxiV-[˗/ǤI*SWi5jt󗽗~9sTzM~TuWT*hZhz[e$8cb,[ ~~~hٲe5( aaaHMMErr2&N-[BRݎ͛7e˖ - #l69ss΅7Q䈈QATT2331k,4nzPx\!( XV\pك\ ,, >>>7 F___znYYYHII5k`Z.T T*닞={u䈈AS򂫫+ZjٌRl68R V gggzzhڻ6\ 5h NNNfngՊC8M rDD9`8Ȱ䈈A䈈䈈A䈈䈈A IDAT䈈AA䈈vXDDW I$IffcPQ*P*P(P( rDDDn8z( PZZ AE'M`0 88pwwk5X("=={A׮]1vXJ)HX>|׳l(..Fvv689s 22P rDDD7#I, 6oތ|h֬Y.QmpqqApp0K"??<4M^ne#"GEի0a.|1~x,^iiiFa#""nGNN;ÇCVCkgU(@NN| {Enn]݆:qF .>_ m۶E{QRRR# ``)-.nnCK||7&~{ɓju֭[ھחmb@Exyz!((CIII`5шvIaZaE ?rpK yUt>B'N `ŊtlEV \h!b߆\omӲǔ#vh4ٹNʱE\t P*e,ՊrDEX,bUMw:aʕ|ׯGLLp Osܹ3fϞ EdyYiiix!"n݊p}T6ȝ>}=8q'`Ϟ=(((ѣG<38P(xWf^o&Vku-wwwعs'e˖AӡCXjA@vv6233ѭ[7[ػw/Zn+V@}?3˭ԩSXj[^Z,W;w ,M_aaaov |_5t"ԩSHKKC-W_ݕ:|:vrr`d[䈈9Q!l6[JOnu|Xz5F СC͛#** 7nD`` Zh!C `2"99$!33AQF`ϟ xǰrJ( ,[ GJ¦M^{ Bjj͛cҤIh4ֹcDFFYfhܸ1w.oæM-7tPlܸ۷?!I6oތ!C@x{{cڴi/^Aq=v9Uc9""j0AFhDII \\\ʵ9R]]ֺFX}f̘oV8fYn'''F_|'Orrr鐐HHH}Wב `֭x70uT`P(HKKʕ+}v/bذazsU~Qt,DZܹ̒?-ZM6!%%hӦ ~gr(qfL&9E躐鐟TnTvA#0|O(D۷CP:t(AC=;wbHJJ G^^T*"""&MܰEn˖-1bz!yeG=xg 9X9.FDDK.YԷo_|w00ضm<BBaXP("gqF@&MЯ_?rk\e򪦲r& yyyt rDDDS(pqqA^^L*zKd5=px1yrƔJ%FӧOgϞر#"##ѩS'(JxzzO>DT*Ѽys,\GFll,k׮ ;JGƂ гgOȑ#ذaJ%ƌcgN '''kC ѣ+SeۧOt 8p ڶm+kлwot =zӧ1rH(Jt8p J%bbbpi$$$T޲V{Te|Q:B آE;^֯>}P/o׮]h߾m}l6HKKSO=ooo$/I|-{z+leºʕ+pvvS'IrssѤI V^G-'''?9y$qˡ$g6QRRpWʹ&绞fCNNΝ޽{#$$u}䈈Ajhٲ%|rL4 ¥N}˟eo!?1n89@Uv[Y{jnnn +%ccٲeC˖-jl䈈A Cjj*1qDl*j:<<<* L u$f̙3;w.:158j>>>Bff&f͚ƍW^.U*nYf,`Zqoسgrss0@V('"Iz[FVVRRRfXV 8BJ777gϞ󃇇G89""jj5VZh4l66D5NTBzzZm GDD >==={EjC!d&9""˜`o[_dXDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD rDDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDD GDDDD rDDDD GDDDD rDDDD rDDDD GDDDDB"_vB """},"""6^Z%"""b#""""9""""b#"""b#""""9""""b#"""b#""""9""""b#""""9""""9""""b#"""ۦbѝ$ $ff@R R BBc/X7 rDDt[v; G^/ja0HJX{u GDDLEcϞ=ڵ+Ǝ @TV9|w6l6#;;9sHj wNjn$It-Z$0/O$X,l޼xЬY3L .`ҥ<FsGx,ԏac#"6łTdggcرpssWti ʕ+Xx1Zl(h4 nx񚈈n#''ǎC||{ yy:./55=(BBB IDQE(cǎXv 凲$I Bh4.̱[p!6mEawI`Z?1c1uTm۶!>>HNN?XneuP( <==`4q]kX( qF̛7)))8w.[gܹsP̙3G,>Js}cʔW۷\Tg-rDDtSv& NNN@e[+IR- W_}o1A$IxWeW^2dl6f̘/"gΜ9 믿;&MGEQQK,^zr]w,wTˎ_pDQ7|ݻw;#kgO`РAgy駟0qD5 $ٳ:JJJpҥrSLҥKpB>L<qqqrTR> `0`2n<nƍѻwo{Xj{9@nn.k̛7& CEtt4ڷo>}`ԩXx1[dݰEuE fDTBRɣ P)))Xbx t 0L I>PݻwLj# J%\8 شiˆ7#22~[_ (--a͐$ o&֭[~\ˊs8t;dgg+]}ޯ_?KXf\&M:)[GA[CM w2-[ (..ưaðbŊr#Ǯ]B}݇Pl޼رc V_u9"")Ah`4QRRW5fO<<Èrrr鐐HHH}Af,YIIIxcUh-3prr;99 yuݬEnh֬7nK.O^ΰaPU6={qqqxѥK=G9 ׯ/k׮׿T|'`fL&h4[nmcv9rYYY={6fϞ 8<222ЫWJ`0TYƕ裏b0 Rʕ+4h.\:wԩzӧOcȑnHXoeڽ{wˁ[?xw裏BT">>O<BBB0d W^XqysE0m4(JL<FLL BQ|I<3!L8?oX]Epqq^k5q,-'"+;ƍQTTB#GDhh('ˍsÇ7:w\cQ[u;;!فfFZZz)x{{'˞V>thҤIyѨQ χW+))zvhܸqUm_eE|W^E^(**M[\\ Z '''@AA\]]+$|#6 999;w.z8;;׻cv>|80j(,(g4*[O<^zaܸq5}Q7JDDբjѲeKa4if'ZӦM+zJCѭVjtzjZqe_lƍ_:•$I(..Ʋe燖-[BcvJV[an^Yn݊>o`3Q7lCl#{(Fjj*.]'e˖PTV+Μ9sQQQR\tra:e2PTTooQ7 r rDDbÇѸqc m۶E͡RbO}`Zqoسgrss0T<w012Qq={YYYիW_eݧP(R___5zɐݭFe""ej^^^puuEV`4a6QZZ J%Z-jk|8  wn䈈ggg899S?)[aꇲCj8X I CE@DDD GDDDD rDDDD GDDD GDDDD rDDDD GDDD GDDDD rDDDDT .3bx#4"""IR """jGA䈈AA䈈AA䈈A䈈䈈A䈈5Z_cOs^oբ aPtW>UJ$HR R BBGq%&qڴ-[4ET!:gHA">:LDDݎBѣ(((@ii)*/V `DFFݽʋSF׬lL3Am|` I.^4m!Řl L&06=NEcϞ=ڵ+v @TV}"P_el6 33ZfScAnpl^hJ\),73qr``t nzT*[g`#"GIł͛7#??=5kƂrp.] OOO<h4w|9SF\m!$8*W 1gFX*I'fMAR (lP kcXl;nnnu믕 \ŋe˖FaF.Ү&Zꚭ{pRƸc18lSI).a}ZmZ usrYDDݎ;v PvkcEǏŋku=O{kevF8=z999 ~;ĉrWL~ƌx'OoQX#==;jB]'p9hJ hlvljEdL}s<?$IhDNN]$Y"juN vuO!?J{=ڵ {իP*Z[^ޭh9# 4IDATEw\8BuGP )))0pvvˡw~;رc+W.\}nf(`̙wT~j,}`rS1wV܉v-ըg>>ya޼yh4SNgd ACRUjj A{zzBh4\]OuO{ظqcb۷\;wĢEiӦ:]mO9nzW9?òuнS ]K /=nd2`0I4[8ʷn8N+;;& -Z?,[ ]t(طou놴4 ꫯsٳxqFtV `ƌ}uVBso֭[w/j~j,9*T~k Ͼ|;#k\rl$/=DQ lh4IVF/̪ `r+7Mŋ!֯_H]^Ѡ)))pww!<<ƃ\e@P_sx}mR(pqqVEjj*1_ScANbhT'^\ Q=C/syCT*^ wWu#"Fш!l˅TC_[hggglݺߺu+x L:!!!ؽ{jAAXV899 fňФIr&k 30LrS]ڵǏkKMMEPP\?^^^Xj___׋//5U?r=Fkc'CTir_rm zJ+jDB4i̿nDDHtχd })+;OR0qD,_.]_?ve1=<n(e'&&bΝ8}4Anܷ.""*]Vm죣L&n;eTwҥ "##xb/"%%=\r ’%K0ydwuk~jE[q >a䍿R?FDtP(pqqA^^7oNWf->%I4uqb+-V\!e@B԰u&Kp .KL%L4͖*b 2f N%cid4Q)Nlh-]Vt sғ'}~y@cc#Prnf޽{9pmmmTWW300ӧ)))UK{6oL}}=۷oJ{{;ǏSNŮ]hhh_z1f{ŢB_}yZ[[q:TTT hjjbϞ=\.WT}b_>iwST`91>[2֥s\-rluY%fgg裏InnnlPsqXX:Q(X,=.z渿G"f3oߎ  `A~̸qK3::JKK ;vpfJ}iٸqc\GJogق+:đF|;˙^^%{{g&/?9Ej"Hq:t՚p ߏ3H=SSS;vl*++lNI,[h>yl+vĐv~ىvԾ&e[7Ņqs.ԩ""P8gHJh.uZZZͥڵkUg>~k<.<@)J'qq q""ܝ;w~rrr|FnRsssܼyͅ pPVVFAAcoȮ$}5=3_򗩮 JY=?](.TLNNr |m)K4F#6lne z'5A`xt^z/ /n*%RBk[ɱj'' fgg BOmkdg00Lddd`XX,L]NIH[ߺKȃD{x{f_Aά}RTϊ9Y9kt DDDDDDDDDANDDDDDDDD1^WANDDD$CܹsR"""")ڵktttPWWGNDDD$BlVICCCq!NcDDDDRիW q#'"""!c6x1맽[|"tttҒn1ޜfpKtμ;WWWpypDntzT*v;pxLj^ZJ\ E]]}ojjl6jޖP. ȤxΐWth{9UxKKVF܆j 2eHyxr `,%.IRIMM +Baa!2 ɴ-5iZ %U/B^NyEWO00~+bRI|uKu#l8i*}sB[[vVCj|wm?VB) \7 EuO?Xȯss&럈BMR&zz߬j*7B#>'(3*1wk>Lgp{9}<'5xz|txurST80N-+0NqǼ Igf5ߋvw]_&~EF@ݨIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/ShowAnnotationsMenu.png0000644000175000017500000006416411665471336032675 0ustar drazzibdrazzibPNG  IHDR!MsRGBbKGD pHYs  tIME  q"tEXtCommentCreated with GIMP on a MacwC IDATxw|{j PZ "E ҹ \WWi>(MPDPBtR "P 9gwrNJ2kr6;eߙJTUu ˲+2VU tI4V ЫW//Z  D||uFϞ=,X@ƍ6lgΜa̘1~9/` 66[oϱcXn&L~ ~nݺu,ꪭIZX,EG~~/T.E3S 6F#F&к*UܺQ7fZ@P1щK s@ B@ 1@@ ! dY/mݺ/'O eF4-==D ,ӤI R(jJג8x qW\ə3g1c8tR<<}ФITUe=zUUi߾=ݻw%/~~~zS 2ܸqRliiiȲ$'';YA$''˗YlL8~f͚֭[IMM%,,<_r˗/Lpp0$oܸSزe Zm۶ܹ4-Nrr2wDxxS:˗/FL0 vܩ57 m۶Z 6d„ 4k֌۷@Ϟ=1 lْh_~ 6yed޽g"CBB<@ y.nUt(BFFF!˽Hw?ΤIcNtt45kԄߟX{1x999<3x{{#2>}Z]yi5jzIXv-yyyf݋;CnݺAǎV;Y;vԖ;w/¹shҤ >>>t:}V+{Z=J\\\/>[عsgq4h@jEWL4(rssTRS9sXF} WUU l~ϟ?5ԫWoooz=&'w[ֺyZfRRRwOtt4%ZzΝٳdddh,ׯcXĉ)Jd 4k֌'OJHHH>===s@yŦzHDjjjSSSU\Qz,3 Hę3gdddADDӶX'1W,K!n󱭪*ׯmۖ-ZvnӦMUnZB*&qFj׮]l@ b^14oޜ#GеkWB촏lJVZ8qbիG Z*ڵ+x1114lؐ#G:ߴiǎo߾e6ۛ$uIIIF7ݷcKDll,ƍaÆEN#IˀzZh!JC hTOzEff&?6-33o///zY5j?$==]v_ⱻt,ܹBff6 ɑ-[ҧOl©SiЦM<ҡCRSS9x ,s)N8Av___\Bfff-[:222_v *LHHЄ`0йsgbbbj'f+%] Tnn>3̝;nܸ'?S3y׮]پ};111hт>}?{l___F͛9x $ѨQ#7n\𧥥vZ&NH:uǣh޼y}5j'1114iҤLK@@gǎȲLHHr?M6 8:}voNΝ %<<5jШQ#:uƍY`ÇI&ʆ 駟c1BJ@ C$ށYΨEAeWeVjYYY\~l~w\B&Mhڴ)zV+,߶/޸q*Ujׇ=##WWW `^^z^?##CkӾ*H;uTT -zz=:N$)7LzFVt:IUUMf @+)hqlB8~m=s޴iS.]Ddd$Elw$ITZ|+E(Sp$IEVt*@ b^ԭ[zJ\@ <2vM@ e.$e4a @#\ !敗;}.AyP)W^͟ >ˋN"??X˓+Wrf̘}^Ϛ5k5k#]"77t:LH 10h ~:Ѭ['xN:K'OڵkN.C Μ9(;v:eG{r<ϧsE(W8f3u a͚5ӢErqy RSSDpuul6nΩ}jժ?.Jmڵ+EJfZ &1d`o߾|'9r=zp_N x'KU^\}q1dYO?aÆ7VZݻv^^^;v`ZiѢv"--ӵkW-N^HNNСCӫW/'Ν#<gΜa۶mLM޽1L;|rjԨ  bΝ۷s͍C2|p9qD撜\K{mƍ_~wTZ*U0x`N>EW><== 22___BCC!44Ǐ;vժUׯOZ* Y&>>>TV bcc aȑ9}SWWWFE˖-i׮/^ݻwwwJݺu֭͛7'""sW^ҠA5WSۥ}'X! NG>}DEEѥKnnn <>, @P*drssY|f=ʲLfff}wnQU8BBBYfl߾ŭWzL&SN֭fm{Ӿjl6$DGGI*UǓիWqqqPڴKs˗/s5<<<8qFmӧQ\ !999ܸqCUUYf~N>O&##BVjll+IZ? QF\|]YHNN&44͛qFoN:u2xB o^M6ԬY$5kV*_۷/IR46lȑ#oڴcǎѷo2 MRRӺ$F&E/BHH}ȑ#Nݤ]IMME0`vM^^)))DEE1p@^V $T>sY ==3gΰyf"##yǵ&ܰ0233 '##EQx"c./W\!338O||>NW 5ӓ2# رY W^ZΩ{lڴyѰaCÏ?ȶmׯ_Mڕ]vk׮bz_B@P1TUUGB:EQeYeժćjF7ndNӸ_ʍ7RJS<'EQѦd29sqN۽^^Gi$9=& ^hDc0tNݗj5kSVR8 lٲqD={WR|cֹ2y$VZb/j}&m@ @ b.@@ !@ 1@ \p~y !!СC$$Itػw/k֬O@ '}uB:V}CNN򊹟/cڵeyL (rrrywD b^94hF~A[wQ._y( s!00OOOwl޼`Wرcٶmxxx0tP]&@=%!OOOԾf Vȗܹs4i;wח0Μ9ܒ20"##ҥ }19!C2e v"99S'PP&DG+] b^99r$\|YNq?>ǏW^}\̂ 裏W~)-Z`ʔ):t`ʔ)oߞ{5k ˲x ejZA%R;ZT6*eɶmpssC+f…L<=z₋ _};w 2ocٳG;Fhh(=/" .ŅڵkP%Ӻu0GյLŻÊ$IE>SzJi CQdY~eYjj!11.] 1**:zUj堨G.T2!/1]P]Qb=PMO@poJ~kam9/;u ! $IZ}[,Z\\(ZV[".\PI.ļoOPT୴^-!zV[QEw?E:ZeTP%り,˚?,Iy_u<̀o ,2sWjxN,U$O399?i?|Jdw߭rUUnZ`HMMnݺу;v<+V ,,HV^͌3JHH`…̜9b^>s#.E CU.p)UEUBtEnWbS&z̴&]$-] ,jf?]߉fԱZ^4Sڭ &twztVuMt|™*[K|6zt&i^_mo@G/qwshfve'Y1OhcۧڼYhFQk?V|KO1;uu3K_5x\-ة[Ӄ5;Яşf߸GbڲmEVʽ?d߾}̙3`V\}ΝO?Mڵ;v,wGQ̙C`` t]dϳ> @n joңGWΐ!Cطom aӦMZ)))Z|||8q_PEy~}sUE*pRzʮ# zxI#&v{3qFRT>d%D6-42f~O xWq َB6:QͶa]@%|>Zϥk*1gvQh\WO SzjLvzm(ѠĿ\ g <{2̂ Ft7bUu Q°tO6Xȷʯٶ3&րY 2}uk?7wcgrynP\1`U _`UTM-UVeb 5jDXXcǎȑ#?~\~ X˲L޽?Yt)- 4/;ͷP@5KsT.awVloBZzm]>W IDATF+bNndێ*1*r,XeaV*43ِҪUC3=Ǟ!:vRZ%XQZȂ®#2Wa6Pfr%|ѓ*cʞU) 33[y[1 GONM 4#z+Q~YJ-uʿ*Ѡl8gRnn-/@ǰXˏ V+VZk- KUUV\ɘ1c$QF Yƍc<g+oߞ+Wb6Y`UT!8 ѥKwMd F-=z6@}ٸq#8p #F`ܹDFF믿9 0s[Xˋm#?~H-=Y QV-nz65 o[.&gGq qn{jF+eYve<}ŊtСH޽{cłHO/~ .F-_l.dM&mٌh֙ft:NiD2zSC-yNNNsWCGpy7%⤨$\VPz~TJv\!W>myĻ01O/=[뙿ʖ' *߿m V%ao][yȳer.~ dD+Kȷ@t"=g.L)j^$CϒNYW Vm\B4q%6V n Mk4{nn.k׮eѢENcҴiSV\YfbN#**J w(_|,?ªU<~IܴiS2228vAAA۷YiҤPG2(MAʁi#=nz5{dmߏTk"[m(SO3n8U:u0rH֮][fL0{Ŝ9sHIIaʔ)i^ϖ-[<==IOOŋDEEtREʕ+S#FPN}.^HBBϧqWCvg~(e]%|HGf`fFRtK]>ܵHRt;0Yˬ:hqW0%~?:[pq^O~pR}/[缗չeyf2gU661#+v\u3 W3TVVx/~c֎ߌxi&~5m^0ɱ>;0fGk<7[hy O*A+囿7?IG+*_Ė>z zΠTEL@edYjj!11Iږ[~zWU2Iow.r]њ=%Ro1Ernf0^_oO 7> v+/l Ql˪7-*X/$㉂0Mjj*~~~E=##|uW\VZHDnn.YYYNۋڧ(\dz1|HC`@kٳL&L&f^Ft:$3j5kUZI 0@eٳ\ល SYZ1\TP`{r$[ |2rDsbt!bwuj7GG*R VvBj׮}S<8\Eib*Zdx7$UEUnI(H x7ۅ8b~ؚB2*ݡR՛ֻ@P,}Bb^kKĕl wRWN d7ʭʠXQsl gJ&*Uo$I!F `y8~cd84!H6- *ay(<454;;B]las-|@-}䎡nݺt:Gvv6JF xP(BNNGAӕ[СCgϞ[N/D$,Yȟ$鑘~xEtvNIIIDEEaZX,Z_}gJG 87Z~t:jԨQy >#553gΰl2Fɂ 1cF/gϞeѢE̞=fʕNDKt:n; g8s\Q>j*"^P_RRRJ<޽Iv'LÙ9s&#Gϯޏ.\̙3 sسgaaaDDDp9ׯPNiժ{NQPq5qq= M*j(/8.p… X,,]T[g:w-Z`N)… iٲ%nnn4nܘ ?kBBBشig_?|0NO>Ԯ]ӧ;oKݺuyd?yhܸ1;wfЭ[7Zo_r%>>>,YUUosNHNN駟vڌ;d-kԩSk׮3w\㤤h0qDJS3f͚ĉ1LL0#GsOӱcG~m{VXAjj*< AAA :T;;#|K,_gԫWS2c ΝKj՜^VXѣi޼9:t`ʕ̜9S~ .G;WQ'!#r{|!,[ .AYs̡N:ޮ];N<ɿoMF^^ϧW^+_ZbٲeHDtt4o{SN̚5:vH^^ .ߧW^|׬^ZsիyfF#$1rHөZ*til8qcǎ`ر9r6m8yܸq⋀mYxx&W^%**@, geƍƲw^puueѣdY.MǷ~gy?=|IUT%SA*ߋu~v}@sxAoeŋQ֭/O>N:ߟ?'k.6l)St/xb6lAGeZnMNXr% =zzm6N.]6lyyyb^u}>Crrr?>7o߾Ã$_Ά 8p7. r{*xżv{hWA=yAB.ܲX壠^Vydd$t:4h@PP۷׏E+0c 0a###Cܘ;w.[fرмys֭[G˖-9gb0a}YTUeС^T{yy1}tNʿ/駟Xvm&QF_駟ɵwwwgӦM3 bZ aÆ ytfۛ޽{3w\ƏϴiS>)=Y ΍['UU Mc_X\ (eqױׅ x'MEQHJJnݺzK%%%??ByRUXVΟ?Ý?+W0Lˣ,\v5kQ;:=QQQ!11шll6c00L F6 X24kUZI 0@emic,XКfؿWP̋U yqϽ6DzS%A;3tŅz<`0w/mz&@JsO悕0ꎣr$BMȋzZoj4@ `yAqwqzqRiׅ *|e(1W-kkZcqmQE@P˫Y޺U%XXM؋^PK#.zq/ŗ2xJȅ ŋ =(G+Y}w^R<ǸBgJr*(eγ9{,%@y9 zA+xōƝRܜeMbb"ƍ#""777߿?_~^ϲe3f#@]SY'c*-ݲj7\bŋmۖN̮]xHII7`ȑ*͛7O>ϔ)S8pfrr2ӧOiӦ|_???Nʌ3;w.ժU*8!2{h4tRrssyw4hƍ1x`w̴iW^'$$ T w(He-XVdYŋw?aOj/FzWW"q9iA֭(?^sںuk-[SK.e˖DGGg-N.]ҥnرc&`sI`` ߄;_իӭ[7ә4iz~Q6mUTwܹ|46nHll,9 įJ=cǎ_` 1qTUEkNVz=UVEӡQUU+e1侉xG;6(8Ш(A$%%BX1b8.dMǎ\~)y kI[DZS]hÃ(3|[:['֭[ٿ?wtbcc1LN~ѻt$IңGmIիf{lrqG1s⊹]zA."!))[r5oI&NS7F$"C.]z͢?>VuN۾ dY)$M6%##cǎiCe4i"r>'hh4:20yE9@@Vy~?{2z(/uG* ڵcر|xzzrF^g֬Y%?h fϞMn۷/ׯɢ\~ 6p7n|رcL0^z!C &qqqӓt.^˗ꫯP+WPvmڴi^g˖-N}17x>  hܸ1}-Q_\;-Wǂ!*en>W]7[pp0[CN (5kƾ}3f ^^^ԭ[K.ѣG:D͚5Kvs!}]~'<ԨQ޽{3w\ƏK-233Yh-rƍǚ5khҤ >>>|'$$$о}{Μ9ӧOgڴi[\xPlܸcҨQ#V+!!!Zrc{Zf0HYYYb 5}$=$%%$ IDATѫWşK/*/Hjj*ΝiӦN)gРANɲ׵tTR\n9995k"Idee9gdd)k1T^]<]vQ^BbYw:ҼͶVR8 oٲEyqZ_T8"8{;lUZnnnګ5jTv={ŋӽ{w\\\Xb.\`ԩNy5 NVs7Ԯ][[vuu-S#(ra W>sQ bX9~fgeepBhڴ);͚57ZpW8v3ٻ*hv!As 駟*(3 xEs@ [@ @ G(AŪ$Tr`pr4ъj d^Ds•eB~Ej~7("@P1\D쬔aO>ƍ?4lԩSyIF Dpzi+f*n@Pa*,Vq*2* "*2lEQdnѵMFYz5Z/:ؿ_Sn,*|# Oowt:=:IG#tHɾ IHH =CČ1AT$U#߷ؘZAcǎtؑ@ vG eWd pq VaIAlֺ}YdIFRT$`rT].\`7hwqݎ=nwbZ$x"SY_kNf;߭Y/je_8w6[l`0s=g3gc)Sxŗo:\0))DFEvؘ͸qXh۶o_f SM$9ݻ2e )WS?g2FҠAUX$$T:wO^tn27Y U_]p0lؓں`Ԩv+.]>bƍDDD0yd:t?ij}6|}}={6->|_CjNj~4nԈ&Ni͝;:u6ڵɓ|L)W^e޽bXٵs'sN&O\Nc&y 5vom7mԪ?Bh5tN`|sG rÝw6=p@ܹ0dyygyp8۷@vϞ=x|8$777 8q:w\#ްj.BX[+… ۙ3g;w$99p֒h`=˘1cm}>@QƏO5jw﮵ܫJ>}alܸ87}t{9V^MTTfbڴi<裒܃xTG>_pBСCnzk uj3P(++#55={6ܳj5!N.[F޽4\.ڶZ>33V3rTQC쉉iYY,_~OX; )..[ná M8{,W\qAAAe/fnk{nfW#/99ٗɆW_}ɓfn{1W_}9}tJJJ(**jS#x]h燄2b0[ixۙuawnZ\ҥ 7tiiiRKoYqU-6mYo" HP?ѻwoI?K=7ą SO@͒zI&8~8DGG?1;;M_18hl6Ɯ ӄRSS߿3gZEdBx5kpY&8s O=/c=~L&p{4gk.ovE^^%$.U:m֤TUoXcklvi|d^ 6o-ž={8y$!(**om}u"8x(N9wDNynjt0wQU?$MJ<YjnWvyI<\.{HXЂJX&N_|*.5R$+T25UtXc帪onn߷,RMy:t={W\A[(((h<N't((&ƄB Ã_et T\lRi?"ss2uT>C2pm<=@<8>r 7t^z]݊{nU^|%駟^Vz^foo F(((՛)KI+2T[BEK'4 CcRQNdN( Vmn̙3DF(<ו7GUUfuj3 p(B# r f(P_ƢxBjDGh%%*hJŋ(PbccdU"r0 aС˺˛F ͭLcj_kxkFDDqqq |ll,&Lh5-E i&P˙ƍ.TDAQA좞w5{s c]Ayy9b>&h*򹰠Y zan_؏J""aTI߫4螙=z'NA~I .'%e?'Np1222tXaai.\.7QPX<E44Q5gU|O\gtJ)%IIݳ¢"4W:$8Yl˖->|/;y3 <}ѣGk8Ջ#G{/gРA۷b!ukB 7srr$'I4I#ȅA" CVm\3N $hP a\nQXTlYD)/,Pρ̹<ґ3$ݮpD M@xUlkx/Y?~ MUgXXt?J4U5vY^IVy%J+ba!ݳ6l@댨[B;ƼyBa222[Yf_yMӸx׍c~)W]uݻw1bSLwE4~s!nʸq M|ժU 6/+BѷÇ's0: HyTguToU~&k3 !yHPEyzӻXV^^1118¨(+k1,%Nҡ3v:KvK&{_nnh DPe>AqqJ;op(F ȅz8BjB 4شf5dYފRJ *, J9ZXJz~%e娕`5O<+Wdڵ!HOO7$55-[p8+**8wB֮]KLL o7nq9spN8~'~Mw>[n~}vl޼ zINN&>>֣V~lleA9r֥K}.XI}36VMjBqVdcEE|g8tRЪdtm{z^ˑE׿=f,Wp->Ar(tQo Bp?FZ$*bI zl*/^$,4 M].J/]M(M[ &ٿu9_<2NseqԩSѣ}v&NhD5jaJ:Y/$%%oj*oOnF{1V\ѣG;عs'YYY7Yghƍ޽{۝Sͪ>#]vc|>͜EU_r$.UFpzq:QKIiL"BpPVR5Tg9]#s ͧq8ǃrmn]?(  nJ>W;J2o&Sa٣Pt~zC(pӁ%^N8 Tᠿ͔)ƹ";;|#Iee^Fq^~h^3Nҩc8;i53sUEE%t G3-ވ#۷|i"""jxZάBnV.?~<5dffܹsB0w\CDDG%99 &0ydyә5kV u/J4t]t1"$n%s&I\BDžoҁd^ԋ CzУGz߳gϞp8KODD &H2Hn1nzC-,"22EQҫ "$CXX%sRGy-)2WD9 +6pizyU4 rկ)#22J/,EHu"s5ͤE_^d}y>'9#oODc"ر1F 7'Oc=FII có^ߩS'233۷}u gq^1cFQƌ뮻~?=0?n lLL cǎe߾}k[f=(Jj[4U氜6Q$dT'ǎ9K7UZtC#s}>Lub7//ʋt @QQ1фT߷0|n#z1;,*LcD$ɒ ޱk}ު> <1Q~!=&׋Y߿?[}s B~5#=\ӻ3?;9d?GpWfCnNLΝkƼٰafذaƼsIIIOwy'sK,{5.\_|)SѷX^z%.\ȕW^Iee%֭cʔ)p ٳqrTc]z ӳ^1113v[Y ug%o]xZףǗd.vj\A(N7BTAU"VOݬܚ\'wEQ9jQ\œbڕ]'pAt7^fg!IV;}G~Q8=FqQch1붤F)Fzu8@ʺgf6'OjZ˅pq8 TtɩzpgI,/<Uݥ|>5t c&LIJ/;zSR𩂱5Лr3u^ql]q}O~_+a΢ j"# EceOeM߶3]~v!|GEE1i$>#jZFz&Y\NUUA)Iq"vߎU3=<0d,I5XS0hJBCi4t}Y~<|nk wؑ5h_rq 7 d֭Ǭ աСK`@!!:6)J~ȱx<̞=lvf֔U37NЁ_S7_'%y#ZH>'WcPjZM>Pn(Mk["tmvڴYCMõzvm{*_'|Ҧ@y֛i(V\'qO$sҲʭZ}ZĿlh-ҭxS<**m۶]:21cm֎N>}lx aH/´iZU_ ݼ9LU-M4tۼLn1dncǎSY]T׭VmJ%Z#[=4@Dn[3=*{H+G\\\v밆f.CڲZIެݯ!d^|Ig޽-Cr4ݾ0 ޣ6"Py;"OSkR7_騖͛gD4@߸(>o^B2gBQ%{VS7d <.G֮צ5DY ,š8HSKHMN:ɓ'6m]v| `Uנ.Kr`n:Э[7#ي+XdI-:޽;֭3_Mp}͛7inKA] Kb]3oлϪgXoj$BiNo 9w)N8Iܹsn+룹Kϊ$Ҏ x>0`׿߿F… 뮻Xvn޼ӧr֜g}I6J| n "oaلsaFi?p@uk j}PUޭ!a.y{'>|8sI&1zh^uTU'##n5k4hΝ;~fcرk :>BFeȸ\/N;w~mϟUUo?FUU4h^UUIOOgԩ7 IDAT7RQQuvvcG屙omn%^#Gd@J )) DI|ȑRcm%rySW^!&&`.]Cjj*Ga{s=q!n,Xo~6mīJ~PUӧO$RRR9s]vkFTT{g^,cL0sqYFuo333)))AUU|>Ot:yYt)3gd߿1c4JSMoyk'r\bp̜9P)(Hѣ%ui =땽ڎQQQvzlٲMXnBGQQ!!!ݛ?]vq9^B|>^4Cwߏ1o[222{,c޼y$$$qFy|^'rz{^ؾ};޽|>cd|{#t%./"nЇ>D⩶ߜ>7N&rIٙBfffҳgO̙@RRNs1k,V\ɰalZCp0a#իfͼ(ٳg}]Kld/L:N:1gbccUρHa؜m!ICvTC OMDBBM\:*]t:G?bŊOC4˝w|F N:˵^ Tygeet:yd|8.؟:u*׿5no abcctսN@.hp8w3߹sgJzz:+WA-Br?< ֨&=זѱ5`mG=YS?rCeذa0c yƏϠA QlօMϙFB6m7\eA^e{HhX͚֯y /|kWUUy뭷ѣgne{Hh]0/۵k&L ~#&Be))u䯽Zn |m.\َ_|#F!C2/B>3z0z= qj tlڴE h!#5LӪתxw㊢H2h إB駟2qD&M"x<u׭k3-!!!!!2dճ=55oz4%%|v~euKHHHHHf>hР$0UCB kHHHHHHt7fԷ%$$$$$Zu;P3mW^j͌}GH^xm%KHHHHH43k ͼn!%KHHHHHq9s [o%KHHHHHU 6Bn[קK2D=y%\BBBBByKD C~S rIENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/EditView.png0000644000175000017500000004212611665471336030424 0ustar drazzibdrazzibPNG  IHDR.!ז9iCCPICC ProfilexWy4o?Zgj-d;,YÌؒDJeo!IH!D=}{u=< `2i(GYΖ$O/o (ih6>O5ɤ4;e6%-u@`yzy *  H/ "l& `d/\e · ?BLP( ES#3 G't:#@(1YlMr @7'G? P= ]ON@ *gg@ ,Xp~r8-hVB.vu߁FP``d GU8mD= yĹV9_Ĭ%$Rko%o([~I1I_9[e\MHP#RTkp 6fgar.yl΂˒dgmd[hwbAaɱߩ9Džjq3+;a'ۇGlO) OgjݙPOq{ {N>,{P&EaZꁴ#EG>||5SwVn9 ~xƢs% ^-Ssi-WT:Vz^#WIV}XUCWK}sVlmw5?io mmn~RwŇmGg;*w>z25MKggo@3gCpXl:yXlxU7#oOƿ3~ebvrbч33C>mc ;>\<~i^9zg ǍAPh͋CH`X^%~{WHK$CSbZrQú.Y|rە\GU8ZgmET5\/CA۶!#i,9ӬؼҢβK9; x;=w~r[{KӛigOo_ƮC{A(!֡TWgS5X̨sXtx= >{ߟ9pP.EaԜGQ4ݎGedd^<ќ5#k/=߶"9bR/xxҽ}Wޔ:_\u]Zf ̍G7+oepzƜm--3.O~pkmƣ t>w=KGݻڷ _ |7T2q xY~;2z]{SS.3\3-f5gg>] 8vgE/2_9~>\b*:%|Cl;uG_0WXN7UʳοDd[ iR\;^m#Q[WEMbJʢ*j8oZcO77\R5AW@`zCmL&Adr^s-)"K+-kM-NnpGCcSsKk[;C֣3KwN >>߫~n~_sw 8h< E´մ^"Ci;U1v]D㽁Gu,$5oU>f|#9R_ևU9s+O%hpN?>}ֻpCTQ͹R.ė闭\l|r(xzr5*tUI5ěn5nzRS/}p] Owv;C9/߾2|}n1:0F5<-QSbiOmpQ,PppPj"0<`%R̡PZ j-G{c9t7zÏQ8c00ݘm.Tp\1n/$NsqrpT}%%;mZ%sr%KD6m/\#fLUZSzuu 9l0(S1PVNvRJ>FTQPqrSҸr QLHZzF́:۷uvUF5ngdali`jMV15G,&-Y~fa[owiG=9%˵ܭǜ[}Ooߜ]_qA낍(a!T|QVJfp3xrTw'0%u'JNQ94Zr&6~B)k$%rDZ~bA9K܋kJq]..x) ¼R˚ګ.ݮڄoj|iyT8NBwYOZ_SĐpc#M6ES?f$D˛y?fp.a)AޡQf(*UBMh#Nt:}݇^Ĉa1CJL?X/lvGypx< o.c\E<<2VD+gIWvOwۗ9:;9Omr7,H -׼̎N.n>KCG_?.d4cاԢװo[W>r8 zp3$yBXRTj MB[#ѹ( dc`eNGVlk.%Xvnylyϐ. 0D ! \#x[W[N$TT\SNBZjQzfu $dAFj|afU"U/֐ժټQF7a@6}QS*y'5R6^&v;xvw8T;688$zHx yycw'᯼K-@>P6H1Xbz$ʉpFyL$*.#v u_T puqR.)׼قKg(^zIٝKRW*v^Q5XVéͻ^P$soǍO$v;ՋA۫[o#oGߎ|=5<8S~ ϖ‹/sq˄ ?6xnu*{׾M6%VPUrYCt XgO75(¹6q:} VwMDDH駟ݻĉ$~WӦMA0O7 M|}*n$ jS+egi;ߧfE%Aժh:wVa3wfJx͟u%cLPx%(')ǿUϘ۾8_1乧cspW=T\?%"aƍcccsS~eEC&]6Ơg&Y cWLiݝuþd1;Ǯ4U۵uYQ:h @-I/{sυm}M?~Dd+G$ #lV `U苠zI60_uVJZ~οoezRһ:f=yw_&Q]_j*%%Aa͚5]jm^^^eNkb A ?$9An%I )ܹJJ%{Y2/5`%}﫹`s7vC~}MLkg%}|ٶ"Jb\]&""x {o0kF&՗w\*$n:$I(VȫE-?7A&9L^ͼZ^w~k,6.:(333'?oĘ '`pEԪ D I*S\:'59zT@g%ˬ^ 7ؤ8 ̋dkP?~oc|qLjTkP[ ذ|fK;fuA씷$Mtd'?Z2U0JlB(KGC)l~`x&[T(UjVP5n"vADn(I`EoYR)ZV's@?͊JNIrExZ+9vd\1XP[-5%HR]{V!I%yWkr+=0t̓ j, Ib"p>(qpҍqjlM.#{6o-Ylrj&+z}Nu/.9UDc<߶a돈^χr67`Wk~[9bӯ +ضd)8r$HV$l.SUrv¡l(U,JMfE֒H IvvKdg/Z޳''r/ͦNϝnѠ$I]2J'YO'<Ю JU5-v M$JC`HVdm-gٌoD 8"v% apF!G vm܏r^\Pq }obVDD|أ'klwpg?sd>Pf+y޷CnCndم.}d6V(471i*5>Y+ sکy >Wd)l̿ZVֵ]>k  ;.~$`uH嚻$Qh1[#Y9d .eMtXlQ\Y0 נ$|=1_=X?8޳կFXǮX3mQ clA!| o#O]˫VϾ e TL&:7s}>!IB+upJ޶zD`@ cadhz~AOhkSK]9^w׹у,A%>[6 Gt֠^2gE<vA~YyV$!kzl([㧿 @T\݃<* 0un뫯OtiWIc9b#?I ʜ~1+"" A"8ΛTm o;d  ?輍[.?OڎTUwmȚy>豠 6Q uu"*W^"IQH39gTz*uMfEj`?o*.4{wyԏC{u'VdK"p8aS5>v~pPr }O>KRXz߆}=;g{_+iZ?Xz$W9"(dvg;"m^y I&4rG9+0 F6>}{P -iU%(gEԾ_wd$98N9s6F`S~oٲeCᵧL2_"J6c'/a BɋHV^Kg‹Z䅃Vxy{L~c7m5{<a,^2g]'n⭊W5j#""x峢C'ZZr Z4%-7ΊJ8IA$sE2??WM>K_Owq1d~~7~WtE(3y~\V\8c$ao"3AXaC(ʪX" /Q1(nλKftlX)7:wA3]ԃ}je8f 4KR&-P RLx|]ճ”h7Htb=YLfKp\ e'Ah%w""|Þ''q.KS(8FCDDu<_Uաko_M\d=MTb6ۼdK٘j [SqZHWCpܰȹEdr HWpI] Usr\vVE\_ z}SW߉$m {;T. LrA?`d%^lܟ;6oIuY(sE%Օl\z4TZP8|g/ k'{UD>x#agٛ~Z3hQ S: A}Ԇd BTB+J%$IG?wW)瓜-ϨoUQ/W!яħX:B <>mF=ziΖrB?)SFJKagT*!b@lg9+i묳^gEB~~>)S8'Jl׮]kϪ,;lf2Eκd4CH6QT{V$Wd0@Uo+6(Zuꩩb0IZy>J/&IU+.hn8+YgnSSS)CYfYRyYyۃP|bU-U޾u^-8W.][>>ׯvTR}%z @Wn ^TrG묳^7obrd2 {BjK:{N(33333T9c_Q) JPAlkj~UI+;ޖ-[jZVFRyyy)Jl vf~Yktnʞ+0YQpgobɖmyi|oQU.Aiаn ":?|NLF{["*;_QI_L̄!];,WN-[+vO<}WL@i(3\owJM⧧DDz"""cUgw;w}/iEG[Or@;U ?mE,;u%" +*_~Y`+Cq߷J-u)3: 6H_i_(DL5osYnl30gRj]hjj' -n;"*'N/֮]{ʕ 6MV$_<=9}RJ;w.yuTBLDŏ"_OG5Q!|{ډSi|Urxnv(SnwBEDtlV믿~G{_V;y!:0ٺ˞иqa/oDpϾQһ[`矏ܠuQؑU~ݖ]J`4Ƨdu*9sEロ={cf5ԝcqv(U@IZ6 8g Ry8! !;DÔeҩ "ƺ DDSqVT^VVŋk}xdsAK7-*ڷgaٻ;S&Iڻ" t)o"@v T6+*aÆcǎ9ŗwؗ}: nQHz{f}p݌El?]- /|SU$+;ܑgEɭ#cVu**t֭\.*Kv zeul[5훽+Ft ?ѰP) q޷?"}JԩsiJ78(Q+5Lo<>1nԷ ^#;s 8~ooL}f0٠vy'IO:?P2g'd\ܳo\f{Y~A~NNߵ*~]ppRmԨQ%ʽUԧ~~O9[\):?uN= oG\NUwӧ޶pQ?8eUǶæV{$"HgEp"""uVkјZ$*}ED7Ɋ<ĭ{-M>Mu1?/'';\999."nt7d7vۙ۸H'Z7@]?qiƢzfmC |_3;& iڶY9;8QUnB{Cu jMVmضvö ;%_ @n9/Rѹ~Gav8~ltgV+ `㓑@lp¼~m,P'|Tg1κt|"iy"`X:dEH>ѽDw9^jwPCqߜ xЇ}w2jtKgEj;~X-"sm"t؁_g#-ؐz@E6Ƌ+{7lX;gk֊vyńmh͉{mYVoaN,763KDVՔz xϜOd0oV ? Iaa͂{Id}׌m^ս_؞Q孭r^v]-{~Xn{diCDbo:vr=)H]?Wd4w.+ +}R҈8W6MfVYv< m Xˇpd57fq.{MDT|E7E,zG-`+"6]u5͂!Hxr'0,yi8{`Ov )4jPyYr3";]gE6{ё1gߗڶQÑ61f@۪[ Nk=TEAL|zRث\3EEzE79c9AIDATN;7twG9UYQȐD8gb4;|x`:t]<" m6kw!8Wq6Vyf lE6΋w&Unq|E~ǎ8}6܀Nq=_Q 6 fDDTGp"""rWDDDlVny_? T7p;U%ij"""r3fEDD6n]r$ͨyz*\Y.jyz.fRhψ.|u_7xGA4DD^~(xLۮU+ QU@ĬVKW_j˯VKg$!W_ڴիz /t]n=;Cљ:tug08!b~JDtǪ4QQH2{/ /+h&ԫjKHZz؇Z}ci[:կmamۜEwp}44 R) MHæM=jDD+RuiSԪ{ enn॔7~xInGj0޷x[\r)Ұ1E}R4'[⃍ "s'+4|mR*FLt1ku1K@ydGL0u(I*?UqO'wbL&8 QVMSh|*|U:mݽqLǀ0z]e+"""1o.@DTGU|Eװ`k4A7vYS":Z"afj^)Y "++2YN;_\N?!P' ?|_>U>7c3jaMB{RN NXx w1'waNNDTVUgEW"ۑ]|M>?y=24tW+,xg?PXf/x4a݋'=0PRn˩;rm_jɊG7~-o,4z✏#Q|{pÃC#CYyt: {S+bkXa5cۺGu?=f\߽MDtU=_T:;Qi6ω y5 *%E1ƿ~zo[~w_4i :5":9UuVdfp˥===sC«J~ûohqR,eR*\Șȥ*Ί!@%[rNyCEܝř _| V^wKԾ9,r󜑈UKVh6hSbڇk~<1λ#~  h?qɱG#]'xN~ 2LJ E萹NlӫoW:^ "jx(be4C/U>6NϷi:DZ<_; b>ִj19.ottDZ^dG"9UU1ZwqWZ_TUh!2CXphPkk QwUL>zȝ9m܆G({.@+)F`wU\rA<+"""7cVDDDnS"sʷKweٌJ3'KQ*͖2<3wbMjy]2;^[^SD+v +-ܵk^\GA؜oZGAY̔qAyKZ+e D_xڌ a턎d %+xs+Ӌ& g "z+ O?Xz.6m_2n'5ᩴsWG%Ĵ+۹U|dNݹinҢ k5:1=wh Ծݿd*om*&%8'0]NNJDDTCPT%{=Q@'f ITԌغ˞"?ޘ{( S܈u)S1Qzw,Wa-Ž>U^w;":+"KkrW}* ײsL,2 D1ųq8mJv[nRa }j9DDFgE`. U%)EcxhznUn=Vڀ MW """V]YэBE!y @u3aܳtV-WR` t)| UلqAB~~>)SOQ|Lm6lPjt FAl0~4hP y6t:O<Sɾ"k˖-jZV{{{jFRJBAnl6;k 3f͚Nӹrc6YNQu@lw kܶ UڲgX:d5wz]shBw]sUYQ]d8CaN&PM~>[|M>?y=2s{Ĝzûj{یW<@oMٰṽXz()9rΤ\r&UKVtϣӁ6kZE6}@\ e@Qh>|Ј"Psskb~Iwbf|/m5iXo0>i>)k;Ka-o{ 9@}5i[UmiOC@/۵oF zL&M?뇄s#ZLUJ(B}|uBd6^}+xBqu@DD\Q_3ɵ-o~oZU@cC|VS@O4:c~sTucjTuc6:]vy"tZ/Ow~dQTMYr~!}CzuGwrUQVY:|o.]ѝ9UY605!""4܆GP RhvW%%ij"""r3fEDD6̊#͊j """̊mG`VDDDnì<"""rfEDD0+"""܆YyfEDD6̊#0+"""qAeǡ\J&UI+"fEDD6̊#0+"""sEDD0+"""܆YyfEDD6̊#0+"""aVDDDY """̊mG`VDDDnìUI+"rYyfEDD6̊#"""rfEDD0+"""܆YyfEDD6̊#0+"""aVDDDY """̊mG`VDDDnʎCF LWDt̊mG`VDDDn犈#0+"""aVDDDY """̊mG`VDDDnì<"""rfEDDfEnuWSj@_WDwxur謸HVWm㈈nlVġjs *{VQU6+YYFqGc*T*w5YQmvDDD5lVT*""k\gE|;*հY j 5"EDDTfEv]M!"K.V"V-"":vn.q("":+zg!"ևYQ&+jٲ_3""[Zl\rrr""dnů<<!IENDB`uimaj-2.4.0/uima-docbook-tools/src/docbook/images/tools/tools.caseditor/Style-TextColor.png0000644000175000017500000000206211665471336031720 0ustar drazzibdrazzibPNG  IHDRApqsRGBbKGD pHYs  tIME  0&"tEXtCommentCreated with GIMP on a MacwCIDATH[Hg5&Ye6DBa m8ٜLb dz#l^ e2isHPRd9I.Be]'^$I8 `p߄).{4W.~{088H___3¾ _xYgT:+y 9$ ??<dF&h,tK]se^@>OC(]]]\. ^b4~dQ+S`lx o0񯨎\ %Giۋś\|B]E ZCrtseRKy ꡼nrXYY!c HOOx^O}$CTK%[ySdǨ}Ile,Ot޺ĦcʒPž#z},I*L1<<ḯnv;z= N# "LVFz=FFw.Rk`z#1n_ƨ|<5Gdŗ[Z&'YK 4$ZWhj:::z JEcc6aQr;i5~M%,s͘fWk8V@ꗅ|ak#'."mݡj|ȿd ْz%yҿLF ECwWl\"r܃yn?Ro[K]IENDB`uimaj-2.4.0/NOTICE0000644000175000017500000000115711665471344013441 0ustar drazzibdrazzibApache UIMA Copyright 2006, 2011 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). Portions of UIMA were originally developed by International Business Machines Corporation and are licensed to the Apache Software Foundation under the "Software Grant License Agreement", informally known as the "IBM UIMA License Agreement". Copyright (c) 2003, 2006 IBM Corporation. This product contains icons developed by the SVG Icons project (http://sourceforge.net/projects/svgicons), licensed under the BSD license (see LICENSE file). uimaj-2.4.0/uimaj-bootstrap/0000755000175000017500000000000011665472372015653 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/pom.xml0000644000175000017500000000413211665471546017172 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-bootstrap jar 2.4.0 Apache UIMA Base: ${project.artifactId}: Bootstrap launcher Configures a classpath from directories, and runs a Java application using that ${uimaWebsiteUrl} org.apache.maven.plugins maven-jar-plugin org.apache.uima.bootstrap.UimaBootstrap uimaj-2.4.0/uimaj-bootstrap/src/0000755000175000017500000000000011665471016016434 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/0000755000175000017500000000000011665471020017353 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/resources/0000755000175000017500000000000011665471020021365 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/0000755000175000017500000000000011665471016020301 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/org/0000755000175000017500000000000011665471016021070 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/org/apache/0000755000175000017500000000000011665471016022311 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/org/apache/uima/0000755000175000017500000000000011665471016023244 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/org/apache/uima/bootstrap/0000755000175000017500000000000011665471016025261 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-bootstrap/src/main/java/org/apache/uima/bootstrap/UimaBootstrap.java0000644000175000017500000001765411665471016030732 0ustar drazzibdrazzib/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.uima.bootstrap; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.List; /** * Run an arbitrary "main" method in a class, after adding classes to the classpath * that are specified as libraries, or as jar files * * Uses arguments: * -Dorg.apache.uima.jarpath=XXXX where XXXX is * a string of file paths to directories connected using File.pathSeparator; each * directory's contained JARs will be added to the class path. * If the directory has no Jars, then it is put in the class path directly. * * The paths can also contain jar files. * * The paths added are added in an arbitrary order. * The normal parent-first delegation is done * * The first argument is taken to be the name of the class to launch; * that is passed the rest of the arguments. * */ public class UimaBootstrap { private static boolean suppressClassPathDisplay; /** * @param args * @throws NoSuchMethodException * @throws SecurityException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws IOException * @throws MalformedURLException * @throws URISyntaxException */ public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, MalformedURLException, IOException, URISyntaxException { if (args == null || args.length == 0) { System.err.println("Usage: specify -Dorg.apache.uima.jarpath=XXXX, where"); System.err.println(" XXXX is a string of file paths to directories or jar files, separated using the proper path separator character."); System.err.println(" For directories, all of the JARs found in these directories will be added to the classpath."); System.err.println(" If the directory has no Jars, then it is put in the class path directly."); System.err.println(" Normal \"parent-first\" delegation is done."); System.err.println(" The first argument is taken to be the name of the class whose \"main\" method will be called and passed the rest of the arguments."); System.err.println(" Set -DUimaBootstrapSuppressClassPathDisplay to suppress the display of the resulting classpath"); System.exit(1); } suppressClassPathDisplay = System.getProperty("UimaBootstrapSuppressClassPathDisplay") != null; URL[] urls = getUrls(); // URLClassLoader cl = new ParentFirstWithResourceClassLoader(urls); // Thread.currentThread().setContextClassLoader(cl); addUrlsToSystemLoader(urls); Class classToLaunch = null; try { classToLaunch = ClassLoader.getSystemClassLoader().loadClass(args[0]); } catch (ClassNotFoundException e) { System.err.println("Cannot find class to launch"); System.exit(1); } Method mainMethod = classToLaunch.getMethod("main", String[].class); int args2length = args.length - 1; String [] args2 = new String[args2length]; System.arraycopy(args, 1, args2, 0, args2length); mainMethod.invoke(null, (Object)args2); } private static URL[] getUrls() throws MalformedURLException, IOException, URISyntaxException { String jps = System.getProperty("org.apache.uima.jarpath"); if (null == jps) { System.err.println("Missing the -Dorg.apache.uima.jarpath=XXXX property"); System.exit(1); } if (!suppressClassPathDisplay) { System.out.println("UimaBootstrap ClassPath:"); } List urls = new ArrayList(); String[] jpaths = jps.split(File.pathSeparator); for (String p : jpaths) { addUrlsFromPath(p, urls); } return urls.toArray(new URL[urls.size()]); } private static FilenameFilter jarFilter = new FilenameFilter() { public boolean accept(File dir, String name) { name = name.toLowerCase(); return (name.endsWith(".jar")); } }; private static void addUrlsFromPath(String p, List urls) throws MalformedURLException, IOException, URISyntaxException { File pf = new File(p); if (pf.isDirectory()) { File[] jars = pf.listFiles(jarFilter); if (jars.length == 0) { // this is the case where the user wants to include // a directory containing non-jar'd .class files add(urls, pf); } else { for (File f : jars) { add(urls, f); } } } else if (p.toLowerCase().endsWith(".jar")) { add(urls, pf); } } private static void add(List urls, File cp) throws MalformedURLException { URL url = cp.toURI().toURL(); if (!suppressClassPathDisplay) { System.out.format( " %s%n", url.toString()); } urls.add(url); } private static void addUrlsToSystemLoader(URL[] urls) throws IOException { URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); try { Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class}); method.setAccessible(true); // is normally "protected" for (URL url : urls) { method.invoke(systemClassLoader, new Object[]{url}); } } catch (Throwable t) { t.printStackTrace(); throw new IOException("Error, could not add URL to system classloader"); } } // private static class ParentFirstWithResourceClassLoader extends URLClassLoader { // // /** // * Creates a new ParentFirstWithResourceClassLoader // * // * @param urls // * an array of URLs representing JAR files // * // * @throws MalformedURLException // * if a malformed URL has occurred in the classpath string. // */ // public ParentFirstWithResourceClassLoader(URL[] urls) { // super(urls); // } // // // @SuppressWarnings("unchecked") // protected synchronized Class loadClass(String name, boolean resolve) // throws ClassNotFoundException { // // First, check if the class has already been loaded // Class c = findLoadedClass(name); // if (c == null) { // // delegate class loading for class // try { // c = super.loadClass(name, false); // } catch (ClassNotFoundException e) { // // try to load class // c = findClass(name); // } // } // if (resolve) { // resolveClass(c); // } // return c; // } // // // make sure resources are looked up first in this loader // // ASSUMES that getResourceAsStream calls getResource //// @Override //// public URL getResource(String resName) { //// URL r = findResource(resName); //// if (r != null) //// return r; //// return super.getResource(resName); //// } // } } uimaj-2.4.0/uimaj-eclipse-update-site/0000755000175000017500000000000011665471336017503 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-update-site/verifySigsEclipseUpdateSite.sh0000644000175000017500000000351111665471336025466 0ustar drazzibdrazzib#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # On windows, run this inside cygwin # Bourne shell syntax, this should hopefully run on pretty much anything. usage() { echo "Usage: cd to eclipseUpdateSite, then verifySigsEclipseUpdateSite.sh )" } # Verify PGP signatures for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do gpg --verify $i.asc; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do gpg --verify $i.asc; done gpg --verify target/eclipse-update-site/digest.zip.asc # Verify MD5 checksums for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do md5sum --check $i.md5; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do md5sum --check $i.md5; done md5sum --check target/eclipse-update-site/digest.zip.md5 # Verify SHA1 checksums for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do sha1sum --check $i.sha1; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do sha1sum --check $i.sha1; done md5sum --check target/eclipse-update-site/digest.zip.md5 uimaj-2.4.0/uimaj-eclipse-update-site/features/0000755000175000017500000000000011665471336021321 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-update-site/pom.xml0000644000175000017500000003112611665471336021023 0ustar drazzibdrazzib 4.0.0 org.apache.uima parent-pom 1 uimaj-eclipse-update-site pom 4-SNAPSHOT Apache UIMAhe UIMA Eclipse: ${project.artifactId} The UIMA Eclipse update site ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/trunk/uimaj-eclipse-update-site scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/trunk/uimaj-eclipse-update-site http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-eclipse-update-site uimaj ${project.artifactId} ${project.build.directory}/eclipse-update-site 2.4.0 2.4.0 eclipse-update-site/web web eclipse-update-site . index.html site.xml org.apache.maven.plugins maven-dependency-plugin copy-plugins-being-released copy org.apache.uima uimaj-ep-cas-editor ${item-maven-release-version} org.apache.uima.caseditor_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-configurator ${item-maven-release-version} org.apache.uima.desceditor_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-debug ${item-maven-release-version} org.apache.uima.debug_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-jcasgen ${item-maven-release-version} org.apache.uima.jcas.jcasgenp_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-pear-packager ${item-maven-release-version} org.apache.uima.pear_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-runtime ${item-maven-release-version} org.apache.uima.runtime_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-deployeditor ${item-maven-release-version} org.apache.uima.deployeditor_${item-eclipse-release-version}.jar org.apache.uima uimaj-ep-runtime-deployeditor ${item-maven-release-version} org.apache.uima.runtime.fragments.deployeditor_${item-eclipse-release-version}.jar ${project.build.directory}/work/plugins copy-features copy org.apache.uima uimaj-eclipse-feature-runtime ${item-maven-release-version} org.apache.uima.runtime_${item-eclipse-release-version}.jar org.apache.uima uimaj-eclipse-feature-tools ${item-maven-release-version} org.apache.uima.tools_${item-eclipse-release-version}.jar org.apache.uima uimaj-eclipse-feature-deployeditor ${item-eclipse-release-version} org.apache.uima.as.deployeditor_${item-eclipse-release-version}.jar ${project.build.directory}/eclipse-update-site/features maven-antrun-plugin BuildUpdateSite package run uimaj-2.4.0/uimaj-eclipse-update-site/plugins/0000755000175000017500000000000011665471336021164 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-update-site/index.html0000644000175000017500000000540511665471336021504 0ustar drazzibdrazzib uima-ep-update-site

uimaj-2.4.0/uimaj-eclipse-update-site/site.xml0000644000175000017500000000775411665471336021206 0ustar drazzibdrazzib Eclipse update site for Apache UIMA. uimaj-2.4.0/uimaj-eclipse-update-site/signEclipseUpdateSite.sh0000644000175000017500000000427211665471336024301 0ustar drazzibdrazzib#!/bin/sh # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # Bourne shell syntax, this should hopefully run on pretty much anything. usage() { echo "Usage: cd to the uimaj-eclipse-update-site project, then ./signEclipseUpdateSite.sh" } if [ "$1" = "-help" ] then usage exit 1 fi # Create PGP signatures for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do gpg --output $i.asc --detach-sig --armor $i; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do gpg --output $i.asc --detach-sig --armor $i; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.pack.gz; do gpg --output $i.asc --detach-sig --armor $i; done gpg --output target/eclipse-update-site/digest.zip.asc --detach-sig --armor target/eclipse-update-site/digest.zip # Create MD5 checksums for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do md5sum --binary $i > $i.md5; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do md5sum --binary $i > $i.md5; done md5sum --binary target/eclipse-update-site/digest.zip > target/eclipse-update-site/digest.zip.md5 # Create SHA1 checksums for i in target/eclipse-update-site/features/org.apache.uima.*.jar; do sha1sum --binary $i > $i.sha1; done for i in target/eclipse-update-site/plugins/org.apache.uima.*.jar; do sha1sum --binary $i > $i.sha1; done sha1sum --binary target/eclipse-update-site/digest.zip > target/eclipse-update-site/digest.zip.sha1 uimaj-2.4.0/uimaj-eclipse-update-site/web/0000755000175000017500000000000011665471336020260 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-update-site/web/site.css0000644000175000017500000000272511665471336021744 0ustar drazzibdrazzib uimaj-2.4.0/uimaj-eclipse-update-site/web/site.xsl0000644000175000017500000001741511665471336021764 0ustar drazzibdrazzib uima-ep-update-site

uima-ep-update-site

dark-row light-row dark-row light-row dark-row light-row

( - )
-

Operating Systems:
Windows Systems:
Languages:
Architecture:


Uncategorized

( - )
-


Operating Systems:
Windows Systems:
Languages:
Architecture:

( - )
-


Operating Systems:
Windows Systems:
Languages:
Architecture:
uimaj-2.4.0/aggregate-uimaj/0000755000175000017500000000000011665472374015566 5ustar drazzibdrazzibuimaj-2.4.0/aggregate-uimaj/pom.xml0000644000175000017500000000664611665471546017117 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml aggregate-uimaj pom 2.4.0 Apache UIMA Aggregate: ${project.artifactId}: UIMA Base The aggregate for the base UIMA framework build and release ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/aggregate-uimaj ${project.artifactId} ../uimaj-core ../uimaj-cpe ../uimaj-examples ../uimaj-tools ../uimaj-adapter-vinci ../uimaj-adapter-soap ../uimaj-test-util ../uimaj-component-test-util ../jVinci ../aggregate-uimaj-eclipse-plugins ../aggregate-uimaj-docbooks ../uimaj-document-annotation ../PearPackagingMavenPlugin ../uimaj-bootstrap uimaj-2.4.0/RELEASE_NOTES.html0000644000175000017500000002017111665471344015450 0ustar drazzibdrazzib Apache UIMA v2.4.0 Release Notes

Apache UIMA (Unstructured Information Management Architecture) v2.4.0 Release Notes

Contents

What is UIMA?
Major Changes in this Release
How to Get Involved
How to Report Issues
List of JIRA Issues Fixed in this Release
Migrating from IBM UIMA to Apache UIMA

1. What is UIMA?

Unstructured Information Management applications are software systems that analyze large volumes of unstructured information in order to discover knowledge that is relevant to an end user. UIMA is a framework and SDK for developing such applications. An example UIM application might ingest plain text and identify entities, such as persons, places, organizations; or relations, such as works-for or located-at. UIMA enables such an application to be decomposed into components, for example "language identification" -> "language specific segmentation" -> "sentence boundary detection" -> "entity detection (person/place names etc.)". Each component must implement interfaces defined by the framework and must provide self-describing metadata via XML descriptor files. The framework manages these components and the data flow between them. Components are written in Java or C++; the data that flows between components is designed for efficient mapping between these languages. UIMA additionally provides capabilities to wrap components as network services, and can scale to very large volumes by replicating processing pipelines over a cluster of networked nodes.

Apache UIMA is an Apache-licensed open source implementation of the UIMA specification (that specification is, in turn, being developed concurrently by a technical committee within OASIS , a standards organization). We invite and encourage you to participate in both the implementation and specification efforts.

UIMA is a component framework for analysing unstructured content such as text, audio and video. It comprises an SDK and tooling for composing and running analytic components written in Java and C++, with some support for Perl, Python and TCL.

Major Changes in this Release

Please see the README for this information.

How to Get Involved

The Apache UIMA project really needs and appreciates any contributions, including documentation help, source code and feedback. If you are interested in contributing, please visit http://uima.apache.org/get-involved.html.

How to Report Issues

The Apache UIMA project uses JIRA for issue tracking. Please report any issues you find at http://issues.apache.org/jira/browse/uima

List of JIRA Issues Fixed in this Release

Click issuesFixed/jira-report.hmtl for the list of issues fixed in this release.

Migrating from IBM UIMA to Apache UIMA

This section describes how to move from pre-Apache versions of UIMA to the Apache version (starting with Apache UIMA 2.1).

Note: Before running the migration utility, be sure to back up your files, just in case you encounter any problems, because the migration tool updates the files in place in the directories where it finds them.

The migration utility is run by executing the script file apache-uima/bin/ibmUimaToApacheUima.bat (Windows) or apache-uima/bin/ibmUimaToApacheUima.sh (UNIX). You must pass one argument: the directory containing the files that you want to be migrated. Subdirectories will be processed recursively.

The script scans your files and applies the necessary updates, for example replacing the com.ibm package names with the new org.apache package names.

The script will only attempt to modify files with the extensions: java, xml, xmi, wsdd, properties, launch, bat, cmd, sh, ksh, or csh; and files with no extension. Also, files with size greater than 1,000,000 bytes will be skipped. (If you want the script to modify files with other extensions, you can edit the script file and change the -ext argument appropriately.)

If the migration tool reports warnings, there may be a few additional steps to take. The following two sections explain some simple manual changes that you might need to make to your code.

3.1. JCas Cover Classes for DocumentAnnotation

If you have run JCasGen it is likely that you have the classes com.ibm.uima.jcas.tcas.DocumentAnnotation and com.ibm.uima.jcas.tcas.DocumentAnnotation_Type as part of your code. This package name is no longer valid, and the migration utility does not move your files between directories so it is unable to fix this.

If you have not made manual modifications to these classes, the best solution is usually to just delete these two classes (and their containing package). There is a default version in the uima-document-annotation.jar file that is included in Apache UIMA. If you have made custom changes, then you should not delete the file but instead move it to the correct package org.apache.uima.jcas.tcas. For more information about JCas and DocumentAnnotation please see Section 5.5.4, "Adding Features to DocumentAnnotation" in the UIMA References manual.

3.2. JCas.getDocumentAnnotation

The deprecated method JCas.getDocumentAnnotation has been removed. Its use must be replaced with JCas.getDocumentAnnotationFs. The method JCas.getDocumentAnnotationFs() returns type TOP, so your code must cast this to type DocumentAnnotation. The reasons for this are described in Section 5.5.4, "Adding Features to DocumentAnnotation" in the UIMA References manual.

3.3. Rare Cases Where Additional Manual Migration is Necessary

For most users there should not be any additional migration steps necessary. However, if the migration tool reported an additional warning or if you are having trouble getting your code to compile or run after running the migration, please see Section 1.4.2. "Rare Cases Where Additional Manual Migration is Necessary," in the Overview and Setup manual.

uimaj-2.4.0/uimaj-eclipse-feature-tools/0000755000175000017500000000000011665472246020051 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-tools/feature.properties0000644000175000017500000000241411665471254023621 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** # do not delete this file - it is required for optimized site generation # feature.properties # contains externalized strings for feature.xml # "%foo" in feature.xml corresponds to the key "foo" in this file # java.io.Properties file (ISO 8859-1 with "\" escapes) # This file should be translated.uimaj-2.4.0/uimaj-eclipse-feature-tools/pom.xml0000644000175000017500000000776211665471546021404 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uimaj-eclipse-feature-tools jar 2.4.0 Apache UIMA Eclipse: ${project.artifactId} UIMA Eclipse Plugin Feature for base uima tooling ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-tools scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-tools http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uimaj-eclipse-feature-tools ${project.artifactId} ${project.artifactId}_${parsedVersion.osgiVersion} ${basedir} feature.properties feature.xml true maven-resources-plugin filter feature.xml generate-resources copy-resources ${basedir} src/main/resources feature.xml true uimaj-2.4.0/uimaj-eclipse-feature-tools/marker-file-identifying-eclipse-feature0000644000175000017500000000000011665471254027540 0ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-tools/build.properties0000644000175000017500000000177011665471254023271 0ustar drazzibdrazzib# *************************************************************** # * Licensed to the Apache Software Foundation (ASF) under one # * or more contributor license agreements. See the NOTICE file # * distributed with this work for additional information # * regarding copyright ownership. The ASF licenses this file # * to you under the Apache License, Version 2.0 (the # * "License"); you may not use this file except in compliance # * with the License. You may obtain a copy of the License at # * # * http://www.apache.org/licenses/LICENSE-2.0 # * # * Unless required by applicable law or agreed to in writing, # * software distributed under the License is distributed on an # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # * KIND, either express or implied. See the License for the # * specific language governing permissions and limitations # * under the License. # *************************************************************** bin.includes = feature.xml uimaj-2.4.0/uimaj-eclipse-feature-tools/src/0000755000175000017500000000000011665471254020636 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-tools/src/main/0000755000175000017500000000000011665471254021562 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-tools/src/main/resources/0000755000175000017500000000000011665471254023574 5ustar drazzibdrazzibuimaj-2.4.0/uimaj-eclipse-feature-tools/src/main/resources/feature.xml0000644000175000017500000001210011665471254025743 0ustar drazzibdrazzib This feature contains a debug structure handler plugin, the Component Descriptor Editor (a forms-based editor for creating and editing the XML descriptors used by UIMA), the JCas generation capability, a CAS Editor, the Launcher, and the PEAR packaging capability. Copyright the Apache Software Foundation and others; see License and NOTICE files Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/uimaj-eclipse-feature-tools/feature.xml0000644000175000017500000001156111665472246022232 0ustar drazzibdrazzib This feature contains a debug structure handler plugin, the Component Descriptor Editor (a forms-based editor for creating and editing the XML descriptors used by UIMA), the JCas generation capability, a CAS Editor, the Launcher, and the PEAR packaging capability. Copyright the Apache Software Foundation and others; see License and NOTICE files Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/0000755000175000017500000000000011665472344022304 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tutorials-and-users-guides/pom.xml0000644000175000017500000000527211665471546023632 0ustar drazzibdrazzib 4.0.0 org.apache.uima uimaj-parent 2.4.0 ../uimaj-parent/pom.xml uima-docbook-tutorials-and-users-guides pom 2.4.0 Apache UIMA SDK Documentation - tutorials and user's guides ${uimaWebsiteUrl} scm:svn:http://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tutorials-and-users-guides scm:svn:https://svn.apache.org/repos/asf/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tutorials-and-users-guides http://svn.apache.org/viewvc/uima/uimaj/tags/uimaj-2.4.0-rc1/uima-docbook-tutorials-and-users-guides ${project.artifactId} tutorials_and_users_guides uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/0000755000175000017500000000000011665471340023066 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/0000755000175000017500000000000011665471342024510 5ustar drazzibdrazzibuimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tug.cpe.xml0000644000175000017500000021130211665471342026576 0ustar drazzibdrazzib %uimaents; ]> Collection Processing Engine Developer's Guide CPE Developer's Guide The UIMA Analysis Engine interface provides support for developing and integrating algorithms that analyze unstructured data. Analysis Engines are designed to operate on a per-document basis. Their interface handles one CAS at a time. UIMA provides additional support for applying analysis engines to collections of unstructured data with its Collection Processing Architecture. The Collection Processing Architecture defines additional components for reading raw data formats from data collections, preparing the data for processing by Analysis Engines, executing the analysis, extracting analysis results, and deploying the overall flow in a variety of local and distributed configurations. The functionality defined in the Collection Processing Architecture is implemented by a Collection Processing Engine (CPE). A CPE includes an Analysis Engine and adds a Collection Reader, a CAS Initializer (deprecated as of version 2), and CAS Consumers. The part of the UIMA Framework that supports the execution of CPEs is called the Collection Processing Manager, or CPM. A Collection Reader provides the interface to the raw input data and knows how to iterate over the data collection. Collection Readers are discussed in . The CAS Initializer CAS Initializers are deprecated in favor of a more general mechanism, multiple subjects of analysis. prepares an individual data item for analysis and loads it into the CAS. CAS Initializers are discussed in A CAS Consumer extracts analysis results from the CAS and may also perform collection level processing, or analysis over a collection of CASes. CAS Consumers are discussed in . Analysis Engines and CAS Consumers are both instances of CAS Processors. A Collection Processing Engine (CPE) may contain multiple CAS Processors. An Analysis Engine contained in a CPE may itself be a Primitive or an Aggregate (composed of other Analysis Engines). Aggregates may contain Cas Consumers. While Collection Readers and CAS Initializers always run in the same JVM as the CPM, a CAS Processor may be deployed in a variety of local and distributed modes, providing a number of options for scalability and robustness. The different deployment options are covered in detail in . Each of the components in a CPE has an interface specified by the UIMA Collection Processing Architecture and is described by a declarative XML descriptor file. Similarly, the CPE itself has a well defined component interface and is described by a declarative XML descriptor file. A user creates a CPE by assembling the components mentioned above. The UIMA SDK provides a graphical tool, called the CPE Configurator, for assisting in the assembly of CPEs. Use of this tool is summarized in , and more details can be found in . Alternatively, a CPE can be assembled by writing an XML CPE descriptor. Details on the CPE descriptor, including its syntax and content, can be found in the . The individual components have associated XML descriptors, each of which can be created and / or edited using the Component Description Editor. A CPE is executed by a UIMA infrastructure component called the Collection Processing Manager (CPM). The CPM provides a number of services and deployment options that cover instantiation and execution of CPEs, error recovery, and local and distributed deployment of the CPE components.
CPE Concepts illustrates the data flow that occurs between the different types of components that make up a CPE.
CPE Components CPE Components and flow between them
The components of a CPE are: Collection Reader – interfaces to a collection of data items (e.g., documents) to be analyzed. Collection Readers return CASes that contain the documents to analyze, possibly along with additional metadata. Analysis Engine – takes a CAS, analyzes its contents, and produces an enriched CAS. Analysis Engines can be recursively composed of other Analysis Engines (called an Aggregate Analysis Engine). Aggregates may also contain CAS Consumers. CAS Consumer – consume the enriched CAS that was produced by the sequence of Analysis Engines before it, and produce an application-specific data structure, such as a search engine index or database. A fourth type of component, the CAS Initializer, may be used by a Collection Reader to populate a CAS from a document. However, as of UIMA version 2 CAS Initializers are now deprecated in favor of a more general mechsanism, multiple Subjects of Analysis. The Collection Processing Manager orchestrates the data flow within a CPE, monitors status, optionally manages the life-cycle of internal components and collects statistics. CASes are not saved in a persistent way by the framework. If you want to save CASes, then you have to save each CAS as it comes through (for example) using a CAS Consumer you write to do this, in whatever format you like. The UIMA SDK supplies an example CAS Consumer to save CASes to XML files, either in the standard XMI format or in an older format called XCAS. It also supplies an example CAS Consumer to extract information from CASes and store the results into a relational Database, using Java's JDBC APIs.
CPE Configurator and CAS viewer
Using the CPE Configurator A CPE can be assembled by writing an XML CPE descriptor. Details on the CPE descriptor, including its syntax and content, can be found in . Rather than edit raw XML, you may develop a CPE Descriptor using the CPE Configurator tool. The CPE Configurator tool is described briefly in this section, and in more detail in . The CPE Configurator tool can be run from Eclipse (see , or using the cpeGui shell script (cpeGui.bat on Windows, cpeGui.sh on Unix), which is located in the bin directory of the UIMA SDK installation. Executing this batch file will display the window shown here: Screenshot of CPE GUI The window is divided into three sections, one each for the Collection Reader, Analysis Engines, and CAS Consumers.There is also a fourth pane, for the CAS Initializer, but it is hidden by default. To enable it click the View → CAS Initializer Panel menu item. In each section, you select the component(s) you want to include in the CPE by browsing to their XML descriptors. The configuration parameters present in the XML descriptors will then be displayed in the GUI; these can be modified to override the values present in the descriptor. For example, the screen shot below shows the CPE Configurator after the following components have been chosen: Collection Reader: %UIMA_HOME%/examples/descriptors/collection_reader/ FileSystemCollectionReader.xml Analysis Engine: %UIMA_HOME%/examples/descriptors/analysis_engine/ NamesAndPersonTitles_TAE.xml CAS Consumer: %UIMA_HOME%/examples/descriptors/cas_consumer/ XmiWriterCasConsumer.xml Screenshot of CPE GUI after fields filled in For the File System Collection Reader, ensure that the Input Directory is set to %UIMA_HOME%\examples\dataReplace %UIMA_HOME% with the path to where you installed UIMA. . The other parameters may be left blank. For the External CAS Writer CAS Consumer, ensure that the Output Directory is set to %UIMA_HOME%\examples\data\processed. After selecting each of the components and providing configuration settings, click the play (forward arrow) button at the bottom of the screen to begin processing. A progress bar should be displayed in the lower left corner. (Note that the progress bar will not begin to move until all components have completed their initialization, which may take several seconds.) Once processing has begun, the pause and stop buttons become enabled. If an error occurs, you will be informed by an error dialog. If processing completes successfully, you will be presented with a performance report. Using the File menu, you can select Save CPE Descriptor to create an .xml descriptor file that defines the CPE you have constructed. Later, you can use Open CPE Descriptor to restore the CPE Configurator to the saved state. Also, CPE descriptors can be used to run a CPE from a Java program – see section . CPE Descriptors allow specifying operational parameters, such as error handling options, that are not currently available for configuration through the CPE Configurator. For more information on manually creating a CPE Descriptor, see the . The CPE configured above runs a simple name and title annotator on the sample data provided with the UIMA SDK and stores the results using the XMI Writer CAS Consumer. To view the results, start the External CAS Annotation Viewer by running the annotationViewer batch file (annotationViewer.bat on Windows, annotationViewer.sh on Unix), which is located in the bin directory of the UIMA SDK installation. Executing this batch file will display the window shown here: Screenshot of Annotation Viewer results Ensure that the Input Directory is the same as the Output Directory specified for the XMI Writer CAS Consumer in the CPE configured above (e.g., %UIMA_HOME%\examples\data\processed) and that the TAE Descriptor File is set to the Analysis Engine used in the CPE configured above (e.g., examples\descriptors\analysis_engine\NamesAndPersonTitles_TAE.xml ). Click the View button to display the Analyzed Documents window: Screenshot of CPE Configurator Analyzed Documents Double click on any document in the list to view the analyzed document. Double clicking the first document, IBM_LifeSciences.txt, will bring up the following window: Screenshot of Document and Annotation Viewer This window shows the analysis results for the document. Clicking on any highlighted annotation causes the details for that annotation to be displayed in the right-hand pane. Here the annotation spanning John M. Thompson has been clicked. Congratulations! You have successfully configured a CPE, saved its descriptor, run the CPE, and viewed the analysis results.
Running the CPE Configurator from Eclipse If you have followed the instructions in and imported the example Eclipse project, then you should already have a Run configuration for the CPE Configurator tool (called UIMA CPE GUI) configured to run in the example project. Simply run that configuration to start the CPE Configurator. If you haven't followed the Eclipse setup instructions and wish to run the CPE Configurator tool from Eclipse, you will need to do the following. As installed, this Eclipse launch configuration is associated with the uimaj-examples project. If you've not already done so, you may wish to import that project into your Eclipse workspace. It's located in %UIMA_HOME%/docs/examples. Doing this will supply the Eclipse launcher with all the class files it needs to run the CPE configurator. If you don't do this, please manually add the JAR files for UIMA to the launch configuration. Also, you need to add any projects or JAR files for any UIMA components you will be running to the launch class path. A simpler alternative may be to change the CPE launch configuration to be based on your project. If you do that, it will pick up all the files in your project's class path, which you should set up to include all the UIMA framework files. An easy way to do this is to specify in your project's properties' build-path that the uimaj-examples project is on the build path, because the uimaj-examples project is set up to include all the UIMA framework classes in its classpath already. Next, in the Eclipse menu select Run → Run..., which brings up the Run configuration screen. In the Main tab, set the main class to org.apache.uima.tools.cpm.CpmFrame In the arguments tab, add the following to the VM arguments: -Xms128M -Xmx256M -Duima.home="C:\Program Files\Apache\uima" (or wherever you installed the UIMA SDK) Click the Run button to launch the CPE Configurator, and use it as previously described in this section.
Running a CPE from Your Own Java Application The simplest way to run a CPE from a Java application is to first create a CPE descriptor as described in the previous section. Then the CPE can be instantiated and run using the following code: //parse CPE descriptor in file specified on command line CpeDescription cpeDesc = UIMAFramework.getXMLParser(). parseCpeDescription(new XMLInputSource(args[0])); //instantiate CPE mCPE = UIMAFramework.produceCollectionProcessingEngine(cpeDesc); //Create and register a Status Callback Listener mCPE.addStatusCallbackListener(new StatusCallbackListenerImpl()); //Start Processing mCPE.process(); This will start the CPE running in a separate thread. The process() method for a CPE can only be called once. If you need to call it again, you have to instantiate a new CPE, and call that new CPE's process method.
Using Listeners Updates of the CPM's progress, including any errors that occur, are sent to the callback handler that is registered by the call to addStatusCallbackListener, above. The callback handler is a class that implements the CPM's StatusCallbackListener interface. It responds to events by printing messages to the console. The source code is fairly straightforward and is not included in this chapter – see the org.apache.uima.examples.cpe.SimpleRunCPE.java in the %UIMA_HOME%\examples\src directory for the complete code. If you need more control over the information in the CPE descriptor, you can manually configure it via its API. See the Javadocs for package org.apache.uima.collection for more details.
Developing Collection Processing Components This section is an introduction to the process of developing Collection Readers, CAS Initializers, and CAS Consumers. The code snippets refer to the classes that can be found in %UIMA_HOME%\examples\src example project. In the following sections, classes you write to represent components need to be public and have public, 0-argument constructors, so that they can be instantiated by the framework. (Although Java classes in which you do not define any constructor will, by default, have a 0-argument constructor that doesn't do anything, a class in which you have defined at least one constructor does not get a default 0-argument constructor.)
Developing Collection Readers A Collection Reader is responsible for obtaining documents from the collection and returning each document as a CAS. Like all UIMA components, a Collection Reader consists of two parts — the code and an XML descriptor. A simple example of a Collection Reader is the File System Collection Reader, which simply reads documents from files in a specified directory. The Java code is in the class org.apache.uima.examples.cpe.FileSystemCollectionReader and the XML descriptor is %UIMA_HOME%/examples/src/main/descriptors/collection_reader/ FileSystemCollectionReader.xml.
Java Class for the Collection Reader The Java class for a Collection Reader must implement the org.apache.uima.collection.CollectionReader interface. You may build your Collection Reader from scratch and implement this interface, or you may extend the convenience base class org.apache.uima.collection.CollectionReader_ImplBase . The convenience base class provides default implementations for many of the methods defined in the CollectionReader interface, and provides abstract definitions for those methods that you are required to implement in your new Collection Reader. Note that if you extend this base class, you do not need to declare that your new Collection Reader implements the CollectionReader interface. Eclipse tip – if you are using Eclipse, you can quickly create the boiler plate code and stubs for all of the required methods by clicking FileNewClass to bring up the New Java Class dialogue, specifying org.apache.uima.collection.CollectionReader_ImplBase as the Superclass, and checking Inherited abstract methods in the section Which method stubs would you like to create?, as in the screenshot below: Screenshot showing Eclipse new class wizard For the rest of this section we will assume that your new Collection Reader extends the CollectionReader_ImplBase class, and we will show examples from the org.apache.uima.examples.cpe.FileSystemCollectionReader . If you must inherit from a different superclass, you must ensure that your Collection Reader implements the CollectionReader interface – see the Javadocs for CollectionReader for more details.
Required Methods in the Collection Reader class The following abstract methods must be implemented:
initialize() The initialize() method is called by the framework when the Collection Reader is first created. CollectionReader_ImplBase actually provides a default implementation of this method (i.e., it is not abstract), so you are not strictly required to implement this method. However, a typical Collection Reader will implement this method to obtain parameter values and perform various initialization steps. In this method, the Collection Reader class can access the values of its configuration parameters and perform other initialization logic. The example File System Collection Reader reads its configuration parameters and then builds a list of files in the specified input directory, as follows: public void initialize() throws ResourceInitializationException { File directory = new File( (String)getConfigParameterValue(PARAM_INPUTDIR)); mEncoding = (String)getConfigParameterValue(PARAM_ENCODING); mDocumentTextXmlTagName = (String)getConfigParameterValue(PARAM_XMLTAG); mLanguage = (String)getConfigParameterValue(PARAM_LANGUAGE); mCurrentIndex = 0; //get list of files (not subdirectories) in the specified directory mFiles = new ArrayList(); File[] files = directory.listFiles(); for (int i = 0; i < files.length; i++) { if (!files[i].isDirectory()) { mFiles.add(files[i]); } } } This is the zero-argument version of the initialize method. There is also a method on the Collection Reader interface called initialize(ResourceSpecifier, Map) but it is not recommended that you override this method in your code. That method performs internal initialization steps and then calls the zero-argument initialize().
hasNext() The hasNext() method returns whether or not there are any documents remaining to be read from the collection. The File System Collection Reader's hasNext() method is very simple. It just checks if there are any more files left to be read: public boolean hasNext() { return mCurrentIndex < mFiles.size(); }
getNext(CAS) The getNext() method reads the next document from the collection and populates a CAS. In the simple case, this amounts to reading the file and calling the CAS's setDocumentText method. The example File System Collection Reader is slightly more complex. It first checks for a CAS Initializer. If the CPE includes a CAS Initializer, the CAS Initializer is used to read the document, and initialize() the CAS. If the CPE does not include a CAS Initializer, the File System Collection Reader reads the document and sets the document text in the CAS. The File System Collection Reader also stores additional metadata about the document in the CAS. In particular, it sets the document's language in the special built-in feature structure uima.tcas.DocumentAnnotation (see for details about this built-in type) and creates an instance of org.apache.uima.examples.SourceDocumentInformation , which stores information about the document's source location. This information may be useful to downstream components such as CAS Consumers. Note that the type system descriptor for this type can be found in org.apache.uima.examples.SourceDocumentInformation.xml , which is located in the examples/src directory. The getNext() method for the File System Collection Reader looks like this: public void getNext(CAS aCAS) throws IOException, CollectionException { JCas jcas; try { jcas = aCAS.getJCas(); } catch (CASException e) { throw new CollectionException(e); } // open input stream to file File file = (File) mFiles.get(mCurrentIndex++); BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file)); try { byte[] contents = new byte[(int) file.length()]; fis.read(contents); String text; if (mEncoding != null) { text = new String(contents, mEncoding); } else { text = new String(contents); } // put document in CAS jcas.setDocumentText(text); } finally { if (fis != null) fis.close(); } // set language if it was explicitly specified //as a configuration parameter if (mLanguage != null) { ((DocumentAnnotation) jcas.getDocumentAnnotationFs()). setLanguage(mLanguage); } // Also store location of source document in CAS. // This information is critical if CAS Consumers will // need to know where the original document contents // are located. // For example, the Semantic Search CAS Indexer // writes this information into the search index that // it creates, which allows applications that use the // search index to locate the documents that satisfy //their semantic queries. SourceDocumentInformation srcDocInfo = new SourceDocumentInformation(jcas); srcDocInfo.setUri( file.getAbsoluteFile().toURL().toString()); srcDocInfo.setOffsetInSource(0); srcDocInfo.setDocumentSize((int) file.length()); srcDocInfo.setLastSegment( mCurrentIndex == mFiles.size()); srcDocInfo.addToIndexes(); } The Collection Reader can create additional annotations in the CAS at this point, in the same way that annotators create annotations.
getProgress() The Collection Reader is responsible for returning progress information; that is, how much of the collection has been read thus far and how much remains to be read. The framework defines progress very generally; the Collection Reader simply returns an array of Progress objects, where each object contains three fields — the amount already completed, the total amount (if known), and a unit (e.g. entities (documents), bytes, or files). The method returns an array so that the Collection Reader can report progress in multiple different units, if that information is available. The File System Collection Reader's getProgress() method looks like this: public Progress[] getProgress() { return new Progress[]{ new ProgressImpl(mCurrentIndex,mFiles.size(),Progress.ENTITIES)}; } In this particular example, the total number of files in the collection is known, but the total size of the collection is not known. As such, a ProgressImpl object for Progress.ENTITIES is returned, but a ProgressImpl object for Progress.BYTES is not.
close() The close method is called when the Collection Reader is no longer needed. The Collection Reader should then release any resources it may be holding. The FileSystemCollectionReader does not hold resources and so has an empty implementation of this method: public void close() throws IOException { }
Optional Methods The following methods may be implemented:
reconfigure() This method is called if the Collection Reader's configuration parameters change.
typeSystemInit() If you are only setting the document text in the CAS, or if you are using the JCas (recommended, as in the current example, you do not have to implement this method. If you are directly using the CAS API, this method is used in the same way as it is used for an annotator – see for more information.
Threading considerations Collection readers do not have to be thread safe; they are run with a single thread per instance, and only one instance per instance of the Collection Processing Manager (CPM) is made.
XML Descriptor for a Collection Reader You can use the Component Description Editor to create and / or edit the File System Collection Reader's descriptor. Here is its descriptor (abbreviated somewhat), which is very similar to an Analysis Engine descriptor: org.apache.uima.java org.apache.uima.examples.cpe.FileSystemCollectionReader File System Collection Reader Reads files from the filesystem. 1.0 The Apache Software Foundation InputDirectory Directory containing input files String false true Encoding Character encoding for the documents. String false false Language ISO language code for the documents String false false InputDirectory C:/Program Files/apache/uima/examples/data org.apache.uima.examples.SourceDocumentInformation true false true ]]>
Developing CAS Initializers CAS Initializers are now deprecated (as of version 2.1). For complex initialization, please use instead the capabilities of creating additional Subjects of Analysis (see ). In UIMA 1.x, the CAS Initializer component was intended to be used as a plug-in to the Collection Reader for when the task of populating the CAS from a raw document is complex and might be reusable with other data collections. A CAS Initializer Java class must implement the interface org.apache.uima.collection.CasInitializer, and will also generally extend from the convenience base class org.apache.uima.collection.CasInitializer_ImplBase. A CAS Initializer also must have an XML descriptor, which has the exact same form as a Collection Reader Descriptor except that the outer tag is <casInitializerDescription>. CAS Initializers have optional initialize(), reconfigure(), and typeSystemInit() methods, which perform the same functions as they do for Collection Readers. The only required method for a CAS Initializer is initializeCas(Object, CAS). This method takes the raw document (for example, an InputStream object from which the document can be read) and a CAS, and populates the CAS from the document.
Developing CAS Consumers In version 2, there is no difference in capability between CAS Consumers and ordinary Analysis Engines, except for the default setting of the XML parameters for multipleDeploymentAllowed and modifiesCas. We recommend for future work that users implement and use Analysis Engine components instead of CAS Consumers. The rest of this section is written using the version 1 style of CAS Consumer; the methods described are also available for Analysis Engines. Note that the CAS Consumer processCAS method is equivalent to the Analysis Engine process method. A CAS Consumer receives each CAS after it has been analyzed by the Analysis Engine. CAS Consumers typically do not update the CAS; they typically extract data from the CAS and persist selected information to aggregate data structures such as search engine indexes or databases. A CAS Consumer Java class must implement the interface org.apache.uima.collection.CasConsumer, and will also generally extend from the convenience base class org.apache.uima.collection.CasConsumer_ImplBase. A CAS Consumer also must have an XML descriptor, which has the exact same form as a Collection Reader Descriptor except that the outer tag is <casConsumerDescription>. CAS Consumers have optional initialize(), reconfigure(), and typeSystemInit() methods, which perform the same functions as they do for Collection Readers and CAS Initializers. The only required method for a CAS Consumer is processCas(CAS), which is where the CAS Consumer does the bulk of its work (i.e., consume the CAS). The CasConsumer interface (as well as the version 2 Analysis Engine interfac) additionally defines batch and collection level processing methods. The CAS Consumer or Analysis Engine can implement the batchProcessComplete() method to perform processing that should occur at the end of each batch of CASes. Similarly, the CAS Consumer or Analysis Engine can implement the collectionProcessComplete() method to perform any collection level processing at the end of the collection. A very simple example of a CAS Consumer, which writes an XML representation of the CAS to a file, is the XMI Writer CAS Consumer. The Java code is in the class org.apache.uima.examples.cpe.XmiWriterCasConsumer and the descriptor is in %UIMA_HOME%/examples/descriptors/cas_consumer/XmiWriterCasConsumer.xml .
Required Methods for a CAS Consumer When extending the convenience class org.apache.uima.collection.CasConsumer_ImplBase, the following abstract methods must be implemented:
initialize() The initialize() method is called by the framework when the CAS Consumer is first created. CasConsumer_ImplBase actually provides a default implementation of this method (i.e., it is not abstract), so you are not strictly required to implement this method. However, a typical CAS Consumer will implement this method to obtain parameter values and perform various initialization steps. In this method, the CAS Consumer can access the values of its configuration parameters and perform other initialization logic. The example XMI Writer CAS Consumer reads its configuration parameters and sets up the output directory: public void initialize() throws ResourceInitializationException { mDocNum = 0; mOutputDir = new File((String) getConfigParameterValue(PARAM_OUTPUTDIR)); if (!mOutputDir.exists()) { mOutputDir.mkdirs(); } }
processCas() The processCas() method is where the CAS Consumer does most of its work. In our example, the XMI Writer CAS Consumer obtains an iterator over the document metadata in the CAS (in the SourceDocumentInformation feature structure, which is created by the File System Collection Reader) and extracts the URI for the current document. From this the output filename is constructed in the output directory and a subroutine (writeXmi) is called to generate the output file. The writeXmi subroutine uses the XmiCasSerializer class provided with the UIMA SDK to serialize the CAS to the output file (see the example source code for details). public void processCas(CAS aCAS) throws ResourceProcessException { String modelFileName = null; JCas jcas; try { jcas = aCAS.getJCas(); } catch (CASException e) { throw new ResourceProcessException(e); } // retreive the filename of the input file from the CAS FSIterator it = jcas .getAnnotationIndex(SourceDocumentInformation.type) .iterator(); File outFile = null; if (it.hasNext()) { SourceDocumentInformation fileLoc = (SourceDocumentInformation) it.next(); File inFile; try { inFile = new File(new URL(fileLoc.getUri()).getPath()); String outFileName = inFile.getName(); if (fileLoc.getOffsetInSource() > 0) { outFileName += ("_" + fileLoc.getOffsetInSource()); } outFileName += ".xmi"; outFile = new File(mOutputDir, outFileName); modelFileName = mOutputDir.getAbsolutePath() + "/" + inFile.getName() + ".ecore"; } catch (MalformedURLException e1) { // invalid URL, use default processing below } } if (outFile == null) { outFile = new File(mOutputDir, "doc" + mDocNum++); } // serialize XCAS and write to output file try { writeXmi(jcas.getCas(), outFile, modelFileName); } catch (IOException e) { throw new ResourceProcessException(e); } catch (SAXException e) { throw new ResourceProcessException(e); } }
Optional Methods The following methods are optional in a CAS Consumer, though they are often used.
batchProcessComplete() The framework calls the batchProcessComplete() method at the end of each batch of CASes. This gives the CAS Consumer or Analysis Engine an opportunity to perform any batch level processing. Our simple XMI Writer CAS Consumer does not perform any batch level processing, so this method is empty. Batch size is set in the Collection Processing Engine descriptor.
collectionProcessComplete() The framework calls the collectionProcessComplete() method at the end of the collection (i.e., when all objects in the collection have been processed). At this point in time, no CAS is passed in as a parameter. This gives the CAS Consumer or Analysis Engine an opportunity to perform collection processing over the entire set of objects in the collection. Our simple XMI Writer CAS Consumer does not perform any collection level processing, so this method is empty.
Deploying a CPE The CPM provides a number of service and deployment options that cover instantiation and execution of CPEs, error recovery, and local and distributed deployment of the CPE components. The behavior of the CPM (and correspondingly, the CPE) is controlled by various options and parameters set in the CPE descriptor. The current version of the CPE Configurator tool, however, supports only default error handling and deployment options. To change these options, you must manually edit the CPE descriptor. Eventually the CPE Configurator tool will support configuring these options and a detailed tutorial for these settings will be provided. In the meantime, we provide only a high-level, conceptual overview of these advanced features in the rest of this chapter, and refer the advanced user to for details on setting these options in the CPE Descriptor. shows a logical view of how an application uses the UIMA framework to instantiate a CPE from a CPE descriptor. The CPE descriptor identifies the CPE components (referencing their corresponding descriptors) and specifies the various options for configuring the CPM and deploying the CPE components.
CPE Instantiation Picture of deployment of a CPE
There are three deployment modes for CAS Processors (Analysis Engines and CAS Consumers) in a CPE: Integrated (runs in the same Java instance as the CPM) Managed (runs in a separate process on the same machine), and Non-managed (runs in a separate process, perhaps on a different machine). An integrated CAS Processor runs in the same JVM as the CPE. A managed CAS Processor runs in a separate process from the CPE, but still on the same computer. The CPE controls startup, shutdown, and recovery of a managed CAS Processor. A non-managed CAS Processor runs as a service and may be on the same computer as the CPE or on a remote computer. A non-managed CAS Processor service is started and managed independently from the CPE. For both managed and non-managed CAS Processors, the CAS must be transmitted between separate processes and possibly between separate computers. This is accomplished using Vinci, a communication protocol used by the CPM and which is provided as a part of Apache UIMA. Vinci handles service naming and location and data transport (see   for more information). Service naming and location are provided by a Vinci Naming Service, or VNS. For managed CAS Processors, the CPE uses its own internal VNS. For non-managed CAS Processors, a separate VNS must be running. The UIMA SDK also supports using unmanaged remote services via the web-standard SOAP communications protocol (see . This approach is based on a proxy implementation, where the proxy is essentially running in an integrated mode. To use this approach with the CPM, use the Integrated mode, with the component being an Aggregate which, in turn, connects to a remote service. The CPE Configurator tool currently only supports constructing CPEs that deploy CAS Processors in integrated mode. To deploy CAS Processors in any other mode, the CPE descriptor must be edited by hand (better tooling may be provided later). Details on the CPE descriptor and the required settings for various CAS Processor deployment modes can be found in . In the following sections we merely summarize the various CAS Processor deployment options.
Deploying Managed CAS Processors Managed CAS Processor deployment is shown in . A managed CAS Processor is deployed by the CPE as a Vinci service. The CPE manages the lifecycle of the CAS Processor including service launch, restart on failures, and service shutdown. A managed CAS Processor runs on the same machine as the CPE, but in a separate process. This provides the necessary fault isolation for the CPE to protect it from non-robust CAS Processors. A fatal failure of a managed CAS Processor does not threaten the stability of the CPE.
CPE with Managed CAS Processors Managed deployment showing separate JVMs and CASes flowing between them
The CPE communicates with managed CAS Processors using the Vinci communication protocol. A CAS Processor is launched as a Vinci service and its process() method is invoked remotely via a Vinci command. The CPE uses its own internal VNS to support managed CAS processors. The VNS, by default, listens on port 9005. If this port is not available, the VNS will increment its listen port until it finds one that is available. All managed CAS Processors are internally configured to talk to the CPE managed VNS. This internal VNS is transparent to the end user launching the CPE. To deploy a managed CAS Processor, the CPE deployer must change the CPE descriptor. The following is a section from the CPE descriptor that shows an example configuration specifying a managed CAS Processor. <casProcessor deployment="local" name="Meeting Detector TAE"> <descriptor> <include href="deploy/vinci/Deploy_MeetingDetectorTAE.xml"/> </descriptor> <runInSeparateProcess> <exec dir="." executable="java"> <env key="CLASSPATH" value="src; C:/Program Files/apache/uima/lib/uima-core.jar; C:/Program Files/apache/uima/lib/uima-cpe.jar; C:/Program Files/apache/uima/lib/uima-examples.jar; C:/Program Files/apache/uima/lib/uima-adapter-vinci.jar; C:/Program Files/apache/uima/lib/jVinci.jar"/> <arg>-DLOG=C:/Temp/service.log</arg> <arg>org.apache.uima.reference_impl.collection. service.vinci.VinciAnalysisEnginerService_impl</arg> <arg>${descriptor}</arg> </exec> </runInSeparateProcess> <deploymentParameters/> <filter/> <errorHandling> <errorRateThreshold action="terminate" value="1/100"/> <maxConsecutiveRestarts action="terminate" value="3"/> <timeout max="100000"/> </errorHandling> <checkpoint batch="10000"/> </casProcessor> See for details and required settings.
Deploying Non-managed CAS Processors Non-managed CAS Processor deployment is shown in . In non-managed mode, the CPE supports connectivity to CAS Processors running on local or remote computers using Vinci. Non-managed processors are different from managed processors in two aspects: Non-managed processors are neither started nor stopped by the CPE. Non-managed processors use an independent VNS, also neither started nor stopped by the CPE.
CPE with non-managed CAS Processors Non-managed CPE deployment
While non-managed CAS Processors provide the same level of fault isolation and robustness as managed CAS Processors, error recovery support for non-managed CAS Processors is much more limited. In particular, the CPE cannot restart a non-managed CAS Processor after an error. Non-managed CAS Processors also require a separate Vinci Naming Service running on the network. This VNS must be manually started and monitored by the end user or application. Instructions for running a VNS can be found in . To deploy a non-managed CAS Processor, the CPE deployer must change the CPE descriptor. The following is a section from the CPE descriptor that shows an example configuration for the non-managed CAS Processor. <casProcessor deployment="remote" name="Meeting Detector TAE"> <descriptor> <include href= "descriptors/vinciService/MeetingDetectorVinciService.xml"/> </descriptor> <deploymentParameters/> <filter/> <errorHandling> <errorRateThreshold action="terminate" value="1/100"/> <maxConsecutiveRestarts action="terminate" value="3"/> <timeout max="100000"/> </errorHandling> <checkpoint batch="10000"/> </casProcessor> See for details and required settings.
Deploying Integrated CAS Processors Integrated CAS Processors are shown in . Here the CAS Processors run in the same JVM as the CPE, just like the Collection Reader and CAS Initializer. This deployment method results in minimal CAS communication and transport overhead as the CAS is shared in the same process space of the JVM. However, a CPE running with all integrated CAS Processors is limited in scalability by the capability of the single computer on which the CPE is running. There is also a stability risk associated with integrated processors because a poorly written CAS Processor can cause the JVM, and hence the entire CPE, to abort.
CPE with integrated CAS Processor CPE with integrated CAS Processor
The following is a section from a CPE descriptor that shows an example configuration for the integrated CAS Processor. <casProcessor deployment=integrated name=Meeting Detector TAE> <descriptor> <include href="descriptors/tutorial/ex4/MeetingDetectorTAE.xml"/> </descriptor> <deploymentParameters/> <filter/> <errorHandling> <errorRateThreshold action="terminate" value="100/1000"/> <maxConsecutiveRestarts action="terminate" value="30"/> <timeout max="100000"/> </errorHandling> <checkpoint batch="10000"/> </casProcessor> See for details and required settings.
Collection Processing Examples The UIMA SDK includes a set of examples illustrating the three modes of deployment, integrated, managed, and non-managed. These are in the /examples/descriptors/collection_processing_engine directory. There are three CPE descriptors that run an example annotator (the Meeting Finder) in these modes. To run either the integrated or managed examples, use the runCPE script in the /bin directory of the UIMA installation, passing the appropriate CPE descriptor as an argument, or if you're using Eclipse and have the uimaj-examples project in your workspace, you can use the Eclipse Menu → Run → Run... → and then pick the launch configuration UIMA Run CPE. The runCPE script must be run from the %UIMA_HOME%\examples directory, because the example CPE descriptors use relative path names that are resolved relative to this working directory. For instance, runCPE descriptors\collection_processing_engine\MeetingFinderCPE_Integrated.xml To run the non-managed example, there are some additional steps. Start a VNS service by running the startVNS script in the /bin directory, or using the Eclipse launcher UIMA Start VNS. Deploy the Meeting Detector Analysis Engine as a Vinci service, by running the startVinciService script in the /bin directory or using the Eclipse launcher for this, and passing it the location of the descriptor to deploy, in this case %UIMA_HOME%/examples/deploy/vinci/Deploy_MeetingDetectorTAE.xml, or if you're using Eclipse and have the uimaj-examples project in your workspace, you can use the Eclipse Menu → Run → Run... → and then pick the launch configuration UIMA Start Vinci Service. Now, run the runCPE script (or if in Eclipse, run the launch configuration UIMA Run CPE), passing it the CPE for the non-managed version (%UIMA_HOME%/examples/descriptors/collection_processing_engine/ MeetingFinderCPE_NonManaged.xml ). This assumes that the Vinci Naming Service, the runCPE application, and the MeetingDetectorTAE service are all running on the same machine. Most of the scripts that need information about VNS will look for values to use in environment variables VNS_HOST and VNS_PORT; these default to localhost and 9000. You may set these to appropriate values before running the scripts, as needed; you can also pass the name of the VNS host as the second argument to the startVinciService script. Alternatively, you can edit the scripts and/or the XML files to specify alternatives for the VNS_HOST and VNS_PORT. For instance, if the runCPE application is running on a different machine from the Vinci Naming Service, you can edit the MeetingFinderCPE_NonManaged.xml and change the vnsHost parameter: <parameter name="vnsHost" value="localhost" type="string"/> to specify the VNS host instead of localhost.
uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tug.cas_multiplier.xml0000644000175000017500000013254311665471342031054 0ustar drazzibdrazzib %uimaents; ]> CAS Multiplier Developer's Guide CAS Multiplier The UIMA analysis components (Annotators and CAS Consumers) described previously in this manual all take a single CAS as input, optionally make modifications to it, and output that same CAS. This chapter describes an advanced feature that became available in the UIMA SDK v2.0: a new type of analysis component called a CAS Multiplier, which can create new CASes during processing. CAS Multipliers are often used to split a large artifact into manageable pieces. This is a common requirement of audio and video analysis applications, but can also occur in text analysis on very large documents. A CAS Multiplier would take as input a single CAS representing the large artifact (perhaps by a remote reference to the actual data — see ) and produce as output a series of new CASes each of which contains only a small portion of the original artifact. CAS Multipliers are not limited to dividing an artifact into smaller pieces, however. A CAS Multiplier can also be used to combine smaller segments together to form larger segments. In general, a CAS Multiplier is used to change the segmentation of a series of CASes; that is, to change how a stream of data is divided among discrete CAS objects.
Developing the CAS Multiplier Code
CAS Multiplier Interface Overview CAS Multiplier implementations should extend from the JCasMultiplier_ImplBase or CasMultiplier_ImplBase classes, depending on which CAS interface they prefer to use. As with other types of analysis components, the CAS Multiplier ImplBase classes define optional initialize, destroy, and reconfigure methods. There are then three required methods: process, hasNext, and next. The framework interacts with these methods as follows: The framework calls the CAS Multiplier's process method, passing it an input CAS. The process method returns, but may hold on to a reference to the input CAS. The framework then calls the CAS Multiplier's hasNext method. The CAS Multiplier should return true from this method if it intends to output one or more new CASes (for instance, segments of this CAS), and false if not. If hasNext returned true, the framework will call the CAS Multiplier's next method. The CAS Multiplier creates a new CAS (we will see how in a moment), populates it, and returns it from the next method. Steps 2 and 3 continue until hasNext returns false. If the framework detects a situation where it needs to cancel this CAS Multiplier, it will stop calling the hasNext and next methods, and when another top-level CAS comes along it will call the annotator's process method again. User's annotator code should interpret this as a signal to cleanup processing related to the previous CAS and then start processing with the new CAS. From the time when process is called until the hasNext method returns false (or process is called again), the CAS Multiplier owns the CAS that was passed to its process method. The CAS Multiplier can store a reference to this CAS in a local field and can read from it or write to it during this time. Once the ending condition occurs, the CAS Multiplier gives up ownership of the input CAS and should no longer retain a reference to it.
How to Get an Empty CAS Instance Getting an empty CAS Instance The CAS Multiplier's next method must return a CAS instance that represents a new representation of the input artifact. Since CAS instances are managed by the framework, the CAS Multiplier cannot actually create a new CAS; instead it should request an empty CAS by calling the method: CAS getEmptyCAS() or JCas getEmptyJCas() which are defined on the CasMultiplier_ImplBase and JCasMultiplier_ImplBase classes, respectively. Note that if it is more convenient you can request an empty CAS during the process or hasNext methods, not just during the next method. By default, a CAS Multiplier is only allowed to hold one output CAS instance at a time. You must return the CAS from the next method before you can request a second CAS. If you try to call getEmptyCAS a second time you will get an Exception. You can change this default behavior by overriding the method getCasInstancesRequired to return the number of CAS instances that you need. Be aware that CAS instances consume a significant amount of memory, so setting this to a large value will cause your application to use a lot of RAM. So, for example, it is not a good practice to attempt to generate a large number of new CASes in the CAS Multiplier's process method. Instead, you should spread your processing out across the calls to the hasNext or next methods. You can only call getEmptyCAS() or getEmptyJCas() from your CAS Multiplier's process, hasNext, or next methods. You cannot call it from other methods such as initialize. This is because the Aggregate AE's Type System is not available until all of the components of the aggregate have finished their initialization. The Type System of the empty CAS will contain all of the type definitions for all components of the outermost Aggregate Analysis Engine or Collection Processing Engine that contains your CAS Multiplier. Therefore downstream components that receive these CASes can add new instances of any type that they define. Be careful to keep the Feature Structures that belong to each CAS separate. You cannot create references from a Feature Structure in one CAS to a Feature Structure in another CAS. You also cannot add a Feature Structure created in one CAS to the indexes of a different CAS. If you attempt to do this, the results are undefined.
Example Code This section walks through the source code of an example CAS Multiplier that breaks text documents into smaller pieces. The Java class for the example is org.apache.uima.examples.casMultiplier.SimpleTextSegmenter and the source code is included in the UIMA SDK under the examples/src directory.
Overall Structure public class SimpleTextSegmenter extends JCasMultiplier_ImplBase { private String mDoc; private int mPos; private int mSegmentSize; private String mDocUri; public void initialize(UimaContext aContext) throws ResourceInitializationException { ... } public void process(JCas aJCas) throws AnalysisEngineProcessException { ... } public boolean hasNext() throws AnalysisEngineProcessException { ... } public AbstractCas next() throws AnalysisEngineProcessException { ... } } The SimpleTextSegmenter class extends JCasMultiplier_ImplBase and implements the optional initialize method as well as the required process, hasNext, and next methods. Each method is described below.
Initialize Method public void initialize(UimaContext aContext) throws ResourceInitializationException { super.initialize(aContext); mSegmentSize = ((Integer)aContext.getConfigParameterValue( "segmentSize")).intValue(); } Like an Annotator, a CAS Multiplier can override the initialize method and read configuration parameter values from the UimaContext. The SimpleTextSegmenter defines one parameter, Segment Size, which determines the approximate size (in characters) of each segment that it will produce.
Process Method public void process(JCas aJCas) throws AnalysisEngineProcessException { mDoc = aJCas.getDocumentText(); mPos = 0; // retreive the filename of the input file from the CAS so that it can // be added to each segment FSIterator it = aJCas. getAnnotationIndex(SourceDocumentInformation.type).iterator(); if (it.hasNext()) { SourceDocumentInformation fileLoc = (SourceDocumentInformation)it.next(); mDocUri = fileLoc.getUri(); } else { mDocUri = null; } } The process method receives a new JCas to be processed(segmented) by this CAS Multiplier. The SimpleTextSegmenter extracts some information from this JCas and stores it in fields (the document text is stored in the field mDoc and the source URI in the field mDocURI). Recall that the CAS Multiplier is considered to own the JCas from the time when process is called until the time when hasNext returns false. Therefore it is acceptable to retain references to objects from the JCas in a CAS Multiplier, whereas this should never be done in an Annotator. The CAS Multiplier could have chosen to store a reference to the JCas itself, but that was not necessary for this example. The CAS Multiplier also initializes the mPos variable to 0. This variable is a position into the document text and will be incremented as each new segment is produced.
HasNext Method public boolean hasNext() throws AnalysisEngineProcessException { return mPos < mDoc.length(); } The job of the hasNext method is to report whether there are any additional output CASes to produce. For this example, the CAS Multiplier will break the entire input document into segments, so we know there will always be a next segment until the very end of the document has been reached.
Next Method public AbstractCas next() throws AnalysisEngineProcessException { int breakAt = mPos + mSegmentSize; if (breakAt > mDoc.length()) breakAt = mDoc.length(); // search for the next newline character. // Note: this example segmenter implementation // assumes that the document contains many newlines. // In the worst case, if this segmenter // is run on a document with no newlines, // it will produce only one segment containing the // entire document text. // A better implementation might specify a maximum segment size as // well as a minimum. while (breakAt < mDoc.length() && mDoc.charAt(breakAt - 1) != '\n') breakAt++; JCas jcas = getEmptyJCas(); try { jcas.setDocumentText(mDoc.substring(mPos, breakAt)); // if original CAS had SourceDocumentInformation, also add SourceDocumentInformatio // to each segment if (mDocUri != null) { SourceDocumentInformation sdi = new SourceDocumentInformation(jcas); sdi.setUri(mDocUri); sdi.setOffsetInSource(mPos); sdi.setDocumentSize(breakAt - mPos); sdi.addToIndexes(); if (breakAt == mDoc.length()) { sdi.setLastSegment(true); } } mPos = breakAt; return jcas; } catch (Exception e) { jcas.release(); throw new AnalysisEngineProcessException(e); } } The next method actually produces the next segment and returns it. The framework guarantees that it will not call next unless hasNext has returned true since the last call to process or next . Note that in order to produce a segment, the CAS Multiplier must get an empty JCas to populate. This is done by the line: JCas jcas = getEmptyJCas(); This requests an empty JCas from the framework, which maintains a pool of JCas instances to draw from. Also, note the use of the try...catch block to ensure that a JCas is released back to the pool if an exception occurs. This is very important to allow a CAS Multiplier to recover from errors.
Creating the CAS Multiplier Descriptor CAS Multiplier Descriptor There is not a separate type of descriptor for a CAS Multiplier. CAS Multiplier are considered a type of Analysis Engine, and so their descriptors use the same syntax as any other Analysis Engine Descriptor. The descriptor for the SimpleTextSegmenter is located in the examples/descriptors/cas_multiplier/SimpleTextSegmenter.xml directory of the UIMA SDK. The Analysis Engine Description, in its Operational Properties section, now contains a new outputsNewCASes property which takes a Boolean value. If the Analysis Engine is a CAS Multiplier, this property should be set to true. If you use the CDE, be sure to check the Outputs new CASes box in the Runtime Information section on the Overview page, as shown here: Screen shot of Component Descriptor Editor on Overview showing checking of "Outputs new CASes" box If you edit the Analysis Engine Descriptor by hand, you need to add a <outputsNewCASes> element to your descriptor as shown here: <operationalProperties> <modifiesCas>false</modifiesCas> <multipleDeploymentAllowed>true</multipleDeploymentAllowed> <outputsNewCASes>true</outputsNewCASes> </operationalProperties> The modifiedCas operational property refers to the input CAS, not the new output CASes produced. So our example SimpleTextSegmenter has modifiesCas set to false since it doesn't modify the input CAS.
Using a CAS Multiplier in an Aggregate Analysis Engine Using CAS Multipliers in Aggregates You can include a CAS Multiplier as a component in an Aggregate Analysis Engine. For example, this allows you to construct an Aggregate Analysis Engine that takes each input CAS, breaks it up into segments, and runs a series of Annotators on each segment.
Adding the CAS Multiplier to the Aggregate Aggregate: Adding the CAS Multiplier Since CAS Multiplier are considered a type of Analysis Engine, adding them to an aggregate works the same way as for other Analysis Engines. Using the CDE, you just click the Add... button in the Component Engines view and browse to the Analysis Engine Descriptor of your CAS Multiplier. If editing the aggregate descriptor directly, just import the Analysis Engine Descriptor of your CAS Multiplier as usual. An example descriptor for an Aggregate Analysis Engine containing a CAS Multiplier is provided in examples/descriptors/cas_multiplier/SegmenterAndTokenizerAE.xml. This Aggregate runs the SimpleTextSegmenter example to break a large document into segments, and then runs each segment through the SimpleTokenAndSentenceAnnotator. Try running it in the Document Analyzer tool with a large text file as input, to see that it outputs multiple output CASes, one for each segment produced by the SimpleTextSegmenter.
CAS Multipliers and Flow Control CAS Multipliers are only supported in the context of Fixed Flow or custom Flow Control. If you use the built-in Fixed Flow for your Aggregate Analysis Engine, you can position the CAS Multiplier anywhere in that flow. Processing then works as follows: When a CAS is input to the Aggregate AE, that CAS is routed to the components in the order specified by the Fixed Flow, until that CAS reaches a CAS Multiplier. Upon reaching a CAS Multiplier, if that CAS Multiplier produces new output CASes, then each output CAS from that CAS Multiplier will continue through the flow, starting at the node immediately after the CAS Multiplier in the Fixed Flow. No further processing will be done on the original input CAS after it has reached a CAS Multiplier – it will not continue in the flow. If the CAS Multiplier does not produce any output CASes for a given input CAS, then that input CAS will continue in the flow. This behavior is appropriate, for example, for a CAS Multiplier that may segment an input CAS into pieces but only does so if the input CAS is larger than a certain size. It is possible to put more than one CAS Multiplier in your flow. In this case, when a new CAS output from the first CAS Multiplier reaches the second CAS Multiplier and if the second CAS Multiplier produces output CASes, then no further processing will occur on the input CAS, and any new output CASes produced by the second CAS Multiplier will continue the flow starting at the node after the second CAS Multiplier. This default behavior can be customized. The FixedFlowController component that implement's UIMA's default flow defines a configuration parameter ActionAfterCasMultiplier that can take the following values: continue – the CAS continues on to the next element in the flow stop – the CAS will no longer continue in the flow, and will be returned from the aggregate if possible. drop – the CAS will no longer continue in the flow, and will be dropped (not returned from the aggregate) if possible. dropIfNewCasProduced (the default) – if the CAS multiplier produced a new CAS as a result of processing this CAS, then this CAS will be dropped. If not, then this CAS will continue. You can override this parameter in your Aggregate Analysis Engine the same way you would override a parameter in a delegate Analysis Engine. But to do so you must first explicitly identify that you are using the FixedFlowController implementation by importing its descriptor into your aggregate as follows: <flowController key="FixedFlowController"> <import name="org.apache.uima.flow.FixedFlowController"/> </flowController> The parameter could then be overriden as, for example: <configurationParameters> <configurationParameter> <name>ActionForIntermediateSegments</name> <type>String</type> <multiValued>false</multiValued> <mandatory>false</mandatory> <overrides> <parameter> FixedFlowController/ActionAfterCasMultiplier </parameter> </overrides> </configurationParameter> </configurationParameters> <configurationParameterSettings> <nameValuePair> <name>ActionForIntermediateSegments</name> <value> <string>drop</string> </value> </nameValuePair> </configurationParameterSettings> This overriding can also be done using the Component Descriptor Editor tool. An example of an Analysis Engine that overrides this parameter can be found in examples/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml. For more information about how to specify a flow controller as part of your Aggregate Analysis Engine descriptor, see . If you would like to further customize the flow, you will need to implement a custom FlowController as described in . For example, you could implement a flow where a CAS that is input to a CAS Multiplier will be processed further by some downstream components, but not others.
Aggregate CAS Multipliers An important consideration when you put a CAS Multiplier inside an Aggregate Analysis Engine is whether you want the Aggregate to also function as a CAS Multiplier – that is, whether you want the new output CASes produced within the Aggregate to be output from the Aggregate. This is controlled by the <outputsNewCASes> element in the Operational Properties of your Aggregate Analysis Engine descriptor. The syntax is the same as what was described in . If you set this property to true, then any new output CASes produced by a CAS Multiplier inside this Aggregate will be output from the Aggregate. Thus the Aggregate will function as a CAS Multiplier and can be used in any of the ways in which a primitive CAS Multiplier can be used. If you set the <outputsNewCASes> property to false , then any new output CASes produced by a CAS Multiplier inside the Aggregate will be dropped (i.e. the CASes will be released back to the pool) once they have finished being processed. Such an Aggregate Analysis Engine functions just like a normal non-CAS-Multiplier Analysis Engine; the fact that CAS Multiplication is occurring inside it is hidden from users of that Analysis Engine. If you want to output some new Output CASes and not others, you need to implement a custom Flow Controller that makes this decision — see .
Using a CAS Multiplier in a Collection Processing Engine CAS Multipliers in CPE's It is currently a limitation that CAS Multiplier cannot be deployed directly in a Collection Processing Engine. The only way that you can use a CAS Multiplier in a CPE is to first wrap it in an Aggregate Analysis Engine whose outputsNewCASes property is set to false, which in effect hides the existence of the CAS Multiplier from the CPE. Note that you can build an Aggregate Analysis Engine that consists of CAS Multipliers and Annotators, followed by CAS Consumers. This can simulate what a CPE would do, but without the deployment and error handling options that the CPE provides.
Calling a CAS Multiplier from an Application Applications: Calling CAS Multipliers
Retrieving Output CASes from the CAS Multiplier Output CASes The AnalysisEngine interface has the following methods that allow you to interact with CAS Multiplier: CasIterator processAndOutputNewCASes(CAS) JCasIterator processAndOutputNewCASes(JCas) From your application, you call processAndOutputNewCASes and pass it the input CAS. An iterator is returned that allows you to step through each of the new output CASes that are produced by the Analysis Engine. It is very important to realize that CASes are pooled objects and so your application must release each CAS (by calling the CAS.release() method) that it obtains from the CasIterator before it calls the CasIterator.next method again. Otherwise, the CAS pool will be exhausted and a deadlock will occur. The example code in the class org.apache.uima.examples.casMultiplier. CasMultiplierExampleApplication illusrates this. Here is the main processing loop: CasIterator casIterator = ae.processAndOutputNewCASes(initialCas); while (casIterator.hasNext()) { CAS outCas = casIterator.next(); //dump the document text and annotations for this segment System.out.println("********* NEW SEGMENT *********"); System.out.println(outCas.getDocumentText()); PrintAnnotations.printAnnotations(outCas, System.out); //release the CAS (important) outCas.release(); Note that as defined by the CAS Multiplier contract in , the CAS Multiplier owns the input CAS (initialCas in the example) until the last new output CAS has been produced. This means that the application should not try to make changes to initialCas until after the CasIterator.hasNext method has returned false, indicating that the segmenter has finished. Note that the processing time of the Analysis Engine is spread out over the calls to the CasIterator's hasNext and next methods. That is, the next output CAS may not actually be produced and annotated until the application asks for it. So the application should not expect calls to the CasIterator to necessarily complete quickly. Also, calls to the CasIterator may throw Exceptions indicating an error has occurred during processing. If an Exception is thrown, all processing of the input CAS will stop, and no more output CASes will be produced. There is currently no error recovery mechanism that will allow processing to continue after an exception.
Using a CAS Multiplier with other Analysis Engines CAS Multipliers with other AEs In your application you can take the output CASes from a CAS Multiplier and pass them to the process method of other Analysis Engines. However there are some special considerations regarding the Type System of these CASes. By default, the output CASes of a CAS Multiplier will have a Type System that contains all of the types and features declared by any component in the outermost Aggregate Analysis Engine or Collection Processing Engine that contains the CAS Multiplier. If in your application you create a CAS Multiplier and another Analysis Engine, where these are not enclosed in an aggregate, then the output CASes from the CAS Multiplier will not support any types or features that are declared in the latter Analysis Engine but not in the CAS Multiplier. This can be remedied by forcing the CAS Multiplier and Analysis Engine to share a single UimaContext when they are created, as follows: //create a "root" UIMA context for your whole application UimaContextAdmin rootContext = UIMAFramework.newUimaContext(UIMAFramework.getLogger(), UIMAFramework.newDefaultResourceManager(), UIMAFramework.newConfigurationManager()); XMLInputSource input = new XMLInputSource("MyCasMultiplier.xml"); AnalysisEngineDescription desc = UIMAFramework.getXMLParser(). parseAnalysisEngineDescription(input); //create a UIMA Context for the new AE we are about to create //first argument is unique key among all AEs used in the application UimaContextAdmin childContext = rootContext.createChild( "myCasMultiplier", Collections.EMPTY_MAP); //instantiate CAS Multiplier AE, passing the UIMA Context through the //additional parameters map Map additionalParams = new HashMap(); additionalParams.put(Resource.PARAM_UIMA_CONTEXT, childContext); AnalysisEngine casMultiplierAE = UIMAFramework.produceAnalysisEngine( desc,additionalParams); //repeat for another AE XMLInputSource input2 = new XMLInputSource("MyAE.xml"); AnalysisEngineDescription desc2 = UIMAFramework.getXMLParser(). parseAnalysisEngineDescription(input2); UimaContextAdmin childContext2 = rootContext.createChild( "myAE", Collections.EMPTY_MAP); Map additionalParams2 = new HashMap(); additionalParams2.put(Resource.PARAM_UIMA_CONTEXT, childContext2); AnalysisEngine myAE = UIMAFramework.produceAnalysisEngine( desc2, additionalParams2);
Using a CAS Multiplier to Merge CASes Merging with CAS Multipliers A CAS Multiplier can also be used to combine smaller CASes together to form larger CASes. In this section we describe how this works and walk through an example.
Overview of How to Merge CASes CAS Merging Overview When the framework first calls the CAS Multiplier's process method, the CAS Multiplier requests an empty CAS (which we'll call the "merged CAS") and copies relevant data from the input CAS into the merged CAS. The class org.apache.uima.util.CasCopier provides utilities for copying Feature Structures between CASes. When the framework then calls the CAS Multiplier's hasNext method, the CAS Multiplier returns false to indicate that it has no output at this time. When the framework calls process again with a new input CAS, the CAS Multiplier copies data from that input CAS into the merged CAS, combining it with the data that was previously copied. Eventually, when the CAS Multiplier decides that it wants to output the merged CAS, it returns true from the hasNext method, and then when the framework subsequently calls the next method, the CAS Multiplier returns the merged CAS. There is no explicit call to flush out any pending CASes from a CAS Multiplier when collection processing completes. It is up to the application to provide some mechanism to let a CAS Multiplier recognize the last CAS in a collection so that it can ensure that its final output CASes are complete.
Example CAS Merger An example CAS Multiplier that merges CASes can be found is provided in the UIMA SDK. The Java class for this example is org.apache.uima.examples.casMultiplier.SimpleTextMerger and the source code is located under the examples/src directory.
Process Method Almost all of the code for this example is in the process method. The first part of the process method shows how to copy Feature Structures from the input CAS to the "merged CAS": public void process(JCas aJCas) throws AnalysisEngineProcessException { // procure a new CAS if we don't have one already if (mMergedCas == null) { mMergedCas = getEmptyJCas(); } // append document text String docText = aJCas.getDocumentText(); int prevDocLen = mDocBuf.length(); mDocBuf.append(docText); // copy specified annotation types // CasCopier takes two args: the CAS to copy from. // the CAS to copy into. CasCopier copier = new CasCopier(aJCas.getCas(), mMergedCas.getCas()); // needed in case one annotation is in two indexes (could // happen if specified annotation types overlap) Set copiedIndexedFs = new HashSet(); for (int i = 0; i < mAnnotationTypesToCopy.length; i++) { Type type = mMergedCas.getTypeSystem() .getType(mAnnotationTypesToCopy[i]); FSIndex index = aJCas.getCas().getAnnotationIndex(type); Iterator iter = index.iterator(); while (iter.hasNext()) { FeatureStructure fs = (FeatureStructure) iter.next(); if (!copiedIndexedFs.contains(fs)) { Annotation copyOfFs = (Annotation) copier.copyFs(fs); // update begin and end copyOfFs.setBegin(copyOfFs.getBegin() + prevDocLen); copyOfFs.setEnd(copyOfFs.getEnd() + prevDocLen); mMergedCas.addFsToIndexes(copyOfFs); copiedIndexedFs.add(fs); } } } The CasCopier class is used to copy Feature Structures of certain types (specified by a configuration parameter) to the merged CAS. The CasCopier does deep copies, meaning that if the copied FeatureStructure references another FeatureStructure, the referenced FeatureStructure will also be copied. This example also merges the document text using a separate StringBuffer. Note that we cannot append document text to the Sofa data of the merged CAS because Sofa data cannot be modified once it is set. The remainder of the process method determines whether it is time to output a new CAS. For this example, we are attempting to merge all CASes that are segments of one original artifact. This is done by checking the SourceDocumentInformation Feature Structure in the CAS to see if its lastSegment feature is set to true. That feature (which is set by the example SimpleTextSegmenter discussed previously) marks the CAS as being the last segment of an artifact, so when the CAS Multiplier sees this segment it knows it is time to produce an output CAS. // get the SourceDocumentInformation FS, // which indicates the sourceURI of the document // and whether the incoming CAS is the last segment FSIterator it = aJCas .getAnnotationIndex(SourceDocumentInformation.type).iterator(); if (!it.hasNext()) { throw new RuntimeException("Missing SourceDocumentInformation"); } SourceDocumentInformation sourceDocInfo = (SourceDocumentInformation) it.next(); if (sourceDocInfo.getLastSegment()) { // time to produce an output CAS // set the document text mMergedCas.setDocumentText(mDocBuf.toString()); // add source document info to destination CAS SourceDocumentInformation destSDI = new SourceDocumentInformation(mMergedCas); destSDI.setUri(sourceDocInfo.getUri()); destSDI.setOffsetInSource(0); destSDI.setLastSegment(true); destSDI.addToIndexes(); mDocBuf = new StringBuffer(); mReadyToOutput = true; } When it is time to produce an output CAS, the CAS Multiplier makes final updates to the merged CAS (setting the document text and adding a SourceDocumentInformation FeatureStructure), and then sets the mReadyToOutput field to true. This field is then used in the hasNext and next methods.
HasNext and Next Methods These methods are relatively simple: public boolean hasNext() throws AnalysisEngineProcessException { return mReadyToOutput; } public AbstractCas next() throws AnalysisEngineProcessException { if (!mReadyToOutput) { throw new RuntimeException("No next CAS"); } JCas casToReturn = mMergedCas; mMergedCas = null; mReadyToOutput = false; return casToReturn; } When the merged CAS is ready to be output, hasNext will return true, and next will return the merged CAS, taking care to set the mMergedCas field to null so that the next call to process will start with a fresh CAS.
Using the SimpleTextMerger in an Aggregate Analysis Engine SimpleTextMerger in an Aggregate An example descriptor for an Aggregate Analysis Engine that uses the SimpleTextMerger is provided in examples/descriptors/cas_multiplier/Segment_Annotate_Merge_AE.xml. This Aggregate first runs the SimpleTextSegmenter example to break a large document into segments. It then runs each segment through the example tokenizer and name recognizer annotators. Finally it runs the SimpleTextMerger to reassemble the segments back into one CAS. The Name annotations are copied to the final merged CAS but the Token annotations are not. This example illustrates how you can break large artifacts into pieces for more efficient processing and then reassemble a single output CAS containing only the results most useful to the application. Intermediate results such as tokens, which may consume a lot of space, need not be retained over the entire input artifact. The intermediate segments are dropped and are never output from the Aggregate Analysis Engine. This is done by configuring the Fixed Flow Controller as described in , above. Try running this Analysis Engine in the Document Analyzer tool with a large text file as input, to see that it outputs just one CAS per input file, and that the final CAS contains only the Name annotations.
uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tug.aas.xml0000644000175000017500000003544711665471342026611 0ustar drazzibdrazzib %uimaents; ]> Annotations, Artifacts, and Sofas Annotations, Artifacts & Sofas Up to this point, the documentation has focused on analyzing strings of Unicode text, producing subtypes of Annotations which reference offsets in those strings. This chapter generalizes this concept and shows how other kinds of artifacts can be handled, including non-text things like audio and images, and how you can define your own kinds of annotations for these.
Terminology
Artifact The Artifact is the unstructured thing being analyzed by an annotator. It could be an HTML web page, an image, a video stream, a recorded audio conversation, an MPEG-4 stream, etc. Artifacts are often restructured in the course of processing to facilitate particular kinds of analysis. For instance, an HTML page may be converted into a de-tagged version. Annotators at different places in the pipeline may be analyzing different versions of the artifact.
Subject of Analysis — Sofa Each representation of an Artifact is called a Subject of Analysis, abbreviated using the acronym Sofa which stands for Subject OF Analysis. Annotation metadata, which have explicit designations of sub-regions of the artifact to which they apply, are always associated with a particular Sofa. For instance, an annotation over text specifies two features, the begin and end, which represent the character offsets into the text string Sofa being analyzed. Other examples of representations of Artifacts, which could be Sofas include: An HTML web page, a detagged web page, the translated text of that document, an audio or video stream, closed-caption text from a video stream, etc. Often, there is one Sofa being analyzed in a CAS. The next chapter will show how UIMA facilitates working with multiple representations of an artifact at the same time, in the same CAS.
Formats of Sofa Data Sofa data can be Java Unicode Strings, Feature Structure arrays of primitive types, or a URI which references remote data available via a network connection. The arrays of primitive types can be things like byte arrays or float arrays, and are intended to be used for artifacts like audio data, image data, etc. The URI form holds a URI specification String. Sofa data can be "serialized" using an XML format; when it is, the String data being serialized must not include invalid XML characters. See .
Setting and Accessing Sofa Data
Setting Sofa Data When a CAS is created, you can set its Sofa Data, just one time; this property insures that metadata describing regions of the Sofa remain valid. As a consequence, the following methods that set data for a given Sofa can only be called once for a given Sofa. The following methods on the CAS set the Sofa Data to one of the 3 formats. Assume that the variable aCas holds a reference to a CAS: aCas.setSofaDataString(document_text_string, mime_type_string); aCas.setSofaDataArray(feature_structure_primitive_array, mime_type_string); aCas.setSofaDataURI(uri_string, mime_type_string); In addition, the method aCas.setDocumentText(document_text_string) may still be used, and is equivalent to setSofaDataString(string, "text"). The mime type is currently not used by the UIMA framework, but may be set and retrieved by user code. Feature Structure primitive arrays are all the UIMA Array types except arrays of Feature Structures, Strings, and Booleans. Typically, these are arrays of bytes, but can be other types, such as floats, longs, etc. The URI string should conform to the standard URI format.
Accessing Sofa Data The analysis algorithms typically work with the Sofa data. The following methods on the CAS access the Sofa Data: String aCas.getDocumentText(); String aCas.getSofaDataString(); FeatureStructure aCas.getSofaDataArray(); String aCas.getSofaDataURI(); String aCas.getSofaMimeType(); The getDocumentText and getSofaDataString return the same text string. The getSofaDataURI returns the URI itself, not the data the URI is pointing to. You can use standard Java I/O capabilities to get the data associated with the URI, or use the UIMA Framework Streaming method described next.
Accessing Sofa Data using a Java Stream The framework provides a consistent method for accessing the Sofa data, independent of it being stored locally, or accessed remotely using the URI. Get a Java InputStream instance from the Sofa data using: InputStream inputStream = aCas.getSofaDataStream(); If the data is local, this method returns a ByteArrayInputStream. This stream provides bytes. If the Sofa data was set using setDocumentText or setSofaDataString, the String is converted to bytes by using the UTF-8 encoding. If the Sofa data was set as a DataArray, the bytes in the data array are serialized, high-byte first. If the Sofa data was specified as a URI, this method returns the handle from url.openStream(). Java offers built-in support for several URI schemes including FILE:, HTTP:, FTP: and has an extensible mechanism, URLStreamHandlerFactory, for customizing access to an arbitrary URI. See more details at .
The Sofa Feature Structure Information about a Sofa is contained in a special built-in Feature Structure of type uima.cas.Sofa. This feature structure is created and managed by the UIMA Framework; users must not create it directly. Although these Sofa type instances are implemented as standard feature structures, generic CAS APIs can not be used to create Sofas or set their features. Instead, Sofas are created implicitly by the creation of new CAS views. Similarly, Sofa features are set by CAS methods such as cas.setDocumentText(). Features of the Sofa type include SofaID: Every Sofa in a CAS has a unique SofaID. SofaIDs are the primary handle for access. This ID is often the same as the name string given to the Sofa by the developer, but it can be mapped to a different name (see . Mime type: This string feature can be used to describe the type of the data represented by a Sofa. It is not used by the framework; the framework provides APIs to set and get its value. Sofa Data: The Sofa data itself. This data can be resident in the CAS or it can be a reference to data outside the CAS.
Annotations Annotators add meta data about a Sofa to the CAS. It is often useful to have this metadata denote a region of the Sofa to which it applies. For instance, assuming the Sofa is a String, the metadata might describe a particular substring as the name of a person. The built-in UIMA type, uima.tcas.Annotation, has two extra features that enable this - the begin and end features - which denote a character position offset into the text string being analyzed. The concept of annotations can be generalized for non-string kinds of Sofas. For instance, an audio stream might have an audio annotation which describes sounds regions in terms of floating point time offsets in the Sofa. An image annotation might use two pairs of x,y coordinates to define the region the annotation applies to.
Built-in Annotation types The built-in CAS type, uima.tcas.Annotation, is just one kind of definition of an Annotation. It was designed for annotating text strings, and has begin and end features which describe which substring of the Sofa being annotated. For applications which have other kinds of Sofas, the UIMA developer will design their own kinds of Annotation types, as needed to describe an annotation, by declaring new types which are subtypes of uima.cas.AnnotationBase. For instance, for images, you might have the concept of a rectangular region to which the annotation applies. In this case, you might describe the region with 2 pairs of x, y coordinates.
Annotations have an associated Sofa Annotations are always associated with a particular Sofa. In subsequent chapters, you will learn how there can be multiple Sofas associated with an artifact; which Sofa an annotation refers to is described by the Annotation feature structure itself. All annotation types extend from the built-in type uima.cas.AnnotationBase. This type has one feature, a reference to the Sofa associated with the annotation. This value is currently used by the Framework to support the getCoveredText() method on the annotation instance - this returns the portion of a text Sofa that the annotation spans. It also is used to insure that the Annotation is indexed only in the CAS View associated with this Sofa.
AnnotationBase A built-in type, uima.cas.AnnotationBase, is provided by UIMA to allow users to extend the Annotation capabilities to different kinds of Annotations. The AnnotationBase type has one feature, named sofa, which holds a reference to the Sofa feature structure with which this annotation is associated. The sofa feature is automatically set when creating an annotation (meaning — any type derived from the built-in uima.cas.AnnotationBase type); it should not be set by the user. There is one method, getView(), provided by AnnotationBase that returns the CAS View for the Sofa the annotation is pointing at. Note that this method always returns a CAS, even when applied to JCas annotation instances. The built-in type uima.tcas.Annotation extends uima.cas.AnnotationBase and adds two features, a begin and an end feature, which are suitable for identifying a span in a text string that the annotation applies to. Users may define other extensions to AnnotationBase with alternative specifications that can denote a particular region within the subject of analysis, as appropriate to their application.
uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tutorials_and_users_guides.xml0000644000175000017500000000347511665471342032674 0ustar drazzibdrazzib UIMA Tutorial and Developers' Guides uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tug.multi_views.xml0000644000175000017500000010147311665471342030405 0ustar drazzibdrazzib %uimaents; ]> Multiple CAS Views of an Artifact Multiple CAS Views UIMA provides an extension to the basic model of the CAS which supports analysis of multiple views of the same artifact, all contained with the CAS. This chapter describes the concepts, terminology, and the API and XML extensions that enable this. Multiple CAS Views can simplify things when different versions of the artifact are needed at different stages of the analysis. They are also key to enabling multimodal analysis where the initial artifact is transformed from one modality to another, or where the artifact itself is multimodal, such as the audio, video and closed-captioned text associated with an MPEG object. Each representation of the artifact can be analyzed independently with the standard UIMA programming model; in addition, multi-view components and applications can be constructed. UIMA supports this by augmenting the CAS with additional light-weight CAS objects, one for each view, where these objects share most of the same underlying CAS, except for two things: each view has its own set of indexed Feature Structures, and each view has its own subject of analysis (Sofa) - its own version of the artifact being analyzed. The Feature Structure instances themselves are in the shared part of the CAS; only the entries in the indexes are unique for each CAS view. All of these CAS view objects are kept together with the CAS, and passed as a unit between components in a UIMA application. APIs exist which allow components and applications to switch among the various view objects, as needed. Feature Structures may be indexed in multiple views, if necessary. New methods on CAS Views facilitate adding or removing Feature Structures to or from their index repositories: aView.addFsToIndexes(aFeatureStructure) aView.removeFsFromIndexes(aFeatureStructure) specify the view in which this Feature Structure should be added to or removed from the indexes.
CAS Views and Sofas Sofas (see ) and CAS Views are linked. In this implementation, every CAS view has one associated Sofa, and every Sofa has one associated CAS View.
Naming CAS Views and Sofas The developer assigns a name to the View / Sofa, which is a simple string (following the rules for Java identifiers, usually without periods, but see special exception below). These names are declared in the component XML metadata, and are used during assembly and by the runtime to enable switching among multiple Views of the CAS at the same time. The name is called the Sofa name, for historical reasons, but it applies equally to the View. In the rest of this chapter, we'll refer to it as the Sofa name. Some applications contain components that expect a variable number of Sofas as input or output. An example of a component that takes a variable number of input Sofas could be one that takes several translations of a document and merges them, where each translation was in a separate Sofa. You can specify a variable number of input or output sofa names, where each name has the same base part, by writing the base part of the name (with no periods), followed by a period character and an asterisk character (.*). These denote sofas that have names matching the base part up to the period; for example, names such as base_name_part.TTX_3d would match a specification of base_name_part.*.
Multi-View, Single-View components & applications Multi/Single View parts in Applications Components and applications can be written to be Multi-View or Single-View. Most components used as primitive building blocks are expected to be Single-View. UIMA provides capabilities to combine these kinds of components with Multi-View components when assembling analysis aggregates or applications. Single-View components and applications use only one subject of analysis, and one CAS View. The code and descriptors for these components do not use the facilities described in this chapter. Conversely, Multi-View components and applications are aware of the possibility of multiple Views and Sofas, and have code and XML descriptors that create and manipulate them.
Multi-View Components
How UIMA decides if a component is Multi-View Deciding: Multi-View Every UIMA component has an associated XML Component Descriptor. Multi-View components are identified simply as those whose descriptors declare one or more Sofa names in their Capability sections, as inputs or outputs. If a Component Descriptor does not mention any input or output Sofa names, the framework treats that component as a Single-View component. A Multi-View component is passed a special kind of a CAS object, called a base CAS, which it must use to switch to the particular view it wishes to process. The base CAS object itself has no Sofa and no ability to use Indexes; only the views have that capability.
Multi-View: additional capabilities Additional capabilities provided for components and applications aware of the possibilities of multiple Views and Sofas include: Creating new Views, and for each, setting up the associated Sofa data Getting a reference to an existing View and its associated Sofa, by name Specifying a view in which to index a particular Feature Structure instance
Component XML metadata Each Multi-View component that creates a Sofa or wants to switch to a specific previously created Sofa must declare the name for the Sofa in the capabilities section. For example, a component expecting as input a web document in html format and creating a plain text document for further processing might declare: <capabilities> <capability> <inputs/> <outputs/> <inputSofas> <sofaName>rawContent</sofaName> </inputSofas> <outputSofas> <sofaName>detagContent</sofaName> </outputSofas> </capability> </capabilities> Details on this specification are found in . The Component Descriptor Editor supports Sofa declarations on the .
Sofa Capabilities and APIs for Applications Sofa Capabilities & APIs for Apps In addition to components, applications can make use of these capabilities. When an application creates a new CAS, it also creates the initial view of that CAS - and this view is the object that is returned from the create call. Additional views beyond this first one can be dynamically created at any time. The application can use the Sofa APIs described in to specify the data to be analyzed. If an Application creates a new CAS, the initial CAS that is created will be a view named _InitialView. This name can be used in the application and in Sofa Mapping (see the next section) to refer to this otherwise unnamed view.
Sofa Name Mapping Sofa Name mapping is the mechanism which enables UIMA component developers to choose locally meaningful Sofa names in their source code and let aggregate, collection processing engine developers, and application developers connect output Sofas created in one component to input Sofas required in another. At a given aggregation level, the assembler or application developer defines names for all the Sofas, and then specifies how these names map to the contained components, using the Sofa Map. Consider annotator code to create a new CAS view: CAS viewX = cas.createView("X"); Or code to get an existing CAS view: CAS viewX = cas.getView("X"); Without Sofa name mapping the SofaID for the new Sofa will be X. However, if a name mapping for X has been specified by the aggregate or CPE calling this annotator, the actual SofaID in the CAS can be different. All Sofas in a CAS must have unique names. This is accomplished by mapping all declared Sofas as described in the following sections. An attempt to create a Sofa with a SofaID already in use will throw an exception. Sofa name mapping must not use the . (period) character. Runtime Sofa mapping maps names up to the . and appends the period and the following characters to the mapped name. To get a Java Iterator for all the views in a CAS: Iterator allViews = cas.getViewIterator(); To get a Java Iterator for selected views in a CAS, for example, views whose name is either exactly equal to namePrefix or is of the form namePrefix.suffix, where suffix can be any String: Iterator someViews = cas.getViewIterator(String namePrefix); Sofa name mapping is applied to namePrefix. Sofa name mappings are not currently supported for remote Analysis Engines. See .
Name Mapping in an Aggregate Descriptor For each component of an Aggregate, name mapping specifies the conversion between component Sofa names and names at the aggregate level. Here's an example. Consider two Multi-View annotators to be assembled into an aggregate which takes an audio segment consisting of spoken English and produces a German text translation. The first annotator takes an audio segment as input Sofa and produces a text transcript as output Sofa. The annotator designer might choose these Sofa names to be AudioInput and TranscribedText. The second annotator is designed to translate text from English to German. This developer might choose the input and output Sofa names to be EnglishDocument and GermanDocument, respectively. In order to hook these two annotators together, the following section would be added to the top level of the aggregate descriptor: SpeechToText AudioInput SegementedAudio SpeechToText TranscribedText EnglishTranscript EnglishToGermanTranslator EnglishDocument EnglishTranscript EnglishToGermanTranslator GermanDocument GermanTranslation ]]> The Component Descriptor Editor supports Sofa name mapping in aggregates and simplifies the task. See for details.
Name Mapping in a CPE Descriptor The CPE descriptor aggregates together a Collection Reader and CAS Processors (Annotators and CAS Consumers). Sofa mappings can be added to the following elements of CPE descriptors: <collectionIterator>, <casInitializer> and the <casProcessor>. To be consistent with the organization of CPE descriptors, the maps for the CPE descriptor are distributed among the XML markup for each of the parts (collectionIterator, casInitializer, casProcessor). Because of this the <componentKey> element is not needed. Finally, rather than sub-elements for the parts, the XML markup for these uses attributes. See . Here's an example. Let's use the aggregate from the previous section in a collection processing engine. Here we will add a Collection Reader that outputs audio segments in an output Sofa named nextSegment. Remember to declare an output Sofa nextSegment in the collection reader description. We'll add a CAS Consumer in the next section. <collectionReader> <collectionIterator> <descriptor> . . . </descriptor> <configurationParameterSettings>...</configurationParameterSettings> <sofaNameMappings> <sofaNameMapping componentSofaName="nextSegment" cpeSofaName="SegementedAudio"/> </sofaNameMappings> </collectionIterator> <casInitializer/> <collectionReader> At this point the CAS Processor section for the aggregate does not need any Sofa mapping because the aggregate input Sofa has the same name, SegementedAudio, as is being produced by the Collection Reader.
Specifying the CAS View for a Single-View Component CAS View for Single-View Parts Single-View components receive a Sofa named _InitialView, or a Sofa that is mapped to this name. For example, assume that the CAS Consumer to be used in our CPE is a Single-View component that expects the analysis results associated with the input CAS, and that we want it to use the results from the translated German text Sofa. The following mapping added to the CAS Processor section for the CPE will instruct the CPE to get the CAS view for the German text Sofa and pass it to the CAS Consumer: <casProcessor> . . . <sofaNameMappings> <sofaNameMapping componentSofaName="_InitialView" cpeSofaName="GermanTranslation"/> <sofaNameMappings> </casProcessor> An alternative syntax for this kind of mapping is to simply leave out the component sofa name in this case.
Name Mapping in a UIMA Application Applications which instantiate UIMA components directly using the UIMAFramework methods can also create a top level Sofa mapping using the additional parameters capability. //create a "root" UIMA context for your whole application UimaContextAdmin rootContext = UIMAFramework.newUimaContext(UIMAFramework.getLogger(), UIMAFramework.newDefaultResourceManager(), UIMAFramework.newConfigurationManager()); input = new XMLInputSource("test.xml"); desc = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(input); //setup sofa name mappings using the api HashMap sofamappings = new HashMap(); sofamappings.put("localName1", "globalName1"); sofamappings.put("localName2", "globalName2"); //create a UIMA Context for the new AE we are about to create //first argument is unique key among all AEs used in the application UimaContextAdmin childContext = rootContext.createChild("myAE", sofamap); //instantiate AE, passing the UIMA Context through the additional //parameters map Map additionalParams = new HashMap(); additionalParams.put(Resource.PARAM_UIMA_CONTEXT, childContext); AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(desc,additionalParams); Sofa mappings are applied from the inside out, i.e., local to global. First, any aggregate mappings are applied, then any CPE mappings, and finally, any specified using this additional parameters capability.
Name Mapping for Remote Services Currently, no client-side Sofa mapping information is passed from a UIMA client to a remote service. This can cause complications for UIMA services in a Multi-View application. Remote Multi-View services will work only if the service is Single-View, or if the Sofa names expected by the service exactly match the Sofa names produced by the client. If your application requires Sofa mappings for a remote Analysis Engine, you can wrap your remotely deployed AE in an aggregate (on the remote side), and specify the necessary Sofa mappings in the descriptor for that aggregate.
JCas extensions for Multiple Views The JCas interface to the CAS can be used with any / all views, as well as the base CAS sent to Multi-View components. You can always get a JCas object from an existing CAS object by using the method getJCas(); this call will create the JCas if it doesn't already exist. If it does exist, it just returns the existing JCas that corresponds to the CAS. JCas implements the getView(...) method, enabling switching to other named views, just like the corresponding method on the CAS. The JCas version, however, returns JCas objects, instead of CAS objects, corresponding to the view.
Sample Multi-View Application The UIMA SDK contains a simple Sofa example application which demonstrates many Sofa specific concepts and methods. The source code for the application driver is in examples/src/org/apache/uima/examples/SofaExampleApplication.java and the Multi-View annotator is given in SofaExampleAnnotator.java in the same directory. This sample application demonstrates a language translator annotator which expects an input text Sofa with an English document and creates an output text Sofa containing a German translation. Some of the key Sofa concepts illustrated here include: Sofa creation. Access of multiple CAS views. Unique feature structure index space for each view. Feature structures containing cross references between annotations in different CAS views. The strong affinity of annotations with a specific Sofa.
Annotator Descriptor The annotator descriptor in examples/descriptors/analysis_engine/SofaExampleAnnotator.xml declares an input Sofa named EnglishDocument and an output Sofa named GermanDocument. A custom type CrossAnnotation is also defined: sofa.test.CrossAnnotation uima.tcas.Annotation otherAnnotation uima.tcas.Annotation ]]> The CrossAnnotation type is derived from uima.tcas.Annotation and includes one new feature: a reference to another annotation.
Application Setup The application driver instantiates an analysis engine, seAnnotator, from the annotator descriptor, obtains a new base CAS using that engine's CAS definition, and creates the expected input Sofa using: CAS cas = seAnnotator.newCAS(); CAS aView = cas.createView("EnglishDocument"); Since seAnnotator is a primitive component, and no Sofa mapping has been defined, the SofaID will be EnglishDocument. Local Sofa data is set using: aView.setDocumentText("this beer is good"); At this point the CAS contains all necessary inputs for the translation annotator and its process method is called.
Annotator Processing Annotator processing consists of parsing the English document into individual words, doing word-by-word translation and concatenating the translations into a German translation. Analysis metadata on the English Sofa will be an annotation for each English word. Analysis metadata on the German Sofa will be a CrossAnnotation for each German word, where the otherAnnotation feature will be a reference to the associated English annotation. Code of interest includes two CAS views: // get View of the English text Sofa englishView = aCas.getView("EnglishDocument"); // Create the output German text Sofa germanView = aCas.createView("GermanDocument"); the indexing of annotations with the appropriate view: englishView.addFsToIndexes(engAnnot); . . . germanView.addFsToIndexes(germAnnot); and the combining of metadata belonging to different Sofas in the same feature structure: // add link to English text germAnnot.setFeatureValue(other, engAnnot);
Accessing the results of analysis The application needs to get the results of analysis, which may be in different views. Analysis results for each Sofa are dumped independently by iterating over all annotations for each associated CAS view. For the English Sofa: //get annotation iterator for this CAS FSIndex anIndex = aView.getAnnotationIndex(); FSIterator anIter = anIndex.iterator(); while (anIter.isValid()) { AnnotationFS annot = (AnnotationFS) anIter.get(); System.out.println(" " + annot.getType().getName() + ": " + annot.getCoveredText()); anIter.moveToNext(); } Iterating over all German annotations looks the same, except for the following: if (annot.getType() == cross) { AnnotationFS crossAnnot = (AnnotationFS) annot.getFeatureValue(other); System.out.println(" other annotation feature: " + crossAnnot.getCoveredText()); } Of particular interest here is the built-in Annotation type method getCoveredText(). This method uses the begin and end features of the annotation to create a substring from the CAS document. The SofaRef feature of the annotation is used to identify the correct Sofa's data from which to create the substring. The example program output is: ---Printing all annotations for English Sofa--- uima.tcas.DocumentAnnotation: this beer is good uima.tcas.Annotation: this uima.tcas.Annotation: beer uima.tcas.Annotation: is uima.tcas.Annotation: good ---Printing all annotations for German Sofa--- uima.tcas.DocumentAnnotation: das bier ist gut sofa.test.CrossAnnotation: das other annotation feature: this sofa.test.CrossAnnotation: bier other annotation feature: beer sofa.test.CrossAnnotation: ist other annotation feature: is sofa.test.CrossAnnotation: gut other annotation feature: good
Views API Summary The recommended way to deliver a particular CAS view to a Single-View component is to use by Sofa-mapping in the CPE and/or aggregate descriptors. For Multi-View components or applications, the following methods are used to create or get a reference to a CAS view for a particular Sofa: Creating a new View: JCas newView = aJCas.createView(String localNameOfTheViewBeforeMapping); CAS newView = aCAS .createView(String localNameOfTheViewBeforeMapping); Getting a View from a CAS or JCas: JCas myView = aJCas.getView(String localNameOfTheViewBeforeMapping); CAS myView = aCAS .getView(String localNameOfTheViewBeforeMapping); Iterator allViews = aCasOrJCas.getViewIterator(); Iterator someViews = aCasOrJCas.getViewIterator(String localViewNamePrefix); The following methods are useful for all annotators and applications: Setting Sofa data for a CAS or JCas: aCasOrJCas.setDocumentText(String docText); aCasOrJCas.setSofaDataString(String docText, String mimeType); aCasOrJCas.setSofaDataArray(FeatureStructure array, String mimeType); aCasOrJCas.setSofaDataURI(String uri, String mimeType); Getting Sofa data for a particular CAS or JCas: String doc = aCasOrJCas.getDocumentText(); String doc = aCasOrJCas.getSofaDataString(); FeatureStructure array = aCasOrJCas.getSofaDataArray(); String uri = aCasOrJCas.getSofaDataURI(); InputStream is = aCasOrJCas.getSofaDataStream();
Sofa Incompatibilities between UIMA version 1 and version 2 Sofa Incompatibilities: V1 and V2 A major change in version 2 is related to the support of Single-View components and applications. Given an analysis engine, ae, the API CAS cas = ae.newCas(); used to return the base CAS. Now it returns a view of the Sofa named _InitialView. This Sofa will actually only be created if any Sofa data is set for this view. The initial view is used for Single-View applications and Multi-View annotators with no Sofa mapping. The process method of Multi-View annotators receive the base CAS, however the base CAS no longer has an index repository to hold global data. Global data needs to be put in a specific named CAS view of your choice. Because of these changes, the following scenarios will break with v2.0 clients: Any version 1.x services (you must migrate the services to version 2). Applications or components explicitly referencing _DefaultTextSofaName in code or descriptors. Multi-View applications using the Base CAS index repository.
uimaj-2.4.0/uima-docbook-tutorials-and-users-guides/src/docbook/tug.application.xml0000644000175000017500000030767111665471342030351 0ustar drazzibdrazzib %uimaents; ]> Application Developer's Guide This chapter describes how to develop an application using the Unstructured Information Management Architecture (UIMA). The term application describes a program that provides end-user functionality. A UIMA application incorporates one or more UIMA components such as Analysis Engines, Collection Processing Engines, a Search Engine, and/or a Document Store and adds application-specific logic and user interfaces.
The UIMAFramework Class An application developer's starting point for accessing UIMA framework functionality is the org.apache.uima.UIMAFramework class. The following is a short introduction to some important methods on this class. Several of these methods are used in examples in the rest of this chapter. For more details, see the Javadocs (in the docs/api directory of the UIMA SDK). UIMAFramework.getXMLParser(): Returns an instance of the UIMA XML Parser class, which then can be used to parse the various types of UIMA component descriptors. Examples of this can be found in the remainder of this chapter. UIMAFramework.produceXXX(ResourceSpecifier): There are various produce methods that are used to create different types of UIMA components from their descriptors. The argument type, ResourceSpecifier, is the base interface that subsumes all types of component descriptors in UIMA. You can get a ResourceSpecifier from the XMLParser. Examples of produce methods are: produceAnalysisEngine produceCasConsumer produceCasInitializer produceCollectionProcessingEngine produceCollectionReader There are other variations of each of these methods that take additional, optional arguments. See the Javadocs for details. UIMAFramework.getLogger(<optional-logger-name>): Gets a reference to the UIMA Logger, to which you can write log messages. If no logger name is passed, the name of the returned logger instance is org.apache.uima. UIMAFramework.getVersionString(): Gets the number of the UIMA version you are using. UIMAFramework.newDefaultResourceManager(): Gets an instance of the UIMA ResourceManager. The key method on ResourceManager is setDataPath, which allows you to specify the location where UIMA components will go to look for their external resources. Once you've obtained and initialized a ResourceManager, you can pass it to any of the produceXXX methods.
Using Analysis Engines This section describes how to add analysis capability to your application by using Analysis Engines developed using the UIMA SDK. An Analysis Engine (AE) is a component that analyzes artifacts (e.g. documents) and infers information about them. An Analysis Engine consists of two parts - Java classes (typically packaged as one or more JAR files) and AE descriptors (one or more XML files). You must put the Java classes in your application's class path, but thereafter you will not need to directly interact with them. The UIMA framework insulates you from this by providing a standard AnalysisEngine interfaces. The term Text Analysis Engine (TAE) is sometimes used to describe an Analysis Engine that analyzes a text document. In the UIMA SDK v1.x, there was a TextAnalysisEngine interface that was commonly used. However, as of the UIMA SDK v2.0, this interface has been deprecated and all applications should switch to using the standard AnalysisEngine interface. The AE descriptor XML files contain the configuration settings for the Analysis Engine as well as a description of the AE's input and output requirements. You may need to edit these files in order to configure the AE appropriately for your application - the supplier of the AE may have provided documentation (or comments in the XML descriptor itself) about how to do this.
Instantiating an Analysis Engine The following code shows how to instantiate an AE from its XML descriptor: //get Resource Specifier from XML file XMLInputSource in = new XMLInputSource("MyDescriptor.xml"); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); //create AE here AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(specifier); The first two lines parse the XML descriptor (for AEs with multiple descriptor files, one of them is the main descriptor - the AE documentation should indicate which it is). The result of the parse is a ResourceSpecifier object. The third line of code invokes a static factory method UIMAFramework.produceAnalysisEngine, which takes the specifier and instantiates an AnalysisEngine object. There is one caveat to using this approach - the Analysis Engine instance that you create will not support multiple threads running through it concurrently. If you need to support this, see .
Analyzing Text Documents There are two ways to use the AE interface to analyze documents. You can either use the JCas interface, which is described in detail by or you can directly use the CAS interface, which is described in detail in . Besides text documents, other kinds of artifacts can also be analyzed; see for more information. The basic structure of your application will look similar in both cases: Using the JCas //create a JCas, given an Analysis Engine (ae) JCas jcas = ae.newJCas(); //analyze a document jcas.setDocumentText(doc1text); ae.process(jcas); doSomethingWithResults(jcas); jcas.reset(); //analyze another document jcas.setDocumentText(doc2text); ae.process(jcas); doSomethingWithResults(jcas); jcas.reset(); ... //done ae.destroy(); Using the CAS //create a CAS CAS aCasView = ae.newCAS(); //analyze a document aCasView.setDocumentText(doc1text); ae.process(aCasView); doSomethingWithResults(aCasView); aCasView.reset(); //analyze another document aCasView.setDocumentText(doc2text); ae.process(aCasView); doSomethingWithResults(aCasView); aCasView.reset(); ... //done ae.destroy(); First, you create the CAS or JCas that you will use. Then, you repeat the following four steps for each document: Put the document text into the CAS or JCas. Call the AE's process method, passing the CAS or JCas as an argument Do something with the results that the AE has added to the CAS or JCas Call the CAS's or JCas's reset() method to prepare for another analysis
Analyzing Non-Text Artifacts Analyzing non-text artifacts is similar to analyzing text documents. The main difference is that instead of using the setDocumentText method, you need to use the Sofa APIs to set the artifact into the CAS. See for details.
Accessing Analysis Results Annotators (and applications) access the results of analysis via the CAS, using the CAS or JCas interfaces. These results are accessed using the CAS Indexes. There is one built-in index for instances of the built-in type uima.tcas.Annotation that can be used to retrieve instances of Annotation or any subtype of Annotation. You can also define additional indexes over other types. Indexes provide a method to obtain an iterators over their contents; the iterator returns the matching elements one at time from the CAS.
Accessing Analysis Results using the JCas See: The Javadocs for org.apache.uima.jcas.JCas.
Accessing Analysis Results using the CAS See: The source code for org.apache.uima.examples.PrintAnnotations, which is in examples\src. The Javadocs for the org.apache.uima.cas and org.apache.uima.cas.text packages.
Multi-threaded Applications The simplest way to use an AE in a multi-threaded environment is to use the Java synchronized keyword to ensure that only one thread is using an AE at any given time. For example: public class MyApplication { private AnalysisEngine mAnalysisEngine; private CAS mCAS; public MyApplication() { //get Resource Specifier from XML file XMLInputSource in = new XMLInputSource("MyDescriptor.xml"); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); //create Analysis Engine here mAnalysisEngine = UIMAFramework.produceAnalysisEngine(specifier); mCAS = mAnalysisEngine.newCAS(); } // Assume some other part of your multi-threaded application could // call analyzeDocument on different threads, asynchronusly public synchronized void analyzeDocument(String aDoc) { //analyze a document mCAS.setDocumentText(aDoc); mAnalysisEngine.process(); doSomethingWithResults(mCAS); mCAS.reset(); } ... } Without the synchronized keyword, this application would not be thread-safe. If multiple threads called the analyzeDocument method simultaneously, they would both use the same CAS and clobber each others' results. The synchronized keyword ensures that no more than one thread is executing this method at any given time. For more information on thread synchronization in Java, see . The synchronized keyword ensures thread-safety, but does not allow you to process more than one document at a time. If you need to process multiple documents simultaneously (for example, to make use of a multiprocessor machine), you'll need to use more than one CAS instance. Because CAS instances use memory and can take some time to construct, you don't want to create a new CAS instance for each request. Instead, you should use a feature of the UIMA SDK called the CAS Pool, implemented by the type CasPool. A CAS Pool contains some number of CAS instances (you specify how many when you create the pool). When a thread wants to use a CAS, it checks out an instance from the pool. When the thread is done using the CAS, it must release the CAS instance back into the pool. If all instances are checked out, additional threads will block and wait for an instance to become available. Here is some example code: public class MyApplication { private CasPool mCasPool; private AnalysisEngine mAnalysisEngine; public MyApplication() { //get Resource Specifier from XML file XMLInputSource in = new XMLInputSource("MyDescriptor.xml"); ResourceSpecifier specifier = UIMAFramework.getXMLParser().parseResourceSpecifier(in); //Create multithreadable AE that will //Accept 3 simultaneous requests //The 3rd parameter specifies a timeout. //When the number of simultaneous requests exceeds 3, // additional requests will wait for other requests to finish. // This parameter determines the maximum number of milliseconds // that a new request should wait before throwing an // - a value of 0 will cause them to wait forever. mAnalysisEngine = UIMAFramework.produceAnalysisEngine(specifier,3,0); //create CAS pool with 3 CAS instances mCasPool = new CasPool(3, mAnalysisEngine); } public void analyzeDocument(String aDoc) { //check out a CAS instance (argument 0 means no timeout) CAS cas = mCasPool.getCas(0); try { //analyze a document cas.setDocumentText(aDoc); mAnalysisEngine.process(cas); doSomethingWithResults(cas); } finally { //MAKE SURE we release the CAS instance mCasPool.releaseCas(cas); } } ... } There is not much more code required here than in the previous example. First, there is one additional parameter to the AnalysisEngine producer, specifying the number of annotator instances to create Both the UIMA Collection Processing Manager framework and the remote deployment services framework have implementations which use CAS pools in this manner, and thereby relieve the annotator developer of the necessity to make their annotators thread-safe. . Then, instead of creating a single CAS in the constructor, we now create a CasPool containing 3 instances. In the analyze method, we check out a CAS, use it, and then release it. Frequently, the two numbers (number of CASes, and the number of AEs) will be the same. It would not make sense to have the number of CASes less than the number of AEs – the extra AE instances would always block waiting for a CAS from the pool. It could make sense to have additional CASes, though – if you had other multi-threaded processes that were using the CASes, other than the AEs. The getCAS() method returns a CAS which is not specialized to any particular subject of analysis. To process things other than this, please refer to . Note the use of the try...finally block. This is very important, as it ensures that the CAS we have checked out will be released back into the pool, even if the analysis code throws an exception. You should always use try...finally when using the CAS pool; if you do not, you risk exhausting the pool and causing deadlock. The parameter 0 passed to the CasPool.getCas() method is a timeout value. If this is set to a positive integer, it is the maximum number of milliseconds that the thread will wait for an instance to become available in the pool. If this time elapses, the getCas method will return null, and the application can do something intelligent, like ask the user to try again later. A value of 0 will cause the thread to wait for an available CAS, potentially forever.
Using Multiple Analysis Engines and Creating Shared CASes Multiple AEs & Creating Shared CASes In most cases, the easiest way to use multiple Analysis Engines from within an application is to combine them into an aggregate AE. For instructions, see . Be sure that you understand this method before deciding to use the more advanced feature described in this section. If you decide that your application does need to instantiate multiple AEs and have those AEs share a single CAS, then you will no longer be able to use the various methods on the AnalysisEngine class that create CASes (or JCases) to create your CAS. This is because these methods create a CAS with a data model specific to a single AE and which therefore cannot be shared by other AEs. Instead, you create a CAS as follows: Suppose you have two analysis engines, and one CAS Consumer, and you want to create one type system from the merge of all of their type specifications. Then you can do the following: AnalysisEngineDescription aeDesc1 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(...); AnalysisEngineDescription aeDesc2 = UIMAFramework.getXMLParser().parseAnalysisEngineDescription(...); CasConsumerDescription ccDesc = UIMAFramework.getXMLParser().parseCasConsumerDescription(...); List list = new ArrayList(); list.add(aeDesc1); list.add(aeDesc2); list.add(ccDesc); CAS cas = CasCreationUtils.createCas(list); // (optional, if using the JCas interface) JCas jcas = cas.getJCas(); The CasCreationUtils class takes care of the work of merging the AEs' type systems and producing a CAS for the combined type system. If the type systems are not compatible, an exception will be thrown.
Saving CASes to file systems The UIMA framework provides APIs to save and restore the contents of a CAS to streams. The CASes are stored in an XML format. There are two forms of this format. The preferred form is the XMI form (see ). An older format is also available, called XCAS. To save an XMI representation of a CAS, use the serialize method of the class org.apache.uima.util.XmlCasSerializer. To save an XCAS representation of a CAS, use the class org.apache.uima.cas.impl.XCASSerializer instead; see the Javadocs for details. Both of these external forms can be read back in, using the deserialize method of the class org.apache.uima.util.XmlCasDeserializer. This method deserializes into a pre-existing CAS, which you must create ahead of time, pre-set-up with the proper type system. See the Javadocs for details.
Using Collection Processing Engines A Collection Processing Engine (CPE) processes collections of artifacts (documents) through the combination of the following components: a Collection Reader, an optional CAS Initializer, Analysis Engines, and CAS Consumers. Collection Processing Engines and their components are described in . Like Analysis Engines, CPEs consist of a set of Java classes and a set of descriptors. You need to make sure the Java classes are in your classpath, but otherwise you only deal with descriptors.
Running a Collection Processing Engine from a Descriptor Running a CPE from a Descriptor describes how to use the APIs to read a CPE descriptor and run it from an application.
Configuring a Collection Processing Engine Descriptor Programmatically Configuring a CPE Descriptor Programmatically For the finest level of control over the CPE descriptor settings, the CPE offers programmatic access to the descriptor via an API. With this API, a developer can create a complete descriptor and then save the result to a file. This also can be used to read in a descriptor (using XMLParser.parseCpeDescription as shown in the previous section), modify it, and write it back out again. The CPE Descriptor API allows a developer to redefine default behavior related to error handling for each component, turn-on check-pointing, change performance characteristics of the CPE, and plug-in a custom timer. Below is some example code that illustrates how this works. See the Javadocs for package org.apache.uima.collection.metadata for more details. //Creates descriptor with default settings CpeDescription cpe = CpeDescriptorFactory.produceDescriptor(); //Add CollectionReader cpe.addCollectionReader([descriptor]); //Add CasInitializer (deprecated) cpe.addCasInitializer(<cas initializer descriptor>); // Provide the number of CASes the CPE will use cpe.setCasPoolSize(2); // Define and add Analysis Engine CpeIntegratedCasProcessor personTitleProcessor = CpeDescriptorFactory.produceCasProcessor (Person); // Provide descriptor for the Analysis Engine personTitleProcessor.setDescriptor([descriptor]); //Continue, despite errors and skip bad Cas personTitleProcessor.setActionOnMaxError(continue); //Increase amount of time in ms the CPE waits for response //from this Analysis Engine personTitleProcessor.setTimeout(100000); //Add Analysis Engine to the descriptor cpe.addCasProcessor(personTitleProcessor); // Define and add CAS Consumer CpeIntegratedCasProcessor consumerProcessor = CpeDescriptorFactory.produceCasProcessor(Printer); consumerProcessor.setDescriptor([descriptor]); //Define batch size consumerProcessor.setBatchSize(100); //Terminate CPE on max errors consumerProcessor.setActionOnMaxError(terminate); //Add CAS Consumer to the descriptor cpe.addCasProcessor(consumerProcessor); // Add Checkpoint file and define checkpoint frequency (ms) cpe.setCheckpoint([path]/checkpoint.dat, 3000); // Plug in custom timer class used for timing events cpe.setTimer(org.apache.uima.internal.util.JavaTimer); // Define number of documents to process cpe.setNumToProcess(1000); // Dump the descriptor to the System.out ((CpeDescriptionImpl)cpe).toXML(System.out); The CPE descriptor for the above configuration looks like this: ... ... 1000 immediate org.apache.uima.reference_impl.util.JavaTimer ]]>
Setting Configuration Parameters Configuration parameters can be set using APIs as well as configured using the XML descriptor metadata specification (see . There are two different places you can set the parameters via the APIs. After reading the XML descriptor for a component, but before you produce the component itself, and After the component has been produced. Setting the parameters before you produce the component is done using the ConfigurationParameterSettings object. You get an instance of this for a particular component by accessing that component description's metadata. For instance, if you produced a component description by using UIMAFramework.getXMLParser().parse... method, you can use that component description's getMetaData() method to get the metadata, and then the metadata's getConfigurationParameterSettings method to get the ConfigurationParameterSettings object. Using that object, you can set individual parameters using the setParameterValue method. Here's an example, for a CAS Consumer component: // Create a description object by reading the XML for the descriptor CasConsumerDescription casConsumerDesc = UIMAFramework.getXMLParser().parseCasConsumerDescription(new XMLInputSource("descriptors/cas_consumer/InlineXmlCasConsumer.xml")); // get the settings from the metadata ConfigurationParameterSettings consumerParamSettings = casConsumerDesc.getMetaData().getConfigurationParameterSettings(); // Set a parameter value consumerParamSettings.setParameterValue( InlineXmlCasConsumer.PARAM_OUTPUTDIR, outputDir.getAbsolutePath()); Then you might produce this component using: CasConsumer component = UIMAFramework.produceCasConsumer(casConsumerDesc); A side effect of producing a component is calling the component's initialize method, allowing it to read its configuration parameters. If you want to change parameters after this, use component.setConfigParameterValue( <parameter-name>, <parameter-value>); and then signal the component to re-read its configuration by calling the component's reconfigure method: component.reconfigure(); Although these examples are for a CAS Consumer component, the parameter APIs also work for other kinds of components.