From c204d95a7c799ba2787ba8089dcbe6049ab53516 Mon Sep 17 00:00:00 2001 From: Simon Graband Date: Tue, 7 Apr 2020 12:50:17 +0100 Subject: [PATCH] Update the Testcases + Travis Integration Tests now have a seperate workspace for easier execution and to make them more robust. Currently the tests are running in a third Travis Build, next to the maven and yarn builds. However, since the tests require maven and yarn to be run, these tests could be put together in the future. Right now two tests are failing due to #103. Signed-off-by: Simon Graband --- .travis.yml | 38 +- client/package.json | 2 +- client/tests/test.ts | 733 +- client/tests/workspace/UML.ecore | 17470 ++++++++++++++++ client/tests/workspace/empty.ecore | 2 + client/tests/workspace/test.ecore | 12 + client/tests/workspace/test.enotation | 77 + client/tests/workspace/testNodesOnly.ecore | 7 + .../tests/workspace/testNodesOnly.enotation | 24 + .../workspace/testNodesWithAttributes.ecore | 21 + .../testNodesWithAttributes.enotation | 24 + 11 files changed, 18022 insertions(+), 388 deletions(-) create mode 100644 client/tests/workspace/UML.ecore create mode 100644 client/tests/workspace/empty.ecore create mode 100644 client/tests/workspace/test.ecore create mode 100644 client/tests/workspace/test.enotation create mode 100644 client/tests/workspace/testNodesOnly.ecore create mode 100644 client/tests/workspace/testNodesOnly.enotation create mode 100644 client/tests/workspace/testNodesWithAttributes.ecore create mode 100644 client/tests/workspace/testNodesWithAttributes.enotation diff --git a/.travis.yml b/.travis.yml index e955fa4..57d6366 100644 --- a/.travis.yml +++ b/.travis.yml @@ -47,4 +47,40 @@ matrix: - xvfb - libx11-dev - libxkbfile-dev - install: false \ No newline at end of file + install: skip + + - dist: bionic + + services: + - xvfb + + language: node_js + node_js: '10' + before_script: + - cd server + - mvn install -U + - cd ../client + - fluxbox >/dev/null 2>&1 & + - sleep 3 + - yarn + script: yarn e2etest + cache: + yarn: true + directories: + - node_modules + env: + global: + - CXX=g++-4.8 + - NODE_OPTIONS="--max_old_space_size=4096" + addons: + firefox: latest + chrome: stable + apt: + update: true + packages: + - g++-4.8 + - libsecret-1-dev + - xvfb + - libx11-dev + - libxkbfile-dev + install: skip \ No newline at end of file diff --git a/client/package.json b/client/package.json index 5603d51..cc1375b 100644 --- a/client/package.json +++ b/client/package.json @@ -11,7 +11,7 @@ "publish:next": "lerna publish --exact --canary=next --npm-tag=next --yes", "theia:start": "cd browser-app && yarn start", "testcafe:start": "testcafe chrome tests/test.ts", - "e2etest": "npm-run-all --parallel --aggregate-output theia:start testcafe:start" + "e2etest": "npm-run-all --parallel --race --aggregate-output theia:start testcafe:start" }, "devDependencies": { "lerna": "2.4.0", diff --git a/client/tests/test.ts b/client/tests/test.ts index a9ecd33..5b6f4c9 100644 --- a/client/tests/test.ts +++ b/client/tests/test.ts @@ -14,154 +14,97 @@ import { Selector } from "testcafe"; import * as config from "./config.json"; // Converts Windows paths to all / for integration with theia -const relPathToWorkspace = resolve(join(__dirname, '..', 'workspace')).replace(/\\/g, "/"); - - -class Helper { - static load = async t => { - await t - .wait(5000); - await Selector('.p-MenuBar-content', { visibilityCheck: true }); - } - - static emptyEcore = () => { - return Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('empty.ecore'); - } - - static glspGraphEcore = () => { - return Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph.ecore'); - } - - static wsSelect = () => { - return Selector('#shell-tab-explorer-view-container'); - } +const relPathToWorkspace = resolve(join(__dirname, 'workspace')).replace(/\\/g, "/"); + +const selectors = { + emptyEcore: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('empty.ecore'), + testEcore: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('test.ecore'), + testEnotation: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('test.enotation'), + testNodesOnlyEcore: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('testNodesOnly.ecore'), + testNodesOnlyEnotation: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('testNodesOnly.enotation'), + testNodesWithAttributesEcore: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('testNodesWithAttributes.ecore'), + testNodesWithAttributesEnotation: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('testNodesWithAttributes.enotation'), + umlEcore: Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('UML.ecore'), + wsSelect: Selector('#shell-tab-explorer-view-container'), + svgCanvas: Selector('svg.sprotty-graph'), + eraser: Selector('.fas.fa-eraser.fa-xs'), + edgePoints: Selector('.sprotty-edge.ecore-edge.selected').child().withAttribute('data-kind', 'manhattan-50%'), + duplicateFile: Selector('.p-Menu-itemLabel').withText('Duplicate'), + deleteFile: Selector('.p-Menu-itemLabel').withText('Delete'), + renameFile: Selector('.p-Menu-itemLabel').withText('Rename'), + okButton: Selector('.theia-button.main').withText('OK'), + renameInput: Selector('div.dialogContent > input'), + openWith: Selector('.p-Menu-itemLabel').withText('Open With'), + codeEditor: Selector('.p-Menu-itemLabel').withText('Code Editor'), + line: Selector('.view-lines'), + input: Selector('div.label-edit input'), + attribute: Selector('div.tool-group > div.tool-button').withText("Attribute"), + literal: Selector('div.tool-group > div.tool-button').withText("Literal"), } -class CreateHelper { - - constructor(private t: TestController) { - } - async createNode(name) { - const selector = Selector('div.tool-group > div.tool-button').withText(name); - const svgCanvas = Selector('svg.sprotty-graph'); - await this.t.click(selector) - .click(svgCanvas); - } - - async createClass() { - return this.createNode('Class'); - } - - async createAbstract() { - return this.createNode('Abstract'); - } - - async createInterface() { - return this.createNode('Interface'); - } - - async createEnum() { - return this.createNode('Enum'); - } +const nodesSelector = { + classNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('Class'), + abstractNode: Selector('g.node.ecore-node.abstract text.name.sprotty-label').withText('Abstract'), + enumNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('Enum'), + interfaceNode: Selector('g.node.ecore-node.interface text.name.sprotty-label').withText('Interface'), + dataTypeNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('DataType') +}; - async createAllNodeTypes() { - const emptyEcore = Helper.emptyEcore(); - const wsSelect = Helper.wsSelect(); - - await this.t - .click(wsSelect) - .click(emptyEcore); - await this.createClass(); - await this.createAbstract(); - await this.createEnum(); - await this.createInterface(); - } +const edgeSelector = { + inheritanceEdge: Selector('g.sprotty-edge.ecore-edge.inheritance'), + containmentEdge: Selector('g.sprotty-edge.ecore-edge.composition text.edge-name.sprotty-label').withText('containment'), + referenceEdge: Selector('g.sprotty-edge.ecore-edge text.edge-name.sprotty-label').withText('reference') +}; - async createEdge(name, a, b) { - const selector = Selector('div.tool-group > div.tool-button').withText(name); - await this.t.click(selector).click(a).hover(b).click(b); - } +const attributeSelector = { + attributeClass: Selector('g.node.ecore-node text.sprotty-label').withText('ClassAttribute : EString'), + attributeAbstract: Selector('g.node.ecore-node text.sprotty-label').withText('AbstractAttribute : EString'), + attributeInterface: Selector('g.node.ecore-node text.sprotty-label').withText('InterfaceAttribute : EString'), + literalEnum: Selector('g.node.ecore-node text.sprotty-label').withText('EnumLiteral'), +} - async layout() { - await this.t.pressKey('alt+l').wait(500); - } - async createAllEdges() { - await this.layout(); - await this.createEdge('Reference', this.nodesSelector.classNode, this.nodesSelector.abstractNode); - await this.createEdge('Inheritance', this.nodesSelector.interfaceNode, this.nodesSelector.abstractNode); - await this.createEdge('Containment', this.nodesSelector.interfaceNode, this.nodesSelector.classNode); - } +const defaultNodesSelector = { + classNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('NewEClass0'), + abstractNode: Selector('g.node.ecore-node.abstract text.name.sprotty-label').withText('NewEClass1'), + interfaceNode: Selector('g.node.ecore-node.interface text.name.sprotty-label').withText('NewEClass2'), + enumNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('NewEEnum3'), + dataTypeNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('NewEDataType4') +}; - async deleteAllNodes(t) { - await t - .click(this.nodesSelector.classNode) - .pressKey('delete') - .click(this.nodesSelector.abstractNode) - .pressKey('delete') - .click(this.nodesSelector.enumNode) - .pressKey('delete') - .click(this.nodesSelector.interfaceNode) - .pressKey('delete'); - } +const defaultEdgeSelector = { + inheritanceEdge: Selector('g.sprotty-edge.ecore-edge.inheritance'), + containmentEdge: Selector('g.sprotty-edge.ecore-edge.composition text.edge-name.sprotty-label').withText('classs'), + referenceEdge: Selector('g.sprotty-edge.ecore-edge text.edge-name.sprotty-label').withText('abstracts') +}; - async addAttributes() { - const attribute = Selector('div.tool-group > div.tool-button').withText("Attribute"); - const literal = Selector('div.tool-group > div.tool-button').withText("Literal"); - - this.layout(); - - await this.t - .click(attribute) - .click(this.nodesSelector.classNode) - .click(attribute) - .click(this.nodesSelector.abstractNode) - .click(attribute) - .click(this.nodesSelector.interfaceNode) - .click(literal) - .click(this.nodesSelector.enumNode); - } +const defaultAttributeSelector = { + attributeClass: Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute4 : EString'), + attributeAbstract: Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute5 : EString'), + attributeInterface: Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute6 : EString'), + literalEnum: Selector('g.node.ecore-node text.sprotty-label').withText('NewEEnumLiteral7'), +} - public nodesSelector = { - classNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('NewEClass0'), - abstractNode: Selector('g.node.ecore-node.abstract text.name.sprotty-label').withText('NewEClass1'), - enumNode: Selector('g.node.ecore-node text.name.sprotty-label').withText('NewEEnum2'), - interfaceNode: Selector('g.node.ecore-node.interface text.name.sprotty-label').withText('NewEClass3') - }; - - public edgeSelector = { - inheritanceEdge: Selector('g.sprotty-edge.ecore-edge.inheritance'), - containmentEdge: Selector('g.sprotty-edge.ecore-edge.composition text.edge-name.sprotty-label').withText('neweclass0s'), - referenceEdge: Selector('g.sprotty-edge.ecore-edge text.edge-name.sprotty-label').withText('neweclass1s') - }; - - async getEdgePosition(s: Selector) { - const x = await (s.getAttribute('cx')); - const y = await (s.getAttribute('cy')); - return { x: parseFloat(x), y: parseFloat(y) }; - } +const openFile = async (t, file) => { + await t + .click(selectors.wsSelect) + .click(file); +} - async getNodePosition(s: Selector) { - const transform = await (s.parent("g.node.ecore-node").getAttribute('transform')); - const regex = new RegExp("\\s*\\w*\\s*\\(\\s*(\\d+(\\.\\d+)?)\\s*,\\s*(\\d+(\\.\\d+)?)\\s*\\)\\s*"); - const match = regex.exec(transform); - if (match) { - return { x: parseFloat(match[1]), y: parseFloat(match[3]) }; - } - return {}; - } +const fileSelect = async (file) => { + return Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText(file); } const checkDefaultWorkbench = async (t) => { - const emptyEcore = Helper.emptyEcore(); - const glspGraphEcore = Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph.ecore'); - const glspGraphEnotation = Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph.enotation'); - const umlEcore = Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('UML.ecore'); await t - .expect(emptyEcore.exists).ok('Check if empty.ecore exists') - .expect(glspGraphEcore.exists).ok('Check if glsp-graph.ecore exists') - .expect(glspGraphEnotation.exists).ok('Check if glsp-graph.enotation exists') - .expect(umlEcore.exists).ok('Check if UML.ecore exists') - .expect(Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').count).eql(4); + .expect(selectors.emptyEcore.exists).ok('Check if empty.ecore exists') + .expect(selectors.testEcore.exists).ok('Check if test.ecore exists') + .expect(selectors.testEnotation.exists).ok('Check if test.enotation exists') + .expect(selectors.testNodesOnlyEcore.exists).ok('Check if testNodesOnly.ecore exists') + .expect(selectors.testNodesOnlyEnotation.exists).ok('Check if testNodesOnly.enotation exists') + .expect(selectors.testNodesWithAttributesEcore.exists).ok('Check if testNodesWithAttributes.ecore exists') + .expect(selectors.testNodesWithAttributesEnotation.exists).ok('Check if testNodesWith Attributes.enotation exists') + .expect(selectors.umlEcore.exists).ok('Check if UML.ecore exists') + .expect(Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').count).eql(8); }; const openQuickAccessBar = async (t) => { @@ -181,19 +124,56 @@ const writeQuickAccessBar = async (t, text) => { .pressKey('Enter'); }; +const createNode = async (t, name) => { + const selector = Selector('div.tool-group > div.tool-button').withText(name); + const svgCanvas = Selector('svg.sprotty-graph'); + await t + .click(selector) + .click(svgCanvas); +}; + +const deleteNode = async (t, selector) => { + await t.click(selector).pressKey('delete'); +}; + +const createEdge = async (t, name, a, b) => { + const selector = Selector('div.tool-group > div.tool-button').withText(name); + await t.click(selector).click(a).hover(b).click(b); +}; + +const getNodePosition = async (s: Selector) => { + const transform = await (s.parent("g.node.ecore-node").getAttribute('transform')); + const regex = new RegExp("\\s*\\w*\\s*\\(\\s*(\\d+(\\.\\d+)?)\\s*,\\s*(\\d+(\\.\\d+)?)\\s*\\)\\s*"); + const match = regex.exec(transform); + if (match) { + return { x: parseFloat(match[1]), y: parseFloat(match[3]) }; + } + return {}; +}; + +const getEdgePosition = async (s: Selector) => { + const x = await (s.getAttribute('cx')); + const y = await (s.getAttribute('cy')); + return { x: parseFloat(x), y: parseFloat(y) }; +}; + +const layout = async (t) => { + await t + .pressKey('alt+l') + .wait(500); +}; + const port = process.env.PORT || config.defaultPort; fixture`Ecore-glsp E2E-Testing`// declare the fixture .page`http://localhost:${port}/#${relPathToWorkspace}` - .beforeEach(async t => { - await Helper.load(t); + .after(async t => { }); // The start page loads the workbench at the above defined Path test('Open Workbench', async t => { - const workspace = Helper.wsSelect(); await t .wait(5000) - .click(workspace); + .click(selectors.wsSelect); await checkDefaultWorkbench(t); }); @@ -214,67 +194,45 @@ test('Switch Theme', async t => { .expect(Selector('div.p-Widget.p-DockPanel.p-SplitPanel-child').getStyleProperty('color')).eql('rgb(97, 97, 97)'); }); -test('Open graph-glsp.ecore', async t => { - const wsSelect = Helper.wsSelect(); - const fileSelect = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph.ecore'); +test('Open UML.ecore (Autolayout/ Big Ecore)', async t => { + openFile(t, selectors.umlEcore); await t - .click(wsSelect) - .click(fileSelect) - .expect(Selector('text.name.sprotty-label').withText('GSeverity').exists).ok('Class GSeverity exists') - .expect(Selector('text.name.sprotty-label').count).eql(50); + .wait(10000) // Necessary to wait as the layouting needs to be executed. + .expect(Selector('text.name.sprotty-label').withText('ConnectorKind').exists).ok('Class ConnectorKind exists') + .expect(Selector('text.name.sprotty-label').count).eql(512) + .expect(Selector('text.name.sprotty-label').withText('ConnectorKind').parent("g.node.ecore-node").getAttribute('transform')).eql('translate(12, 12)'); }); test('Deletion/Renaming of enotation', async t => { - const wsSelect = Helper.wsSelect(); - const fileSelect = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph.enotation'); - const duplicateFile = Selector('.p-Menu-itemLabel').withText('Duplicate'); - const deleteFile = Selector('.p-Menu-itemLabel').withText('Delete'); - const renameFile = Selector('.p-Menu-itemLabel').withText('Rename'); - const okButton = Selector('.theia-button.main').withText('OK'); - const duplicateFileSelect = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('glsp-graph_copy.enotation'); - const renameInput = Selector('div.dialogContent > input'); - await t - .click(wsSelect) - .rightClick(fileSelect) - .click(duplicateFile) + .click(selectors.wsSelect) + .rightClick(selectors.testEnotation) + .click(selectors.duplicateFile) .wait(200) - .rightClick(fileSelect) - .click(deleteFile) - .click(okButton) - .expect(Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').count).eql(4) - - .rightClick(duplicateFileSelect) - .click(renameFile) + .rightClick(selectors.testEnotation) + .click(selectors.deleteFile) + .click(selectors.okButton) + .expect(Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').count).eql(8) + .rightClick(await fileSelect('test_copy.enotation')) + .click(selectors.renameFile) .pressKey('ctrl+a') - .typeText(renameInput, "glsp-graph.enotation") + .typeText(selectors.renameInput, "test.enotation") .pressKey('Enter'); }).after(checkDefaultWorkbench); -test('Open Ecore without enotation', async t => { - const wsSelect = Helper.wsSelect(); - const fileSelect = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('UML.ecore'); - const classSelect = Selector("text.name.sprotty-label").withText("ConnectorKind").parent("g.node.ecore-node"); - - await t - .click(wsSelect) - .click(fileSelect).wait(10000) // Necessary to wait as the layouting needs to be executed. - .expect(classSelect.getAttribute('transform')).notEql('translate(0, 0)'); -}); - test('Create and Delete ecore file', async t => { - const wsSelect = Helper.wsSelect(); + const wsSelect = Selector('#shell-tab-explorer-view-container'); const deleteFile = Selector('.p-Menu-itemLabel').withText('Delete'); const okButton = Selector('.theia-button.main').withText('OK'); - const newEcore = Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('Test.ecore'); + const newEcore = Selector('div.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('Creation.ecore'); openQuickAccessBar(t); writeQuickAccessBar(t, "New Ecore-File"); - writeQuickAccessBar(t, "Test"); - writeQuickAccessBar(t, "testPrefix"); - writeQuickAccessBar(t, "testURI"); + writeQuickAccessBar(t, "Creation"); + writeQuickAccessBar(t, "creationPrefix"); + writeQuickAccessBar(t, "creationURI"); await t .click(wsSelect) @@ -288,244 +246,198 @@ test('Create and Delete ecore file', async t => { }).after(checkDefaultWorkbench); test('Create Nodes', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.layout(); + openFile(t, selectors.emptyEcore); + + createNode(t, "Class"); + createNode(t, "Abstract"); + createNode(t, "Interface"); + createNode(t, "Enum"); + createNode(t, "DataType"); + + layout(t); await t - .expect(creator.nodesSelector.classNode.exists).ok("Class has been created") - .expect(creator.nodesSelector.abstractNode.exists).ok("Abstract has been created") - .expect(creator.nodesSelector.enumNode.exists).ok("Enum has been created") - .expect(creator.nodesSelector.interfaceNode.exists).ok("Interface has been created") + .expect(defaultNodesSelector.classNode.exists).ok("Class has been created") + .expect(defaultNodesSelector.abstractNode.exists).ok("Abstract has been created") + .expect(defaultNodesSelector.interfaceNode.exists).ok("Interface has been created") + .expect(defaultNodesSelector.enumNode.exists).ok("Enum has been created") + .expect(defaultNodesSelector.dataTypeNode.exists).ok("DataType has been created") .pressKey('ctrl+s'); // Check Serialization - const fileSelect = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('empty.enotation'); - const emptyFile = Selector('.theia-TreeNodeSegment.theia-TreeNodeSegmentGrow').withText('empty.ecore'); - const openWith = Selector('.p-Menu-itemLabel').withText('Open With'); - const codeEditor = Selector('.p-Menu-itemLabel').withText('Code Editor'); - const line = Selector('.view-lines'); // Enotation await t - .click(fileSelect) - .expect(line.child().child().withText('NewEClass0').exists).ok('Enotation serialization worked'); + .click(await fileSelect('empty.enotation')) + .expect(selectors.line.child().child().withText('NewEClass0').exists).ok('Enotation serialization worked') + .expect(selectors.line.child().child().withText('NewEClass1').exists).ok('Enotation serialization worked') + .expect(selectors.line.child().child().withText('NewEClass2').exists).ok('Enotation serialization worked') + .expect(selectors.line.child().child().withText('NewEEnum3').exists).ok('Enotation serialization worked') + .expect(selectors.line.child().child().withText('NewEDataType4').exists).ok('Enotation serialization worked'); // Ecore await t - .rightClick(emptyFile) - .hover(openWith) - .click(codeEditor) - .click(emptyFile) - .expect(line.child().child().withText('NewEClass0').exists).ok('Ecore serialization worked'); + .rightClick(selectors.emptyEcore) + .hover(selectors.openWith) + .click(selectors.codeEditor) + .click(selectors.emptyEcore) + .expect(selectors.line.child().child().withText('NewEClass0').exists).ok('Ecore serialization worked') + .expect(selectors.line.child().child().withText('NewEClass1').exists).ok('Ecore serialization worked') + .expect(selectors.line.child().child().withText('NewEClass2').exists).ok('Ecore serialization worked') + .expect(selectors.line.child().child().withText('NewEEnum3').exists).ok('Ecore serialization worked') + .expect(selectors.line.child().child().withText('NewEDataType4').exists).ok('Ecore serialization worked'); // Delete again - const deleteFile = Selector('.p-Menu-itemLabel').withText('Delete'); - const okButton = Selector('.theia-button.main').withText('OK'); - creator.deleteAllNodes(t); + await t.wait(500); + deleteNode(t, defaultNodesSelector.classNode); + await t.wait(500); + deleteNode(t, defaultNodesSelector.abstractNode); + await t.wait(500); + deleteNode(t, defaultNodesSelector.interfaceNode); + await t.wait(500); + deleteNode(t, defaultNodesSelector.enumNode); + await t.wait(500); + deleteNode(t, defaultNodesSelector.dataTypeNode); + await t.wait(500); await t .pressKey('ctrl+s') - .rightClick(fileSelect) - .click(deleteFile) - .click(okButton); + .rightClick(await fileSelect('empty.enotation')) + .click(selectors.deleteFile) + .click(selectors.okButton); }).after(checkDefaultWorkbench); -// Could check for Serialization -test('Move Class', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.layout(); - const drag_distance = 100; - const original_pos = await creator.getNodePosition(creator.nodesSelector.classNode); - await t - .drag(creator.nodesSelector.classNode, drag_distance, drag_distance, { speed: 0.1 }); - const new_pos = await creator.getNodePosition(creator.nodesSelector.classNode); - await t - .expect(original_pos.x + drag_distance).eql(new_pos.x) - .expect(original_pos.y + drag_distance).eql(new_pos.y); -}); +test('Create Edges', async t => { + openFile(t, selectors.testNodesOnlyEcore); -test('Delete Nodes with Eraser', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - const eraser = Selector('.fas.fa-eraser.fa-xs'); - await creator.layout(); - await t - .click(eraser) - .click(creator.nodesSelector.classNode) - .click(eraser) - .click(creator.nodesSelector.abstractNode) - .click(eraser) - .click(creator.nodesSelector.enumNode) - .click(eraser) - .click(creator.nodesSelector.interfaceNode) - .expect(creator.nodesSelector.classNode.exists).notOk("Class has been deleted") - .expect(creator.nodesSelector.abstractNode.exists).notOk("Abstract has been deleted") - .expect(creator.nodesSelector.enumNode.exists).notOk("Enum has been deleted") - .expect(creator.nodesSelector.interfaceNode.exists).notOk("Interface has been deleted"); -}); + createEdge(t, 'Reference', nodesSelector.classNode, nodesSelector.abstractNode); + createEdge(t, 'Inheritance', nodesSelector.interfaceNode, nodesSelector.abstractNode); + createEdge(t, 'Containment', nodesSelector.interfaceNode, nodesSelector.classNode); -test('Delete Nodes with DEL', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.layout(); - await creator.deleteAllNodes(t); await t - .expect(creator.nodesSelector.classNode.exists).notOk("Class has been deleted") - .expect(creator.nodesSelector.abstractNode.exists).notOk("Abstract has been deleted") - .expect(creator.nodesSelector.enumNode.exists).notOk("Enum has been deleted") - .expect(creator.nodesSelector.interfaceNode.exists).notOk("Interface has been deleted"); + .expect(defaultEdgeSelector.referenceEdge.exists).ok('Reference exists') + .expect(defaultEdgeSelector.containmentEdge.exists).ok('Containment exists') + .expect(defaultEdgeSelector.inheritanceEdge.exists).ok('Inheritance exists'); }); -test('Create Edges', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); +test('Add Attributes/Literals', async t => { + openFile(t, selectors.testNodesOnlyEcore); - await creator.createAllEdges(); + await t + .click(selectors.attribute) + .click(nodesSelector.classNode) + .click(selectors.attribute) + .click(nodesSelector.abstractNode) + .click(selectors.attribute) + .click(nodesSelector.interfaceNode) + .click(selectors.literal) + .click(nodesSelector.enumNode); - await t.expect(creator.edgeSelector.referenceEdge.exists).ok('Reference exists'); - await t.expect(creator.edgeSelector.containmentEdge.exists).ok('Containment exists'); - await t.expect(creator.edgeSelector.inheritanceEdge.exists).ok('Inheritance exists'); + await t + .expect(defaultAttributeSelector.attributeClass.exists).ok("Adding Attribute to Class") + .expect(defaultAttributeSelector.attributeAbstract.exists).ok("Adding Attribute to Abstract") + .expect(defaultAttributeSelector.attributeInterface.exists).ok("Adding Attribute to Interface") + .expect(defaultAttributeSelector.literalEnum.exists).ok("Adding Literal to Enum"); }); -test('Move Edges', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.createAllEdges(); - await creator.layout(); +test('Layout new Diagram', async t => { + openFile(t, selectors.emptyEcore); + createNode(t, "Class"); + createNode(t, "Abstract"); + createNode(t, "Interface"); + createNode(t, "Enum"); - const points = Selector('.sprotty-edge.ecore-edge.selected').child().withAttribute('data-kind', 'manhattan-50%'); - const svgCanvas = Selector('svg.sprotty-graph'); + layout(t); await t - .click(creator.edgeSelector.referenceEdge); - - const original_pos1 = await creator.getEdgePosition(points.nth(0)); - const original_pos2 = await creator.getEdgePosition(points.nth(1)); - const original_pos3 = await creator.getEdgePosition(points.nth(2)); - - await t - .drag(points.nth(0), -10, 0, { speed: 0.1 }) - .click(svgCanvas) - .click(creator.edgeSelector.referenceEdge) - .drag(points.nth(1), 0, -10, { speed: 0.1 }) - .click(svgCanvas) - .click(creator.edgeSelector.referenceEdge) - .drag(points.nth(2), 10, 0, { speed: 0.1 }) - .click(svgCanvas) - .click(creator.edgeSelector.referenceEdge); - - const new_pos1 = await creator.getEdgePosition(points.nth(0)); - const new_pos2 = await creator.getEdgePosition(points.nth(1)); - const new_pos3 = await creator.getEdgePosition(points.nth(2)); + .expect(defaultNodesSelector.classNode.parent("g.node.ecore-node").getAttribute('transform')).eql('translate(12, 12)') + .expect(defaultNodesSelector.enumNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)') + .expect(defaultNodesSelector.interfaceNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)') + .expect(defaultNodesSelector.abstractNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)'); +}); +test('Move Class', async t => { + openFile(t, selectors.testEcore); + await t.wait(500); + const drag_distance = 100; + const original_pos = await getNodePosition(nodesSelector.classNode); await t - .expect(original_pos1.x - 10).eql(new_pos1.x) - .expect(original_pos1.y).eql(new_pos1.y) - .expect(original_pos2.y - 10).eql(new_pos2.y) - .expect(original_pos3.x + 10).eql(new_pos3.x); -}); -test('Delete Edges', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.createAllEdges(); - const eraser = Selector('.fas.fa-eraser.fa-xs'); - await creator.layout(); + .drag(nodesSelector.classNode, drag_distance, drag_distance, { speed: 0.1 }); + const new_pos = await getNodePosition(nodesSelector.classNode); await t - .click(eraser) - .click(creator.edgeSelector.referenceEdge) - .click(eraser) - .click(creator.edgeSelector.containmentEdge) - .click(eraser) - .click(creator.edgeSelector.inheritanceEdge); - await t.expect(creator.edgeSelector.referenceEdge.exists).notOk('Reference deleted'); - await t.expect(creator.edgeSelector.containmentEdge.exists).notOk('Containment deleted'); - await t.expect(creator.edgeSelector.inheritanceEdge.exists).notOk('Inheritance deleted'); + .expect(original_pos.x + drag_distance).eql(new_pos.x) + .expect(original_pos.y + drag_distance).eql(new_pos.y); }); -test('Delete Edges with DEL', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.createAllEdges(); - await creator.layout(); +test('Move Edges', async t => { + openFile(t, selectors.testEcore); + await t - .click(creator.edgeSelector.referenceEdge) - .pressKey('delete') - .click(creator.edgeSelector.containmentEdge) - .pressKey('delete') - .click(creator.edgeSelector.inheritanceEdge) - .pressKey('delete'); - await t.expect(creator.edgeSelector.referenceEdge.exists).notOk('Reference deleted'); - await t.expect(creator.edgeSelector.containmentEdge.exists).notOk('Containment deleted'); - await t.expect(creator.edgeSelector.inheritanceEdge.exists).notOk('Inheritance deleted'); -}); + .click(edgeSelector.referenceEdge); -test('Add Attributes/Literals', async t => { - const creator = new CreateHelper(t); - const attributeClass = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute4 : EString'); - const attributeAbstract = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute5 : EString'); - const attributeInterface = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute6 : EString'); - const attributeEnum = Selector('g.node.ecore-node text.sprotty-label').withText('NewEEnumLiteral7'); + const original_pos1 = await getEdgePosition(selectors.edgePoints.nth(0)); + const original_pos2 = await getEdgePosition(selectors.edgePoints.nth(1)); + const original_pos3 = await getEdgePosition(selectors.edgePoints.nth(2)); - await creator.createAllNodeTypes(); - await creator.addAttributes(); + await t + .drag(selectors.edgePoints.nth(0), 0, -5, { speed: 0.1 }) + .click(selectors.svgCanvas) + .click(edgeSelector.referenceEdge) + .drag(selectors.edgePoints.nth(1), -10, 0, { speed: 0.1 }) + .click(selectors.svgCanvas) + .click(edgeSelector.referenceEdge) + .drag(selectors.edgePoints.nth(2), 0, 5, { speed: 0.1 }) + .click(selectors.svgCanvas) + .click(edgeSelector.referenceEdge); + + const new_pos1 = await getEdgePosition(selectors.edgePoints.nth(0)); + const new_pos2 = await getEdgePosition(selectors.edgePoints.nth(1)); + const new_pos3 = await getEdgePosition(selectors.edgePoints.nth(2)); await t - .expect(attributeClass.exists).ok("Adding Attribute to Class") - .expect(attributeAbstract.exists).ok("Adding Attribute to Abstract") - .expect(attributeInterface.exists).ok("Adding Attribute to Interface") - .expect(attributeEnum.exists).ok("Adding Literal to Enum"); + .expect(original_pos1.y).notEql(new_pos1.y) + .expect(original_pos2.x).notEql(new_pos2.x) + .expect(original_pos3.y).notEql(new_pos3.y); }); -// Could check for Serialization test('Renaming Classes/Attributes', async t => { - const creator = new CreateHelper(t); - const nameClass = creator.nodesSelector.classNode; - const nameAbstract = creator.nodesSelector.abstractNode; - const nameInterface = creator.nodesSelector.interfaceNode; - const nameEnum = creator.nodesSelector.enumNode; - const attributeClass = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute4 : EString'); - const attributeAbstract = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute5 : EString'); - const attributeInterface = Selector('g.node.ecore-node text.sprotty-label').withText('NewEAttribute6 : EString'); - const attributeEnum = Selector('g.node.ecore-node text.sprotty-label').withText('NewEEnumLiteral7'); + const attributeClassRenamed = Selector('g.node.ecore-node text.sprotty-label').withText('TestAttributeClass : EString'); const attributeAbstractRenamed = Selector('g.node.ecore-node text.sprotty-label').withText('TestAttributeAbstract : EString'); const attributeInterfaceRenamed = Selector('g.node.ecore-node text.sprotty-label').withText('TestAttributeInterface : EString'); const attributeEnumRenamed = Selector('g.node.ecore-node text.sprotty-label').withText('TestLiteralEnum'); + const nameClassRenamed = Selector('g.node.ecore-node text.name.sprotty-label').withText('TestClass'); const nameAbstractRenamed = Selector('g.node.ecore-node text.name.sprotty-label').withText('TestAbstract'); const nameInterfaceRenamed = Selector('g.node.ecore-node text.name.sprotty-label').withText('TestInterface'); const nameEnumRenamed = Selector('g.node.ecore-node text.name.sprotty-label').withText('TestEnum'); - const input = Selector('div.label-edit input'); - await creator.createAllNodeTypes(); - await creator.addAttributes(); + openFile(t, selectors.testNodesWithAttributesEcore); await t - .doubleClick(nameClass) - .typeText(input, "TestClass") - .click(nameAbstract) - .doubleClick(nameAbstract) - .typeText(input, "TestAbstract") - .click(nameInterface) - .doubleClick(nameInterface) - .typeText(input, "TestInterface") - .click(nameEnum) - .doubleClick(nameEnum) - .typeText(input, "TestEnum") - .click(attributeClass) - .doubleClick(attributeClass) - .typeText(input, "TestAttributeClass") - .click(attributeAbstract) - .doubleClick(attributeAbstract) - .typeText(input, "TestAttributeAbstract") - .click(attributeInterface) - .doubleClick(attributeInterface) - .typeText(input, "TestAttributeInterface") - .click(attributeEnum) - .doubleClick(attributeEnum) - .typeText(input, "TestLiteralEnum") + .doubleClick(nodesSelector.classNode) + .typeText(selectors.input, "TestClass") + .click(nodesSelector.abstractNode) + .doubleClick(nodesSelector.abstractNode) + .typeText(selectors.input, "TestAbstract") + .click(nodesSelector.interfaceNode) + .doubleClick(nodesSelector.interfaceNode) + .typeText(selectors.input, "TestInterface") + .click(nodesSelector.enumNode) + .doubleClick(nodesSelector.enumNode) + .typeText(selectors.input, "TestEnum") + .click(attributeSelector.attributeClass) + .doubleClick(attributeSelector.attributeClass) + .typeText(selectors.input, "TestAttributeClass") + .click(attributeSelector.attributeAbstract) + .doubleClick(attributeSelector.attributeAbstract) + .typeText(selectors.input, "TestAttributeAbstract") + .click(attributeSelector.attributeInterface) + .doubleClick(attributeSelector.attributeInterface) + .typeText(selectors.input, "TestAttributeInterface") + .click(attributeSelector.literalEnum) + .doubleClick(attributeSelector.literalEnum) + .typeText(selectors.input, "TestLiteralEnum") .click(nameClassRenamed) .expect(nameClassRenamed.exists).ok("Renamed Class") .expect(nameAbstractRenamed.exists).ok("Renamed Abstract") @@ -537,39 +449,88 @@ test('Renaming Classes/Attributes', async t => { .expect(attributeEnumRenamed.exists).ok("Renamed Literal in Enum"); }); -// Could check for Serialization test('Change Attributetype', async t => { - const wsSelect = Helper.wsSelect(); - const glspEcore = Helper.glspGraphEcore(); - const attributeSelector = Selector('g.node.ecore-node text.sprotty-label').withText('layout : EString'); + openFile(t, selectors.testNodesWithAttributesEcore) const changedAttribute = Selector('g.node.ecore-node text.sprotty-label').withText('test : EDate'); const changedAttributeWrite = Selector('g.node.ecore-node text.sprotty-label').withText('layout : EString'); - const input = Selector('div.label-edit input'); await t - .click(wsSelect) - .click(glspEcore) - .click(attributeSelector) - .doubleClick(attributeSelector) - .typeText(input, 'test : EDa') + .click(attributeSelector.attributeClass) + .doubleClick(attributeSelector.attributeClass) + .typeText(selectors.input, 'test : EDa') .pressKey('ctrl+space') .pressKey('down') .pressKey('Enter') .expect(changedAttribute.exists).ok("Changing the attributetype via Autocompletion") .doubleClick(changedAttribute) - .typeText(input, 'layout : EString') + .typeText(selectors.input, 'layout : EString') .pressKey('Enter') .expect(changedAttributeWrite.exists).ok("Changing the attributetype via Typing"); }); -test('Style new Diagram', async t => { - const creator = new CreateHelper(t); - await creator.createAllNodeTypes(); - await creator.createAllEdges(); +test('Delete Nodes with Eraser', async t => { + openFile(t, selectors.testEcore); + await t + .click(selectors.eraser) + .click(nodesSelector.classNode, { offsetY: -40 }) + .click(selectors.eraser) + .click(nodesSelector.abstractNode, { offsetY: -40 }) + .click(selectors.eraser) + .click(nodesSelector.enumNode, { offsetY: -40 }) + .click(selectors.eraser) + .click(nodesSelector.interfaceNode, { offsetY: -40 }) + .expect(nodesSelector.classNode.exists).notOk("Class has been deleted") + .expect(nodesSelector.abstractNode.exists).notOk("Abstract has been deleted") + .expect(nodesSelector.enumNode.exists).notOk("Enum has been deleted") + .expect(nodesSelector.interfaceNode.exists).notOk("Interface has been deleted"); +}); - await t.pressKey('alt+l').wait(500) - .expect(creator.nodesSelector.enumNode.parent("g.node.ecore-node").getAttribute('transform')).eql('translate(12, 12)') - .expect(creator.nodesSelector.classNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)') - .expect(creator.nodesSelector.interfaceNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)') - .expect(creator.nodesSelector.abstractNode.parent("g.node.ecore-node").getAttribute('transform')).notEql('translate(12, 12)'); +test('Delete Nodes with DEL', async t => { + openFile(t, selectors.testEcore); + await t + .wait(200) + .click(nodesSelector.classNode, { offsetY: -40 }) + .pressKey('delete') + .wait(200) + .click(nodesSelector.abstractNode, { offsetY: -40 }) + .pressKey('delete') + .wait(200) + .click(nodesSelector.interfaceNode, { offsetY: -40 }) + .pressKey('delete') + .wait(200) + .click(nodesSelector.enumNode, { offsetY: -40 }) + .pressKey('delete') + .wait(200) + .expect(nodesSelector.classNode.exists).notOk("Class has been deleted") + .expect(nodesSelector.abstractNode.exists).notOk("Abstract has been deleted") + .expect(nodesSelector.interfaceNode.exists).notOk("Interface has been deleted") + .expect(nodesSelector.enumNode.exists).notOk("Enum has been deleted"); +}); + +test('Delete Edges', async t => { + openFile(t, selectors.testEcore); + await t + .click(selectors.eraser) + .click(nodesSelector.classNode, { offsetX: 90 }) + .click(selectors.eraser) + .click(nodesSelector.classNode, { offsetY: 60, offsetX: 15 }) + .click(selectors.eraser) + .click(nodesSelector.interfaceNode, { offsetY: -60, offsetX: 28 }) + .expect(edgeSelector.referenceEdge.exists).notOk('Reference deleted') + .expect(edgeSelector.containmentEdge.exists).notOk('Containment deleted') + .expect(edgeSelector.inheritanceEdge.exists).notOk('Inheritance deleted'); +}); + +test('Delete Edges with DEL', async t => { + openFile(t, selectors.testEcore); + await t + .click(edgeSelector.referenceEdge) + .pressKey('delete') + .click(edgeSelector.containmentEdge) + .pressKey('delete') + .click(edgeSelector.inheritanceEdge) + .pressKey('delete') + .expect(edgeSelector.containmentEdge.exists).notOk('Containment deleted') + .expect(edgeSelector.inheritanceEdge.exists).notOk('Inheritance deleted') + .expect(edgeSelector.referenceEdge.exists).notOk('Reference deleted'); }); diff --git a/client/tests/workspace/UML.ecore b/client/tests/workspace/UML.ecore new file mode 100644 index 0000000..a8ca41b --- /dev/null +++ b/client/tests/workspace/UML.ecore @@ -0,0 +1,17470 @@ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + + + + +
+ + + + + +
+ + +
+ + +
+
+ + + + + +
+ + + + + +
+ + +
+ + +
+
+ + + + + +
+
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + +
+ + + +
+ + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+
+ + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + + + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + + + +
+ + + + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+
+
+
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + + +
+ + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+
+ + + +
+ + + + + +
+ + + + + + +
+ + + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + + +
+ + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+
+ + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + + + +
+ + + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + + +
+ + + +
+ + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + + + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + +
+ + + + + +
+ + + +
+
+ + + +
+ + + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+
+ + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + +
+ + + + + +
+
+ + +
+ + + + +
+
+ + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + + + +
+ + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + + +
+ + + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + + +
+ + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ + + + + +
+ + + + + + +
+ + + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + +
+ + + + +
+ + + + + + + + + +
+ + + + + +
+ + + +
+ + +
+ + + +
+ + + + + +
+ + + + + + + +
+ + + +
+ + + + +
+ + + + diff --git a/client/tests/workspace/empty.ecore b/client/tests/workspace/empty.ecore new file mode 100644 index 0000000..e0c2564 --- /dev/null +++ b/client/tests/workspace/empty.ecore @@ -0,0 +1,2 @@ + + diff --git a/client/tests/workspace/test.ecore b/client/tests/workspace/test.ecore new file mode 100644 index 0000000..5d19dfe --- /dev/null +++ b/client/tests/workspace/test.ecore @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/client/tests/workspace/test.enotation b/client/tests/workspace/test.enotation new file mode 100644 index 0000000..472534d --- /dev/null +++ b/client/tests/workspace/test.enotation @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/tests/workspace/testNodesOnly.ecore b/client/tests/workspace/testNodesOnly.ecore new file mode 100644 index 0000000..acb5e5e --- /dev/null +++ b/client/tests/workspace/testNodesOnly.ecore @@ -0,0 +1,7 @@ + + + + + + + diff --git a/client/tests/workspace/testNodesOnly.enotation b/client/tests/workspace/testNodesOnly.enotation new file mode 100644 index 0000000..27954a3 --- /dev/null +++ b/client/tests/workspace/testNodesOnly.enotation @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/client/tests/workspace/testNodesWithAttributes.ecore b/client/tests/workspace/testNodesWithAttributes.ecore new file mode 100644 index 0000000..4165ef3 --- /dev/null +++ b/client/tests/workspace/testNodesWithAttributes.ecore @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/client/tests/workspace/testNodesWithAttributes.enotation b/client/tests/workspace/testNodesWithAttributes.enotation new file mode 100644 index 0000000..1fb1291 --- /dev/null +++ b/client/tests/workspace/testNodesWithAttributes.enotation @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + +