diff --git a/Sda2/P/JaxRs/Intro/.gitignore b/Sda2/P/JaxRs/Intro/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..b83d22266ac8aa2f8df2edef68082c789727841d --- /dev/null +++ b/Sda2/P/JaxRs/Intro/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/Sda2/P/JaxRs/Intro/README.md b/Sda2/P/JaxRs/Intro/README.md new file mode 100644 index 0000000000000000000000000000000000000000..d1c531f84718653d5713e95e18eedba68265d60e --- /dev/null +++ b/Sda2/P/JaxRs/Intro/README.md @@ -0,0 +1,17 @@ +Your first JAX_RS Client and Server +======================== +This project is a simple example showing usage of @Path, @GET, PUT, POST, and @PathParam. + +System Requirements: +------------------------- +- Maven 3.0.4 or higher + +Building the project: +------------------------- +1. In root directory + +mvn clean install + +This will build a WAR and run it with embedded Jetty + +mvn jetty:run will start jetty separately \ No newline at end of file diff --git a/Sda2/P/JaxRs/Intro/pom.xml b/Sda2/P/JaxRs/Intro/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..dcddbeb4ccf63951552015dfef1da1a1b5791476 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/pom.xml @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + <groupId>de.hdm-stuttgart.mi.sda2</groupId> + <artifactId>jaxrs-intro</artifactId> + <version>2.0</version> + <packaging>war</packaging> + <name>jaxrs-intro</name> + <description/> + + <properties> + <resteasy.version>3.0.10.Final</resteasy.version> + </properties> + + <dependencies> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>resteasy-jaxrs</artifactId> + <version>${resteasy.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>resteasy-client</artifactId> + <version>${resteasy.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>async-http-servlet-3.0</artifactId> + <version>${resteasy.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>jaxrs-api</artifactId> + <version>${resteasy.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>resteasy-servlet-initializer</artifactId> + <version>${resteasy.version}</version> + </dependency> + <dependency> + <groupId>org.jboss.resteasy</groupId> + <artifactId>resteasy-jaxb-provider</artifactId> + <version>${resteasy.version}</version> + </dependency> + <!-- + --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.1</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <finalName>ex03_1</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + <executions> + <execution> + <id>surefire-it</id> + <phase>integration-test</phase> + <goals> + <goal>test</goal> + </goals> + <configuration> + <skip>false</skip> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.mortbay.jetty</groupId> + <artifactId>jetty-maven-plugin</artifactId> + <version>8.1.13.v20130916</version> + <configuration> + <webApp> + <contextPath>/</contextPath> + </webApp> + <scanIntervalSeconds>2</scanIntervalSeconds> + <stopKey>foo</stopKey> + <stopPort>9999</stopPort> + </configuration> + <executions> + <execution> + <id>start-jetty</id> + <phase>pre-integration-test</phase> + <goals> + <goal>run</goal> + </goals> + <configuration> + <scanIntervalSeconds>0</scanIntervalSeconds> + <daemon>true</daemon> + </configuration> + </execution> + <execution> + <id>stop-jetty</id> + <phase>post-integration-test</phase> + <goals> + <goal>stop</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-deploy-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java new file mode 100644 index 0000000000000000000000000000000000000000..ee4c9a351fdb76657ab131c58a980887d7c0fb17 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/domain/Customer.java @@ -0,0 +1,89 @@ +package com.restfully.shop.domain; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class Customer { + + @XmlAttribute + private int id; + + private String + firstName + ,lastName + ,street + ,city + ,state + ,zip + ,country; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java new file mode 100644 index 0000000000000000000000000000000000000000..6232e3886c55cd5703e64f1ca29d2f4eac47aed1 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrint.java @@ -0,0 +1,15 @@ +package com.restfully.shop.helper; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.xml.bind.Marshaller; + +import org.jboss.resteasy.annotations.Decorator; + +@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Decorator(processor = PrettyPrintProcessor.class, target = Marshaller.class) +public @interface PrettyPrint {} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java new file mode 100644 index 0000000000000000000000000000000000000000..e9889352864928a004e7b5b8d92efc35c6b094b5 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/helper/PrettyPrintProcessor.java @@ -0,0 +1,26 @@ +package com.restfully.shop.helper; + +import java.lang.annotation.Annotation; + +import javax.ws.rs.core.MediaType; +import javax.xml.bind.Marshaller; +import javax.xml.bind.PropertyException; + +import org.jboss.resteasy.annotations.DecorateTypes; +import org.jboss.resteasy.spi.interception.DecoratorProcessor; + +@DecorateTypes({ "text/*+xml", "application/*+xml" }) +public class PrettyPrintProcessor implements + DecoratorProcessor<Marshaller, PrettyPrint> { + + public Marshaller decorate(Marshaller target, PrettyPrint annotation, Class type, + Annotation[] annotations, MediaType mediaType) { + try { + target.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + } catch (PropertyException e) { + System.err.println("Unable to activate XML pretty-printing "); + } + return target; + } + +} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java new file mode 100644 index 0000000000000000000000000000000000000000..6e72044842c699e4a9af36ef220b92fafe20f2a4 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/CustomerResource.java @@ -0,0 +1,90 @@ +package com.restfully.shop.services; + +import java.io.InputStream; +import java.net.URI; +import java.util.Collection; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +import org.jboss.resteasy.annotations.providers.jaxb.XmlHeader; + +import com.restfully.shop.domain.Customer; +import com.restfully.shop.helper.PrettyPrint; + +@SuppressWarnings("javadoc") +@Path("/customers") +public class CustomerResource { + + public final static String xsltUrl = "<?xml-stylesheet type='text/xsl' href='/static/customer2html.xsl' ?>"; + + private Map<Integer, Customer> customerDB = new ConcurrentHashMap<Integer, Customer>(); + private AtomicInteger idCounter = new AtomicInteger(); + + public CustomerResource() {} + + @GET + @Produces("application/xml") + @PrettyPrint + @XmlHeader(xsltUrl) + public Collection<Customer> getAllCustomers() { + return customerDB.values(); + } + + @POST + @Consumes("application/xml") + public Response createCustomer(final Customer customer) { + + customer.setId(idCounter.incrementAndGet()); + customerDB.put(customer.getId(), customer); + System.out.println("Created customer " + customer.getId() + ", first name =" + customer.getFirstName() + ", city=" + customer.getCity() ); + return Response.created(URI.create("/customers/" + customer.getId())).build(); + } + + @GET + @Path("{id}") + @Produces("application/xml") + @PrettyPrint + @XmlHeader(xsltUrl) + public Customer getCustomer(@PathParam("id") int id) { + final Customer customer = customerDB.get(id); + if (customer == null) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } else { + return customer; + } + } + + @PUT + @Path("{id}") + @Consumes("application/xml") + public void updateCustomer(@PathParam("id") int id, Customer customer) { + Customer current = customerDB.get(id); + if (current == null) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } else { + customer.setId(current.getId()); + customerDB.put(id, customer); + } + } + + @DELETE + @Path("{id}") + public void deleteCustomer(@PathParam("id") int id, InputStream is) { + final Customer removed = customerDB.remove(id); + if (null == removed) { + throw new WebApplicationException(Response.Status.NOT_FOUND); + } + } +} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..584d1b0010f50628b07a19a6e78ff0af37cad9f1 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/com/restfully/shop/services/ShoppingApplication.java @@ -0,0 +1,20 @@ +package com.restfully.shop.services; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; +import java.util.HashSet; +import java.util.Set; + +@ApplicationPath("/services") +public class ShoppingApplication extends Application { + private Set<Object> singletons = new HashSet<Object>(); + + public ShoppingApplication() { + singletons.add(new CustomerResource()); + } + + @Override + public Set<Object> getSingletons() { + return singletons; + } +} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java b/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java new file mode 100644 index 0000000000000000000000000000000000000000..37dfdf7767887fdceffa32f55398577e9c1b298d --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/DeleteCustomer.java @@ -0,0 +1,29 @@ +package de.hdm_stuttgart.mi.sda2; + +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; + +public class DeleteCustomer { + public static void main(String[] args) throws Exception { + + + Client client = ClientBuilder.newClient(); + try { + + + String location = "http://localhost:8080/services/customers/1"; + System.out.println("Location: " + location); + System.out.println("*** DELETE Customer **"); + Response response = client.target(location).request().delete (); + response.close(); +// System.out.println(deletedCustomer); +// response.close(); + System.out.println("**** After delete ***"); + } finally { + client.close(); + } + + } +} diff --git a/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java b/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java new file mode 100644 index 0000000000000000000000000000000000000000..3bc36d0739697ae228c169cff0bef5c1f95f1fd8 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/java/de/hdm_stuttgart/mi/sda2/MyClient.java @@ -0,0 +1,69 @@ +package de.hdm_stuttgart.mi.sda2; + +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.jboss.resteasy.client.ClientResponse; + +import com.restfully.shop.domain.Customer; + +public class MyClient { + public static void main(String[] args) throws Exception { + + + Client client = ClientBuilder.newClient(); + try { + System.out.println("*** Create a new Customer ***"); + Customer goik = new Customer(); + goik.setFirstName("Martin"); + goik.setLastName("Goik"); + goik.setStreet("Nobelstr. 2"); + goik.setCity("Stuttgart"); + goik.setZip("70589"); + goik.setCountry("Germany"); + + Response response = client.target( + "http://localhost:8080/services/customers") + .request().post(Entity.entity(goik, MediaType.APPLICATION_XML_TYPE)); + + if (response.getStatus() != 201) { + throw new RuntimeException("Failed to create entity"); + } + + final String location = response.getLocation().toString(); + System.out.println("Location: " + location); + response.close(); + + System.out.println("*** GET Created Customer **"); + String customer = client.target(location).request().get(String.class); + System.out.println(customer); + + // Update record + goik.setLastName("Wurm"); + + System.out.println("Client side: update first name =" + goik.getFirstName()); + + response = client.target(location) + .request() + .put(Entity.entity(goik, MediaType.APPLICATION_XML_TYPE)); + + if (response.getStatus() != 204) + throw new RuntimeException("Failed to update"); + response.close(); + System.out.println("**** After Update ***"); + customer = client.target(location).request().get(String.class); + System.out.println(customer); + + //Get all Customers + String customerList = client.target("http://localhost:8080/services/customers").request().get(String.class); + System.out.println("Customers:\n" + customerList); + + } finally { + client.close(); + } + + } +} diff --git a/Sda2/P/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml b/Sda2/P/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000000000000000000000000000000000..0f80d8e06873639f7a5ab9edf47633729de09e58 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<web-app xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" + version="3.0"> +</web-app> diff --git a/Sda2/P/JaxRs/Intro/src/main/webapp/static/customer2html.xsl b/Sda2/P/JaxRs/Intro/src/main/webapp/static/customer2html.xsl new file mode 100644 index 0000000000000000000000000000000000000000..7732aef21903f621009b52f4051448456c76e2a7 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/main/webapp/static/customer2html.xsl @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + exclude-result-prefixes="xs" + version="2.0"> + + <xsl:template match="/"> + <html> + <head> + <title>JAX-RS example</title> + </head> + <body> + <xsl:apply-templates select="*"/> + + </body> + </html> + + </xsl:template> + + <xsl:template match="collection"> + <ul> + <xsl:apply-templates select="*"/> + </ul> + </xsl:template> + + + <xsl:template match="customer"> + <li> + <p> + <xsl:value-of select="firstName"/> + <xsl:text> </xsl:text> + <em><xsl:value-of select="lastName"/></em> + </p> + <p><xsl:value-of select="street"/></p> + <p> + <xsl:value-of select="zip"/> + <xsl:text> </xsl:text> + <em><xsl:value-of select="city"/></em> + </p> + </li> + </xsl:template> + + + + + <xsl:template match="*"> + <p> + <xsl:text>Error: No template matches lement '</xsl:text> + <xsl:value-of select="name(.)"/> + <xsl:text>'</xsl:text> + </p> + </xsl:template> + +</xsl:stylesheet> \ No newline at end of file diff --git a/Sda2/P/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java b/Sda2/P/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..21866f4d89d249f8923ff8e49bc48f85c5c2d5b5 --- /dev/null +++ b/Sda2/P/JaxRs/Intro/src/test/java/com/restfully/shop/test/CustomerResourceTest.java @@ -0,0 +1,64 @@ +package com.restfully.shop.test; + +import org.junit.Test; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.Response; + + +/** + * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> + * @version $Revision: 1 $ + */ +public class CustomerResourceTest +{ + @Test + public void testCustomerResource() throws Exception + { + Client client = ClientBuilder.newClient(); + try { + System.out.println("*** Create a new Customer ***"); + + String xml = "<customer>" + + "<first-name>Bill</first-name>" + + "<last-name>Burke</last-name>" + + "<street>256 Clarendon Street</street>" + + "<city>Boston</city>" + + "<state>MA</state>" + + "<zip>02115</zip>" + + "<country>USA</country>" + + "</customer>"; + + Response response = client.target("http://localhost:8080/services/customers") + .request().post(Entity.xml(xml)); + if (response.getStatus() != 201) throw new RuntimeException("Failed to create"); + String location = response.getLocation().toString(); + System.out.println("Location: " + location); + response.close(); + + System.out.println("*** GET Created Customer **"); + String customer = client.target(location).request().get(String.class); + System.out.println(customer); + + String updateCustomer = "<customer>" + + "<first-name>William</first-name>" + + "<last-name>Burke</last-name>" + + "<street>256 Clarendon Street</street>" + + "<city>Boston</city>" + + "<state>MA</state>" + + "<zip>02115</zip>" + + "<country>USA</country>" + + "</customer>"; + response = client.target(location).request().put(Entity.xml(updateCustomer)); + if (response.getStatus() != 204) throw new RuntimeException("Failed to update"); + response.close(); + System.out.println("**** After Update ***"); + customer = client.target(location).request().get(String.class); + System.out.println(customer); + } finally { + client.close(); + } + } +} diff --git a/Sda2/Ref/Fig/jaxRs.svg b/Sda2/Ref/Fig/jaxRs.svg new file mode 100644 index 0000000000000000000000000000000000000000..c47cb8f0688b773ada77343931e2ec145dab032a --- /dev/null +++ b/Sda2/Ref/Fig/jaxRs.svg @@ -0,0 +1,4721 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:ns1="https://launchpad.net/jessyink" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="1052.3622" + height="744.09448" + id="svg2" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="jaxRs.svg"> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="1.3667619" + inkscape:cx="464.77167" + inkscape:cy="222.75083" + inkscape:document-units="px" + inkscape:current-layer="layer2" + showgrid="true" + inkscape:window-width="1600" + inkscape:window-height="1176" + inkscape:window-x="0" + inkscape:window-y="24" + inkscape:window-maximized="1" + inkscape:snap-global="true" + showguides="true" + inkscape:guide-bbox="true" + inkscape:snap-grids="true"> + <inkscape:grid + type="xygrid" + id="grid5239" + empspacing="5" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" /> + <sodipodi:guide + orientation="0,1" + position="680,750" + id="guide3149" /> + </sodipodi:namedview> + <defs + id="defs4"> + <marker + style="overflow:visible" + id="EmptyTriangleOutL" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="EmptyTriangleOutL"> + <path + transform="scale(0.8) translate(-6,0)" + style="fill-rule:evenodd;fill:#FFFFFF;stroke:#000000;stroke-width:1.0pt" + d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " + id="path4949" /> + </marker> + <marker + style="overflow:visible" + id="EmptyTriangleInL" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="EmptyTriangleInL"> + <path + transform="scale(-0.8) translate(-6,0)" + style="fill-rule:evenodd;fill:#FFFFFF;stroke:#000000;stroke-width:1.0pt" + d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " + id="path4940" /> + </marker> + <marker + inkscape:stockid="DotM" + orient="auto" + refY="0.0" + refX="0.0" + id="DotM" + style="overflow:visible"> + <path + id="path4359" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mend" + style="overflow:visible;"> + <path + id="path5023" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" + transform="scale(0.4) rotate(180) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mstart" + style="overflow:visible"> + <path + id="path5020" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt" + transform="scale(0.4) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lend" + style="overflow:visible;"> + <path + id="path5017" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + id="path5014" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mstart-8" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5020-3" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-2" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-9" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mstart-4" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5020-1" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-22" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-1" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mstart" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mstart-6" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5020-8" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMo" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMo" + style="overflow:visible"> + <path + id="path5187" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#d40000;stroke-width:1.0pt;fill:#d40000;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6o" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6o" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5190" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#d40000;stroke-width:1pt;fill:#d40000;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMo1" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMo1" + style="overflow:visible"> + <path + id="path6031" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;fill:#000000" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6n" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6n" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6034" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#000000;stroke-width:1pt;fill:#000000;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMoc" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMoc" + style="overflow:visible"> + <path + id="path6037" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;fill:#000000" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6F" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6F" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6040" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#000000;stroke-width:1pt;fill:#000000;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMocK" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMocK" + style="overflow:visible"> + <path + id="path6279" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#000000;stroke-width:1.0pt;fill:#000000;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6Fa" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6Fa" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6282" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;fill:#000000" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMo17" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMo17" + style="overflow:visible"> + <path + id="path6529" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#d40000;stroke-width:1.0pt;fill:#d40000;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6nl" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6nl" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6532" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#d40000;stroke-width:1pt;fill:#d40000" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMocKE" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMocKE" + style="overflow:visible"> + <path + id="path6535" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#d40000;stroke-width:1.0pt;fill:#d40000" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FaK" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FaK" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6538" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#d40000;stroke-width:1pt;fill:#d40000;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5-4" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <inkscape:perspective + id="perspective2492" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective3257" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + id="perspective2425" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2410" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective2459" /> + <inkscape:perspective + id="perspective8826" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_x="0 : 526.18109 : 1" + sodipodi:type="inkscape:persp3d" /> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 526.18109 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="744.09448 : 526.18109 : 1" + inkscape:persp3d-origin="372.04724 : 350.78739 : 1" + id="perspective10" /> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMQ" + style="overflow:visible"> + <path + id="path5711" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#008000;stroke-width:1.0pt;fill:#008000;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#008000;stroke-width:1pt;fill:#008000" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-9" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-3" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-6" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-3" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <linearGradient + id="linearGradient11067"> + <stop + id="stop11069" + offset="0" + style="stop-color:#e9fffb;stop-opacity:0.91774893;" /> + <stop + id="stop11071" + offset="1" + style="stop-color:#72dac5;stop-opacity:0;" /> + </linearGradient> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-1" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-9" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-5" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-5" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-2" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-1" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-0" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-8" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-56" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-1" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-8" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-87" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-4" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-55" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-9" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-4" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-26" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-2" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-7" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-2" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-27" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-7" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-82" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-25" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-3" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5711-27" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-95" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-6" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <g + id="g6072"> + <symbol + id="glyph0-0" + overflow="visible"> + <path + id="path6075" + d="M 5.5 -6.546875 C 5.546875 -6.65625 5.546875 -6.671875 5.546875 -6.71875 C 5.546875 -6.8125 5.46875 -6.921875 5.34375 -6.921875 C 5.21875 -6.921875 5.15625 -6.796875 5.109375 -6.6875 L 4.28125 -4.5 L 1.25 -4.5 L 0.421875 -6.6875 C 0.375 -6.828125 0.328125 -6.921875 0.203125 -6.921875 C 0.09375 -6.921875 0 -6.8125 0 -6.71875 C 0 -6.703125 0 -6.671875 0.0625 -6.546875 L 2.546875 -0.015625 C 2.59375 0.125 2.640625 0.21875 2.765625 0.21875 C 2.90625 0.21875 2.953125 0.109375 2.984375 0.015625 Z M 1.421875 -4.09375 L 4.125 -4.09375 L 2.765625 -0.546875 Z M 1.421875 -4.09375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-1" + overflow="visible"> + <path + id="path6078" + d="M 3.546875 -5.75 C 3.46875 -5.921875 3.40625 -5.96875 3.3125 -5.96875 C 3.1875 -5.96875 3.15625 -5.890625 3.09375 -5.75 L 0.625 -0.171875 C 0.5625 -0.046875 0.546875 -0.03125 0.546875 0.015625 C 0.546875 0.125 0.640625 0.21875 0.75 0.21875 C 0.8125 0.21875 0.890625 0.203125 0.984375 0.015625 L 3.3125 -5.28125 L 5.65625 0.015625 C 5.75 0.21875 5.859375 0.21875 5.890625 0.21875 C 6 0.21875 6.09375 0.125 6.09375 0.015625 C 6.09375 0 6.09375 -0.015625 6.03125 -0.140625 Z M 3.546875 -5.75 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-2" + overflow="visible"> + <path + id="path6081" + d="M 7.234375 -3.265625 C 7.65625 -2.90625 8.171875 -2.640625 8.5 -2.5 C 8.140625 -2.328125 7.640625 -2.078125 7.234375 -1.71875 L 0.90625 -1.71875 C 0.734375 -1.71875 0.546875 -1.71875 0.546875 -1.53125 C 0.546875 -1.328125 0.734375 -1.328125 0.890625 -1.328125 L 6.78125 -1.328125 C 6.3125 -0.875 5.796875 0.015625 5.796875 0.140625 C 5.796875 0.25 5.921875 0.25 5.984375 0.25 C 6.0625 0.25 6.125 0.25 6.171875 0.171875 C 6.375 -0.203125 6.65625 -0.734375 7.3125 -1.3125 C 8 -1.921875 8.65625 -2.1875 9.1875 -2.34375 C 9.34375 -2.40625 9.359375 -2.40625 9.375 -2.4375 C 9.40625 -2.4375 9.40625 -2.46875 9.40625 -2.5 C 9.40625 -2.515625 9.40625 -2.53125 9.390625 -2.546875 L 9.359375 -2.578125 C 9.34375 -2.578125 9.328125 -2.59375 9.140625 -2.65625 C 7.796875 -3.046875 6.796875 -3.953125 6.234375 -5.03125 C 6.125 -5.21875 6.125 -5.234375 5.984375 -5.234375 C 5.921875 -5.234375 5.796875 -5.234375 5.796875 -5.125 C 5.796875 -5 6.296875 -4.125 6.78125 -3.65625 L 0.890625 -3.65625 C 0.734375 -3.65625 0.546875 -3.65625 0.546875 -3.453125 C 0.546875 -3.265625 0.734375 -3.265625 0.90625 -3.265625 Z M 7.234375 -3.265625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-0" + overflow="visible"> + <path + id="path6084" + d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-1" + overflow="visible"> + <path + id="path6087" + d="M 1.46875 -0.109375 C 1.46875 0.265625 1.40625 0.71875 0.921875 1.15625 C 0.90625 1.1875 0.875 1.21875 0.875 1.25 C 0.875 1.296875 0.9375 1.34375 0.96875 1.34375 C 1.078125 1.34375 1.671875 0.78125 1.671875 -0.046875 C 1.671875 -0.46875 1.5 -0.796875 1.171875 -0.796875 C 0.953125 -0.796875 0.78125 -0.625 0.78125 -0.40625 C 0.78125 -0.1875 0.9375 0 1.1875 0 C 1.359375 0 1.46875 -0.109375 1.46875 -0.109375 Z M 1.46875 -0.109375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-2" + overflow="visible"> + <path + id="path6090" + d="M 3.0625 -4.359375 C 3.0625 -4.46875 2.96875 -4.625 2.78125 -4.625 C 2.578125 -4.625 2.390625 -4.421875 2.390625 -4.234375 C 2.390625 -4.125 2.46875 -3.96875 2.671875 -3.96875 C 2.859375 -3.96875 3.0625 -4.15625 3.0625 -4.359375 Z M 1.578125 0.34375 C 1.46875 0.828125 1.09375 1.21875 0.6875 1.21875 C 0.59375 1.21875 0.515625 1.21875 0.4375 1.1875 C 0.609375 1.09375 0.671875 0.9375 0.671875 0.828125 C 0.671875 0.65625 0.53125 0.578125 0.390625 0.578125 C 0.1875 0.578125 0 0.765625 0 0.984375 C 0 1.25 0.265625 1.421875 0.6875 1.421875 C 1.109375 1.421875 1.921875 1.171875 2.140625 0.328125 L 2.765625 -2.171875 C 2.78125 -2.25 2.796875 -2.3125 2.796875 -2.421875 C 2.796875 -2.796875 2.46875 -3.078125 2.0625 -3.078125 C 1.28125 -3.078125 0.84375 -2.109375 0.84375 -2 C 0.84375 -1.921875 0.9375 -1.921875 0.953125 -1.921875 C 1.03125 -1.921875 1.046875 -1.9375 1.09375 -2.046875 C 1.265625 -2.453125 1.625 -2.875 2.03125 -2.875 C 2.203125 -2.875 2.265625 -2.765625 2.265625 -2.53125 C 2.265625 -2.453125 2.265625 -2.359375 2.25 -2.328125 Z M 1.578125 0.34375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-0" + overflow="visible"> + <path + id="path6093" + d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-1" + overflow="visible"> + <path + id="path6096" + d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375 -3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-0" + overflow="visible"> + <path + id="path6099" + d="M 2.375 -6.8125 C 2.375 -6.8125 2.375 -6.921875 2.25 -6.921875 C 2.03125 -6.921875 1.296875 -6.84375 1.03125 -6.8125 C 0.953125 -6.8125 0.84375 -6.796875 0.84375 -6.625 C 0.84375 -6.5 0.9375 -6.5 1.09375 -6.5 C 1.5625 -6.5 1.578125 -6.4375 1.578125 -6.328125 C 1.578125 -6.265625 1.5 -5.921875 1.453125 -5.71875 L 0.625 -2.46875 C 0.515625 -1.96875 0.46875 -1.796875 0.46875 -1.453125 C 0.46875 -0.515625 1 0.109375 1.734375 0.109375 C 2.90625 0.109375 4.140625 -1.375 4.140625 -2.8125 C 4.140625 -3.71875 3.609375 -4.40625 2.8125 -4.40625 C 2.359375 -4.40625 1.9375 -4.109375 1.640625 -3.8125 Z M 1.453125 -3.046875 C 1.5 -3.265625 1.5 -3.28125 1.59375 -3.390625 C 2.078125 -4.03125 2.53125 -4.1875 2.796875 -4.1875 C 3.15625 -4.1875 3.421875 -3.890625 3.421875 -3.25 C 3.421875 -2.65625 3.09375 -1.515625 2.90625 -1.140625 C 2.578125 -0.46875 2.125 -0.109375 1.734375 -0.109375 C 1.390625 -0.109375 1.0625 -0.375 1.0625 -1.109375 C 1.0625 -1.3125 1.0625 -1.5 1.21875 -2.125 Z M 1.453125 -3.046875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-1" + overflow="visible"> + <path + id="path6102" + d="M 3.953125 -3.78125 C 3.78125 -3.78125 3.65625 -3.78125 3.515625 -3.65625 C 3.34375 -3.5 3.328125 -3.328125 3.328125 -3.265625 C 3.328125 -3.015625 3.515625 -2.90625 3.703125 -2.90625 C 3.984375 -2.90625 4.25 -3.15625 4.25 -3.546875 C 4.25 -4.03125 3.78125 -4.40625 3.078125 -4.40625 C 1.734375 -4.40625 0.40625 -2.984375 0.40625 -1.578125 C 0.40625 -0.671875 0.984375 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.421875 -0.109375 1.140625 -0.59375 1.140625 -1.203125 C 1.140625 -1.609375 1.34375 -2.578125 1.6875 -3.1875 C 2 -3.765625 2.546875 -4.1875 3.09375 -4.1875 C 3.421875 -4.1875 3.8125 -4.0625 3.953125 -3.78125 Z M 3.953125 -3.78125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-2" + overflow="visible"> + <path + id="path6105" + d="M 3.71875 -3.765625 C 3.53125 -4.140625 3.25 -4.40625 2.796875 -4.40625 C 1.640625 -4.40625 0.40625 -2.9375 0.40625 -1.484375 C 0.40625 -0.546875 0.953125 0.109375 1.71875 0.109375 C 1.921875 0.109375 2.421875 0.0625 3.015625 -0.640625 C 3.09375 -0.21875 3.453125 0.109375 3.921875 0.109375 C 4.28125 0.109375 4.5 -0.125 4.671875 -0.4375 C 4.828125 -0.796875 4.96875 -1.40625 4.96875 -1.421875 C 4.96875 -1.53125 4.875 -1.53125 4.84375 -1.53125 C 4.75 -1.53125 4.734375 -1.484375 4.703125 -1.34375 C 4.53125 -0.703125 4.359375 -0.109375 3.953125 -0.109375 C 3.671875 -0.109375 3.65625 -0.375 3.65625 -0.5625 C 3.65625 -0.78125 3.671875 -0.875 3.78125 -1.3125 C 3.890625 -1.71875 3.90625 -1.828125 4 -2.203125 L 4.359375 -3.59375 C 4.421875 -3.875 4.421875 -3.890625 4.421875 -3.9375 C 4.421875 -4.109375 4.3125 -4.203125 4.140625 -4.203125 C 3.890625 -4.203125 3.75 -3.984375 3.71875 -3.765625 Z M 3.078125 -1.1875 C 3.015625 -1 3.015625 -0.984375 2.875 -0.8125 C 2.4375 -0.265625 2.03125 -0.109375 1.75 -0.109375 C 1.25 -0.109375 1.109375 -0.65625 1.109375 -1.046875 C 1.109375 -1.546875 1.421875 -2.765625 1.65625 -3.234375 C 1.96875 -3.8125 2.40625 -4.1875 2.8125 -4.1875 C 3.453125 -4.1875 3.59375 -3.375 3.59375 -3.3125 C 3.59375 -3.25 3.578125 -3.1875 3.5625 -3.140625 Z M 3.078125 -1.1875 " + style="stroke:none;" /> + </symbol> + </g> + <g + id="g6444"> + <symbol + id="glyph0-0-6" + overflow="visible"> + <path + id="path6447" + d="M 5.5 -6.546875 C 5.546875 -6.65625 5.546875 -6.671875 5.546875 -6.71875 C 5.546875 -6.8125 5.46875 -6.921875 5.34375 -6.921875 C 5.21875 -6.921875 5.15625 -6.796875 5.109375 -6.6875 L 4.28125 -4.5 L 1.25 -4.5 L 0.421875 -6.6875 C 0.375 -6.828125 0.328125 -6.921875 0.203125 -6.921875 C 0.09375 -6.921875 0 -6.8125 0 -6.71875 C 0 -6.703125 0 -6.671875 0.0625 -6.546875 L 2.546875 -0.015625 C 2.59375 0.125 2.640625 0.21875 2.765625 0.21875 C 2.90625 0.21875 2.953125 0.109375 2.984375 0.015625 Z M 1.421875 -4.09375 L 4.125 -4.09375 L 2.765625 -0.546875 Z M 1.421875 -4.09375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-1-9" + overflow="visible"> + <path + id="path6450" + d="M 3.546875 -5.75 C 3.46875 -5.921875 3.40625 -5.96875 3.3125 -5.96875 C 3.1875 -5.96875 3.15625 -5.890625 3.09375 -5.75 L 0.625 -0.171875 C 0.5625 -0.046875 0.546875 -0.03125 0.546875 0.015625 C 0.546875 0.125 0.640625 0.21875 0.75 0.21875 C 0.8125 0.21875 0.890625 0.203125 0.984375 0.015625 L 3.3125 -5.28125 L 5.65625 0.015625 C 5.75 0.21875 5.859375 0.21875 5.890625 0.21875 C 6 0.21875 6.09375 0.125 6.09375 0.015625 C 6.09375 0 6.09375 -0.015625 6.03125 -0.140625 Z M 3.546875 -5.75 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-2-9" + overflow="visible"> + <path + id="path6453" + d="M 7.234375 -3.265625 C 7.65625 -2.90625 8.171875 -2.640625 8.5 -2.5 C 8.140625 -2.328125 7.640625 -2.078125 7.234375 -1.71875 L 0.90625 -1.71875 C 0.734375 -1.71875 0.546875 -1.71875 0.546875 -1.53125 C 0.546875 -1.328125 0.734375 -1.328125 0.890625 -1.328125 L 6.78125 -1.328125 C 6.3125 -0.875 5.796875 0.015625 5.796875 0.140625 C 5.796875 0.25 5.921875 0.25 5.984375 0.25 C 6.0625 0.25 6.125 0.25 6.171875 0.171875 C 6.375 -0.203125 6.65625 -0.734375 7.3125 -1.3125 C 8 -1.921875 8.65625 -2.1875 9.1875 -2.34375 C 9.34375 -2.40625 9.359375 -2.40625 9.375 -2.4375 C 9.40625 -2.4375 9.40625 -2.46875 9.40625 -2.5 C 9.40625 -2.515625 9.40625 -2.53125 9.390625 -2.546875 L 9.359375 -2.578125 C 9.34375 -2.578125 9.328125 -2.59375 9.140625 -2.65625 C 7.796875 -3.046875 6.796875 -3.953125 6.234375 -5.03125 C 6.125 -5.21875 6.125 -5.234375 5.984375 -5.234375 C 5.921875 -5.234375 5.796875 -5.234375 5.796875 -5.125 C 5.796875 -5 6.296875 -4.125 6.78125 -3.65625 L 0.890625 -3.65625 C 0.734375 -3.65625 0.546875 -3.65625 0.546875 -3.453125 C 0.546875 -3.265625 0.734375 -3.265625 0.90625 -3.265625 Z M 7.234375 -3.265625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-0-9" + overflow="visible"> + <path + id="path6456" + d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-1-3" + overflow="visible"> + <path + id="path6459" + d="M 1.46875 -0.109375 C 1.46875 0.265625 1.40625 0.71875 0.921875 1.15625 C 0.90625 1.1875 0.875 1.21875 0.875 1.25 C 0.875 1.296875 0.9375 1.34375 0.96875 1.34375 C 1.078125 1.34375 1.671875 0.78125 1.671875 -0.046875 C 1.671875 -0.46875 1.5 -0.796875 1.171875 -0.796875 C 0.953125 -0.796875 0.78125 -0.625 0.78125 -0.40625 C 0.78125 -0.1875 0.9375 0 1.1875 0 C 1.359375 0 1.46875 -0.109375 1.46875 -0.109375 Z M 1.46875 -0.109375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-2-9" + overflow="visible"> + <path + id="path6462" + d="M 3.0625 -4.359375 C 3.0625 -4.46875 2.96875 -4.625 2.78125 -4.625 C 2.578125 -4.625 2.390625 -4.421875 2.390625 -4.234375 C 2.390625 -4.125 2.46875 -3.96875 2.671875 -3.96875 C 2.859375 -3.96875 3.0625 -4.15625 3.0625 -4.359375 Z M 1.578125 0.34375 C 1.46875 0.828125 1.09375 1.21875 0.6875 1.21875 C 0.59375 1.21875 0.515625 1.21875 0.4375 1.1875 C 0.609375 1.09375 0.671875 0.9375 0.671875 0.828125 C 0.671875 0.65625 0.53125 0.578125 0.390625 0.578125 C 0.1875 0.578125 0 0.765625 0 0.984375 C 0 1.25 0.265625 1.421875 0.6875 1.421875 C 1.109375 1.421875 1.921875 1.171875 2.140625 0.328125 L 2.765625 -2.171875 C 2.78125 -2.25 2.796875 -2.3125 2.796875 -2.421875 C 2.796875 -2.796875 2.46875 -3.078125 2.0625 -3.078125 C 1.28125 -3.078125 0.84375 -2.109375 0.84375 -2 C 0.84375 -1.921875 0.9375 -1.921875 0.953125 -1.921875 C 1.03125 -1.921875 1.046875 -1.9375 1.09375 -2.046875 C 1.265625 -2.453125 1.625 -2.875 2.03125 -2.875 C 2.203125 -2.875 2.265625 -2.765625 2.265625 -2.53125 C 2.265625 -2.453125 2.265625 -2.359375 2.25 -2.328125 Z M 1.578125 0.34375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-0-7" + overflow="visible"> + <path + id="path6465" + d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-1-6" + overflow="visible"> + <path + id="path6468" + d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375 -3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-0-5" + overflow="visible"> + <path + id="path6471" + d="M 2.375 -6.8125 C 2.375 -6.8125 2.375 -6.921875 2.25 -6.921875 C 2.03125 -6.921875 1.296875 -6.84375 1.03125 -6.8125 C 0.953125 -6.8125 0.84375 -6.796875 0.84375 -6.625 C 0.84375 -6.5 0.9375 -6.5 1.09375 -6.5 C 1.5625 -6.5 1.578125 -6.4375 1.578125 -6.328125 C 1.578125 -6.265625 1.5 -5.921875 1.453125 -5.71875 L 0.625 -2.46875 C 0.515625 -1.96875 0.46875 -1.796875 0.46875 -1.453125 C 0.46875 -0.515625 1 0.109375 1.734375 0.109375 C 2.90625 0.109375 4.140625 -1.375 4.140625 -2.8125 C 4.140625 -3.71875 3.609375 -4.40625 2.8125 -4.40625 C 2.359375 -4.40625 1.9375 -4.109375 1.640625 -3.8125 Z M 1.453125 -3.046875 C 1.5 -3.265625 1.5 -3.28125 1.59375 -3.390625 C 2.078125 -4.03125 2.53125 -4.1875 2.796875 -4.1875 C 3.15625 -4.1875 3.421875 -3.890625 3.421875 -3.25 C 3.421875 -2.65625 3.09375 -1.515625 2.90625 -1.140625 C 2.578125 -0.46875 2.125 -0.109375 1.734375 -0.109375 C 1.390625 -0.109375 1.0625 -0.375 1.0625 -1.109375 C 1.0625 -1.3125 1.0625 -1.5 1.21875 -2.125 Z M 1.453125 -3.046875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-1-1" + overflow="visible"> + <path + id="path6474" + d="M 3.953125 -3.78125 C 3.78125 -3.78125 3.65625 -3.78125 3.515625 -3.65625 C 3.34375 -3.5 3.328125 -3.328125 3.328125 -3.265625 C 3.328125 -3.015625 3.515625 -2.90625 3.703125 -2.90625 C 3.984375 -2.90625 4.25 -3.15625 4.25 -3.546875 C 4.25 -4.03125 3.78125 -4.40625 3.078125 -4.40625 C 1.734375 -4.40625 0.40625 -2.984375 0.40625 -1.578125 C 0.40625 -0.671875 0.984375 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.421875 -0.109375 1.140625 -0.59375 1.140625 -1.203125 C 1.140625 -1.609375 1.34375 -2.578125 1.6875 -3.1875 C 2 -3.765625 2.546875 -4.1875 3.09375 -4.1875 C 3.421875 -4.1875 3.8125 -4.0625 3.953125 -3.78125 Z M 3.953125 -3.78125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-2-3" + overflow="visible"> + <path + id="path6477" + d="M 3.71875 -3.765625 C 3.53125 -4.140625 3.25 -4.40625 2.796875 -4.40625 C 1.640625 -4.40625 0.40625 -2.9375 0.40625 -1.484375 C 0.40625 -0.546875 0.953125 0.109375 1.71875 0.109375 C 1.921875 0.109375 2.421875 0.0625 3.015625 -0.640625 C 3.09375 -0.21875 3.453125 0.109375 3.921875 0.109375 C 4.28125 0.109375 4.5 -0.125 4.671875 -0.4375 C 4.828125 -0.796875 4.96875 -1.40625 4.96875 -1.421875 C 4.96875 -1.53125 4.875 -1.53125 4.84375 -1.53125 C 4.75 -1.53125 4.734375 -1.484375 4.703125 -1.34375 C 4.53125 -0.703125 4.359375 -0.109375 3.953125 -0.109375 C 3.671875 -0.109375 3.65625 -0.375 3.65625 -0.5625 C 3.65625 -0.78125 3.671875 -0.875 3.78125 -1.3125 C 3.890625 -1.71875 3.90625 -1.828125 4 -2.203125 L 4.359375 -3.59375 C 4.421875 -3.875 4.421875 -3.890625 4.421875 -3.9375 C 4.421875 -4.109375 4.3125 -4.203125 4.140625 -4.203125 C 3.890625 -4.203125 3.75 -3.984375 3.71875 -3.765625 Z M 3.078125 -1.1875 C 3.015625 -1 3.015625 -0.984375 2.875 -0.8125 C 2.4375 -0.265625 2.03125 -0.109375 1.75 -0.109375 C 1.25 -0.109375 1.109375 -0.65625 1.109375 -1.046875 C 1.109375 -1.546875 1.421875 -2.765625 1.65625 -3.234375 C 1.96875 -3.8125 2.40625 -4.1875 2.8125 -4.1875 C 3.453125 -4.1875 3.59375 -3.375 3.59375 -3.3125 C 3.59375 -3.25 3.578125 -3.1875 3.5625 -3.140625 Z M 3.078125 -1.1875 " + style="stroke:none;" /> + </symbol> + </g> + <g + id="g7052"> + <symbol + id="glyph0-0-2" + overflow="visible"> + <path + id="path7055" + d="M 3.71875 -3.765625 C 3.53125 -4.140625 3.25 -4.40625 2.796875 -4.40625 C 1.640625 -4.40625 0.40625 -2.9375 0.40625 -1.484375 C 0.40625 -0.546875 0.953125 0.109375 1.71875 0.109375 C 1.921875 0.109375 2.421875 0.0625 3.015625 -0.640625 C 3.09375 -0.21875 3.453125 0.109375 3.921875 0.109375 C 4.28125 0.109375 4.5 -0.125 4.671875 -0.4375 C 4.828125 -0.796875 4.96875 -1.40625 4.96875 -1.421875 C 4.96875 -1.53125 4.875 -1.53125 4.84375 -1.53125 C 4.75 -1.53125 4.734375 -1.484375 4.703125 -1.34375 C 4.53125 -0.703125 4.359375 -0.109375 3.953125 -0.109375 C 3.671875 -0.109375 3.65625 -0.375 3.65625 -0.5625 C 3.65625 -0.78125 3.671875 -0.875 3.78125 -1.3125 C 3.890625 -1.71875 3.90625 -1.828125 4 -2.203125 L 4.359375 -3.59375 C 4.421875 -3.875 4.421875 -3.890625 4.421875 -3.9375 C 4.421875 -4.109375 4.3125 -4.203125 4.140625 -4.203125 C 3.890625 -4.203125 3.75 -3.984375 3.71875 -3.765625 Z M 3.078125 -1.1875 C 3.015625 -1 3.015625 -0.984375 2.875 -0.8125 C 2.4375 -0.265625 2.03125 -0.109375 1.75 -0.109375 C 1.25 -0.109375 1.109375 -0.65625 1.109375 -1.046875 C 1.109375 -1.546875 1.421875 -2.765625 1.65625 -3.234375 C 1.96875 -3.8125 2.40625 -4.1875 2.8125 -4.1875 C 3.453125 -4.1875 3.59375 -3.375 3.59375 -3.3125 C 3.59375 -3.25 3.578125 -3.1875 3.5625 -3.140625 Z M 3.078125 -1.1875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-1-96" + overflow="visible"> + <path + id="path7058" + d="M 2.375 -6.8125 C 2.375 -6.8125 2.375 -6.921875 2.25 -6.921875 C 2.03125 -6.921875 1.296875 -6.84375 1.03125 -6.8125 C 0.953125 -6.8125 0.84375 -6.796875 0.84375 -6.625 C 0.84375 -6.5 0.9375 -6.5 1.09375 -6.5 C 1.5625 -6.5 1.578125 -6.4375 1.578125 -6.328125 C 1.578125 -6.265625 1.5 -5.921875 1.453125 -5.71875 L 0.625 -2.46875 C 0.515625 -1.96875 0.46875 -1.796875 0.46875 -1.453125 C 0.46875 -0.515625 1 0.109375 1.734375 0.109375 C 2.90625 0.109375 4.140625 -1.375 4.140625 -2.8125 C 4.140625 -3.71875 3.609375 -4.40625 2.8125 -4.40625 C 2.359375 -4.40625 1.9375 -4.109375 1.640625 -3.8125 Z M 1.453125 -3.046875 C 1.5 -3.265625 1.5 -3.28125 1.59375 -3.390625 C 2.078125 -4.03125 2.53125 -4.1875 2.796875 -4.1875 C 3.15625 -4.1875 3.421875 -3.890625 3.421875 -3.25 C 3.421875 -2.65625 3.09375 -1.515625 2.90625 -1.140625 C 2.578125 -0.46875 2.125 -0.109375 1.734375 -0.109375 C 1.390625 -0.109375 1.0625 -0.375 1.0625 -1.109375 C 1.0625 -1.3125 1.0625 -1.5 1.21875 -2.125 Z M 1.453125 -3.046875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-2-6" + overflow="visible"> + <path + id="path7061" + d="M 2.03125 -0.015625 C 2.03125 -0.671875 1.78125 -1.0625 1.390625 -1.0625 C 1.0625 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.265625 1.0625 0 1.390625 0 C 1.5 0 1.640625 -0.046875 1.734375 -0.125 C 1.765625 -0.15625 1.78125 -0.15625 1.78125 -0.15625 C 1.796875 -0.15625 1.796875 -0.15625 1.796875 -0.015625 C 1.796875 0.734375 1.453125 1.328125 1.125 1.65625 C 1.015625 1.765625 1.015625 1.78125 1.015625 1.8125 C 1.015625 1.890625 1.0625 1.921875 1.109375 1.921875 C 1.21875 1.921875 2.03125 1.15625 2.03125 -0.015625 Z M 2.03125 -0.015625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-3" + overflow="visible"> + <path + id="path7064" + d="M 3.953125 -3.78125 C 3.78125 -3.78125 3.65625 -3.78125 3.515625 -3.65625 C 3.34375 -3.5 3.328125 -3.328125 3.328125 -3.265625 C 3.328125 -3.015625 3.515625 -2.90625 3.703125 -2.90625 C 3.984375 -2.90625 4.25 -3.15625 4.25 -3.546875 C 4.25 -4.03125 3.78125 -4.40625 3.078125 -4.40625 C 1.734375 -4.40625 0.40625 -2.984375 0.40625 -1.578125 C 0.40625 -0.671875 0.984375 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.421875 -0.109375 1.140625 -0.59375 1.140625 -1.203125 C 1.140625 -1.609375 1.34375 -2.578125 1.6875 -3.1875 C 2 -3.765625 2.546875 -4.1875 3.09375 -4.1875 C 3.421875 -4.1875 3.8125 -4.0625 3.953125 -3.78125 Z M 3.953125 -3.78125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-0-6" + overflow="visible"> + <path + id="path7067" + d="M 8.3125 -2.296875 C 7.765625 -1.875 7.5 -1.46875 7.421875 -1.328125 C 6.96875 -0.640625 6.890625 -0.015625 6.890625 -0.015625 C 6.890625 0.109375 7.015625 0.109375 7.09375 0.109375 C 7.25 0.109375 7.265625 0.09375 7.3125 -0.09375 C 7.53125 -1.0625 8.125 -1.90625 9.25 -2.359375 C 9.375 -2.40625 9.40625 -2.421875 9.40625 -2.5 C 9.40625 -2.5625 9.34375 -2.59375 9.328125 -2.609375 C 8.875 -2.765625 7.671875 -3.265625 7.296875 -4.9375 C 7.265625 -5.0625 7.25 -5.09375 7.09375 -5.09375 C 7.015625 -5.09375 6.890625 -5.09375 6.890625 -4.96875 C 6.890625 -4.953125 6.984375 -4.328125 7.390625 -3.65625 C 7.59375 -3.359375 7.890625 -3.015625 8.3125 -2.6875 L 0.90625 -2.6875 C 0.734375 -2.6875 0.546875 -2.6875 0.546875 -2.5 C 0.546875 -2.296875 0.734375 -2.296875 0.90625 -2.296875 Z M 8.3125 -2.296875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-1-5" + overflow="visible"> + <path + id="path7070" + d="M 2.53125 -3.65625 C 3.09375 -4.3125 3.40625 -5.03125 3.40625 -5.109375 C 3.40625 -5.234375 3.296875 -5.234375 3.203125 -5.234375 C 3.046875 -5.234375 3.046875 -5.21875 2.953125 -5.03125 C 2.546875 -4.109375 1.8125 -3.1875 0.515625 -2.625 C 0.375 -2.578125 0.34375 -2.5625 0.34375 -2.5 C 0.34375 -2.46875 0.34375 -2.453125 0.34375 -2.4375 C 0.375 -2.40625 0.375 -2.40625 0.578125 -2.3125 C 1.671875 -1.859375 2.5 -1 3 0.15625 C 3.046875 0.234375 3.078125 0.25 3.203125 0.25 C 3.296875 0.25 3.40625 0.25 3.40625 0.125 C 3.40625 0.046875 3.09375 -0.671875 2.53125 -1.328125 L 7.421875 -1.328125 C 6.859375 -0.671875 6.5625 0.046875 6.5625 0.125 C 6.5625 0.25 6.671875 0.25 6.765625 0.25 C 6.90625 0.25 6.90625 0.234375 7 0.046875 C 7.40625 -0.875 8.140625 -1.796875 9.453125 -2.359375 C 9.59375 -2.40625 9.625 -2.421875 9.625 -2.5 C 9.625 -2.515625 9.625 -2.53125 9.609375 -2.546875 C 9.59375 -2.578125 9.578125 -2.578125 9.375 -2.671875 C 8.28125 -3.125 7.46875 -3.984375 6.953125 -5.140625 C 6.921875 -5.21875 6.875 -5.234375 6.765625 -5.234375 C 6.671875 -5.234375 6.5625 -5.234375 6.5625 -5.109375 C 6.5625 -5.03125 6.859375 -4.3125 7.421875 -3.65625 Z M 2.140625 -1.71875 C 1.84375 -2.015625 1.5 -2.25 1.09375 -2.5 C 1.640625 -2.8125 1.9375 -3.0625 2.140625 -3.265625 L 7.8125 -3.265625 C 8.109375 -2.96875 8.453125 -2.734375 8.859375 -2.5 C 8.3125 -2.171875 8.015625 -1.921875 7.8125 -1.71875 Z M 2.140625 -1.71875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-2-99" + overflow="visible"> + <path + id="path7073" + d="M 5.5 -6.546875 C 5.546875 -6.65625 5.546875 -6.671875 5.546875 -6.71875 C 5.546875 -6.8125 5.46875 -6.921875 5.34375 -6.921875 C 5.21875 -6.921875 5.15625 -6.796875 5.109375 -6.6875 L 4.28125 -4.5 L 1.25 -4.5 L 0.421875 -6.6875 C 0.375 -6.828125 0.328125 -6.921875 0.203125 -6.921875 C 0.09375 -6.921875 0 -6.8125 0 -6.71875 C 0 -6.703125 0 -6.671875 0.0625 -6.546875 L 2.546875 -0.015625 C 2.59375 0.125 2.640625 0.21875 2.765625 0.21875 C 2.90625 0.21875 2.953125 0.109375 2.984375 0.015625 Z M 1.421875 -4.09375 L 4.125 -4.09375 L 2.765625 -0.546875 Z M 1.421875 -4.09375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-3" + overflow="visible"> + <path + id="path7076" + d="M 3.546875 -5.75 C 3.46875 -5.921875 3.40625 -5.96875 3.3125 -5.96875 C 3.1875 -5.96875 3.15625 -5.890625 3.09375 -5.75 L 0.625 -0.171875 C 0.5625 -0.046875 0.546875 -0.03125 0.546875 0.015625 C 0.546875 0.125 0.640625 0.21875 0.75 0.21875 C 0.8125 0.21875 0.890625 0.203125 0.984375 0.015625 L 3.3125 -5.28125 L 5.65625 0.015625 C 5.75 0.21875 5.859375 0.21875 5.890625 0.21875 C 6 0.21875 6.09375 0.125 6.09375 0.015625 C 6.09375 0 6.09375 -0.015625 6.03125 -0.140625 Z M 3.546875 -5.75 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-4" + overflow="visible"> + <path + id="path7079" + d="M 7.234375 -3.265625 C 7.65625 -2.90625 8.171875 -2.640625 8.5 -2.5 C 8.140625 -2.328125 7.640625 -2.078125 7.234375 -1.71875 L 0.90625 -1.71875 C 0.734375 -1.71875 0.546875 -1.71875 0.546875 -1.53125 C 0.546875 -1.328125 0.734375 -1.328125 0.890625 -1.328125 L 6.78125 -1.328125 C 6.3125 -0.875 5.796875 0.015625 5.796875 0.140625 C 5.796875 0.25 5.921875 0.25 5.984375 0.25 C 6.0625 0.25 6.125 0.25 6.171875 0.171875 C 6.375 -0.203125 6.65625 -0.734375 7.3125 -1.3125 C 8 -1.921875 8.65625 -2.1875 9.1875 -2.34375 C 9.34375 -2.40625 9.359375 -2.40625 9.375 -2.4375 C 9.40625 -2.4375 9.40625 -2.46875 9.40625 -2.5 C 9.40625 -2.515625 9.40625 -2.53125 9.390625 -2.546875 L 9.359375 -2.578125 C 9.34375 -2.578125 9.328125 -2.59375 9.140625 -2.65625 C 7.796875 -3.046875 6.796875 -3.953125 6.234375 -5.03125 C 6.125 -5.21875 6.125 -5.234375 5.984375 -5.234375 C 5.921875 -5.234375 5.796875 -5.234375 5.796875 -5.125 C 5.796875 -5 6.296875 -4.125 6.78125 -3.65625 L 0.890625 -3.65625 C 0.734375 -3.65625 0.546875 -3.65625 0.546875 -3.453125 C 0.546875 -3.265625 0.734375 -3.265625 0.90625 -3.265625 Z M 7.234375 -3.265625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-0-2" + overflow="visible"> + <path + id="path7082" + d="M 3.296875 2.390625 C 3.296875 2.359375 3.296875 2.34375 3.125 2.171875 C 1.890625 0.921875 1.5625 -0.96875 1.5625 -2.5 C 1.5625 -4.234375 1.9375 -5.96875 3.171875 -7.203125 C 3.296875 -7.328125 3.296875 -7.34375 3.296875 -7.375 C 3.296875 -7.453125 3.265625 -7.484375 3.203125 -7.484375 C 3.09375 -7.484375 2.203125 -6.796875 1.609375 -5.53125 C 1.109375 -4.4375 0.984375 -3.328125 0.984375 -2.5 C 0.984375 -1.71875 1.09375 -0.515625 1.640625 0.625 C 2.25 1.84375 3.09375 2.5 3.203125 2.5 C 3.265625 2.5 3.296875 2.46875 3.296875 2.390625 Z M 3.296875 2.390625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-1-8" + overflow="visible"> + <path + id="path7085" + d="M 2.875 -2.5 C 2.875 -3.265625 2.765625 -4.46875 2.21875 -5.609375 C 1.625 -6.828125 0.765625 -7.484375 0.671875 -7.484375 C 0.609375 -7.484375 0.5625 -7.4375 0.5625 -7.375 C 0.5625 -7.34375 0.5625 -7.328125 0.75 -7.140625 C 1.734375 -6.15625 2.296875 -4.578125 2.296875 -2.5 C 2.296875 -0.78125 1.9375 0.96875 0.703125 2.21875 C 0.5625 2.34375 0.5625 2.359375 0.5625 2.390625 C 0.5625 2.453125 0.609375 2.5 0.671875 2.5 C 0.765625 2.5 1.671875 1.8125 2.25 0.546875 C 2.765625 -0.546875 2.875 -1.65625 2.875 -2.5 Z M 2.875 -2.5 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-2" + overflow="visible"> + <path + id="path7088" + d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-3" + overflow="visible"> + <path + id="path7091" + d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375 -3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-0-6" + overflow="visible"> + <path + id="path7094" + d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-1-0" + overflow="visible"> + <path + id="path7097" + d="M 1.46875 -0.109375 C 1.46875 0.265625 1.40625 0.71875 0.921875 1.15625 C 0.90625 1.1875 0.875 1.21875 0.875 1.25 C 0.875 1.296875 0.9375 1.34375 0.96875 1.34375 C 1.078125 1.34375 1.671875 0.78125 1.671875 -0.046875 C 1.671875 -0.46875 1.5 -0.796875 1.171875 -0.796875 C 0.953125 -0.796875 0.78125 -0.625 0.78125 -0.40625 C 0.78125 -0.1875 0.9375 0 1.1875 0 C 1.359375 0 1.46875 -0.109375 1.46875 -0.109375 Z M 1.46875 -0.109375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-2-35" + overflow="visible"> + <path + id="path7100" + d="M 3.0625 -4.359375 C 3.0625 -4.46875 2.96875 -4.625 2.78125 -4.625 C 2.578125 -4.625 2.390625 -4.421875 2.390625 -4.234375 C 2.390625 -4.125 2.46875 -3.96875 2.671875 -3.96875 C 2.859375 -3.96875 3.0625 -4.15625 3.0625 -4.359375 Z M 1.578125 0.34375 C 1.46875 0.828125 1.09375 1.21875 0.6875 1.21875 C 0.59375 1.21875 0.515625 1.21875 0.4375 1.1875 C 0.609375 1.09375 0.671875 0.9375 0.671875 0.828125 C 0.671875 0.65625 0.53125 0.578125 0.390625 0.578125 C 0.1875 0.578125 0 0.765625 0 0.984375 C 0 1.25 0.265625 1.421875 0.6875 1.421875 C 1.109375 1.421875 1.921875 1.171875 2.140625 0.328125 L 2.765625 -2.171875 C 2.78125 -2.25 2.796875 -2.3125 2.796875 -2.421875 C 2.796875 -2.796875 2.46875 -3.078125 2.0625 -3.078125 C 1.28125 -3.078125 0.84375 -2.109375 0.84375 -2 C 0.84375 -1.921875 0.9375 -1.921875 0.953125 -1.921875 C 1.03125 -1.921875 1.046875 -1.9375 1.09375 -2.046875 C 1.265625 -2.453125 1.625 -2.875 2.03125 -2.875 C 2.203125 -2.875 2.265625 -2.765625 2.265625 -2.53125 C 2.265625 -2.453125 2.265625 -2.359375 2.25 -2.328125 Z M 1.578125 0.34375 " + style="stroke:none;" /> + </symbol> + </g> + <g + id="g3909"> + <symbol + id="glyph0-0-24" + overflow="visible"> + <path + id="path3912" + d="M 3.71875 -3.765625 C 3.53125 -4.140625 3.25 -4.40625 2.796875 -4.40625 C 1.640625 -4.40625 0.40625 -2.9375 0.40625 -1.484375 C 0.40625 -0.546875 0.953125 0.109375 1.71875 0.109375 C 1.921875 0.109375 2.421875 0.0625 3.015625 -0.640625 C 3.09375 -0.21875 3.453125 0.109375 3.921875 0.109375 C 4.28125 0.109375 4.5 -0.125 4.671875 -0.4375 C 4.828125 -0.796875 4.96875 -1.40625 4.96875 -1.421875 C 4.96875 -1.53125 4.875 -1.53125 4.84375 -1.53125 C 4.75 -1.53125 4.734375 -1.484375 4.703125 -1.34375 C 4.53125 -0.703125 4.359375 -0.109375 3.953125 -0.109375 C 3.671875 -0.109375 3.65625 -0.375 3.65625 -0.5625 C 3.65625 -0.78125 3.671875 -0.875 3.78125 -1.3125 C 3.890625 -1.71875 3.90625 -1.828125 4 -2.203125 L 4.359375 -3.59375 C 4.421875 -3.875 4.421875 -3.890625 4.421875 -3.9375 C 4.421875 -4.109375 4.3125 -4.203125 4.140625 -4.203125 C 3.890625 -4.203125 3.75 -3.984375 3.71875 -3.765625 Z M 3.078125 -1.1875 C 3.015625 -1 3.015625 -0.984375 2.875 -0.8125 C 2.4375 -0.265625 2.03125 -0.109375 1.75 -0.109375 C 1.25 -0.109375 1.109375 -0.65625 1.109375 -1.046875 C 1.109375 -1.546875 1.421875 -2.765625 1.65625 -3.234375 C 1.96875 -3.8125 2.40625 -4.1875 2.8125 -4.1875 C 3.453125 -4.1875 3.59375 -3.375 3.59375 -3.3125 C 3.59375 -3.25 3.578125 -3.1875 3.5625 -3.140625 Z M 3.078125 -1.1875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph0-1-8" + overflow="visible"> + <path + id="path3915" + d="M 3.953125 -3.78125 C 3.78125 -3.78125 3.65625 -3.78125 3.515625 -3.65625 C 3.34375 -3.5 3.328125 -3.328125 3.328125 -3.265625 C 3.328125 -3.015625 3.515625 -2.90625 3.703125 -2.90625 C 3.984375 -2.90625 4.25 -3.15625 4.25 -3.546875 C 4.25 -4.03125 3.78125 -4.40625 3.078125 -4.40625 C 1.734375 -4.40625 0.40625 -2.984375 0.40625 -1.578125 C 0.40625 -0.671875 0.984375 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.421875 -0.109375 1.140625 -0.59375 1.140625 -1.203125 C 1.140625 -1.609375 1.34375 -2.578125 1.6875 -3.1875 C 2 -3.765625 2.546875 -4.1875 3.09375 -4.1875 C 3.421875 -4.1875 3.8125 -4.0625 3.953125 -3.78125 Z M 3.953125 -3.78125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-0-0" + overflow="visible"> + <path + id="path3918" + d="M 8.3125 -2.296875 C 7.765625 -1.875 7.5 -1.46875 7.421875 -1.328125 C 6.96875 -0.640625 6.890625 -0.015625 6.890625 -0.015625 C 6.890625 0.109375 7.015625 0.109375 7.09375 0.109375 C 7.25 0.109375 7.265625 0.09375 7.3125 -0.09375 C 7.53125 -1.0625 8.125 -1.90625 9.25 -2.359375 C 9.375 -2.40625 9.40625 -2.421875 9.40625 -2.5 C 9.40625 -2.5625 9.34375 -2.59375 9.328125 -2.609375 C 8.875 -2.765625 7.671875 -3.265625 7.296875 -4.9375 C 7.265625 -5.0625 7.25 -5.09375 7.09375 -5.09375 C 7.015625 -5.09375 6.890625 -5.09375 6.890625 -4.96875 C 6.890625 -4.953125 6.984375 -4.328125 7.390625 -3.65625 C 7.59375 -3.359375 7.890625 -3.015625 8.3125 -2.6875 L 0.90625 -2.6875 C 0.734375 -2.6875 0.546875 -2.6875 0.546875 -2.5 C 0.546875 -2.296875 0.734375 -2.296875 0.90625 -2.296875 Z M 8.3125 -2.296875 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-1-7" + overflow="visible"> + <path + id="path3921" + d="M 9.0625 -1.328125 C 9.234375 -1.328125 9.40625 -1.328125 9.40625 -1.53125 C 9.40625 -1.71875 9.234375 -1.71875 9.046875 -1.71875 L 2.71875 -1.71875 C 2.296875 -2.078125 1.796875 -2.34375 1.46875 -2.5 C 1.828125 -2.65625 2.3125 -2.90625 2.71875 -3.265625 L 9.046875 -3.265625 C 9.234375 -3.265625 9.40625 -3.265625 9.40625 -3.453125 C 9.40625 -3.65625 9.234375 -3.65625 9.0625 -3.65625 L 3.171875 -3.65625 C 3.65625 -4.109375 4.171875 -5 4.171875 -5.125 C 4.171875 -5.234375 4.03125 -5.234375 3.984375 -5.234375 C 3.890625 -5.234375 3.828125 -5.234375 3.78125 -5.15625 C 3.578125 -4.78125 3.296875 -4.25 2.65625 -3.671875 C 1.96875 -3.0625 1.296875 -2.796875 0.78125 -2.640625 C 0.609375 -2.578125 0.59375 -2.578125 0.578125 -2.546875 C 0.5625 -2.546875 0.5625 -2.515625 0.5625 -2.5 C 0.5625 -2.46875 0.5625 -2.453125 0.5625 -2.4375 L 0.59375 -2.40625 C 0.625 -2.40625 0.625 -2.390625 0.8125 -2.328125 C 2.15625 -1.9375 3.15625 -1.03125 3.71875 0.046875 C 3.828125 0.234375 3.84375 0.25 3.984375 0.25 C 4.03125 0.25 4.171875 0.25 4.171875 0.140625 C 4.171875 0.015625 3.65625 -0.859375 3.171875 -1.328125 Z M 9.0625 -1.328125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-2-3" + overflow="visible"> + <path + id="path3924" + d="M 7.234375 -3.265625 C 7.65625 -2.90625 8.171875 -2.640625 8.5 -2.5 C 8.140625 -2.328125 7.640625 -2.078125 7.234375 -1.71875 L 0.90625 -1.71875 C 0.734375 -1.71875 0.546875 -1.71875 0.546875 -1.53125 C 0.546875 -1.328125 0.734375 -1.328125 0.890625 -1.328125 L 6.78125 -1.328125 C 6.3125 -0.875 5.796875 0.015625 5.796875 0.140625 C 5.796875 0.25 5.921875 0.25 5.984375 0.25 C 6.0625 0.25 6.125 0.25 6.171875 0.171875 C 6.375 -0.203125 6.65625 -0.734375 7.3125 -1.3125 C 8 -1.921875 8.65625 -2.1875 9.1875 -2.34375 C 9.34375 -2.40625 9.359375 -2.40625 9.375 -2.4375 C 9.40625 -2.4375 9.40625 -2.46875 9.40625 -2.5 C 9.40625 -2.515625 9.40625 -2.53125 9.390625 -2.546875 L 9.359375 -2.578125 C 9.34375 -2.578125 9.328125 -2.59375 9.140625 -2.65625 C 7.796875 -3.046875 6.796875 -3.953125 6.234375 -5.03125 C 6.125 -5.21875 6.125 -5.234375 5.984375 -5.234375 C 5.921875 -5.234375 5.796875 -5.234375 5.796875 -5.125 C 5.796875 -5 6.296875 -4.125 6.78125 -3.65625 L 0.890625 -3.65625 C 0.734375 -3.65625 0.546875 -3.65625 0.546875 -3.453125 C 0.546875 -3.265625 0.734375 -3.265625 0.90625 -3.265625 Z M 7.234375 -3.265625 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph1-3-6" + overflow="visible"> + <path + id="path3927" + d="M 5.5 -6.546875 C 5.546875 -6.65625 5.546875 -6.671875 5.546875 -6.71875 C 5.546875 -6.8125 5.46875 -6.921875 5.34375 -6.921875 C 5.21875 -6.921875 5.15625 -6.796875 5.109375 -6.6875 L 4.28125 -4.5 L 1.25 -4.5 L 0.421875 -6.6875 C 0.375 -6.828125 0.328125 -6.921875 0.203125 -6.921875 C 0.09375 -6.921875 0 -6.8125 0 -6.71875 C 0 -6.703125 0 -6.671875 0.0625 -6.546875 L 2.546875 -0.015625 C 2.59375 0.125 2.640625 0.21875 2.765625 0.21875 C 2.90625 0.21875 2.953125 0.109375 2.984375 0.015625 Z M 1.421875 -4.09375 L 4.125 -4.09375 L 2.765625 -0.546875 Z M 1.421875 -4.09375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-0-29" + overflow="visible"> + <path + id="path3930" + d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph2-1-69" + overflow="visible"> + <path + id="path3933" + d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375 -3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-0-0" + overflow="visible"> + <path + id="path3936" + d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-1-4" + overflow="visible"> + <path + id="path3939" + d="M 1.46875 -0.109375 C 1.46875 0.265625 1.40625 0.71875 0.921875 1.15625 C 0.90625 1.1875 0.875 1.21875 0.875 1.25 C 0.875 1.296875 0.9375 1.34375 0.96875 1.34375 C 1.078125 1.34375 1.671875 0.78125 1.671875 -0.046875 C 1.671875 -0.46875 1.5 -0.796875 1.171875 -0.796875 C 0.953125 -0.796875 0.78125 -0.625 0.78125 -0.40625 C 0.78125 -0.1875 0.9375 0 1.1875 0 C 1.359375 0 1.46875 -0.109375 1.46875 -0.109375 Z M 1.46875 -0.109375 " + style="stroke:none;" /> + </symbol> + <symbol + id="glyph3-2-0" + overflow="visible"> + <path + id="path3942" + d="M 3.0625 -4.359375 C 3.0625 -4.46875 2.96875 -4.625 2.78125 -4.625 C 2.578125 -4.625 2.390625 -4.421875 2.390625 -4.234375 C 2.390625 -4.125 2.46875 -3.96875 2.671875 -3.96875 C 2.859375 -3.96875 3.0625 -4.15625 3.0625 -4.359375 Z M 1.578125 0.34375 C 1.46875 0.828125 1.09375 1.21875 0.6875 1.21875 C 0.59375 1.21875 0.515625 1.21875 0.4375 1.1875 C 0.609375 1.09375 0.671875 0.9375 0.671875 0.828125 C 0.671875 0.65625 0.53125 0.578125 0.390625 0.578125 C 0.1875 0.578125 0 0.765625 0 0.984375 C 0 1.25 0.265625 1.421875 0.6875 1.421875 C 1.109375 1.421875 1.921875 1.171875 2.140625 0.328125 L 2.765625 -2.171875 C 2.78125 -2.25 2.796875 -2.3125 2.796875 -2.421875 C 2.796875 -2.796875 2.46875 -3.078125 2.0625 -3.078125 C 1.28125 -3.078125 0.84375 -2.109375 0.84375 -2 C 0.84375 -1.921875 0.9375 -1.921875 0.953125 -1.921875 C 1.03125 -1.921875 1.046875 -1.9375 1.09375 -2.046875 C 1.265625 -2.453125 1.625 -2.875 2.03125 -2.875 C 2.203125 -2.875 2.265625 -2.765625 2.265625 -2.53125 C 2.265625 -2.453125 2.265625 -2.359375 2.25 -2.328125 Z M 1.578125 0.34375 " + style="stroke:none;" /> + </symbol> + </g> + <marker + inkscape:stockid="Arrow1Mend-6-8l" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8l" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6164" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#ff00ff;stroke-width:1pt;fill:#ff00ff;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotM1" + orient="auto" + refY="0.0" + refX="0.0" + id="DotM1" + style="overflow:visible"> + <path + id="path6167" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#ff00ff;stroke-width:1.0pt;fill:#ff00ff;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6-8n" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8n" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path6170" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#ff00ff;stroke-width:1pt;fill:#ff00ff;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <g + id="g7705"> + <symbol + overflow="visible" + id="glyph0-0-26"> + <path + style="stroke:none;" + d="M 3.71875 -3.765625 C 3.53125 -4.140625 3.25 -4.40625 2.796875 -4.40625 C 1.640625 -4.40625 0.40625 -2.9375 0.40625 -1.484375 C 0.40625 -0.546875 0.953125 0.109375 1.71875 0.109375 C 1.921875 0.109375 2.421875 0.0625 3.015625 -0.640625 C 3.09375 -0.21875 3.453125 0.109375 3.921875 0.109375 C 4.28125 0.109375 4.5 -0.125 4.671875 -0.4375 C 4.828125 -0.796875 4.96875 -1.40625 4.96875 -1.421875 C 4.96875 -1.53125 4.875 -1.53125 4.84375 -1.53125 C 4.75 -1.53125 4.734375 -1.484375 4.703125 -1.34375 C 4.53125 -0.703125 4.359375 -0.109375 3.953125 -0.109375 C 3.671875 -0.109375 3.65625 -0.375 3.65625 -0.5625 C 3.65625 -0.78125 3.671875 -0.875 3.78125 -1.3125 C 3.890625 -1.71875 3.90625 -1.828125 4 -2.203125 L 4.359375 -3.59375 C 4.421875 -3.875 4.421875 -3.890625 4.421875 -3.9375 C 4.421875 -4.109375 4.3125 -4.203125 4.140625 -4.203125 C 3.890625 -4.203125 3.75 -3.984375 3.71875 -3.765625 Z M 3.078125 -1.1875 C 3.015625 -1 3.015625 -0.984375 2.875 -0.8125 C 2.4375 -0.265625 2.03125 -0.109375 1.75 -0.109375 C 1.25 -0.109375 1.109375 -0.65625 1.109375 -1.046875 C 1.109375 -1.546875 1.421875 -2.765625 1.65625 -3.234375 C 1.96875 -3.8125 2.40625 -4.1875 2.8125 -4.1875 C 3.453125 -4.1875 3.59375 -3.375 3.59375 -3.3125 C 3.59375 -3.25 3.578125 -3.1875 3.5625 -3.140625 Z M 3.078125 -1.1875 " + id="path7708" /> + </symbol> + <symbol + overflow="visible" + id="glyph0-1-88"> + <path + style="stroke:none;" + d="M 2.375 -6.8125 C 2.375 -6.8125 2.375 -6.921875 2.25 -6.921875 C 2.03125 -6.921875 1.296875 -6.84375 1.03125 -6.8125 C 0.953125 -6.8125 0.84375 -6.796875 0.84375 -6.625 C 0.84375 -6.5 0.9375 -6.5 1.09375 -6.5 C 1.5625 -6.5 1.578125 -6.4375 1.578125 -6.328125 C 1.578125 -6.265625 1.5 -5.921875 1.453125 -5.71875 L 0.625 -2.46875 C 0.515625 -1.96875 0.46875 -1.796875 0.46875 -1.453125 C 0.46875 -0.515625 1 0.109375 1.734375 0.109375 C 2.90625 0.109375 4.140625 -1.375 4.140625 -2.8125 C 4.140625 -3.71875 3.609375 -4.40625 2.8125 -4.40625 C 2.359375 -4.40625 1.9375 -4.109375 1.640625 -3.8125 Z M 1.453125 -3.046875 C 1.5 -3.265625 1.5 -3.28125 1.59375 -3.390625 C 2.078125 -4.03125 2.53125 -4.1875 2.796875 -4.1875 C 3.15625 -4.1875 3.421875 -3.890625 3.421875 -3.25 C 3.421875 -2.65625 3.09375 -1.515625 2.90625 -1.140625 C 2.578125 -0.46875 2.125 -0.109375 1.734375 -0.109375 C 1.390625 -0.109375 1.0625 -0.375 1.0625 -1.109375 C 1.0625 -1.3125 1.0625 -1.5 1.21875 -2.125 Z M 1.453125 -3.046875 " + id="path7711" /> + </symbol> + <symbol + overflow="visible" + id="glyph0-2-4"> + <path + style="stroke:none;" + d="M 2.03125 -0.015625 C 2.03125 -0.671875 1.78125 -1.0625 1.390625 -1.0625 C 1.0625 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.265625 1.0625 0 1.390625 0 C 1.5 0 1.640625 -0.046875 1.734375 -0.125 C 1.765625 -0.15625 1.78125 -0.15625 1.78125 -0.15625 C 1.796875 -0.15625 1.796875 -0.15625 1.796875 -0.015625 C 1.796875 0.734375 1.453125 1.328125 1.125 1.65625 C 1.015625 1.765625 1.015625 1.78125 1.015625 1.8125 C 1.015625 1.890625 1.0625 1.921875 1.109375 1.921875 C 1.21875 1.921875 2.03125 1.15625 2.03125 -0.015625 Z M 2.03125 -0.015625 " + id="path7714" /> + </symbol> + <symbol + overflow="visible" + id="glyph0-3-1"> + <path + style="stroke:none;" + d="M 3.953125 -3.78125 C 3.78125 -3.78125 3.65625 -3.78125 3.515625 -3.65625 C 3.34375 -3.5 3.328125 -3.328125 3.328125 -3.265625 C 3.328125 -3.015625 3.515625 -2.90625 3.703125 -2.90625 C 3.984375 -2.90625 4.25 -3.15625 4.25 -3.546875 C 4.25 -4.03125 3.78125 -4.40625 3.078125 -4.40625 C 1.734375 -4.40625 0.40625 -2.984375 0.40625 -1.578125 C 0.40625 -0.671875 0.984375 0.109375 2.03125 0.109375 C 3.453125 0.109375 4.28125 -0.953125 4.28125 -1.0625 C 4.28125 -1.125 4.234375 -1.203125 4.171875 -1.203125 C 4.109375 -1.203125 4.09375 -1.171875 4.03125 -1.09375 C 3.25 -0.109375 2.15625 -0.109375 2.046875 -0.109375 C 1.421875 -0.109375 1.140625 -0.59375 1.140625 -1.203125 C 1.140625 -1.609375 1.34375 -2.578125 1.6875 -3.1875 C 2 -3.765625 2.546875 -4.1875 3.09375 -4.1875 C 3.421875 -4.1875 3.8125 -4.0625 3.953125 -3.78125 Z M 3.953125 -3.78125 " + id="path7717" /> + </symbol> + <symbol + overflow="visible" + id="glyph1-0-62"> + <path + style="stroke:none;" + d="M 8.3125 -2.296875 C 7.765625 -1.875 7.5 -1.46875 7.421875 -1.328125 C 6.96875 -0.640625 6.890625 -0.015625 6.890625 -0.015625 C 6.890625 0.109375 7.015625 0.109375 7.09375 0.109375 C 7.25 0.109375 7.265625 0.09375 7.3125 -0.09375 C 7.53125 -1.0625 8.125 -1.90625 9.25 -2.359375 C 9.375 -2.40625 9.40625 -2.421875 9.40625 -2.5 C 9.40625 -2.5625 9.34375 -2.59375 9.328125 -2.609375 C 8.875 -2.765625 7.671875 -3.265625 7.296875 -4.9375 C 7.265625 -5.0625 7.25 -5.09375 7.09375 -5.09375 C 7.015625 -5.09375 6.890625 -5.09375 6.890625 -4.96875 C 6.890625 -4.953125 6.984375 -4.328125 7.390625 -3.65625 C 7.59375 -3.359375 7.890625 -3.015625 8.3125 -2.6875 L 0.90625 -2.6875 C 0.734375 -2.6875 0.546875 -2.6875 0.546875 -2.5 C 0.546875 -2.296875 0.734375 -2.296875 0.90625 -2.296875 Z M 8.3125 -2.296875 " + id="path7720" /> + </symbol> + <symbol + overflow="visible" + id="glyph1-1-59"> + <path + style="stroke:none;" + d="M 9.0625 -1.328125 C 9.234375 -1.328125 9.40625 -1.328125 9.40625 -1.53125 C 9.40625 -1.71875 9.234375 -1.71875 9.046875 -1.71875 L 2.71875 -1.71875 C 2.296875 -2.078125 1.796875 -2.34375 1.46875 -2.5 C 1.828125 -2.65625 2.3125 -2.90625 2.71875 -3.265625 L 9.046875 -3.265625 C 9.234375 -3.265625 9.40625 -3.265625 9.40625 -3.453125 C 9.40625 -3.65625 9.234375 -3.65625 9.0625 -3.65625 L 3.171875 -3.65625 C 3.65625 -4.109375 4.171875 -5 4.171875 -5.125 C 4.171875 -5.234375 4.03125 -5.234375 3.984375 -5.234375 C 3.890625 -5.234375 3.828125 -5.234375 3.78125 -5.15625 C 3.578125 -4.78125 3.296875 -4.25 2.65625 -3.671875 C 1.96875 -3.0625 1.296875 -2.796875 0.78125 -2.640625 C 0.609375 -2.578125 0.59375 -2.578125 0.578125 -2.546875 C 0.5625 -2.546875 0.5625 -2.515625 0.5625 -2.5 C 0.5625 -2.46875 0.5625 -2.453125 0.5625 -2.4375 L 0.59375 -2.40625 C 0.625 -2.40625 0.625 -2.390625 0.8125 -2.328125 C 2.15625 -1.9375 3.15625 -1.03125 3.71875 0.046875 C 3.828125 0.234375 3.84375 0.25 3.984375 0.25 C 4.03125 0.25 4.171875 0.25 4.171875 0.140625 C 4.171875 0.015625 3.65625 -0.859375 3.171875 -1.328125 Z M 9.0625 -1.328125 " + id="path7723" /> + </symbol> + <symbol + overflow="visible" + id="glyph1-2-2"> + <path + style="stroke:none;" + d="M 7.234375 -3.265625 C 7.65625 -2.90625 8.171875 -2.640625 8.5 -2.5 C 8.140625 -2.328125 7.640625 -2.078125 7.234375 -1.71875 L 0.90625 -1.71875 C 0.734375 -1.71875 0.546875 -1.71875 0.546875 -1.53125 C 0.546875 -1.328125 0.734375 -1.328125 0.890625 -1.328125 L 6.78125 -1.328125 C 6.3125 -0.875 5.796875 0.015625 5.796875 0.140625 C 5.796875 0.25 5.921875 0.25 5.984375 0.25 C 6.0625 0.25 6.125 0.25 6.171875 0.171875 C 6.375 -0.203125 6.65625 -0.734375 7.3125 -1.3125 C 8 -1.921875 8.65625 -2.1875 9.1875 -2.34375 C 9.34375 -2.40625 9.359375 -2.40625 9.375 -2.4375 C 9.40625 -2.4375 9.40625 -2.46875 9.40625 -2.5 C 9.40625 -2.515625 9.40625 -2.53125 9.390625 -2.546875 L 9.359375 -2.578125 C 9.34375 -2.578125 9.328125 -2.59375 9.140625 -2.65625 C 7.796875 -3.046875 6.796875 -3.953125 6.234375 -5.03125 C 6.125 -5.21875 6.125 -5.234375 5.984375 -5.234375 C 5.921875 -5.234375 5.796875 -5.234375 5.796875 -5.125 C 5.796875 -5 6.296875 -4.125 6.78125 -3.65625 L 0.890625 -3.65625 C 0.734375 -3.65625 0.546875 -3.65625 0.546875 -3.453125 C 0.546875 -3.265625 0.734375 -3.265625 0.90625 -3.265625 Z M 7.234375 -3.265625 " + id="path7726" /> + </symbol> + <symbol + overflow="visible" + id="glyph1-3-8"> + <path + style="stroke:none;" + d="M 5.5 -6.546875 C 5.546875 -6.65625 5.546875 -6.671875 5.546875 -6.71875 C 5.546875 -6.8125 5.46875 -6.921875 5.34375 -6.921875 C 5.21875 -6.921875 5.15625 -6.796875 5.109375 -6.6875 L 4.28125 -4.5 L 1.25 -4.5 L 0.421875 -6.6875 C 0.375 -6.828125 0.328125 -6.921875 0.203125 -6.921875 C 0.09375 -6.921875 0 -6.8125 0 -6.71875 C 0 -6.703125 0 -6.671875 0.0625 -6.546875 L 2.546875 -0.015625 C 2.59375 0.125 2.640625 0.21875 2.765625 0.21875 C 2.90625 0.21875 2.953125 0.109375 2.984375 0.015625 Z M 1.421875 -4.09375 L 4.125 -4.09375 L 2.765625 -0.546875 Z M 1.421875 -4.09375 " + id="path7729" /> + </symbol> + <symbol + overflow="visible" + id="glyph1-4-7"> + <path + style="stroke:none;" + d="M 3.546875 -5.75 C 3.46875 -5.921875 3.40625 -5.96875 3.3125 -5.96875 C 3.1875 -5.96875 3.15625 -5.890625 3.09375 -5.75 L 0.625 -0.171875 C 0.5625 -0.046875 0.546875 -0.03125 0.546875 0.015625 C 0.546875 0.125 0.640625 0.21875 0.75 0.21875 C 0.8125 0.21875 0.890625 0.203125 0.984375 0.015625 L 3.3125 -5.28125 L 5.65625 0.015625 C 5.75 0.21875 5.859375 0.21875 5.890625 0.21875 C 6 0.21875 6.09375 0.125 6.09375 0.015625 C 6.09375 0 6.09375 -0.015625 6.03125 -0.140625 Z M 3.546875 -5.75 " + id="path7732" /> + </symbol> + <symbol + overflow="visible" + id="glyph2-0-6"> + <path + style="stroke:none;" + d="M 3.296875 2.390625 C 3.296875 2.359375 3.296875 2.34375 3.125 2.171875 C 1.890625 0.921875 1.5625 -0.96875 1.5625 -2.5 C 1.5625 -4.234375 1.9375 -5.96875 3.171875 -7.203125 C 3.296875 -7.328125 3.296875 -7.34375 3.296875 -7.375 C 3.296875 -7.453125 3.265625 -7.484375 3.203125 -7.484375 C 3.09375 -7.484375 2.203125 -6.796875 1.609375 -5.53125 C 1.109375 -4.4375 0.984375 -3.328125 0.984375 -2.5 C 0.984375 -1.71875 1.09375 -0.515625 1.640625 0.625 C 2.25 1.84375 3.09375 2.5 3.203125 2.5 C 3.265625 2.5 3.296875 2.46875 3.296875 2.390625 Z M 3.296875 2.390625 " + id="path7735" /> + </symbol> + <symbol + overflow="visible" + id="glyph2-1-4"> + <path + style="stroke:none;" + d="M 2.875 -2.5 C 2.875 -3.265625 2.765625 -4.46875 2.21875 -5.609375 C 1.625 -6.828125 0.765625 -7.484375 0.671875 -7.484375 C 0.609375 -7.484375 0.5625 -7.4375 0.5625 -7.375 C 0.5625 -7.34375 0.5625 -7.328125 0.75 -7.140625 C 1.734375 -6.15625 2.296875 -4.578125 2.296875 -2.5 C 2.296875 -0.78125 1.9375 0.96875 0.703125 2.21875 C 0.5625 2.34375 0.5625 2.359375 0.5625 2.390625 C 0.5625 2.453125 0.609375 2.5 0.671875 2.5 C 0.765625 2.5 1.671875 1.8125 2.25 0.546875 C 2.765625 -0.546875 2.875 -1.65625 2.875 -2.5 Z M 2.875 -2.5 " + id="path7738" /> + </symbol> + <symbol + overflow="visible" + id="glyph2-2-5"> + <path + style="stroke:none;" + d="M 1.90625 -3.765625 C 1.90625 -4.0625 1.671875 -4.296875 1.390625 -4.296875 C 1.09375 -4.296875 0.859375 -4.0625 0.859375 -3.765625 C 0.859375 -3.484375 1.09375 -3.234375 1.390625 -3.234375 C 1.671875 -3.234375 1.90625 -3.484375 1.90625 -3.765625 Z M 1.90625 -0.53125 C 1.90625 -0.8125 1.671875 -1.0625 1.390625 -1.0625 C 1.09375 -1.0625 0.859375 -0.8125 0.859375 -0.53125 C 0.859375 -0.234375 1.09375 0 1.390625 0 C 1.671875 0 1.90625 -0.234375 1.90625 -0.53125 Z M 1.90625 -0.53125 " + id="path7741" /> + </symbol> + <symbol + overflow="visible" + id="glyph2-3-7"> + <path + style="stroke:none;" + d="M 6.84375 -3.265625 C 7 -3.265625 7.1875 -3.265625 7.1875 -3.453125 C 7.1875 -3.65625 7 -3.65625 6.859375 -3.65625 L 0.890625 -3.65625 C 0.75 -3.65625 0.5625 -3.65625 0.5625 -3.453125 C 0.5625 -3.265625 0.75 -3.265625 0.890625 -3.265625 Z M 6.859375 -1.328125 C 7 -1.328125 7.1875 -1.328125 7.1875 -1.53125 C 7.1875 -1.71875 7 -1.71875 6.84375 -1.71875 L 0.890625 -1.71875 C 0.75 -1.71875 0.5625 -1.71875 0.5625 -1.53125 C 0.5625 -1.328125 0.75 -1.328125 0.890625 -1.328125 Z M 6.859375 -1.328125 " + id="path7744" /> + </symbol> + <symbol + overflow="visible" + id="glyph3-0-1"> + <path + style="stroke:none;" + d="M 2.265625 -4.359375 C 2.265625 -4.46875 2.171875 -4.625 1.984375 -4.625 C 1.796875 -4.625 1.59375 -4.4375 1.59375 -4.234375 C 1.59375 -4.125 1.671875 -3.96875 1.875 -3.96875 C 2.0625 -3.96875 2.265625 -4.171875 2.265625 -4.359375 Z M 0.84375 -0.8125 C 0.8125 -0.71875 0.78125 -0.640625 0.78125 -0.515625 C 0.78125 -0.1875 1.046875 0.0625 1.4375 0.0625 C 2.125 0.0625 2.4375 -0.890625 2.4375 -1 C 2.4375 -1.09375 2.34375 -1.09375 2.328125 -1.09375 C 2.234375 -1.09375 2.21875 -1.046875 2.1875 -0.96875 C 2.03125 -0.40625 1.734375 -0.125 1.453125 -0.125 C 1.3125 -0.125 1.28125 -0.21875 1.28125 -0.375 C 1.28125 -0.53125 1.328125 -0.65625 1.390625 -0.8125 C 1.46875 -1 1.546875 -1.1875 1.609375 -1.375 C 1.671875 -1.546875 1.9375 -2.171875 1.953125 -2.265625 C 1.984375 -2.328125 2 -2.40625 2 -2.484375 C 2 -2.8125 1.71875 -3.078125 1.34375 -3.078125 C 0.640625 -3.078125 0.328125 -2.125 0.328125 -2 C 0.328125 -1.921875 0.421875 -1.921875 0.453125 -1.921875 C 0.546875 -1.921875 0.546875 -1.953125 0.578125 -2.03125 C 0.75 -2.625 1.0625 -2.875 1.3125 -2.875 C 1.421875 -2.875 1.484375 -2.828125 1.484375 -2.640625 C 1.484375 -2.46875 1.453125 -2.375 1.28125 -1.9375 Z M 0.84375 -0.8125 " + id="path7747" /> + </symbol> + <symbol + overflow="visible" + id="glyph3-1-8"> + <path + style="stroke:none;" + d="M 1.46875 -0.109375 C 1.46875 0.265625 1.40625 0.71875 0.921875 1.15625 C 0.90625 1.1875 0.875 1.21875 0.875 1.25 C 0.875 1.296875 0.9375 1.34375 0.96875 1.34375 C 1.078125 1.34375 1.671875 0.78125 1.671875 -0.046875 C 1.671875 -0.46875 1.5 -0.796875 1.171875 -0.796875 C 0.953125 -0.796875 0.78125 -0.625 0.78125 -0.40625 C 0.78125 -0.1875 0.9375 0 1.1875 0 C 1.359375 0 1.46875 -0.109375 1.46875 -0.109375 Z M 1.46875 -0.109375 " + id="path7750" /> + </symbol> + <symbol + overflow="visible" + id="glyph3-2-5"> + <path + style="stroke:none;" + d="M 3.0625 -4.359375 C 3.0625 -4.46875 2.96875 -4.625 2.78125 -4.625 C 2.578125 -4.625 2.390625 -4.421875 2.390625 -4.234375 C 2.390625 -4.125 2.46875 -3.96875 2.671875 -3.96875 C 2.859375 -3.96875 3.0625 -4.15625 3.0625 -4.359375 Z M 1.578125 0.34375 C 1.46875 0.828125 1.09375 1.21875 0.6875 1.21875 C 0.59375 1.21875 0.515625 1.21875 0.4375 1.1875 C 0.609375 1.09375 0.671875 0.9375 0.671875 0.828125 C 0.671875 0.65625 0.53125 0.578125 0.390625 0.578125 C 0.1875 0.578125 0 0.765625 0 0.984375 C 0 1.25 0.265625 1.421875 0.6875 1.421875 C 1.109375 1.421875 1.921875 1.171875 2.140625 0.328125 L 2.765625 -2.171875 C 2.78125 -2.25 2.796875 -2.3125 2.796875 -2.421875 C 2.796875 -2.796875 2.46875 -3.078125 2.0625 -3.078125 C 1.28125 -3.078125 0.84375 -2.109375 0.84375 -2 C 0.84375 -1.921875 0.9375 -1.921875 0.953125 -1.921875 C 1.03125 -1.921875 1.046875 -1.9375 1.09375 -2.046875 C 1.265625 -2.453125 1.625 -2.875 2.03125 -2.875 C 2.203125 -2.875 2.265625 -2.765625 2.265625 -2.53125 C 2.265625 -2.453125 2.265625 -2.359375 2.25 -2.328125 Z M 1.578125 0.34375 " + id="path7753" /> + </symbol> + </g> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-6" + style="overflow:visible"> + <path + id="path5711-8" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-1" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-7" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="DotMQ-0" + style="overflow:visible"> + <path + id="path5711-10" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6FL-78" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5714-86" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMQ" + orient="auto" + refY="0" + refX="0" + id="marker4013" + style="overflow:visible"> + <path + id="path4015" + d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(0.4,0,0,0.4,2.96,0.4)" + inkscape:connector-curvature="0" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6FL" + orient="auto" + refY="0" + refX="0" + id="marker4017" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path4019" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill:#008000;fill-rule:evenodd;stroke:#008000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMs" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMs" + style="overflow:visible"> + <path + id="path8214" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#0000ff;stroke-width:1.0pt;fill:#0000ff;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6-8V" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8V" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path8217" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#0000ff;stroke-width:1pt;fill:#0000ff;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="DotMU" + orient="auto" + refY="0.0" + refX="0.0" + id="DotMU" + style="overflow:visible"> + <path + id="path8220" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="stroke:#0000ff;stroke-width:1.0pt;fill:#0000ff;fill-rule:evenodd" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend-6-8U" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8U" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path8223" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="stroke:#0000ff;stroke-width:1pt;fill:#0000ff;fill-rule:evenodd" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + style="overflow:visible" + id="EmptyTriangleOutLX" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="EmptyTriangleOutLX"> + <path + transform="scale(0.8) translate(-6,0)" + style="stroke-width:1.0pt;stroke:#0000ff;fill:#0000ff;fill-rule:evenodd" + d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " + id="path10660" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8-5" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5-4-2" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + style="overflow:visible" + id="EmptyTriangleOutLX-9" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="EmptyTriangleOutLX"> + <path + transform="matrix(0.8,0,0,0.8,-4.8,0)" + style="fill:#0000ff;fill-rule:evenodd;stroke:#0000ff;stroke-width:1pt" + d="m 5.77,0 -8.65,5 0,-10 8.65,5 z" + id="path10660-4" + inkscape:connector-curvature="0" /> + </marker> + <marker + style="overflow:visible" + id="EmptyTriangleOutLXF" + refX="0.0" + refY="0.0" + orient="auto" + inkscape:stockid="EmptyTriangleOutLXF"> + <path + transform="scale(0.8) translate(-6,0)" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;fill:#000000" + d="M 5.77,0.0 L -2.88,5.0 L -2.88,-5.0 L 5.77,0.0 z " + id="path5855" /> + </marker> + <marker + style="overflow:visible" + id="EmptyTriangleOutL-4" + refX="0" + refY="0" + orient="auto" + inkscape:stockid="EmptyTriangleOutL"> + <path + inkscape:connector-curvature="0" + transform="matrix(0.8,0,0,0.8,-4.8,0)" + style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + d="m 5.77,0 -8.65,5 0,-10 8.65,5 z" + id="path4949-1" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8-5-0" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5-4-2-7" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8-5-8" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5-4-2-4" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0" + refX="0" + id="Arrow1Mend-6-8-5-89" + style="overflow:visible"> + <path + inkscape:connector-curvature="0" + id="path5023-5-4-2-73" + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z" + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt" + transform="matrix(-0.4,0,0,-0.4,-4,0)" /> + </marker> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + style="display:inline" + inkscape:groupmode="layer" + id="layer4" + inkscape:label="MASTER" + ns1:masterSlide="masterSlide" + sodipodi:insensitive="true"> + <rect + style="color:#000000;fill:#ffcc00;fill-opacity:1;stroke:#d4aa00;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect3358" + width="1050" + height="50" + x="0" + y="4.0944824" /> + <text + xml:space="preserve" + style="font-size:20px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="980" + y="44.094482" + id="text3607" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + x="980" + y="44.094482" + id="tspan4266">JAX-RS</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer1" + inkscape:label="JAXB support" + style="display:none"> + <rect + style="color:#000000;fill:#ffeeaa;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect6133" + width="960" + height="360" + x="40" + y="364.09448" /> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans" + x="10" + y="44.094482" + id="text6985-6" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6987-1" + x="10" + y="44.094482">JAXB support</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-9" + y="114.09448" + x="10" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + y="114.09448" + x="10" + id="tspan3069-9-3" + sodipodi:role="line">➢ </tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-6" + y="204.09448" + x="10" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + y="204.09448" + x="10" + id="tspan3069-9-0" + sodipodi:role="line">➢ @XmlRootElement / @XmlType</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-4" + y="304.09448" + x="10" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + y="304.09448" + x="10" + id="tspan3069-9-05" + sodipodi:role="line">➢ Nested class support</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-7" + y="394.09448" + x="50" + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Monospace;-inkscape-font-specification:Monospace" + xml:space="preserve"><tspan + y="394.09448" + x="50" + sodipodi:role="line" + id="tspan6120">@Path("/customers")</tspan><tspan + y="429.09448" + x="50" + sodipodi:role="line" + id="tspan6079">public class CustomerResource {</tspan><tspan + y="464.09448" + x="50" + sodipodi:role="line" + id="tspan6129" /><tspan + y="499.09448" + x="50" + sodipodi:role="line" + id="tspan6083"> @GET @Path("{id}")</tspan><tspan + y="534.09448" + x="50" + sodipodi:role="line" + id="tspan6085" + style="font-size:28px;fill:#ff0000"> @Produces("application/xml")</tspan><tspan + y="569.09448" + x="50" + sodipodi:role="line" + id="tspan6087"> public Customer getCustomer(@PathParam("id") int id) {</tspan><tspan + y="604.09448" + x="50" + sodipodi:role="line" + id="tspan6089"> Customer cust = findCustomer(id);</tspan><tspan + y="639.09448" + x="50" + sodipodi:role="line" + id="tspan6091"> return cust;</tspan><tspan + y="674.09448" + x="50" + sodipodi:role="line" + id="tspan6101"> } ...</tspan><tspan + y="709.09448" + x="50" + sodipodi:role="line" + id="tspan6105">}</tspan></text> + <text + xml:space="preserve" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans" + x="52.064919" + y="116.42295" + id="text6071" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + x="52.064919" + y="116.42295" + id="tspan6075">JAX-RS spec requires JAXB marshalling / unmarshalling </tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer2" + inkscape:label="JAXB decorator" + style="display:inline"> + <rect + style="color:#000000;fill:#ffe680;fill-opacity:1;stroke:none;stroke-width:3;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" + id="rect7507" + width="720" + height="290" + x="10" + y="224.09448" /> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Sans" + x="10" + y="44.094482" + id="text6985-6-2" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6987-1-4" + x="10" + y="44.094482">JAXB decorators</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-77" + y="124.09448" + x="20" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + y="124.09448" + x="20" + id="tspan3069-9-1" + sodipodi:role="line">➢ Modify XML transport layer</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9-60" + y="204.09448" + x="20" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve" + inkscape:transform-center-x="-36.207031" + inkscape:transform-center-y="-51.285156"><tspan + y="204.09448" + x="20" + id="tspan3069-9-4" + sodipodi:role="line">➢ Examples: XML pretty-print, validation</tspan></text> + <text + xml:space="preserve" + style="font-size:24px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace" + x="10" + y="244.09448" + id="text7345" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7347" + x="10" + y="244.09448">@Path("/customers")</tspan><tspan + sodipodi:role="line" + x="10" + y="274.09448" + id="tspan7349">public class CustomerResource {</tspan><tspan + sodipodi:role="line" + x="10" + y="304.09448" + id="tspan7365"> @GET</tspan><tspan + sodipodi:role="line" + x="10" + y="334.09448" + id="tspan7406"> @Produces("application/xml")</tspan><tspan + sodipodi:role="line" + x="10" + y="364.09448" + id="tspan7367" + style="fill:#ff0000"> @PrettyPrint</tspan><tspan + sodipodi:role="line" + x="10" + y="394.09448" + id="tspan7371"> public Collection<Customer> getAllCustomers() {</tspan><tspan + sodipodi:role="line" + x="10" + y="424.09448" + id="tspan7373"> return customerDB.values();</tspan><tspan + sodipodi:role="line" + x="10" + y="454.09448" + id="tspan7375"> }</tspan><tspan + sodipodi:role="line" + x="10" + y="484.09448" + id="tspan7412"> ...</tspan><tspan + sodipodi:role="line" + x="10" + y="514.09448" + id="tspan7414">}</tspan><tspan + sodipodi:role="line" + x="10" + y="544.09448" + id="tspan7410" /></text> + <rect + style="color:#000000;fill:#b3ff80;stroke:none;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;fill-opacity:1" + id="rect7511" + width="510" + height="250" + x="480" + y="494.09448" /> + <text + xml:space="preserve" + style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace" + x="490" + y="514.09448" + id="text7418" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7420" + x="490" + y="514.09448"><collection></tspan><tspan + sodipodi:role="line" + x="490" + y="541.59448" + id="tspan7422"> <customer id="1"></tspan><tspan + sodipodi:role="line" + x="490" + y="569.09448" + id="tspan7424"> <firstName>Martin</firstName></tspan><tspan + sodipodi:role="line" + x="490" + y="596.59448" + id="tspan7436"> ...</tspan><tspan + sodipodi:role="line" + x="490" + y="624.09448" + id="tspan7476"> </customer></tspan><tspan + sodipodi:role="line" + x="490" + y="651.59448" + id="tspan7438"> <customer id="2"></tspan><tspan + sodipodi:role="line" + x="490" + y="679.09448" + id="tspan7505"> ...</tspan><tspan + sodipodi:role="line" + x="490" + y="706.59448" + id="tspan7452"> </customer></tspan><tspan + sodipodi:role="line" + x="490" + y="734.09448" + id="tspan7454"></collection></tspan></text> + <a + id="a7554" + xlink:href="http://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html/Built_in_JAXB_providers.html#decorators" + xlink:title="http://docs.jboss.org/resteasy/docs/3.0.9.Final/userguide/html/Built_in_JAXB_providers.html#decorators"> + <text + sodipodi:linespacing="125%" + id="text7517" + y="694.09448" + x="10" + style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Monospace;-inkscape-font-specification:Monospace" + xml:space="preserve"><tspan + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Sans;-inkscape-font-specification:Sans;fill:#0000ff" + y="694.09448" + x="10" + id="tspan7519" + sodipodi:role="line">Jboss Resteasy documentation</tspan></text> + </a> + <text + xml:space="preserve" + style="font-size:22px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;display:inline;font-family:Monospace;-inkscape-font-specification:Monospace" + x="10" + y="654.09448" + id="text7517-1" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan7519-7" + x="10" + y="654.09448" + style="font-size:28px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Sans;-inkscape-font-specification:Sans">See:</tspan></text> + </g> + <g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Helpful links" + style="display:none"> + <text + xml:space="preserve" + style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans" + x="290" + y="44.094482" + id="text6985" + sodipodi:linespacing="125%"><tspan + sodipodi:role="line" + id="tspan6987" + x="290" + y="44.094482">Helpful links</tspan></text> + <text + sodipodi:linespacing="125%" + id="text3063" + y="381.0863" + x="53.511169" + style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Monospace;-inkscape-font-specification:Monospace" + xml:space="preserve"><tspan + y="381.0863" + x="53.511169" + id="tspan3065" + sodipodi:role="line" /></text> + <text + sodipodi:linespacing="125%" + id="text3067" + y="114.09448" + x="10" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + id="tspan3151" + y="114.09448" + x="10" + sodipodi:role="line">➢ RESTful Java with JAX-RS 2.0, 2nd edition </tspan></text> + <text + sodipodi:linespacing="125%" + id="text3067-9" + y="234.09448" + x="10" + style="font-size:36px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:125%;letter-spacing:0px;word-spacing:0px;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" + xml:space="preserve"><tspan + y="234.09448" + x="10" + id="tspan3069-9" + sodipodi:role="line">➢</tspan></text> + </g> + <script + id="JessyInk" + ns1:version="1.5.5">// Copyright 2008, 2009 Hannes Hochreiner +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. + +// Set onload event handler. +window.onload = jessyInkInit; + +// Creating a namespace dictionary. The standard Inkscape namespaces are taken from inkex.py. +var NSS = new Object(); +NSS['sodipodi']='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd'; +NSS['cc']='http://web.resource.org/cc/'; +NSS['svg']='http://www.w3.org/2000/svg'; +NSS['dc']='http://purl.org/dc/elements/1.1/'; +NSS['rdf']='http://www.w3.org/1999/02/22-rdf-syntax-ns#'; +NSS['inkscape']='http://www.inkscape.org/namespaces/inkscape'; +NSS['xlink']='http://www.w3.org/1999/xlink'; +NSS['xml']='http://www.w3.org/XML/1998/namespace'; +NSS['jessyink']='https://launchpad.net/jessyink'; + +// Keycodes. +var LEFT_KEY = 37; // cursor left keycode +var UP_KEY = 38; // cursor up keycode +var RIGHT_KEY = 39; // cursor right keycode +var DOWN_KEY = 40; // cursor down keycode +var PAGE_UP_KEY = 33; // page up keycode +var PAGE_DOWN_KEY = 34; // page down keycode +var HOME_KEY = 36; // home keycode +var END_KEY = 35; // end keycode +var ENTER_KEY = 13; // next slide +var SPACE_KEY = 32; +var ESCAPE_KEY = 27; + +// Presentation modes. +var SLIDE_MODE = 1; +var INDEX_MODE = 2; +var DRAWING_MODE = 3; + +// Mouse handler actions. +var MOUSE_UP = 1; +var MOUSE_DOWN = 2; +var MOUSE_MOVE = 3; +var MOUSE_WHEEL = 4; + +// Parameters. +var ROOT_NODE = document.getElementsByTagNameNS(NSS["svg"], "svg")[0]; +var HEIGHT = 0; +var WIDTH = 0; +var INDEX_COLUMNS_DEFAULT = 4; +var INDEX_COLUMNS = INDEX_COLUMNS_DEFAULT; +var INDEX_OFFSET = 0; +var STATE_START = -1; +var STATE_END = -2; +var BACKGROUND_COLOR = null; +var slides = new Array(); + +// Initialisation. +var currentMode = SLIDE_MODE; +var masterSlide = null; +var activeSlide = 0; +var activeEffect = 0; +var timeStep = 30; // 40 ms equal 25 frames per second. +var lastFrameTime = null; +var processingEffect = false; +var transCounter = 0; +var effectArray = 0; +var defaultTransitionInDict = new Object(); +defaultTransitionInDict["name"] = "appear"; +var defaultTransitionOutDict = new Object(); +defaultTransitionOutDict["name"] = "appear"; +var jessyInkInitialised = false; + +// Initialise char and key code dictionaries. +var charCodeDictionary = getDefaultCharCodeDictionary(); +var keyCodeDictionary = getDefaultKeyCodeDictionary(); + +// Initialise mouse handler dictionary. +var mouseHandlerDictionary = getDefaultMouseHandlerDictionary(); + +var progress_bar_visible = false; +var timer_elapsed = 0; +var timer_start = timer_elapsed; +var timer_duration = 15; // 15 minutes + +var history_counter = 0; +var history_original_elements = new Array(); +var history_presentation_elements = new Array(); + +var mouse_original_path = null; +var mouse_presentation_path = null; +var mouse_last_x = -1; +var mouse_last_y = -1; +var mouse_min_dist_sqr = 3 * 3; +var path_colour = "red"; +var path_width_default = 3; +var path_width = path_width_default; +var path_paint_width = path_width; + +var number_of_added_slides = 0; + +/** Initialisation function. + * The whole presentation is set-up in this function. + */ +function jessyInkInit() +{ + // Make sure we only execute this code once. Double execution can occur if the onload event handler is set + // in the main svg tag as well (as was recommended in earlier versions). Executing this function twice does + // not lead to any problems, but it takes more time. + if (jessyInkInitialised) + return; + + // Making the presentation scaleable. + var VIEWBOX = ROOT_NODE.getAttribute("viewBox"); + + if (VIEWBOX) + { + WIDTH = ROOT_NODE.viewBox.animVal.width; + HEIGHT = ROOT_NODE.viewBox.animVal.height; + } + else + { + HEIGHT = parseFloat(ROOT_NODE.getAttribute("height")); + WIDTH = parseFloat(ROOT_NODE.getAttribute("width")); + ROOT_NODE.setAttribute("viewBox", "0 0 " + WIDTH + " " + HEIGHT); + } + + ROOT_NODE.setAttribute("width", "100%"); + ROOT_NODE.setAttribute("height", "100%"); + + // Setting the background color. + var namedViews = document.getElementsByTagNameNS(NSS["sodipodi"], "namedview"); + + for (var counter = 0; counter < namedViews.length; counter++) + { + if (namedViews[counter].hasAttribute("id") && namedViews[counter].hasAttribute("pagecolor")) + { + if (namedViews[counter].getAttribute("id") == "base") + { + BACKGROUND_COLOR = namedViews[counter].getAttribute("pagecolor"); + var newAttribute = "background-color:" + BACKGROUND_COLOR + ";"; + + if (ROOT_NODE.hasAttribute("style")) + newAttribute += ROOT_NODE.getAttribute("style"); + + ROOT_NODE.setAttribute("style", newAttribute); + } + } + } + + // Defining clip-path. + var defsNodes = document.getElementsByTagNameNS(NSS["svg"], "defs"); + + if (defsNodes.length > 0) + { + var existingClipPath = document.getElementById("jessyInkSlideClipPath"); + + if (!existingClipPath) + { + var rectNode = document.createElementNS(NSS["svg"], "rect"); + var clipPath = document.createElementNS(NSS["svg"], "clipPath"); + + rectNode.setAttribute("x", 0); + rectNode.setAttribute("y", 0); + rectNode.setAttribute("width", WIDTH); + rectNode.setAttribute("height", HEIGHT); + + clipPath.setAttribute("id", "jessyInkSlideClipPath"); + clipPath.setAttribute("clipPathUnits", "userSpaceOnUse"); + + clipPath.appendChild(rectNode); + defsNodes[0].appendChild(clipPath); + } + } + + // Making a list of the slide and finding the master slide. + var nodes = document.getElementsByTagNameNS(NSS["svg"], "g"); + var tempSlides = new Array(); + var existingJessyInkPresentationLayer = null; + + for (var counter = 0; counter < nodes.length; counter++) + { + if (nodes[counter].getAttributeNS(NSS["inkscape"], "groupmode") && (nodes[counter].getAttributeNS(NSS["inkscape"], "groupmode") == "layer")) + { + if (nodes[counter].getAttributeNS(NSS["inkscape"], "label") && nodes[counter].getAttributeNS(NSS["jessyink"], "masterSlide") == "masterSlide") + masterSlide = nodes[counter]; + else if (nodes[counter].getAttributeNS(NSS["inkscape"], "label") && nodes[counter].getAttributeNS(NSS["jessyink"], "presentationLayer") == "presentationLayer") + existingJessyInkPresentationLayer = nodes[counter]; + else + tempSlides.push(nodes[counter].getAttribute("id")); + } + else if (nodes[counter].getAttributeNS(NSS['jessyink'], 'element')) + { + handleElement(nodes[counter]); + } + } + + // Hide master slide set default transitions. + if (masterSlide) + { + masterSlide.style.display = "none"; + + if (masterSlide.hasAttributeNS(NSS["jessyink"], "transitionIn")) + defaultTransitionInDict = propStrToDict(masterSlide.getAttributeNS(NSS["jessyink"], "transitionIn")); + + if (masterSlide.hasAttributeNS(NSS["jessyink"], "transitionOut")) + defaultTransitionOutDict = propStrToDict(masterSlide.getAttributeNS(NSS["jessyink"], "transitionOut")); + } + + if (existingJessyInkPresentationLayer != null) + { + existingJessyInkPresentationLayer.parentNode.removeChild(existingJessyInkPresentationLayer); + } + + // Set start slide. + var hashObj = new LocationHash(window.location.hash); + + activeSlide = hashObj.slideNumber; + activeEffect = hashObj.effectNumber; + + if (activeSlide < 0) + activeSlide = 0; + else if (activeSlide >= tempSlides.length) + activeSlide = tempSlides.length - 1; + + var originalNode = document.getElementById(tempSlides[counter]); + + var JessyInkPresentationLayer = document.createElementNS(NSS["svg"], "g"); + JessyInkPresentationLayer.setAttributeNS(NSS["inkscape"], "groupmode", "layer"); + JessyInkPresentationLayer.setAttributeNS(NSS["inkscape"], "label", "JessyInk Presentation Layer"); + JessyInkPresentationLayer.setAttributeNS(NSS["jessyink"], "presentationLayer", "presentationLayer"); + JessyInkPresentationLayer.setAttribute("id", "jessyink_presentation_layer"); + JessyInkPresentationLayer.style.display = "inherit"; + ROOT_NODE.appendChild(JessyInkPresentationLayer); + + // Gathering all the information about the transitions and effects of the slides, set the background + // from the master slide and substitute the auto-texts. + for (var counter = 0; counter < tempSlides.length; counter++) + { + var originalNode = document.getElementById(tempSlides[counter]); + originalNode.style.display = "none"; + var node = suffixNodeIds(originalNode.cloneNode(true), "_" + counter); + JessyInkPresentationLayer.appendChild(node); + slides[counter] = new Object(); + slides[counter]["original_element"] = originalNode; + slides[counter]["element"] = node; + + // Set build in transition. + slides[counter]["transitionIn"] = new Object(); + + var dict; + + if (node.hasAttributeNS(NSS["jessyink"], "transitionIn")) + dict = propStrToDict(node.getAttributeNS(NSS["jessyink"], "transitionIn")); + else + dict = defaultTransitionInDict; + + slides[counter]["transitionIn"]["name"] = dict["name"]; + slides[counter]["transitionIn"]["options"] = new Object(); + + for (key in dict) + if (key != "name") + slides[counter]["transitionIn"]["options"][key] = dict[key]; + + // Set build out transition. + slides[counter]["transitionOut"] = new Object(); + + if (node.hasAttributeNS(NSS["jessyink"], "transitionOut")) + dict = propStrToDict(node.getAttributeNS(NSS["jessyink"], "transitionOut")); + else + dict = defaultTransitionOutDict; + + slides[counter]["transitionOut"]["name"] = dict["name"]; + slides[counter]["transitionOut"]["options"] = new Object(); + + for (key in dict) + if (key != "name") + slides[counter]["transitionOut"]["options"][key] = dict[key]; + + // Copy master slide content. + if (masterSlide) + { + var clonedNode = suffixNodeIds(masterSlide.cloneNode(true), "_" + counter); + clonedNode.removeAttributeNS(NSS["inkscape"], "groupmode"); + clonedNode.removeAttributeNS(NSS["inkscape"], "label"); + clonedNode.style.display = "inherit"; + + node.insertBefore(clonedNode, node.firstChild); + } + + // Setting clip path. + node.setAttribute("clip-path", "url(#jessyInkSlideClipPath)"); + + // Substitute auto texts. + substituteAutoTexts(node, node.getAttributeNS(NSS["inkscape"], "label"), counter + 1, tempSlides.length); + + node.removeAttributeNS(NSS["inkscape"], "groupmode"); + node.removeAttributeNS(NSS["inkscape"], "label"); + + // Set effects. + var tempEffects = new Array(); + var groups = new Object(); + + for (var IOCounter = 0; IOCounter <= 1; IOCounter++) + { + var propName = ""; + var dir = 0; + + if (IOCounter == 0) + { + propName = "effectIn"; + dir = 1; + } + else if (IOCounter == 1) + { + propName = "effectOut"; + dir = -1; + } + + var effects = getElementsByPropertyNS(node, NSS["jessyink"], propName); + + for (var effectCounter = 0; effectCounter < effects.length; effectCounter++) + { + var element = document.getElementById(effects[effectCounter]); + var dict = propStrToDict(element.getAttributeNS(NSS["jessyink"], propName)); + + // Put every element that has an effect associated with it, into its own group. + // Unless of course, we already put it into its own group. + if (!(groups[element.id])) + { + var newGroup = document.createElementNS(NSS["svg"], "g"); + + element.parentNode.insertBefore(newGroup, element); + newGroup.appendChild(element.parentNode.removeChild(element)); + groups[element.id] = newGroup; + } + + var effectDict = new Object(); + + effectDict["effect"] = dict["name"]; + effectDict["dir"] = dir; + effectDict["element"] = groups[element.id]; + + for (var option in dict) + { + if ((option != "name") && (option != "order")) + { + if (!effectDict["options"]) + effectDict["options"] = new Object(); + + effectDict["options"][option] = dict[option]; + } + } + + if (!tempEffects[dict["order"]]) + tempEffects[dict["order"]] = new Array(); + + tempEffects[dict["order"]][tempEffects[dict["order"]].length] = effectDict; + } + } + + // Make invisible, but keep in rendering tree to ensure that bounding box can be calculated. + node.setAttribute("opacity",0); + node.style.display = "inherit"; + + // Create a transform group. + var transformGroup = document.createElementNS(NSS["svg"], "g"); + + // Add content to transform group. + while (node.firstChild) + transformGroup.appendChild(node.firstChild); + + // Transfer the transform attribute from the node to the transform group. + if (node.getAttribute("transform")) + { + transformGroup.setAttribute("transform", node.getAttribute("transform")); + node.removeAttribute("transform"); + } + + // Create a view group. + var viewGroup = document.createElementNS(NSS["svg"], "g"); + + viewGroup.appendChild(transformGroup); + slides[counter]["viewGroup"] = node.appendChild(viewGroup); + + // Insert background. + if (BACKGROUND_COLOR != null) + { + var rectNode = document.createElementNS(NSS["svg"], "rect"); + + rectNode.setAttribute("x", 0); + rectNode.setAttribute("y", 0); + rectNode.setAttribute("width", WIDTH); + rectNode.setAttribute("height", HEIGHT); + rectNode.setAttribute("id", "jessyInkBackground" + counter); + rectNode.setAttribute("fill", BACKGROUND_COLOR); + + slides[counter]["viewGroup"].insertBefore(rectNode, slides[counter]["viewGroup"].firstChild); + } + + // Set views. + var tempViews = new Array(); + var views = getElementsByPropertyNS(node, NSS["jessyink"], "view"); + var matrixOld = (new matrixSVG()).fromElements(1, 0, 0, 0, 1, 0, 0, 0, 1); + + // Set initial view even if there are no other views. + slides[counter]["viewGroup"].setAttribute("transform", matrixOld.toAttribute()); + slides[counter].initialView = matrixOld.toAttribute(); + + for (var viewCounter = 0; viewCounter < views.length; viewCounter++) + { + var element = document.getElementById(views[viewCounter]); + var dict = propStrToDict(element.getAttributeNS(NSS["jessyink"], "view")); + + if (dict["order"] == 0) + { + matrixOld = pointMatrixToTransformation(rectToMatrix(element)).mult((new matrixSVG()).fromSVGMatrix(slides[counter].viewGroup.getScreenCTM()).inv().mult((new matrixSVG()).fromSVGMatrix(element.parentNode.getScreenCTM())).inv()); + slides[counter].initialView = matrixOld.toAttribute(); + } + else + { + var effectDict = new Object(); + + effectDict["effect"] = dict["name"]; + effectDict["dir"] = 1; + effectDict["element"] = slides[counter]["viewGroup"]; + effectDict["order"] = dict["order"]; + + for (var option in dict) + { + if ((option != "name") && (option != "order")) + { + if (!effectDict["options"]) + effectDict["options"] = new Object(); + + effectDict["options"][option] = dict[option]; + } + } + + effectDict["options"]["matrixNew"] = pointMatrixToTransformation(rectToMatrix(element)).mult((new matrixSVG()).fromSVGMatrix(slides[counter].viewGroup.getScreenCTM()).inv().mult((new matrixSVG()).fromSVGMatrix(element.parentNode.getScreenCTM())).inv()); + + tempViews[dict["order"]] = effectDict; + } + + // Remove element. + element.parentNode.removeChild(element); + } + + // Consolidate view array and append it to the effect array. + if (tempViews.length > 0) + { + for (var viewCounter = 0; viewCounter < tempViews.length; viewCounter++) + { + if (tempViews[viewCounter]) + { + tempViews[viewCounter]["options"]["matrixOld"] = matrixOld; + matrixOld = tempViews[viewCounter]["options"]["matrixNew"]; + + if (!tempEffects[tempViews[viewCounter]["order"]]) + tempEffects[tempViews[viewCounter]["order"]] = new Array(); + + tempEffects[tempViews[viewCounter]["order"]][tempEffects[tempViews[viewCounter]["order"]].length] = tempViews[viewCounter]; + } + } + } + + // Set consolidated effect array. + if (tempEffects.length > 0) + { + slides[counter]["effects"] = new Array(); + + for (var effectCounter = 0; effectCounter < tempEffects.length; effectCounter++) + { + if (tempEffects[effectCounter]) + slides[counter]["effects"][slides[counter]["effects"].length] = tempEffects[effectCounter]; + } + } + + node.setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + counter + ")) { indexSetActiveSlide(" + counter + "); };"); + + // Set visibility for initial state. + if (counter == activeSlide) + { + node.style.display = "inherit"; + node.setAttribute("opacity",1); + } + else + { + node.style.display = "none"; + node.setAttribute("opacity",0); + } + } + + // Set key handler. + var jessyInkObjects = document.getElementsByTagNameNS(NSS["svg"], "g"); + + for (var counter = 0; counter < jessyInkObjects.length; counter++) + { + var elem = jessyInkObjects[counter]; + + if (elem.getAttributeNS(NSS["jessyink"], "customKeyBindings")) + { + if (elem.getCustomKeyBindings != undefined) + keyCodeDictionary = elem.getCustomKeyBindings(); + + if (elem.getCustomCharBindings != undefined) + charCodeDictionary = elem.getCustomCharBindings(); + } + } + + // Set mouse handler. + var jessyInkMouseHandler = document.getElementsByTagNameNS(NSS["jessyink"], "mousehandler"); + + for (var counter = 0; counter < jessyInkMouseHandler.length; counter++) + { + var elem = jessyInkMouseHandler[counter]; + + if (elem.getMouseHandler != undefined) + { + var tempDict = elem.getMouseHandler(); + + for (mode in tempDict) + { + if (!mouseHandlerDictionary[mode]) + mouseHandlerDictionary[mode] = new Object(); + + for (handler in tempDict[mode]) + mouseHandlerDictionary[mode][handler] = tempDict[mode][handler]; + } + } + } + + // Check effect number. + if ((activeEffect < 0) || (!slides[activeSlide].effects)) + { + activeEffect = 0; + } + else if (activeEffect > slides[activeSlide].effects.length) + { + activeEffect = slides[activeSlide].effects.length; + } + + createProgressBar(JessyInkPresentationLayer); + hideProgressBar(); + setProgressBarValue(activeSlide); + setTimeIndicatorValue(0); + setInterval("updateTimer()", 1000); + setSlideToState(activeSlide, activeEffect); + jessyInkInitialised = true; +} + +/** Function to subtitute the auto-texts. + * + * @param node the node + * @param slideName name of the slide the node is on + * @param slideNumber number of the slide the node is on + * @param numberOfSlides number of slides in the presentation + */ +function substituteAutoTexts(node, slideName, slideNumber, numberOfSlides) +{ + var texts = node.getElementsByTagNameNS(NSS["svg"], "tspan"); + + for (var textCounter = 0; textCounter < texts.length; textCounter++) + { + if (texts[textCounter].getAttributeNS(NSS["jessyink"], "autoText") == "slideNumber") + texts[textCounter].firstChild.nodeValue = slideNumber; + else if (texts[textCounter].getAttributeNS(NSS["jessyink"], "autoText") == "numberOfSlides") + texts[textCounter].firstChild.nodeValue = numberOfSlides; + else if (texts[textCounter].getAttributeNS(NSS["jessyink"], "autoText") == "slideTitle") + texts[textCounter].firstChild.nodeValue = slideName; + } +} + +/** Convenience function to get an element depending on whether it has a property with a particular name. + * This function emulates some dearly missed XPath functionality. + * + * @param node the node + * @param namespace namespace of the attribute + * @param name attribute name + */ +function getElementsByPropertyNS(node, namespace, name) +{ + var elems = new Array(); + + if (node.getAttributeNS(namespace, name)) + elems.push(node.getAttribute("id")); + + for (var counter = 0; counter < node.childNodes.length; counter++) + { + if (node.childNodes[counter].nodeType == 1) + elems = elems.concat(getElementsByPropertyNS(node.childNodes[counter], namespace, name)); + } + + return elems; +} + +/** Function to dispatch the next effect, if there is none left, change the slide. + * + * @param dir direction of the change (1 = forwards, -1 = backwards) + */ +function dispatchEffects(dir) +{ + if (slides[activeSlide]["effects"] && (((dir == 1) && (activeEffect < slides[activeSlide]["effects"].length)) || ((dir == -1) && (activeEffect > 0)))) + { + processingEffect = true; + + if (dir == 1) + { + effectArray = slides[activeSlide]["effects"][activeEffect]; + activeEffect += dir; + } + else if (dir == -1) + { + activeEffect += dir; + effectArray = slides[activeSlide]["effects"][activeEffect]; + } + + transCounter = 0; + startTime = (new Date()).getTime(); + lastFrameTime = null; + effect(dir); + } + else if (((dir == 1) && (activeSlide < (slides.length - 1))) || (((dir == -1) && (activeSlide > 0)))) + { + changeSlide(dir); + } +} + +/** Function to skip effects and directly either put the slide into start or end state or change slides. + * + * @param dir direction of the change (1 = forwards, -1 = backwards) + */ +function skipEffects(dir) +{ + if (slides[activeSlide]["effects"] && (((dir == 1) && (activeEffect < slides[activeSlide]["effects"].length)) || ((dir == -1) && (activeEffect > 0)))) + { + processingEffect = true; + + if (slides[activeSlide]["effects"] && (dir == 1)) + activeEffect = slides[activeSlide]["effects"].length; + else + activeEffect = 0; + + if (dir == 1) + setSlideToState(activeSlide, STATE_END); + else + setSlideToState(activeSlide, STATE_START); + + processingEffect = false; + } + else if (((dir == 1) && (activeSlide < (slides.length - 1))) || (((dir == -1) && (activeSlide > 0)))) + { + changeSlide(dir); + } +} + +/** Function to change between slides. + * + * @param dir direction (1 = forwards, -1 = backwards) + */ +function changeSlide(dir) +{ + processingEffect = true; + effectArray = new Array(); + + effectArray[0] = new Object(); + if (dir == 1) + { + effectArray[0]["effect"] = slides[activeSlide]["transitionOut"]["name"]; + effectArray[0]["options"] = slides[activeSlide]["transitionOut"]["options"]; + effectArray[0]["dir"] = -1; + } + else if (dir == -1) + { + effectArray[0]["effect"] = slides[activeSlide]["transitionIn"]["name"]; + effectArray[0]["options"] = slides[activeSlide]["transitionIn"]["options"]; + effectArray[0]["dir"] = 1; + } + effectArray[0]["element"] = slides[activeSlide]["element"]; + + activeSlide += dir; + setProgressBarValue(activeSlide); + + effectArray[1] = new Object(); + + if (dir == 1) + { + effectArray[1]["effect"] = slides[activeSlide]["transitionIn"]["name"]; + effectArray[1]["options"] = slides[activeSlide]["transitionIn"]["options"]; + effectArray[1]["dir"] = 1; + } + else if (dir == -1) + { + effectArray[1]["effect"] = slides[activeSlide]["transitionOut"]["name"]; + effectArray[1]["options"] = slides[activeSlide]["transitionOut"]["options"]; + effectArray[1]["dir"] = -1; + } + + effectArray[1]["element"] = slides[activeSlide]["element"]; + + if (slides[activeSlide]["effects"] && (dir == -1)) + activeEffect = slides[activeSlide]["effects"].length; + else + activeEffect = 0; + + if (dir == -1) + setSlideToState(activeSlide, STATE_END); + else + setSlideToState(activeSlide, STATE_START); + + transCounter = 0; + startTime = (new Date()).getTime(); + lastFrameTime = null; + effect(dir); +} + +/** Function to toggle between index and slide mode. +*/ +function toggleSlideIndex() +{ + var suspendHandle = ROOT_NODE.suspendRedraw(500); + + if (currentMode == SLIDE_MODE) + { + hideProgressBar(); + INDEX_OFFSET = -1; + indexSetPageSlide(activeSlide); + currentMode = INDEX_MODE; + } + else if (currentMode == INDEX_MODE) + { + for (var counter = 0; counter < slides.length; counter++) + { + slides[counter]["element"].setAttribute("transform","scale(1)"); + + if (counter == activeSlide) + { + slides[counter]["element"].style.display = "inherit"; + slides[counter]["element"].setAttribute("opacity",1); + activeEffect = 0; + } + else + { + slides[counter]["element"].setAttribute("opacity",0); + slides[counter]["element"].style.display = "none"; + } + } + currentMode = SLIDE_MODE; + setSlideToState(activeSlide, STATE_START); + setProgressBarValue(activeSlide); + + if (progress_bar_visible) + { + showProgressBar(); + } + } + + ROOT_NODE.unsuspendRedraw(suspendHandle); + ROOT_NODE.forceRedraw(); +} + +/** Function to run an effect. + * + * @param dir direction in which to play the effect (1 = forwards, -1 = backwards) + */ +function effect(dir) +{ + var done = true; + + var suspendHandle = ROOT_NODE.suspendRedraw(200); + + for (var counter = 0; counter < effectArray.length; counter++) + { + if (effectArray[counter]["effect"] == "fade") + done &= fade(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]); + else if (effectArray[counter]["effect"] == "appear") + done &= appear(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]); + else if (effectArray[counter]["effect"] == "pop") + done &= pop(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]); + else if (effectArray[counter]["effect"] == "view") + done &= view(parseInt(effectArray[counter]["dir"]) * dir, effectArray[counter]["element"], transCounter, effectArray[counter]["options"]); + } + + ROOT_NODE.unsuspendRedraw(suspendHandle); + ROOT_NODE.forceRedraw(); + + if (!done) + { + var currentTime = (new Date()).getTime(); + var timeDiff = 1; + + transCounter = currentTime - startTime; + + if (lastFrameTime != null) + { + timeDiff = timeStep - (currentTime - lastFrameTime); + + if (timeDiff <= 0) + timeDiff = 1; + } + + lastFrameTime = currentTime; + + window.setTimeout("effect(" + dir + ")", timeDiff); + } + else + { + window.location.hash = (activeSlide + 1) + '_' + activeEffect; + processingEffect = false; + } +} + +/** Function to display the index sheet. + * + * @param offsetNumber offset number + */ +function displayIndex(offsetNumber) +{ + var offsetX = 0; + var offsetY = 0; + + if (offsetNumber < 0) + offsetNumber = 0; + else if (offsetNumber >= slides.length) + offsetNumber = slides.length - 1; + + for (var counter = 0; counter < slides.length; counter++) + { + if ((counter < offsetNumber) || (counter > offsetNumber + INDEX_COLUMNS * INDEX_COLUMNS - 1)) + { + slides[counter]["element"].setAttribute("opacity",0); + slides[counter]["element"].style.display = "none"; + } + else + { + offsetX = ((counter - offsetNumber) % INDEX_COLUMNS) * WIDTH; + offsetY = Math.floor((counter - offsetNumber) / INDEX_COLUMNS) * HEIGHT; + + slides[counter]["element"].setAttribute("transform","scale("+1/INDEX_COLUMNS+") translate("+offsetX+","+offsetY+")"); + slides[counter]["element"].style.display = "inherit"; + slides[counter]["element"].setAttribute("opacity",0.5); + } + + setSlideToState(counter, STATE_END); + } + + //do we need to save the current offset? + if (INDEX_OFFSET != offsetNumber) + INDEX_OFFSET = offsetNumber; +} + +/** Function to set the active slide in the slide view. + * + * @param nbr index of the active slide + */ +function slideSetActiveSlide(nbr) +{ + if (nbr >= slides.length) + nbr = slides.length - 1; + else if (nbr < 0) + nbr = 0; + + slides[activeSlide]["element"].setAttribute("opacity",0); + slides[activeSlide]["element"].style.display = "none"; + + activeSlide = parseInt(nbr); + + setSlideToState(activeSlide, STATE_START); + slides[activeSlide]["element"].style.display = "inherit"; + slides[activeSlide]["element"].setAttribute("opacity",1); + + activeEffect = 0; + setProgressBarValue(nbr); +} + +/** Function to set the active slide in the index view. + * + * @param nbr index of the active slide + */ +function indexSetActiveSlide(nbr) +{ + if (nbr >= slides.length) + nbr = slides.length - 1; + else if (nbr < 0) + nbr = 0; + + slides[activeSlide]["element"].setAttribute("opacity",0.5); + + activeSlide = parseInt(nbr); + window.location.hash = (activeSlide + 1) + '_0'; + + slides[activeSlide]["element"].setAttribute("opacity",1); +} + +/** Function to set the page and active slide in index view. + * + * @param nbr index of the active slide + * + * NOTE: To force a redraw, + * set INDEX_OFFSET to -1 before calling indexSetPageSlide(). + * + * This is necessary for zooming (otherwise the index might not + * get redrawn) and when switching to index mode. + * + * INDEX_OFFSET = -1 + * indexSetPageSlide(activeSlide); + */ +function indexSetPageSlide(nbr) +{ + if (nbr >= slides.length) + nbr = slides.length - 1; + else if (nbr < 0) + nbr = 0; + + //calculate the offset + var offset = nbr - nbr % (INDEX_COLUMNS * INDEX_COLUMNS); + + if (offset < 0) + offset = 0; + + //if different from kept offset, then record and change the page + if (offset != INDEX_OFFSET) + { + INDEX_OFFSET = offset; + displayIndex(INDEX_OFFSET); + } + + //set the active slide + indexSetActiveSlide(nbr); +} + +/** Event handler for key press. + * + * @param e the event + */ +function keydown(e) +{ + if (!e) + e = window.event; + + code = e.keyCode || e.charCode; + + if (!processingEffect && keyCodeDictionary[currentMode] && keyCodeDictionary[currentMode][code]) + return keyCodeDictionary[currentMode][code](); + else + document.onkeypress = keypress; +} +// Set event handler for key down. +document.onkeydown = keydown; + +/** Event handler for key press. + * + * @param e the event + */ +function keypress(e) +{ + document.onkeypress = null; + + if (!e) + e = window.event; + + str = String.fromCharCode(e.keyCode || e.charCode); + + if (!processingEffect && charCodeDictionary[currentMode] && charCodeDictionary[currentMode][str]) + return charCodeDictionary[currentMode][str](); +} + +/** Function to supply the default char code dictionary. + * + * @returns default char code dictionary + */ +function getDefaultCharCodeDictionary() +{ + var charCodeDict = new Object(); + + charCodeDict[SLIDE_MODE] = new Object(); + charCodeDict[INDEX_MODE] = new Object(); + charCodeDict[DRAWING_MODE] = new Object(); + + charCodeDict[SLIDE_MODE]["i"] = function () { return toggleSlideIndex(); }; + charCodeDict[SLIDE_MODE]["d"] = function () { return slideSwitchToDrawingMode(); }; + charCodeDict[SLIDE_MODE]["D"] = function () { return slideQueryDuration(); }; + charCodeDict[SLIDE_MODE]["n"] = function () { return slideAddSlide(activeSlide); }; + charCodeDict[SLIDE_MODE]["p"] = function () { return slideToggleProgressBarVisibility(); }; + charCodeDict[SLIDE_MODE]["t"] = function () { return slideResetTimer(); }; + charCodeDict[SLIDE_MODE]["e"] = function () { return slideUpdateExportLayer(); }; + + charCodeDict[DRAWING_MODE]["d"] = function () { return drawingSwitchToSlideMode(); }; + charCodeDict[DRAWING_MODE]["0"] = function () { return drawingResetPathWidth(); }; + charCodeDict[DRAWING_MODE]["1"] = function () { return drawingSetPathWidth(1.0); }; + charCodeDict[DRAWING_MODE]["3"] = function () { return drawingSetPathWidth(3.0); }; + charCodeDict[DRAWING_MODE]["5"] = function () { return drawingSetPathWidth(5.0); }; + charCodeDict[DRAWING_MODE]["7"] = function () { return drawingSetPathWidth(7.0); }; + charCodeDict[DRAWING_MODE]["9"] = function () { return drawingSetPathWidth(9.0); }; + charCodeDict[DRAWING_MODE]["b"] = function () { return drawingSetPathColour("blue"); }; + charCodeDict[DRAWING_MODE]["c"] = function () { return drawingSetPathColour("cyan"); }; + charCodeDict[DRAWING_MODE]["g"] = function () { return drawingSetPathColour("green"); }; + charCodeDict[DRAWING_MODE]["k"] = function () { return drawingSetPathColour("black"); }; + charCodeDict[DRAWING_MODE]["m"] = function () { return drawingSetPathColour("magenta"); }; + charCodeDict[DRAWING_MODE]["o"] = function () { return drawingSetPathColour("orange"); }; + charCodeDict[DRAWING_MODE]["r"] = function () { return drawingSetPathColour("red"); }; + charCodeDict[DRAWING_MODE]["w"] = function () { return drawingSetPathColour("white"); }; + charCodeDict[DRAWING_MODE]["y"] = function () { return drawingSetPathColour("yellow"); }; + charCodeDict[DRAWING_MODE]["z"] = function () { return drawingUndo(); }; + + charCodeDict[INDEX_MODE]["i"] = function () { return toggleSlideIndex(); }; + charCodeDict[INDEX_MODE]["-"] = function () { return indexDecreaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]["="] = function () { return indexIncreaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]["+"] = function () { return indexIncreaseNumberOfColumns(); }; + charCodeDict[INDEX_MODE]["0"] = function () { return indexResetNumberOfColumns(); }; + + return charCodeDict; +} + +/** Function to supply the default key code dictionary. + * + * @returns default key code dictionary + */ +function getDefaultKeyCodeDictionary() +{ + var keyCodeDict = new Object(); + + keyCodeDict[SLIDE_MODE] = new Object(); + keyCodeDict[INDEX_MODE] = new Object(); + keyCodeDict[DRAWING_MODE] = new Object(); + + keyCodeDict[SLIDE_MODE][LEFT_KEY] = function() { return dispatchEffects(-1); }; + keyCodeDict[SLIDE_MODE][RIGHT_KEY] = function() { return dispatchEffects(1); }; + keyCodeDict[SLIDE_MODE][UP_KEY] = function() { return skipEffects(-1); }; + keyCodeDict[SLIDE_MODE][DOWN_KEY] = function() { return skipEffects(1); }; + keyCodeDict[SLIDE_MODE][PAGE_UP_KEY] = function() { return dispatchEffects(-1); }; + keyCodeDict[SLIDE_MODE][PAGE_DOWN_KEY] = function() { return dispatchEffects(1); }; + keyCodeDict[SLIDE_MODE][HOME_KEY] = function() { return slideSetActiveSlide(0); }; + keyCodeDict[SLIDE_MODE][END_KEY] = function() { return slideSetActiveSlide(slides.length - 1); }; + keyCodeDict[SLIDE_MODE][SPACE_KEY] = function() { return dispatchEffects(1); }; + + keyCodeDict[INDEX_MODE][LEFT_KEY] = function() { return indexSetPageSlide(activeSlide - 1); }; + keyCodeDict[INDEX_MODE][RIGHT_KEY] = function() { return indexSetPageSlide(activeSlide + 1); }; + keyCodeDict[INDEX_MODE][UP_KEY] = function() { return indexSetPageSlide(activeSlide - INDEX_COLUMNS); }; + keyCodeDict[INDEX_MODE][DOWN_KEY] = function() { return indexSetPageSlide(activeSlide + INDEX_COLUMNS); }; + keyCodeDict[INDEX_MODE][PAGE_UP_KEY] = function() { return indexSetPageSlide(activeSlide - INDEX_COLUMNS * INDEX_COLUMNS); }; + keyCodeDict[INDEX_MODE][PAGE_DOWN_KEY] = function() { return indexSetPageSlide(activeSlide + INDEX_COLUMNS * INDEX_COLUMNS); }; + keyCodeDict[INDEX_MODE][HOME_KEY] = function() { return indexSetPageSlide(0); }; + keyCodeDict[INDEX_MODE][END_KEY] = function() { return indexSetPageSlide(slides.length - 1); }; + keyCodeDict[INDEX_MODE][ENTER_KEY] = function() { return toggleSlideIndex(); }; + + keyCodeDict[DRAWING_MODE][ESCAPE_KEY] = function () { return drawingSwitchToSlideMode(); }; + + return keyCodeDict; +} + +/** Function to handle all mouse events. + * + * @param evnt event + * @param action type of event (e.g. mouse up, mouse wheel) + */ +function mouseHandlerDispatch(evnt, action) +{ + if (!evnt) + evnt = window.event; + + var retVal = true; + + if (!processingEffect && mouseHandlerDictionary[currentMode] && mouseHandlerDictionary[currentMode][action]) + { + var subRetVal = mouseHandlerDictionary[currentMode][action](evnt); + + if (subRetVal != null && subRetVal != undefined) + retVal = subRetVal; + } + + if (evnt.preventDefault && !retVal) + evnt.preventDefault(); + + evnt.returnValue = retVal; + + return retVal; +} + +// Set mouse event handler. +document.onmousedown = function(e) { return mouseHandlerDispatch(e, MOUSE_DOWN); }; +document.onmouseup = function(e) { return mouseHandlerDispatch(e, MOUSE_UP); }; +document.onmousemove = function(e) { return mouseHandlerDispatch(e, MOUSE_MOVE); }; + +// Moz +if (window.addEventListener) +{ + window.addEventListener('DOMMouseScroll', function(e) { return mouseHandlerDispatch(e, MOUSE_WHEEL); }, false); +} + +// Opera Safari OK - may not work in IE +window.onmousewheel = function(e) { return mouseHandlerDispatch(e, MOUSE_WHEEL); }; + +/** Function to supply the default mouse handler dictionary. + * + * @returns default mouse handler dictionary + */ +function getDefaultMouseHandlerDictionary() +{ + var mouseHandlerDict = new Object(); + + mouseHandlerDict[SLIDE_MODE] = new Object(); + mouseHandlerDict[INDEX_MODE] = new Object(); + mouseHandlerDict[DRAWING_MODE] = new Object(); + + mouseHandlerDict[SLIDE_MODE][MOUSE_DOWN] = function(evnt) { return dispatchEffects(1); }; + mouseHandlerDict[SLIDE_MODE][MOUSE_WHEEL] = function(evnt) { return slideMousewheel(evnt); }; + + mouseHandlerDict[INDEX_MODE][MOUSE_DOWN] = function(evnt) { return toggleSlideIndex(); }; + + mouseHandlerDict[DRAWING_MODE][MOUSE_DOWN] = function(evnt) { return drawingMousedown(evnt); }; + mouseHandlerDict[DRAWING_MODE][MOUSE_UP] = function(evnt) { return drawingMouseup(evnt); }; + mouseHandlerDict[DRAWING_MODE][MOUSE_MOVE] = function(evnt) { return drawingMousemove(evnt); }; + + return mouseHandlerDict; +} + +/** Function to switch from slide mode to drawing mode. +*/ +function slideSwitchToDrawingMode() +{ + currentMode = DRAWING_MODE; + + var tempDict; + + if (ROOT_NODE.hasAttribute("style")) + tempDict = propStrToDict(ROOT_NODE.getAttribute("style")); + else + tempDict = new Object(); + + tempDict["cursor"] = "crosshair"; + ROOT_NODE.setAttribute("style", dictToPropStr(tempDict)); +} + +/** Function to switch from drawing mode to slide mode. +*/ +function drawingSwitchToSlideMode() +{ + currentMode = SLIDE_MODE; + + var tempDict; + + if (ROOT_NODE.hasAttribute("style")) + tempDict = propStrToDict(ROOT_NODE.getAttribute("style")); + else + tempDict = new Object(); + + tempDict["cursor"] = "auto"; + ROOT_NODE.setAttribute("style", dictToPropStr(tempDict)); +} + +/** Function to decrease the number of columns in index mode. +*/ +function indexDecreaseNumberOfColumns() +{ + if (INDEX_COLUMNS >= 3) + { + INDEX_COLUMNS -= 1; + INDEX_OFFSET = -1 + indexSetPageSlide(activeSlide); + } +} + +/** Function to increase the number of columns in index mode. +*/ +function indexIncreaseNumberOfColumns() +{ + if (INDEX_COLUMNS < 7) + { + INDEX_COLUMNS += 1; + INDEX_OFFSET = -1 + indexSetPageSlide(activeSlide); + } +} + +/** Function to reset the number of columns in index mode. +*/ +function indexResetNumberOfColumns() +{ + if (INDEX_COLUMNS != INDEX_COLUMNS_DEFAULT) + { + INDEX_COLUMNS = INDEX_COLUMNS_DEFAULT; + INDEX_OFFSET = -1 + indexSetPageSlide(activeSlide); + } +} + +/** Function to reset path width in drawing mode. +*/ +function drawingResetPathWidth() +{ + path_width = path_width_default; + set_path_paint_width(); +} + +/** Function to set path width in drawing mode. + * + * @param width new path width + */ +function drawingSetPathWidth(width) +{ + path_width = width; + set_path_paint_width(); +} + +/** Function to set path colour in drawing mode. + * + * @param colour new path colour + */ +function drawingSetPathColour(colour) +{ + path_colour = colour; +} + +/** Function to query the duration of the presentation from the user in slide mode. +*/ +function slideQueryDuration() +{ + var new_duration = prompt("Length of presentation in minutes?", timer_duration); + + if ((new_duration != null) && (new_duration != '')) + { + timer_duration = new_duration; + } + + updateTimer(); +} + +/** Function to add new slide in slide mode. + * + * @param afterSlide after which slide to insert the new one + */ +function slideAddSlide(afterSlide) +{ + addSlide(afterSlide); + slideSetActiveSlide(afterSlide + 1); + updateTimer(); +} + +/** Function to toggle the visibility of the progress bar in slide mode. +*/ +function slideToggleProgressBarVisibility() +{ + if (progress_bar_visible) + { + progress_bar_visible = false; + hideProgressBar(); + } + else + { + progress_bar_visible = true; + showProgressBar(); + } +} + +/** Function to reset the timer in slide mode. +*/ +function slideResetTimer() +{ + timer_start = timer_elapsed; + updateTimer(); +} + +/** Convenience function to pad a string with zero in front up to a certain length. + */ +function padString(str, len) +{ + var outStr = str; + + while (outStr.length < len) + { + outStr = '0' + outStr; + } + + return outStr; +} + +/** Function to update the export layer. + */ +function slideUpdateExportLayer() +{ + // Suspend redraw since we are going to mess with the slides. + var suspendHandle = ROOT_NODE.suspendRedraw(2000); + + var tmpActiveSlide = activeSlide; + var tmpActiveEffect = activeEffect; + var exportedLayers = new Array(); + + for (var counterSlides = 0; counterSlides < slides.length; counterSlides++) + { + var exportNode; + + setSlideToState(counterSlides, STATE_START); + + var maxEffect = 0; + + if (slides[counterSlides].effects) + { + maxEffect = slides[counterSlides].effects.length; + } + + exportNode = slides[counterSlides].element.cloneNode(true); + exportNode.setAttributeNS(NSS["inkscape"], "groupmode", "layer"); + exportNode.setAttributeNS(NSS["inkscape"], "label", "slide_" + padString((counterSlides + 1).toString(), slides.length.toString().length) + "_effect_" + padString("0", maxEffect.toString().length)); + + exportedLayers.push(exportNode); + + if (slides[counterSlides]["effects"]) + { + for (var counter = 0; counter < slides[counterSlides]["effects"].length; counter++) + { + for (var subCounter = 0; subCounter < slides[counterSlides]["effects"][counter].length; subCounter++) + { + var effect = slides[counterSlides]["effects"][counter][subCounter]; + if (effect["effect"] == "fade") + fade(parseInt(effect["dir"]), effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "appear") + appear(parseInt(effect["dir"]), effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "pop") + pop(parseInt(effect["dir"]), effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "view") + view(parseInt(effect["dir"]), effect["element"], STATE_END, effect["options"]); + } + + var layerName = "slide_" + padString((counterSlides + 1).toString(), slides.length.toString().length) + "_effect_" + padString((counter + 1).toString(), maxEffect.toString().length); + exportNode = slides[counterSlides].element.cloneNode(true); + exportNode.setAttributeNS(NSS["inkscape"], "groupmode", "layer"); + exportNode.setAttributeNS(NSS["inkscape"], "label", layerName); + exportNode.setAttribute("id", layerName); + + exportedLayers.push(exportNode); + } + } + } + + activeSlide = tmpActiveSlide; + activeEffect = tmpActiveEffect; + setSlideToState(activeSlide, activeEffect); + + // Copy image. + var newDoc = document.documentElement.cloneNode(true); + + // Delete viewbox form new imag and set width and height. + newDoc.removeAttribute('viewbox'); + newDoc.setAttribute('width', WIDTH); + newDoc.setAttribute('height', HEIGHT); + + // Delete all layers and script elements. + var nodesToBeRemoved = new Array(); + + for (var childCounter = 0; childCounter < newDoc.childNodes.length; childCounter++) + { + var child = newDoc.childNodes[childCounter]; + + if (child.nodeType == 1) + { + if ((child.nodeName.toUpperCase() == 'G') || (child.nodeName.toUpperCase() == 'SCRIPT')) + { + nodesToBeRemoved.push(child); + } + } + } + + for (var ndCounter = 0; ndCounter < nodesToBeRemoved.length; ndCounter++) + { + var nd = nodesToBeRemoved[ndCounter]; + + // Before removing the node, check whether it contains any definitions. + var defs = nd.getElementsByTagNameNS(NSS["svg"], "defs"); + + for (var defsCounter = 0; defsCounter < defs.length; defsCounter++) + { + if (defs[defsCounter].id) + { + newDoc.appendChild(defs[defsCounter].cloneNode(true)); + } + } + + // Remove node. + nd.parentNode.removeChild(nd); + } + + // Set current layer. + if (exportedLayers[0]) + { + var namedView; + + for (var nodeCounter = 0; nodeCounter < newDoc.childNodes.length; nodeCounter++) + { + if ((newDoc.childNodes[nodeCounter].nodeType == 1) && (newDoc.childNodes[nodeCounter].getAttribute('id') == 'base')) + { + namedView = newDoc.childNodes[nodeCounter]; + } + } + + if (namedView) + { + namedView.setAttributeNS(NSS['inkscape'], 'current-layer', exportedLayers[0].getAttributeNS(NSS['inkscape'], 'label')); + } + } + + // Add exported layers. + while (exportedLayers.length > 0) + { + var nd = exportedLayers.pop(); + + nd.setAttribute("opacity",1); + nd.style.display = "inherit"; + + newDoc.appendChild(nd); + } + + // Serialise the new document. + var serializer = new XMLSerializer(); + var strm = + { + content : "", + close : function() {}, + flush : function() {}, + write : function(str, count) { this.content += str; } + }; + + var xml = serializer.serializeToStream(newDoc, strm, 'UTF-8'); + + window.location = 'data:application/svg+xml;base64;charset=utf-8,' + window.btoa(strm.content); + + // Unsuspend redraw. + ROOT_NODE.unsuspendRedraw(suspendHandle); + ROOT_NODE.forceRedraw(); +} + +/** Function to undo last drawing operation. +*/ +function drawingUndo() +{ + mouse_presentation_path = null; + mouse_original_path = null; + + if (history_presentation_elements.length > 0) + { + var p = history_presentation_elements.pop(); + var parent = p.parentNode.removeChild(p); + + p = history_original_elements.pop(); + parent = p.parentNode.removeChild(p); + } +} + +/** Event handler for mouse down in drawing mode. + * + * @param e the event + */ +function drawingMousedown(e) +{ + var value = 0; + + if (e.button) + value = e.button; + else if (e.which) + value = e.which; + + if (value == 1) + { + history_counter++; + + var p = calcCoord(e); + + mouse_last_x = e.clientX; + mouse_last_y = e.clientY; + mouse_original_path = document.createElementNS(NSS["svg"], "path"); + mouse_original_path.setAttribute("stroke", path_colour); + mouse_original_path.setAttribute("stroke-width", path_paint_width); + mouse_original_path.setAttribute("fill", "none"); + mouse_original_path.setAttribute("id", "path " + Date()); + mouse_original_path.setAttribute("d", "M" + p.x + "," + p.y); + slides[activeSlide]["original_element"].appendChild(mouse_original_path); + history_original_elements.push(mouse_original_path); + + mouse_presentation_path = document.createElementNS(NSS["svg"], "path"); + mouse_presentation_path.setAttribute("stroke", path_colour); + mouse_presentation_path.setAttribute("stroke-width", path_paint_width); + mouse_presentation_path.setAttribute("fill", "none"); + mouse_presentation_path.setAttribute("id", "path " + Date() + " presentation copy"); + mouse_presentation_path.setAttribute("d", "M" + p.x + "," + p.y); + + if (slides[activeSlide]["viewGroup"]) + slides[activeSlide]["viewGroup"].appendChild(mouse_presentation_path); + else + slides[activeSlide]["element"].appendChild(mouse_presentation_path); + + history_presentation_elements.push(mouse_presentation_path); + + return false; + } + + return true; +} + +/** Event handler for mouse up in drawing mode. + * + * @param e the event + */ +function drawingMouseup(e) +{ + if(!e) + e = window.event; + + if (mouse_presentation_path != null) + { + var p = calcCoord(e); + var d = mouse_presentation_path.getAttribute("d"); + d += " L" + p.x + "," + p.y; + mouse_presentation_path.setAttribute("d", d); + mouse_presentation_path = null; + mouse_original_path.setAttribute("d", d); + mouse_original_path = null; + + return false; + } + + return true; +} + +/** Event handler for mouse move in drawing mode. + * + * @param e the event + */ +function drawingMousemove(e) +{ + if(!e) + e = window.event; + + var dist = (mouse_last_x - e.clientX) * (mouse_last_x - e.clientX) + (mouse_last_y - e.clientY) * (mouse_last_y - e.clientY); + + if (mouse_presentation_path == null) + { + return true; + } + + if (dist >= mouse_min_dist_sqr) + { + var p = calcCoord(e); + var d = mouse_presentation_path.getAttribute("d"); + d += " L" + p.x + "," + p.y; + mouse_presentation_path.setAttribute("d", d); + mouse_original_path.setAttribute("d", d); + mouse_last_x = e.clientX; + mouse_last_y = e.clientY; + } + + return false; +} + +/** Event handler for mouse wheel events in slide mode. + * based on http://adomas.org/javascript-mouse-wheel/ + * + * @param e the event + */ +function slideMousewheel(e) +{ + var delta = 0; + + if (!e) + e = window.event; + + if (e.wheelDelta) + { // IE Opera + delta = e.wheelDelta/120; + } + else if (e.detail) + { // MOZ + delta = -e.detail/3; + } + + if (delta > 0) + skipEffects(-1); + else if (delta < 0) + skipEffects(1); + + if (e.preventDefault) + e.preventDefault(); + + e.returnValue = false; +} + +/** Event handler for mouse wheel events in index mode. + * based on http://adomas.org/javascript-mouse-wheel/ + * + * @param e the event + */ +function indexMousewheel(e) +{ + var delta = 0; + + if (!e) + e = window.event; + + if (e.wheelDelta) + { // IE Opera + delta = e.wheelDelta/120; + } + else if (e.detail) + { // MOZ + delta = -e.detail/3; + } + + if (delta > 0) + indexSetPageSlide(activeSlide - INDEX_COLUMNS * INDEX_COLUMNS); + else if (delta < 0) + indexSetPageSlide(activeSlide + INDEX_COLUMNS * INDEX_COLUMNS); + + if (e.preventDefault) + e.preventDefault(); + + e.returnValue = false; +} + +/** Function to set the path paint width. +*/ +function set_path_paint_width() +{ + var svgPoint1 = document.documentElement.createSVGPoint(); + var svgPoint2 = document.documentElement.createSVGPoint(); + + svgPoint1.x = 0.0; + svgPoint1.y = 0.0; + svgPoint2.x = 1.0; + svgPoint2.y = 0.0; + + var matrix = slides[activeSlide]["element"].getTransformToElement(ROOT_NODE); + + if (slides[activeSlide]["viewGroup"]) + matrix = slides[activeSlide]["viewGroup"].getTransformToElement(ROOT_NODE); + + svgPoint1 = svgPoint1.matrixTransform(matrix); + svgPoint2 = svgPoint2.matrixTransform(matrix); + + path_paint_width = path_width / Math.sqrt((svgPoint2.x - svgPoint1.x) * (svgPoint2.x - svgPoint1.x) + (svgPoint2.y - svgPoint1.y) * (svgPoint2.y - svgPoint1.y)); +} + +/** The view effect. + * + * @param dir direction the effect should be played (1 = forwards, -1 = backwards) + * @param element the element the effect should be applied to + * @param time the time that has elapsed since the beginning of the effect + * @param options a dictionary with additional options (e.g. length of the effect); for the view effect the options need to contain the old and the new matrix. + */ +function view(dir, element, time, options) +{ + var length = 250; + var fraction; + + if (!options["matrixInitial"]) + { + var tempString = slides[activeSlide]["viewGroup"].getAttribute("transform"); + + if (tempString) + options["matrixInitial"] = (new matrixSVG()).fromAttribute(tempString); + else + options["matrixInitial"] = (new matrixSVG()).fromSVGElements(1, 0, 0, 1, 0, 0); + } + + if ((time == STATE_END) || (time == STATE_START)) + fraction = 1; + else + { + if (options && options["length"]) + length = options["length"]; + + fraction = time / length; + } + + if (dir == 1) + { + if (fraction <= 0) + { + element.setAttribute("transform", options["matrixInitial"].toAttribute()); + } + else if (fraction >= 1) + { + element.setAttribute("transform", options["matrixNew"].toAttribute()); + + set_path_paint_width(); + + options["matrixInitial"] = null; + return true; + } + else + { + element.setAttribute("transform", options["matrixInitial"].mix(options["matrixNew"], fraction).toAttribute()); + } + } + else if (dir == -1) + { + if (fraction <= 0) + { + element.setAttribute("transform", options["matrixInitial"].toAttribute()); + } + else if (fraction >= 1) + { + element.setAttribute("transform", options["matrixOld"].toAttribute()); + set_path_paint_width(); + + options["matrixInitial"] = null; + return true; + } + else + { + element.setAttribute("transform", options["matrixInitial"].mix(options["matrixOld"], fraction).toAttribute()); + } + } + + return false; +} + +/** The fade effect. + * + * @param dir direction the effect should be played (1 = forwards, -1 = backwards) + * @param element the element the effect should be applied to + * @param time the time that has elapsed since the beginning of the effect + * @param options a dictionary with additional options (e.g. length of the effect) + */ +function fade(dir, element, time, options) +{ + var length = 250; + var fraction; + + if ((time == STATE_END) || (time == STATE_START)) + fraction = 1; + else + { + if (options && options["length"]) + length = options["length"]; + + fraction = time / length; + } + + if (dir == 1) + { + if (fraction <= 0) + { + element.style.display = "none"; + element.setAttribute("opacity", 0); + } + else if (fraction >= 1) + { + element.style.display = "inherit"; + element.setAttribute("opacity", 1); + return true; + } + else + { + element.style.display = "inherit"; + element.setAttribute("opacity", fraction); + } + } + else if (dir == -1) + { + if (fraction <= 0) + { + element.style.display = "inherit"; + element.setAttribute("opacity", 1); + } + else if (fraction >= 1) + { + element.setAttribute("opacity", 0); + element.style.display = "none"; + return true; + } + else + { + element.style.display = "inherit"; + element.setAttribute("opacity", 1 - fraction); + } + } + return false; +} + +/** The appear effect. + * + * @param dir direction the effect should be played (1 = forwards, -1 = backwards) + * @param element the element the effect should be applied to + * @param time the time that has elapsed since the beginning of the effect + * @param options a dictionary with additional options (e.g. length of the effect) + */ +function appear(dir, element, time, options) +{ + if (dir == 1) + { + element.style.display = "inherit"; + element.setAttribute("opacity",1); + } + else if (dir == -1) + { + element.style.display = "none"; + element.setAttribute("opacity",0); + } + return true; +} + +/** The pop effect. + * + * @param dir direction the effect should be played (1 = forwards, -1 = backwards) + * @param element the element the effect should be applied to + * @param time the time that has elapsed since the beginning of the effect + * @param options a dictionary with additional options (e.g. length of the effect) + */ +function pop(dir, element, time, options) +{ + var length = 500; + var fraction; + + if ((time == STATE_END) || (time == STATE_START)) + fraction = 1; + else + { + if (options && options["length"]) + length = options["length"]; + + fraction = time / length; + } + + if (dir == 1) + { + if (fraction <= 0) + { + element.setAttribute("opacity", 0); + element.setAttribute("transform", "scale(0)"); + element.style.display = "none"; + } + else if (fraction >= 1) + { + element.setAttribute("opacity", 1); + element.removeAttribute("transform"); + element.style.display = "inherit"; + return true; + } + else + { + element.style.display = "inherit"; + var opacityFraction = fraction * 3; + if (opacityFraction > 1) + opacityFraction = 1; + element.setAttribute("opacity", opacityFraction); + var offsetX = WIDTH * (1.0 - fraction) / 2.0; + var offsetY = HEIGHT * (1.0 - fraction) / 2.0; + element.setAttribute("transform", "translate(" + offsetX + "," + offsetY + ") scale(" + fraction + ")"); + } + } + else if (dir == -1) + { + if (fraction <= 0) + { + element.setAttribute("opacity", 1); + element.setAttribute("transform", "scale(1)"); + element.style.display = "inherit"; + } + else if (fraction >= 1) + { + element.setAttribute("opacity", 0); + element.removeAttribute("transform"); + element.style.display = "none"; + return true; + } + else + { + element.setAttribute("opacity", 1 - fraction); + element.setAttribute("transform", "scale(" + 1 - fraction + ")"); + element.style.display = "inherit"; + } + } + return false; +} + +/** Function to set a slide either to the start or the end state. + * + * @param slide the slide to use + * @param state the state into which the slide should be set + */ +function setSlideToState(slide, state) +{ + slides[slide]["viewGroup"].setAttribute("transform", slides[slide].initialView); + + if (slides[slide]["effects"]) + { + if (state == STATE_END) + { + for (var counter = 0; counter < slides[slide]["effects"].length; counter++) + { + for (var subCounter = 0; subCounter < slides[slide]["effects"][counter].length; subCounter++) + { + var effect = slides[slide]["effects"][counter][subCounter]; + if (effect["effect"] == "fade") + fade(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "appear") + appear(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "pop") + pop(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "view") + view(effect["dir"], effect["element"], STATE_END, effect["options"]); + } + } + } + else if (state == STATE_START) + { + for (var counter = slides[slide]["effects"].length - 1; counter >= 0; counter--) + { + for (var subCounter = 0; subCounter < slides[slide]["effects"][counter].length; subCounter++) + { + var effect = slides[slide]["effects"][counter][subCounter]; + if (effect["effect"] == "fade") + fade(parseInt(effect["dir"]) * -1, effect["element"], STATE_START, effect["options"]); + else if (effect["effect"] == "appear") + appear(parseInt(effect["dir"]) * -1, effect["element"], STATE_START, effect["options"]); + else if (effect["effect"] == "pop") + pop(parseInt(effect["dir"]) * -1, effect["element"], STATE_START, effect["options"]); + else if (effect["effect"] == "view") + view(parseInt(effect["dir"]) * -1, effect["element"], STATE_START, effect["options"]); + } + } + } + else + { + setSlideToState(slide, STATE_START); + + for (var counter = 0; counter < slides[slide]["effects"].length && counter < state; counter++) + { + for (var subCounter = 0; subCounter < slides[slide]["effects"][counter].length; subCounter++) + { + var effect = slides[slide]["effects"][counter][subCounter]; + if (effect["effect"] == "fade") + fade(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "appear") + appear(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "pop") + pop(effect["dir"], effect["element"], STATE_END, effect["options"]); + else if (effect["effect"] == "view") + view(effect["dir"], effect["element"], STATE_END, effect["options"]); + } + } + } + } + + window.location.hash = (activeSlide + 1) + '_' + activeEffect; +} + +/** Convenience function to translate a attribute string into a dictionary. + * + * @param str the attribute string + * @return a dictionary + * @see dictToPropStr + */ +function propStrToDict(str) +{ + var list = str.split(";"); + var obj = new Object(); + + for (var counter = 0; counter < list.length; counter++) + { + var subStr = list[counter]; + var subList = subStr.split(":"); + if (subList.length == 2) + { + obj[subList[0]] = subList[1]; + } + } + + return obj; +} + +/** Convenience function to translate a dictionary into a string that can be used as an attribute. + * + * @param dict the dictionary to convert + * @return a string that can be used as an attribute + * @see propStrToDict + */ +function dictToPropStr(dict) +{ + var str = ""; + + for (var key in dict) + { + str += key + ":" + dict[key] + ";"; + } + + return str; +} + +/** Sub-function to add a suffix to the ids of the node and all its children. + * + * @param node the node to change + * @param suffix the suffix to add + * @param replace dictionary of replaced ids + * @see suffixNodeIds + */ +function suffixNoneIds_sub(node, suffix, replace) +{ + if (node.nodeType == 1) + { + if (node.getAttribute("id")) + { + var id = node.getAttribute("id") + replace["#" + id] = id + suffix; + node.setAttribute("id", id + suffix); + } + + if ((node.nodeName == "use") && (node.getAttributeNS(NSS["xlink"], "href")) && (replace[node.getAttribute(NSS["xlink"], "href")])) + node.setAttribute(NSS["xlink"], "href", node.getAttribute(NSS["xlink"], "href") + suffix); + + if (node.childNodes) + { + for (var counter = 0; counter < node.childNodes.length; counter++) + suffixNoneIds_sub(node.childNodes[counter], suffix, replace); + } + } +} + +/** Function to add a suffix to the ids of the node and all its children. + * + * @param node the node to change + * @param suffix the suffix to add + * @return the changed node + * @see suffixNodeIds_sub + */ +function suffixNodeIds(node, suffix) +{ + var replace = new Object(); + + suffixNoneIds_sub(node, suffix, replace); + + return node; +} + +/** Function to build a progress bar. + * + * @param parent node to attach the progress bar to + */ +function createProgressBar(parent_node) +{ + var g = document.createElementNS(NSS["svg"], "g"); + g.setAttribute("clip-path", "url(#jessyInkSlideClipPath)"); + g.setAttribute("id", "layer_progress_bar"); + g.setAttribute("style", "display: none;"); + + var rect_progress_bar = document.createElementNS(NSS["svg"], "rect"); + rect_progress_bar.setAttribute("style", "marker: none; fill: rgb(128, 128, 128); stroke: none;"); + rect_progress_bar.setAttribute("id", "rect_progress_bar"); + rect_progress_bar.setAttribute("x", 0); + rect_progress_bar.setAttribute("y", 0.99 * HEIGHT); + rect_progress_bar.setAttribute("width", 0); + rect_progress_bar.setAttribute("height", 0.01 * HEIGHT); + g.appendChild(rect_progress_bar); + + var circle_timer_indicator = document.createElementNS(NSS["svg"], "circle"); + circle_timer_indicator.setAttribute("style", "marker: none; fill: rgb(255, 0, 0); stroke: none;"); + circle_timer_indicator.setAttribute("id", "circle_timer_indicator"); + circle_timer_indicator.setAttribute("cx", 0.005 * HEIGHT); + circle_timer_indicator.setAttribute("cy", 0.995 * HEIGHT); + circle_timer_indicator.setAttribute("r", 0.005 * HEIGHT); + g.appendChild(circle_timer_indicator); + + parent_node.appendChild(g); +} + +/** Function to hide the progress bar. + * + */ +function hideProgressBar() +{ + var progress_bar = document.getElementById("layer_progress_bar"); + + if (!progress_bar) + { + return; + } + + progress_bar.setAttribute("style", "display: none;"); +} + +/** Function to show the progress bar. + * + */ +function showProgressBar() +{ + var progress_bar = document.getElementById("layer_progress_bar"); + + if (!progress_bar) + { + return; + } + + progress_bar.setAttribute("style", "display: inherit;"); +} + +/** Set progress bar value. + * + * @param value the current slide number + * + */ +function setProgressBarValue(value) +{ + var rect_progress_bar = document.getElementById("rect_progress_bar"); + + if (!rect_progress_bar) + { + return; + } + + if (value < 1) + { + // First slide, assumed to be the title of the presentation + var x = 0; + var w = 0.01 * HEIGHT; + } + else if (value >= slides.length - 1) + { + // Last slide, assumed to be the end of the presentation + var x = WIDTH - 0.01 * HEIGHT; + var w = 0.01 * HEIGHT; + } + else + { + value -= 1; + value /= (slides.length - 2); + + var x = WIDTH * value; + var w = WIDTH / (slides.length - 2); + } + + rect_progress_bar.setAttribute("x", x); + rect_progress_bar.setAttribute("width", w); +} + +/** Set time indicator. + * + * @param value the percentage of time elapse so far between 0.0 and 1.0 + * + */ +function setTimeIndicatorValue(value) +{ + var circle_timer_indicator = document.getElementById("circle_timer_indicator"); + + if (!circle_timer_indicator) + { + return; + } + + if (value < 0.0) + { + value = 0.0; + } + + if (value > 1.0) + { + value = 1.0; + } + + var cx = (WIDTH - 0.01 * HEIGHT) * value + 0.005 * HEIGHT; + circle_timer_indicator.setAttribute("cx", cx); +} + +/** Update timer. + * + */ +function updateTimer() +{ + timer_elapsed += 1; + setTimeIndicatorValue((timer_elapsed - timer_start) / (60 * timer_duration)); +} + +/** Convert screen coordinates to document coordinates. + * + * @param e event with screen coordinates + * + * @return coordinates in SVG file coordinate system + */ +function calcCoord(e) +{ + var svgPoint = document.documentElement.createSVGPoint(); + svgPoint.x = e.clientX + window.pageXOffset; + svgPoint.y = e.clientY + window.pageYOffset; + + var matrix = slides[activeSlide]["element"].getScreenCTM(); + + if (slides[activeSlide]["viewGroup"]) + matrix = slides[activeSlide]["viewGroup"].getScreenCTM(); + + svgPoint = svgPoint.matrixTransform(matrix.inverse()); + return svgPoint; +} + +/** Add slide. + * + * @param after_slide after which slide the new slide should be inserted into the presentation + */ +function addSlide(after_slide) +{ + number_of_added_slides++; + + var g = document.createElementNS(NSS["svg"], "g"); + g.setAttribute("clip-path", "url(#jessyInkSlideClipPath)"); + g.setAttribute("id", "Whiteboard " + Date() + " presentation copy"); + g.setAttribute("style", "display: none;"); + + var new_slide = new Object(); + new_slide["element"] = g; + + // Set build in transition. + new_slide["transitionIn"] = new Object(); + var dict = defaultTransitionInDict; + new_slide["transitionIn"]["name"] = dict["name"]; + new_slide["transitionIn"]["options"] = new Object(); + + for (key in dict) + if (key != "name") + new_slide["transitionIn"]["options"][key] = dict[key]; + + // Set build out transition. + new_slide["transitionOut"] = new Object(); + dict = defaultTransitionOutDict; + new_slide["transitionOut"]["name"] = dict["name"]; + new_slide["transitionOut"]["options"] = new Object(); + + for (key in dict) + if (key != "name") + new_slide["transitionOut"]["options"][key] = dict[key]; + + // Copy master slide content. + if (masterSlide) + { + var clonedNode = suffixNodeIds(masterSlide.cloneNode(true), "_" + Date() + " presentation_copy"); + clonedNode.removeAttributeNS(NSS["inkscape"], "groupmode"); + clonedNode.removeAttributeNS(NSS["inkscape"], "label"); + clonedNode.style.display = "inherit"; + + g.appendChild(clonedNode); + } + + // Substitute auto texts. + substituteAutoTexts(g, "Whiteboard " + number_of_added_slides, "W" + number_of_added_slides, slides.length); + + g.setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + (after_slide + 1) + ")) { indexSetActiveSlide(" + (after_slide + 1) + "); };"); + + // Create a transform group. + var transformGroup = document.createElementNS(NSS["svg"], "g"); + + // Add content to transform group. + while (g.firstChild) + transformGroup.appendChild(g.firstChild); + + // Transfer the transform attribute from the node to the transform group. + if (g.getAttribute("transform")) + { + transformGroup.setAttribute("transform", g.getAttribute("transform")); + g.removeAttribute("transform"); + } + + // Create a view group. + var viewGroup = document.createElementNS(NSS["svg"], "g"); + + viewGroup.appendChild(transformGroup); + new_slide["viewGroup"] = g.appendChild(viewGroup); + + // Insert background. + if (BACKGROUND_COLOR != null) + { + var rectNode = document.createElementNS(NSS["svg"], "rect"); + + rectNode.setAttribute("x", 0); + rectNode.setAttribute("y", 0); + rectNode.setAttribute("width", WIDTH); + rectNode.setAttribute("height", HEIGHT); + rectNode.setAttribute("id", "jessyInkBackground" + Date()); + rectNode.setAttribute("fill", BACKGROUND_COLOR); + + new_slide["viewGroup"].insertBefore(rectNode, new_slide["viewGroup"].firstChild); + } + + // Set initial view even if there are no other views. + var matrixOld = (new matrixSVG()).fromElements(1, 0, 0, 0, 1, 0, 0, 0, 1); + + new_slide["viewGroup"].setAttribute("transform", matrixOld.toAttribute()); + new_slide.initialView = matrixOld.toAttribute(); + + // Insert slide + var node = slides[after_slide]["element"]; + var next_node = node.nextSibling; + var parent_node = node.parentNode; + + if (next_node) + { + parent_node.insertBefore(g, next_node); + } + else + { + parent_node.appendChild(g); + } + + g = document.createElementNS(NSS["svg"], "g"); + g.setAttributeNS(NSS["inkscape"], "groupmode", "layer"); + g.setAttributeNS(NSS["inkscape"], "label", "Whiteboard " + number_of_added_slides); + g.setAttribute("clip-path", "url(#jessyInkSlideClipPath)"); + g.setAttribute("id", "Whiteboard " + Date()); + g.setAttribute("style", "display: none;"); + + new_slide["original_element"] = g; + + node = slides[after_slide]["original_element"]; + next_node = node.nextSibling; + parent_node = node.parentNode; + + if (next_node) + { + parent_node.insertBefore(g, next_node); + } + else + { + parent_node.appendChild(g); + } + + before_new_slide = slides.slice(0, after_slide + 1); + after_new_slide = slides.slice(after_slide + 1); + slides = before_new_slide.concat(new_slide, after_new_slide); + + //resetting the counter attributes on the slides that follow the new slide... + for (var counter = after_slide+2; counter < slides.length; counter++) + { + slides[counter]["element"].setAttribute("onmouseover", "if ((currentMode == INDEX_MODE) && ( activeSlide != " + counter + ")) { indexSetActiveSlide(" + counter + "); };"); + } +} + +/** Convenience function to obtain a transformation matrix from a point matrix. + * + * @param mPoints Point matrix. + * @return A transformation matrix. + */ +function pointMatrixToTransformation(mPoints) +{ + mPointsOld = (new matrixSVG()).fromElements(0, WIDTH, WIDTH, 0, 0, HEIGHT, 1, 1, 1); + + return mPointsOld.mult(mPoints.inv()); +} + +/** Convenience function to obtain a matrix with three corners of a rectangle. + * + * @param rect an svg rectangle + * @return a matrixSVG containing three corners of the rectangle + */ +function rectToMatrix(rect) +{ + rectWidth = rect.getBBox().width; + rectHeight = rect.getBBox().height; + rectX = rect.getBBox().x; + rectY = rect.getBBox().y; + rectXcorr = 0; + rectYcorr = 0; + + scaleX = WIDTH / rectWidth; + scaleY = HEIGHT / rectHeight; + + if (scaleX > scaleY) + { + scaleX = scaleY; + rectXcorr -= (WIDTH / scaleX - rectWidth) / 2; + rectWidth = WIDTH / scaleX; + } + else + { + scaleY = scaleX; + rectYcorr -= (HEIGHT / scaleY - rectHeight) / 2; + rectHeight = HEIGHT / scaleY; + } + + if (rect.transform.baseVal.numberOfItems < 1) + { + mRectTrans = (new matrixSVG()).fromElements(1, 0, 0, 0, 1, 0, 0, 0, 1); + } + else + { + mRectTrans = (new matrixSVG()).fromSVGMatrix(rect.transform.baseVal.consolidate().matrix); + } + + newBasePoints = (new matrixSVG()).fromElements(rectX, rectX, rectX, rectY, rectY, rectY, 1, 1, 1); + newVectors = (new matrixSVG()).fromElements(rectXcorr, rectXcorr + rectWidth, rectXcorr + rectWidth, rectYcorr, rectYcorr, rectYcorr + rectHeight, 0, 0, 0); + + return mRectTrans.mult(newBasePoints.add(newVectors)); +} + +/** Function to handle JessyInk elements. + * + * @param node Element node. + */ +function handleElement(node) +{ + if (node.getAttributeNS(NSS['jessyink'], 'element') == 'core.video') + { + var url; + var width; + var height; + var x; + var y; + var transform; + + var tspans = node.getElementsByTagNameNS("http://www.w3.org/2000/svg", "tspan"); + + for (var tspanCounter = 0; tspanCounter < tspans.length; tspanCounter++) + { + if (tspans[tspanCounter].getAttributeNS("https://launchpad.net/jessyink", "video") == "url") + { + url = tspans[tspanCounter].firstChild.nodeValue; + } + } + + var rects = node.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect"); + + for (var rectCounter = 0; rectCounter < rects.length; rectCounter++) + { + if (rects[rectCounter].getAttributeNS("https://launchpad.net/jessyink", "video") == "rect") + { + x = rects[rectCounter].getAttribute("x"); + y = rects[rectCounter].getAttribute("y"); + width = rects[rectCounter].getAttribute("width"); + height = rects[rectCounter].getAttribute("height"); + transform = rects[rectCounter].getAttribute("transform"); + } + } + + for (var childCounter = 0; childCounter < node.childNodes.length; childCounter++) + { + if (node.childNodes[childCounter].nodeType == 1) + { + if (node.childNodes[childCounter].style) + { + node.childNodes[childCounter].style.display = 'none'; + } + else + { + node.childNodes[childCounter].setAttribute("style", "display: none;"); + } + } + } + + var foreignNode = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"); + foreignNode.setAttribute("x", x); + foreignNode.setAttribute("y", y); + foreignNode.setAttribute("width", width); + foreignNode.setAttribute("height", height); + foreignNode.setAttribute("transform", transform); + + var videoNode = document.createElementNS("http://www.w3.org/1999/xhtml", "video"); + videoNode.setAttribute("src", url); + + foreignNode.appendChild(videoNode); + node.appendChild(foreignNode); + } +} + +/** Class processing the location hash. + * + * @param str location hash + */ +function LocationHash(str) +{ + this.slideNumber = 0; + this.effectNumber = 0; + + str = str.substr(1, str.length - 1); + + var parts = str.split('_'); + + // Try to extract slide number. + if (parts.length >= 1) + { + try + { + var slideNumber = parseInt(parts[0]); + + if (!isNaN(slideNumber)) + { + this.slideNumber = slideNumber - 1; + } + } + catch (e) + { + } + } + + // Try to extract effect number. + if (parts.length >= 2) + { + try + { + var effectNumber = parseInt(parts[1]); + + if (!isNaN(effectNumber)) + { + this.effectNumber = effectNumber; + } + } + catch (e) + { + } + } +} + +/** Class representing an svg matrix. +*/ +function matrixSVG() +{ + this.e11 = 0; // a + this.e12 = 0; // c + this.e13 = 0; // e + this.e21 = 0; // b + this.e22 = 0; // d + this.e23 = 0; // f + this.e31 = 0; + this.e32 = 0; + this.e33 = 0; +} + +/** Constructor function. + * + * @param a element a (i.e. 1, 1) as described in the svg standard. + * @param b element b (i.e. 2, 1) as described in the svg standard. + * @param c element c (i.e. 1, 2) as described in the svg standard. + * @param d element d (i.e. 2, 2) as described in the svg standard. + * @param e element e (i.e. 1, 3) as described in the svg standard. + * @param f element f (i.e. 2, 3) as described in the svg standard. + */ +matrixSVG.prototype.fromSVGElements = function(a, b, c, d, e, f) +{ + this.e11 = a; + this.e12 = c; + this.e13 = e; + this.e21 = b; + this.e22 = d; + this.e23 = f; + this.e31 = 0; + this.e32 = 0; + this.e33 = 1; + + return this; +} + +/** Constructor function. + * + * @param matrix an svg matrix as described in the svg standard. + */ +matrixSVG.prototype.fromSVGMatrix = function(m) +{ + this.e11 = m.a; + this.e12 = m.c; + this.e13 = m.e; + this.e21 = m.b; + this.e22 = m.d; + this.e23 = m.f; + this.e31 = 0; + this.e32 = 0; + this.e33 = 1; + + return this; +} + +/** Constructor function. + * + * @param e11 element 1, 1 of the matrix. + * @param e12 element 1, 2 of the matrix. + * @param e13 element 1, 3 of the matrix. + * @param e21 element 2, 1 of the matrix. + * @param e22 element 2, 2 of the matrix. + * @param e23 element 2, 3 of the matrix. + * @param e31 element 3, 1 of the matrix. + * @param e32 element 3, 2 of the matrix. + * @param e33 element 3, 3 of the matrix. + */ +matrixSVG.prototype.fromElements = function(e11, e12, e13, e21, e22, e23, e31, e32, e33) +{ + this.e11 = e11; + this.e12 = e12; + this.e13 = e13; + this.e21 = e21; + this.e22 = e22; + this.e23 = e23; + this.e31 = e31; + this.e32 = e32; + this.e33 = e33; + + return this; +} + +/** Constructor function. + * + * @param attrString string value of the "transform" attribute (currently only "matrix" is accepted) + */ +matrixSVG.prototype.fromAttribute = function(attrString) +{ + str = attrString.substr(7, attrString.length - 8); + + str = str.trim(); + + strArray = str.split(","); + + // Opera does not use commas to separate the values of the matrix, only spaces. + if (strArray.length != 6) + strArray = str.split(" "); + + this.e11 = parseFloat(strArray[0]); + this.e21 = parseFloat(strArray[1]); + this.e31 = 0; + this.e12 = parseFloat(strArray[2]); + this.e22 = parseFloat(strArray[3]); + this.e32 = 0; + this.e13 = parseFloat(strArray[4]); + this.e23 = parseFloat(strArray[5]); + this.e33 = 1; + + return this; +} + +/** Output function + * + * @return a string that can be used as the "transform" attribute. + */ +matrixSVG.prototype.toAttribute = function() +{ + return "matrix(" + this.e11 + ", " + this.e21 + ", " + this.e12 + ", " + this.e22 + ", " + this.e13 + ", " + this.e23 + ")"; +} + +/** Matrix nversion. + * + * @return the inverse of the matrix + */ +matrixSVG.prototype.inv = function() +{ + out = new matrixSVG(); + + det = this.e11 * (this.e33 * this.e22 - this.e32 * this.e23) - this.e21 * (this.e33 * this.e12 - this.e32 * this.e13) + this.e31 * (this.e23 * this.e12 - this.e22 * this.e13); + + out.e11 = (this.e33 * this.e22 - this.e32 * this.e23) / det; + out.e12 = -(this.e33 * this.e12 - this.e32 * this.e13) / det; + out.e13 = (this.e23 * this.e12 - this.e22 * this.e13) / det; + out.e21 = -(this.e33 * this.e21 - this.e31 * this.e23) / det; + out.e22 = (this.e33 * this.e11 - this.e31 * this.e13) / det; + out.e23 = -(this.e23 * this.e11 - this.e21 * this.e13) / det; + out.e31 = (this.e32 * this.e21 - this.e31 * this.e22) / det; + out.e32 = -(this.e32 * this.e11 - this.e31 * this.e12) / det; + out.e33 = (this.e22 * this.e11 - this.e21 * this.e12) / det; + + return out; +} + +/** Matrix multiplication. + * + * @param op another svg matrix + * @return this * op + */ +matrixSVG.prototype.mult = function(op) +{ + out = new matrixSVG(); + + out.e11 = this.e11 * op.e11 + this.e12 * op.e21 + this.e13 * op.e31; + out.e12 = this.e11 * op.e12 + this.e12 * op.e22 + this.e13 * op.e32; + out.e13 = this.e11 * op.e13 + this.e12 * op.e23 + this.e13 * op.e33; + out.e21 = this.e21 * op.e11 + this.e22 * op.e21 + this.e23 * op.e31; + out.e22 = this.e21 * op.e12 + this.e22 * op.e22 + this.e23 * op.e32; + out.e23 = this.e21 * op.e13 + this.e22 * op.e23 + this.e23 * op.e33; + out.e31 = this.e31 * op.e11 + this.e32 * op.e21 + this.e33 * op.e31; + out.e32 = this.e31 * op.e12 + this.e32 * op.e22 + this.e33 * op.e32; + out.e33 = this.e31 * op.e13 + this.e32 * op.e23 + this.e33 * op.e33; + + return out; +} + +/** Matrix addition. + * + * @param op another svg matrix + * @return this + op + */ +matrixSVG.prototype.add = function(op) +{ + out = new matrixSVG(); + + out.e11 = this.e11 + op.e11; + out.e12 = this.e12 + op.e12; + out.e13 = this.e13 + op.e13; + out.e21 = this.e21 + op.e21; + out.e22 = this.e22 + op.e22; + out.e23 = this.e23 + op.e23; + out.e31 = this.e31 + op.e31; + out.e32 = this.e32 + op.e32; + out.e33 = this.e33 + op.e33; + + return out; +} + +/** Matrix mixing. + * + * @param op another svg matrix + * @parma contribOp contribution of the other matrix (0 <= contribOp <= 1) + * @return (1 - contribOp) * this + contribOp * op + */ +matrixSVG.prototype.mix = function(op, contribOp) +{ + contribThis = 1.0 - contribOp; + out = new matrixSVG(); + + out.e11 = contribThis * this.e11 + contribOp * op.e11; + out.e12 = contribThis * this.e12 + contribOp * op.e12; + out.e13 = contribThis * this.e13 + contribOp * op.e13; + out.e21 = contribThis * this.e21 + contribOp * op.e21; + out.e22 = contribThis * this.e22 + contribOp * op.e22; + out.e23 = contribThis * this.e23 + contribOp * op.e23; + out.e31 = contribThis * this.e31 + contribOp * op.e31; + out.e32 = contribThis * this.e32 + contribOp * op.e32; + out.e33 = contribThis * this.e33 + contribOp * op.e33; + + return out; +} + +/** Trimming function for strings. +*/ +String.prototype.trim = function() +{ + return this.replace(/^\s+|\s+$/g, ''); +} + +</script> + <ns1:mousehandler + ns1:subtype="jessyInk_core_mouseHandler_noclick"> + <script + id="script5840">// Copyright 2008, 2009 Hannes Hochreiner +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see http://www.gnu.org/licenses/. + +// Add event listener for initialisation. +document.addEventListener("DOMContentLoaded", jessyInk_core_mouseHandler_noclick_init, false); + +/** Initialisation function. + * + * This function looks for the objects of the appropriate sub-type and hands them to another function that will add the required methods. + */ +function jessyInk_core_mouseHandler_noclick_init() +{ + var elems = document.getElementsByTagNameNS("https://launchpad.net/jessyink", "mousehandler"); + + for (var counter = 0; counter < elems.length; counter++) + { + if (elems[counter].getAttributeNS("https://launchpad.net/jessyink", "subtype") == "jessyInk_core_mouseHandler_noclick") + jessyInk_core_mouseHandler_noclick(elems[counter]); + } +} + +/** Function to initialise an object. + * + * @param obj Object to be initialised. + */ +function jessyInk_core_mouseHandler_noclick(obj) +{ + /** Function supplying a custom mouse handler. + * + * @returns A dictionary containing the new mouse handler functions. + */ + obj.getMouseHandler = function () + { + var handlerDictio = new Object(); + + handlerDictio[SLIDE_MODE] = new Object(); + handlerDictio[SLIDE_MODE][MOUSE_DOWN] = null; + + return handlerDictio; + } +} + +</script> + </ns1:mousehandler> +</svg> diff --git a/Sda2/sda2.xml b/Sda2/sda2.xml index cfa30c74af61ce2099c8e27b652021daa6c87f3a..1e265ae5634bb2cedc688bfa83e2606260e708a9 100644 --- a/Sda2/sda2.xml +++ b/Sda2/sda2.xml @@ -3834,6 +3834,9 @@ <chapter xml:id="jax-rs"> <title>REST applications based on <xref linkend="glo_Java"/>-rs</title> + <para><link xlink:href="Ref/Fig/jaxRs.svg">Introductory + slides</link>.</para> + <para>Sample chapters from <xref linkend="bib_Burke13"/> available at <uri xlink:href="https://github.com/oreillymedia/restful_java_jax-rs_2_0">https://github.com/oreillymedia/restful_java_jax-rs_2_0</uri>.</para> </chapter>