Commit d35899ba6cf9c2449cf5008bfe1cbc772477f9a3

Authored by Rémi Emonet
1 parent 24e1951f04
Exists in master

cm jpa

Showing 5 changed files with 1189 additions and 4 deletions

... ... @@ -39,15 +39,17 @@
39 39 <a href="lesson-01.html">Slides 1 <br/> introduction</a>
40 40 <a href="lesson-02.html">Slides 2 <br/> HTML+CSS</a>
41 41 <a href="raw/cours-2.zip">Fichiers HTML et CSS du cours</a>
42   - <a href="lesson-03.html">Slides 2 <br/> HTML+CSS</a>
  42 + <a href="lesson-03.html">Slides 3 <br/> HTML+CSS</a>
  43 + <a href="raw/cours-3.zip">Projet du cours 3 (tp2)</a>
  44 + <a href="lesson-04.html">Slides 4 <br/> HTML+CSS</a>
  45 + <a href="raw/cours-4-pre.zip">Projet du cours 4 (tp2)</a>
  46 + <a href="raw/cours-4-post.zip">Projet du cours 4 avec JPA (tp2)</a>
43 47  
44 48 <a href="export-lesson-01.pdf">Slides 1, pdf <br/> (ne pas imprimer) </a>
45 49 <a href="export-lesson-02.pdf">Slides 2, pdf <br/> (ne pas imprimer) </a>
46 50 <a href="export-lesson-03.pdf">Slides 3, pdf <br/> (ne pas imprimer) </a>
47   - <a href="raw/cours-3.zip">Projet du cours 3</a>
  51 + <a href="export-lesson-04.pdf">Slides 3, pdf <br/> (ne pas imprimer) </a>
48 52 <!--
49   - <a href="lesson-3.html">Slides 3 <br/> HTTP+Servlets</a>
50   - <a href="lesson-4.html">Slides 4 <br/> DI+MVC+Spring</a>
51 53 <a href="lesson-5.html">Slides 5 <br/> Git</a>
52 54 <a href="lesson-6.html">Slides 6 <br/> Reboot</a>
53 55 <a href="lesson-7.html">Slides 7 <br/> JPA + Spring Data</a>
lesson-04.html View file @ d35899b
  1 +<!DOCTYPE html>
  2 +<html>
  3 + <head>
  4 + <meta charset="utf-8">
  5 + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  6 +
  7 + <title>Programmation Web Avancée   Spring MVC, Injection de Dépendances</title>
  8 + <meta name="cours-n" content="4">
  9 +
  10 + <meta name="author" content="Rémi Emonet">
  11 + <meta name="venue" content="PWA M1 DSC">
  12 + <meta name="date" content="2016">
  13 + <meta name="affiliation" content="Université Jean Monnet − Laboratoire Hubert Curien">
  14 +
  15 + <style type="text/css">
  16 + .slide.densish>ul {font-size: 70%;}
  17 + </style>
  18 +
  19 + <!--
  20 + <script src="deck.js/extensions/includedeck/load.js"></script>
  21 + <script src="extensions/slides-dev.js"></script>
  22 + -->
  23 + <script src="extensions/deck-packed.js"></script>
  24 + <script src="extensions/slides.js"></script>
  25 + <script>go()</script>
  26 + </head>
  27 +
  28 +<body>
  29 +
  30 +<div class="deck-container">
  31 +
  32 + <div class="deck-loading-splash" style="background: black; color: chartreuse;"><span class="vcenter" style="font-size: 30px; font-family: Arial; ">Please wait, while our marmots are preparing the hot chocolate…</span></div>
  33 +
  34 +<section class="smart">
  35 +
  36 +# @chunk: chunks/title.md
  37 +
  38 +# Questions ? <br/> Commentaires ? {no-print}
  39 +
  40 +# @chunk: chunks/objectives.md
  41 +
  42 +## Programmation Impérative <span>{var-cours-n}</span> : Plan {#plan overview}
  43 +- MVC Web et Spring MVC {mvcweb}
  44 +- Projets {projects}
  45 +- Rappel : MVC Web en Pratique {mvcdemo}
  46 +- Injection de Dépendances {di}
  47 +- Introduction à la persistance en Java {persi}
  48 +- Java Persistence API (JPA) {jpa}
  49 +# @copy:#plan
  50 +
  51 +
  52 +
  53 +
  54 +<!-- MVC Web Spring (et un peu Java EE) -->
  55 +# @copy:#plan: %+class:inred: .mvcweb
  56 +
  57 +## MVC avec Spring dans ce cours {libyli}
  58 +- Modèle
  59 + - JavaBeans (objets Java)
  60 + - persistance avec JPA et Repositories de Spring Data
  61 +- Contrôleur
  62 + - description de route : annotations Java
  63 + - méthodes Java, avec injection de paramètres
  64 + - classe `Model` pour le ViewModel
  65 +- Vue
  66 + - templates Thymeleaf
  67 + - accès automatique au ViewModel
  68 +
  69 +
  70 +## Interaction Client Serveur et MVC
  71 +<p> </p>
  72 +
  73 +@svg: media/client-server-mvc/server-mvc.svg 700px 400px
  74 +
  75 +- @anim: #user, #client |#server |#r0 |#a0 |#s0,#router |#s1,#controller |#s2,#service |#s3,#db |#s4 |#s5,#view |#s6 |#s7 |#legend
  76 +
  77 +
  78 +<!-- ################################## -->
  79 +# @copy:#plan: %+class:inred: .projects
  80 +
  81 +## Les Projets {libyli}
  82 +- But
  83 + - faire une application web
  84 + - avec génération de page en coté serveur
  85 + - avec serveur REST + client ReactJS
  86 +- Organisation
  87 + - équipes de 3 personnes
  88 + - composition des équipes pour lundi (10 oct.)
  89 + - soutenances le 2 décembre
  90 +- Conseils
  91 + - choisir/proposer son sujet
  92 + - commencer tout de suite (partie que serveur)
  93 + - utiliser git
  94 +- Détails sur le site, <a href="http://learn.heeere.com/2016-pwa-6a41/more-projects.html" target="_blank">projets</a>
  95 +
  96 +# Git : installer git avant vendredi (pour windows, voir le lien sur le <a href="http://learn.heeere.com/DSC/guide.html" target="_blank">guide DSC</a>)
  97 +
  98 +<!-- ################################### -->
  99 +# @copy:#plan: %+class:inred: .mvcdemo
  100 +
  101 +## Previously in PWA (+ astuces) {libyli densish}
  102 +- Un modèle « beurk »
  103 + - des équipes avec des co-équipiers
  104 + - sous forme d'objets Java dans une variable « globale »
  105 +- Un/des contrôleur(s) {libyli}
  106 + - annotation de classe `@Controller`
  107 + - annotation de méthode `@RequestMapping(.....)`
  108 + - paramètre « magique » `Model m`, qui sera passé à la vue
  109 + - `m.addAttribute("letruc", valeur)` pour remplir le « modèle de vue »
  110 + - paramètre et annotation `@RequestParameter` pour les formulaires {unseen}
  111 + - capture de pattern dans l'url avec `@PathVariable` {unseen}
  112 +- Une/des vue(s) {libyli}
  113 + - fichiers Thymeleaf = XHTML + `th:....` (templates dite naturelles)
  114 + - remplacer le contenu d'une balise, attribut `... th:text="${letruc}"`
  115 + - ...
  116 + - accès à une propriété d'un objet `${letruc.machin}{}` équivalent à `letruc.getMachin()` en Java
  117 + - répéter la balise donnée, attribut `... th:each="e : ${letruc}"`
  118 + - mélanger texte et variables dans une balise
  119 + - la balise doit avoir `th:inline="text"` (ou il faut utiliser Thymeleaf 3)
  120 + - dans la balise, utiliser des doubles crochets, e.g., `Bonjour [[${nom}]] !` {unseen}
  121 + - gérer les formulaires (cf TP) avec `th:action`, `th:object`, `th:field` {unseen}
  122 +- Convention maven (système de build) + Spring
  123 + - fichiers Java dans `src/main/java/.....`
  124 + - fichiers templates dans `src/main/resources/templates/`
  125 + - fichiers statiques dans `src/main/resources/static/` (pour les .css, .js, images etc)
  126 +
  127 +# Fait entre temps : ajout d'un "id" aux classe du modèle (Equipe et Personne)
  128 +
  129 +# `th:inline="text"`, lien détails (`th:href="@{....}"`)
  130 +
  131 +# suppression, `@RequestParam`, `return "redirect:/....";`
  132 +
  133 +# page de détails `@PathVariable`
  134 +
  135 +# formulaire d'ajout avec `th:action` (et `th:object`, `th:field`, et constructeur vide)
  136 +
  137 +<!-- ################################### -->
  138 +# @copy:#plan: %+class:inred: .di
  139 +
  140 +## Injection de dépendance (DI) {libyli}
  141 +- Cas sans injection de dépendance
  142 + - il nous faut une instance (par ex, une connection DB)
  143 + - on la crée (ou on utilise une « Factory »)
  144 +- Patron « injection de dépendance »
  145 + - Dependency Injection (DI) Inversion of Control (IoC)
  146 + - quelqu'un fourni l'instance (e.g. avec `@Component`), qui est injectée dans notre programme
  147 + - injection par constructeur ou par “setter”
  148 +```java
  149 +class UserObject {
  150 + @Inject Connection connection;
  151 + @Inject BlablaService blabla;
  152 +}
  153 +{slide denser}
  154 +```
  155 +- Ce que fait à peu près le framework d'injection : il cherche des implémentations de Connection et BlablaService, puis
  156 +```java
  157 +Connection cDB = new SQLDataConnection();
  158 +BlablaService s = new BlaBlaServiceImpl();
  159 +UserObject obj = new UserObject();
  160 +obj.setConnection(cDB);
  161 +obj.setService(s);
  162 +{slide denser}
  163 +```
  164 +
  165 +# Injectons avec `@Inject` et `@Component` (+ ajout de dépendance maven à javax.inject)
  166 +
  167 +
  168 +
  169 +
  170 +<!-- ###################### -->
  171 +# @copy:#plan: %+class:inred: .persi
  172 +
  173 +## Persistence: motivation {libyli}
  174 +- When we close/restart an application
  175 + - memory is freed
  176 + - all objects are lost
  177 +- Persistence
  178 + - saving objects state
  179 + - ... on a permanent storage (non-volatile), e.g., database, file, etc
  180 + - allows for reloading objects later
  181 +
  182 +## Persistence Options in Java {libyli}
  183 +- Simple JDBC with or without DAOs (DataAccessObjects)
  184 + - direct access to the SQL database
  185 + - DAO: object that encapsulates/hides SQL requests
  186 +- ORM Concept: Object-Relational Mapping
  187 + - systematic mapping between Java objects and database relations/tables
  188 +- Persistence Frameworks with ORM
  189 + - JPA (Java Persistence API) // most recent
  190 + - JDO (Java Data Objects) // most complete (more than JPA)
  191 + - EJB 3 (Entreprise JavaBeans) // higher level
  192 + - Hibernate (Spring), via JPA // just a JPA backend now
  193 +
  194 +
  195 +## Simple JDBC Example
  196 +```
  197 +import java.sql.*;
  198 +…
  199 +// JDBC driver name and database URL
  200 +static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
  201 +static final String DB_URL = "jdbc:mysql://localhost/EMP";
  202 +// Database credentials
  203 +static final String USER = "username";
  204 +static final String PASS = "password";
  205 +
  206 +public static void main(String[] args) throws ... {
  207 +
  208 + Class.forName(JDBC_DRIVER);
  209 +
  210 + Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
  211 +
  212 + Statement stmt = conn.createStatement();
  213 +
  214 + ResultSet rs = stmt.executeQuery("SELECT id, prenom, nom, age FROM Employes");
  215 +
  216 + while(rs.next()){
  217 +
  218 + int id = rs.getInt("id");
  219 + int age = rs.getInt("age");
  220 + String first = rs.getString("prenom");
  221 + String last = rs.getString("nom");
  222 +
  223 + System.out.print(id + " : " + first + " " + last + " agé de " + age);
  224 + }
  225 +
  226 + rs.close(); // hum....
  227 + stmt.close(); // hum....
  228 + conn.close(); // hum....
  229 +}
  230 +…
  231 +{denser}
  232 +```
  233 +<div class="slide anim-show" data-dur="400" data-what="code>span:nth-of-type(-n+10)"></div>
  234 +<div class="slide anim-show" data-dur="400" data-what="code>span:nth-of-type(n+10):nth-of-type(-n+18)"></div>
  235 +<div class="slide anim-show" data-dur="400" data-what="code>span:nth-of-type(n+18):nth-of-type(-n+28)"></div>
  236 +<div class="slide anim-show" data-dur="400" data-what="code>span:nth-of-type(n+28):nth-of-type(-n+34)"></div>
  237 +
  238 +## Simple JDBC example, Java 7+
  239 +```java
  240 +import java.sql.*;
  241 +…
  242 +// JDBC driver name and database URL
  243 +static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
  244 +static final String DB_URL = "jdbc:mysql://localhost/EMP";
  245 +// Database credentials
  246 +static final String USER = "username";
  247 +static final String PASS = "password";
  248
  249 +public static void main(String[] args) throws ... {
  250 +  
  251 + Class.forName(JDBC_DRIVER);
  252 +  
  253 + try (
  254 + Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
  255 + Statement stmt = conn.createStatement();
  256 + ResultSet rs = stmt.executeQuery("SELECT id, prenom, nom, age FROM Employes");
  257 + ) {
  258 +  
  259 + while(rs.next()){
  260 +  
  261 + int id = rs.getInt("id");
  262 + int age = rs.getInt("age");
  263 + String first = rs.getString("prenom");
  264 + String last = rs.getString("nom");
  265 +  
  266 + System.out.print(id + " : " + first + " " + last + " agé de " + age);
  267 + }
  268 + }
  269 +}
  270 +{denser}
  271 +```
  272 +
  273 +# JDBC simple : avantages/inconvénients ?
  274 +
  275 +
  276 +## Objet-Relational Mapping: concept
  277 +
  278 +- @anim: #objs |#rel |#car |#table |#arr0 |#arr1 |#arr2 |#arr3 |#arr4
  279 +- @anim: #optionClass |#optionTable |#arr678 |#optColumn |#arr5
  280 +
  281 +@SVG: media/orm.svg 800 420
  282 +
  283 +
  284 +
  285 +## Object-Relational Mapping {libyli}
  286 +- Questions?
  287 + - what class corresponds to what table
  288 + - what attribute corresponds to what column
  289 + - what attribute corresponds to what foreign key
  290 + - what are the multiplicities
  291 +- In practice{libyli}
  292 + - using JDBC, manually… tedious
  293 + - source code very long (most of the app) // 30%
  294 + - very repetitive code
  295 + - dangerous code (error-prone)
  296 + - difficult to evolve
  297 + - using a persistence framework
  298 + - JPA, JDO, Hibernate
  299 + - writing metadata on Java classes and attributes
  300 +
  301 +
  302 +<!-- ###################### -->
  303 +# @copy:#plan: %+class:inred: .jpa
  304 +
  305 +## JPA: Java Persistance API {libyli}
  306 +- Why the JPA standard? {libyli}
  307 + - Pure JDBC: tedious
  308 + - Data Access Objects: abstraction, but too much code
  309 + - need a Object/Relational Mapping (ORM) description
  310 + - XML description too verbose and not DRY (Don't Repeat Yourself)
  311 + - proliferation of frameworks (hibernate, toplink, ...)
  312 + - need a usable standard
  313 +- What is JPA?
  314 + - a set of annotations and conventions // default values etc
  315 + - description of object/relational mappings
  316 + - originally, a part EJB 3 (Entreprise Java Beans)
  317 + - an `EntityManager` to manage data (transparent in Spring)
  318 + - to save, `em.persist()`
  319 + - to delete, `em.remove()`
  320 + - to read, `em.find()`, …
  321 +
  322 +## JPA Annotations: simple example
  323 +```java
  324 +import javax.persistence.Column;
  325 +import javax.persistence.Entity;
  326 +import javax.persistence.Id;
  327 +import javax.persistence.GeneratedValue;
  328 +
  329 +
  330 +
  331 +@Entity
  332 +public class Car {
  333 +
  334 +
  335 + @Id
  336 + @GeneratedValue(strategy = GenerationType.AUTO)
  337 + private long id;
  338 +
  339 +
  340 + private String company;
  341 +
  342 +
  343 + private String model;
  344 +
  345 +
  346 + private long price;
  347 +
  348 + ...constr/get/set... Important!
  349 +}
  350 +
  351 +...
  352 +
  353 +EntityManager em;
  354 +...
  355 +em.persist(myCar);
  356 +{}
  357 +```
  358 +
  359 +## JPA Annotations: simple example
  360 +```java
  361 +import javax.persistence.Column;
  362 +import javax.persistence.Entity;
  363 +import javax.persistence.Id;
  364 +import javax.persistence.GeneratedValue;
  365 +import javax.persistence.Table;
  366 +
  367 +@Entity
  368 +@Table(name = "Vehicle")
  369 +public class Car {
  370 +
  371 + @Id
  372 + @Column(name = "id")
  373 + @GeneratedValue(strategy = GenerationType.AUTO)
  374 + private long id;
  375 +
  376 + @Column(name = "company")
  377 + private String company;
  378 +
  379 + @Column(name = "model")
  380 + private String model;
  381 +
  382 + @Column(name = "price")
  383 + private long price;
  384 +
  385 + ...constr/get/set... Important!
  386 +}
  387 +
  388 +...
  389 +
  390 +EntityManager em;
  391 +...
  392 +em.persist(myCar);
  393 +{}
  394 +```
  395 +
  396 +
  397 +## JPA Annotations // make them write something
  398 +- Others {right autre}
  399 + - @PersistenceContext // expliquer qu'il faut sauver les EJB
  400 + - …
  401 +- Class-level
  402 + - @Entity
  403 + - @Table
  404 + - (EJB @Stateless)
  405 + - (EJB @Stateful)
  406 + - …
  407 +- Attribute-level, JavaBean relations {right relations}
  408 + - @OneToOne
  409 + - @ManyToOne
  410 + - @OneToMany
  411 + - @ManyToMany
  412 + - @MapKey
  413 + - @OrderBy
  414 + - …
  415 +- Attribute-level, JavaBean {attr}
  416 + - @Column
  417 + - @Id
  418 + - @GeneratedValue
  419 + - @Temporal, @Lob, @Basic
  420 + - @Version
  421 + - @Transient
  422 + - …
  423 + - @anim: .attr | .relations | .autre
  424 +
  425 +## Manipulating JPA Entities {libyli}
  426 +- (Using an `EntityManager`)
  427 + - to read, `em.find()`, …
  428 + - to save, `em.persist()`
  429 + - to delete, `em.remove()`
  430 +- Using `Repositories`
  431 + - abstraction to list and filter objects
  432 + - need to define an interface
  433 + - implemented automatically, e.g., by Spring Data
  434 + - interfaces: Repository, CrudRepository, PagingAndSortingRepository
  435 + - implementation is obtained via dependency injection
  436 +
  437 +# JPA (`@Entity`, `@Id`, `@OneToMany`, ...), Spring Data (`CrudRepository` x2 + `.save`), `/TEST`
  438 +
  439 +## What Did We Just Do? {libyli}
  440 +- Update the model
  441 + - add an `@Entity` on the class
  442 + - add a `long id` field, <br/> with `@Id @GeneratedValue(strategy=GenerationType.AUTO) {dense}`
  443 +- Create a new repository
  444 + - an (empty) interface (not a class)
  445 + - extending *CrudRepository&lt;MyEntity, Long>{smartcode}*
  446 +- Used the new repository interface
  447 + - injected it
  448 + - used `findAll` and `save`
  449 + - the implementation being provided by spring data
  450 +- According to project configuration (and defaults)
  451 + - spring automatically uses an H2 database
  452 + - the database is in memory (by default)
  453 + - the database schema is automatically created
  454 + - the database is dropped at startup
  455 +
  456 +# Keeping Our Data! <br/> Tuning `application.properties{dense}`
  457 +
  458 +## What Did We Just Do? {libyli}
  459 +- Changing project configuration
  460 + - to override default configuration
  461 + - adding key=value properties in `application.properties`
  462 +- Using a file database (instead of solely in-memory)
  463 + - `spring.datasource.url=jdbc:h2:/tmp/mytestdb`
  464 +- Stopped dropping (and recreating) the database everytime
  465 + - `spring.jpa.hibernate.ddl-auto=none`
  466 +- NB about previous point
  467 + - in case one need to re-create the databse (schema update)
  468 + - the line can be remove
  469 + - or, use `spring.jpa.hibernate.ddl-auto=create-drop`
  470 +- Some properties
  471 + - `spring.datasource.password`, `spring.datasource.username`
  472 + - `server.port`
  473 + - and <a href="http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html" target="_blank">WAY more</a>
  474 +
  475 +
  476 +# ORM : avantages/inconvénients ?
  477 +
  478 +
  479 +<!-- key points -->
  480 +
  481 +## Points Clés {key deck-status-fake-end}
  482 +
  483 +</section>
  484 +
  485 + <!-- deck.status snippet -->
  486 + <p class="deck-status deck-progress-10"> <span class="deck-status-current"></span> / <span class="deck-status-total"></span> − <span class="var-author">will be replaced by the author</span> − <span class="var-title">will be replaced by the title</span></p>
  487 +
  488 + <a data-progress-size=": spe.top(15, 555); height: 45*designRatio; left: slide.right - 90*designRatio; width: 90*designRatio" class="ccby" href="http://en.wikipedia.org/wiki/Creative_Commons_license" title="This work is under CC-BY licence." target="_blank"></a>
  489 +
  490 + <a class="ujm" data-progress-size=": spe.top(15, 525); height: 65*designRatio; left: slide.left; width: 130*designRatio" target="_blank"></a>
  491 +
  492 +</div>
  493 +<!-- clicky Cla -->
  494 +<script type="text/javascript">
  495 +var clicky_site_ids = clicky_site_ids || [];
  496 +clicky_site_ids.push(100779706);
  497 +(function() {
  498 + var s = document.createElement('script');
  499 + s.type = 'text/javascript';
  500 + s.async = true;
  501 + s.src = '//static.getclicky.com/js';
  502 + ( document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0] ).appendChild( s );
  503 +})();
  504 +</script>
  505 +<noscript><p><img alt="Clicky" width="1" height="1" src="//in.getclicky.com/100779706ns.gif" /></p></noscript>
  506 +
  507 +
  508 +<!-- Histats.com START (aync)-->
  509 +<script type="text/javascript">var _Hasync= _Hasync|| [];
  510 +_Hasync.push(['Histats.start', '1,2767123,4,0,0,0,00010000']);
  511 +_Hasync.push(['Histats.fasi', '1']);
  512 +_Hasync.push(['Histats.track_hits', '']);
  513 +(function() {
  514 +var hs = document.createElement('script'); hs.type = 'text/javascript'; hs.async = true;
  515 +hs.src = ('http://s10.histats.com/js15_as.js');
  516 +(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(hs);
  517 +})();</script>
  518 +<noscript><a href="http://www.histats.com" target="_blank"><img src="http://sstatic1.histats.com/0.gif?2767123&101" alt="javascript hit counter" border="0"></a></noscript>
  519 +<!-- Histats.com END -->
  520 +</body>
  521 +</html>
media/orm.svg View file @ d35899b
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<!-- Created with Inkscape (http://www.inkscape.org/) -->
  3 +
  4 +<svg
  5 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  6 + xmlns:cc="http://creativecommons.org/ns#"
  7 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  8 + xmlns:svg="http://www.w3.org/2000/svg"
  9 + xmlns="http://www.w3.org/2000/svg"
  10 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  11 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  12 + width="626.6828"
  13 + height="347.30179"
  14 + id="svg2"
  15 + version="1.1"
  16 + inkscape:version="0.91 r"
  17 + sodipodi:docname="orm.svg">
  18 + <sodipodi:namedview
  19 + id="base"
  20 + pagecolor="#ffffff"
  21 + bordercolor="#666666"
  22 + borderopacity="1.0"
  23 + inkscape:pageopacity="0.0"
  24 + inkscape:pageshadow="2"
  25 + inkscape:zoom="1.979899"
  26 + inkscape:cx="190.23093"
  27 + inkscape:cy="57.772035"
  28 + inkscape:document-units="px"
  29 + inkscape:current-layer="layer1"
  30 + showgrid="false"
  31 + inkscape:window-width="1600"
  32 + inkscape:window-height="848"
  33 + inkscape:window-x="0"
  34 + inkscape:window-y="0"
  35 + inkscape:window-maximized="1"
  36 + fit-margin-top="0"
  37 + fit-margin-left="0"
  38 + fit-margin-right="0"
  39 + fit-margin-bottom="0" />
  40 + <defs
  41 + id="defs4">
  42 + <marker
  43 + style="overflow:visible"
  44 + id="Arrow2Mend"
  45 + refX="0"
  46 + refY="0"
  47 + orient="auto"
  48 + inkscape:stockid="Arrow2Mend">
  49 + <path
  50 + transform="scale(-0.6,-0.6)"
  51 + d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
  52 + style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
  53 + id="path3868"
  54 + inkscape:connector-curvature="0" />
  55 + </marker>
  56 + <marker
  57 + style="overflow:visible"
  58 + id="EmptyDiamondL"
  59 + refX="0"
  60 + refY="0"
  61 + orient="auto"
  62 + inkscape:stockid="EmptyDiamondL">
  63 + <path
  64 + transform="scale(0.8,0.8)"
  65 + style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
  66 + d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
  67 + id="path3947"
  68 + inkscape:connector-curvature="0" />
  69 + </marker>
  70 + <marker
  71 + style="overflow:visible"
  72 + id="DiamondL"
  73 + refX="0"
  74 + refY="0"
  75 + orient="auto"
  76 + inkscape:stockid="DiamondL">
  77 + <path
  78 + transform="scale(0.8,0.8)"
  79 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
  80 + d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
  81 + id="path3920"
  82 + inkscape:connector-curvature="0" />
  83 + </marker>
  84 + <marker
  85 + style="overflow:visible"
  86 + id="Arrow1Mend"
  87 + refX="0"
  88 + refY="0"
  89 + orient="auto"
  90 + inkscape:stockid="Arrow1Mend">
  91 + <path
  92 + inkscape:connector-curvature="0"
  93 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  94 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
  95 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  96 + id="path3861" />
  97 + </marker>
  98 + <marker
  99 + style="overflow:visible"
  100 + id="Arrow1Mend-0"
  101 + refX="0"
  102 + refY="0"
  103 + orient="auto"
  104 + inkscape:stockid="Arrow1Mend">
  105 + <path
  106 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  107 + style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
  108 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  109 + id="path3861-8"
  110 + inkscape:connector-curvature="0" />
  111 + </marker>
  112 + <marker
  113 + style="overflow:visible"
  114 + id="Arrow1Mend4"
  115 + refX="0"
  116 + refY="0"
  117 + orient="auto"
  118 + inkscape:stockid="Arrow1Mend4">
  119 + <path
  120 + inkscape:connector-curvature="0"
  121 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  122 + style="fill:#008080;fill-rule:evenodd;stroke:#008080;stroke-width:1pt"
  123 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  124 + id="path4944" />
  125 + </marker>
  126 + <marker
  127 + style="overflow:visible"
  128 + id="Arrow1Mend4-5"
  129 + refX="0"
  130 + refY="0"
  131 + orient="auto"
  132 + inkscape:stockid="Arrow1Mend4">
  133 + <path
  134 + inkscape:connector-curvature="0"
  135 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  136 + style="fill:#008080;fill-rule:evenodd;stroke:#008080;stroke-width:1pt"
  137 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  138 + id="path4944-1" />
  139 + </marker>
  140 + <marker
  141 + style="overflow:visible"
  142 + id="Arrow1Mend4-54"
  143 + refX="0"
  144 + refY="0"
  145 + orient="auto"
  146 + inkscape:stockid="Arrow1Mend4">
  147 + <path
  148 + inkscape:connector-curvature="0"
  149 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  150 + style="fill:#008080;fill-rule:evenodd;stroke:#008080;stroke-width:1pt"
  151 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  152 + id="path4944-0" />
  153 + </marker>
  154 + <marker
  155 + style="overflow:visible"
  156 + id="Arrow1Mend4-9"
  157 + refX="0"
  158 + refY="0"
  159 + orient="auto"
  160 + inkscape:stockid="Arrow1Mend4">
  161 + <path
  162 + inkscape:connector-curvature="0"
  163 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  164 + style="fill:#008080;fill-rule:evenodd;stroke:#008080;stroke-width:1pt"
  165 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  166 + id="path4944-8" />
  167 + </marker>
  168 + <marker
  169 + style="overflow:visible"
  170 + id="Arrow1Mend4-99"
  171 + refX="0"
  172 + refY="0"
  173 + orient="auto"
  174 + inkscape:stockid="Arrow1Mend4">
  175 + <path
  176 + inkscape:connector-curvature="0"
  177 + transform="matrix(-0.4,0,0,-0.4,-4,0)"
  178 + style="fill:#008080;fill-rule:evenodd;stroke:#008080;stroke-width:1pt"
  179 + d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
  180 + id="path4944-6" />
  181 + </marker>
  182 + </defs>
  183 + <metadata
  184 + id="metadata7">
  185 + <rdf:RDF>
  186 + <cc:Work
  187 + rdf:about="">
  188 + <dc:format>image/svg+xml</dc:format>
  189 + <dc:type
  190 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
  191 + <dc:title />
  192 + </cc:Work>
  193 + </rdf:RDF>
  194 + </metadata>
  195 + <g
  196 + transform="translate(-34.5,-13.28125)"
  197 + id="layer1"
  198 + inkscape:groupmode="layer"
  199 + inkscape:label="Layer 1">
  200 + <g
  201 + inkscape:label="#g4378"
  202 + id="table">
  203 + <rect
  204 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000080;stroke-width:1px;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"
  205 + id="rect3048-9"
  206 + width="267.6568"
  207 + height="25.731838"
  208 + x="326.20322"
  209 + y="87.448105" />
  210 + <g
  211 + id="g3056"
  212 + transform="translate(-35.739783,0)">
  213 + <g
  214 + transform="translate(-10.747322,20)"
  215 + id="g3020">
  216 + <rect
  217 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;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"
  218 + id="rect3008"
  219 + width="66.165031"
  220 + height="167.6853"
  221 + x="372.74628"
  222 + y="93.222343" />
  223 + <text
  224 + xml:space="preserve"
  225 + style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  226 + x="404.32242"
  227 + y="110.89999"
  228 + id="text3014"
  229 + sodipodi:linespacing="125%"><tspan
  230 + sodipodi:role="line"
  231 + id="tspan3016"
  232 + x="404.32242"
  233 + y="110.89999">id</tspan></text>
  234 + <path
  235 + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  236 + d="m 373.03572,117.89789 65.71428,0"
  237 + id="path3018"
  238 + inkscape:connector-curvature="0" />
  239 + </g>
  240 + <g
  241 + transform="translate(56.417709,20)"
  242 + id="g3026">
  243 + <rect
  244 + y="93.222343"
  245 + x="372.74628"
  246 + height="167.6853"
  247 + width="66.165031"
  248 + id="rect3028"
  249 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;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" />
  250 + <text
  251 + sodipodi:linespacing="125%"
  252 + id="text3030"
  253 + y="108.8797"
  254 + x="404.32242"
  255 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  256 + xml:space="preserve"><tspan
  257 + y="108.8797"
  258 + x="404.32242"
  259 + id="tspan3032"
  260 + sodipodi:role="line">company</tspan></text>
  261 + <path
  262 + inkscape:connector-curvature="0"
  263 + id="path3034"
  264 + d="m 373.03572,117.89789 65.71428,0"
  265 + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  266 + </g>
  267 + <g
  268 + id="g3036"
  269 + transform="translate(123.58274,20)">
  270 + <rect
  271 + y="93.222343"
  272 + x="372.74628"
  273 + height="167.6853"
  274 + width="66.165031"
  275 + id="rect3038"
  276 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;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" />
  277 + <text
  278 + sodipodi:linespacing="125%"
  279 + id="text3040"
  280 + y="108.8797"
  281 + x="404.32242"
  282 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  283 + xml:space="preserve"><tspan
  284 + y="108.8797"
  285 + x="404.32242"
  286 + id="tspan3042"
  287 + sodipodi:role="line">model</tspan></text>
  288 + <path
  289 + inkscape:connector-curvature="0"
  290 + id="path3044"
  291 + d="m 373.03572,117.89789 65.71428,0"
  292 + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  293 + </g>
  294 + <g
  295 + id="g3046"
  296 + transform="translate(190.74777,20)">
  297 + <rect
  298 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;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"
  299 + id="rect3048"
  300 + width="66.165031"
  301 + height="167.6853"
  302 + x="372.74628"
  303 + y="93.222343" />
  304 + <text
  305 + xml:space="preserve"
  306 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  307 + x="404.32242"
  308 + y="108.8797"
  309 + id="text3050"
  310 + sodipodi:linespacing="125%"><tspan
  311 + sodipodi:role="line"
  312 + id="tspan3052"
  313 + x="404.32242"
  314 + y="108.8797">price</tspan></text>
  315 + <path
  316 + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
  317 + d="m 373.03572,117.89789 65.71428,0"
  318 + id="path3054"
  319 + inkscape:connector-curvature="0" />
  320 + </g>
  321 + <g
  322 + transform="translate(257.48507,20)"
  323 + id="optColumn"
  324 + inkscape:label="#g4861">
  325 + <rect
  326 + y="93.222343"
  327 + x="372.74628"
  328 + height="167.6853"
  329 + width="66.165031"
  330 + id="rect4863"
  331 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1px;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" />
  332 + <text
  333 + sodipodi:linespacing="125%"
  334 + id="text4865"
  335 + y="108.8797"
  336 + x="404.32242"
  337 + style="font-size:10px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  338 + xml:space="preserve"><tspan
  339 + y="108.8797"
  340 + x="404.32242"
  341 + id="tspan4867"
  342 + sodipodi:role="line">opt_id</tspan></text>
  343 + <path
  344 + inkscape:connector-curvature="0"
  345 + id="path4869"
  346 + d="m 373.03572,117.89789 65.71428,0"
  347 + style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  348 + <rect
  349 + y="67.448097"
  350 + x="104.45793"
  351 + height="25.589649"
  352 + width="334.48849"
  353 + id="rect5172"
  354 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000080;stroke-width:1px;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" />
  355 + </g>
  356 + </g>
  357 + <text
  358 + xml:space="preserve"
  359 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000080;fill-opacity:1;stroke:none"
  360 + x="458.10419"
  361 + y="106.35432"
  362 + id="text4374"
  363 + sodipodi:linespacing="125%"><tspan
  364 + sodipodi:role="line"
  365 + id="tspan4376"
  366 + x="458.10419"
  367 + y="106.35432">Vehicle</tspan></text>
  368 + </g>
  369 + <g
  370 + inkscape:label="#g4337"
  371 + id="car">
  372 + <rect
  373 + style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#800000;stroke-width:1px;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"
  374 + id="rect2986"
  375 + width="212.22081"
  376 + height="136.26067"
  377 + x="35"
  378 + y="29.505035" />
  379 + <rect
  380 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1px;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"
  381 + id="rect2988"
  382 + width="80.714287"
  383 + height="25.357143"
  384 + x="41.428574"
  385 + y="13.790756" />
  386 + <text
  387 + xml:space="preserve"
  388 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20px;line-height:125%;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
  389 + x="81.517784"
  390 + y="35.481583"
  391 + id="text2982"
  392 + sodipodi:linespacing="125%"><tspan
  393 + sodipodi:role="line"
  394 + id="tspan2984"
  395 + x="81.517784"
  396 + y="35.481583">Car</tspan></text>
  397 + <text
  398 + xml:space="preserve"
  399 + style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  400 + x="58.354218"
  401 + y="69.082764"
  402 + id="text2990"
  403 + sodipodi:linespacing="125%"><tspan
  404 + sodipodi:role="line"
  405 + id="tspan2992"
  406 + x="58.354218"
  407 + y="69.082764">id: long</tspan><tspan
  408 + sodipodi:role="line"
  409 + x="58.354218"
  410 + y="94.082764"
  411 + id="tspan2996">price: long</tspan><tspan
  412 + sodipodi:role="line"
  413 + x="58.354218"
  414 + y="119.08276"
  415 + id="tspan4331">model: String</tspan><tspan
  416 + sodipodi:role="line"
  417 + x="58.354218"
  418 + y="144.08276"
  419 + id="tspan4325">company: String</tspan></text>
  420 + </g>
  421 + <text
  422 + inkscape:label="#text3000"
  423 + sodipodi:linespacing="125%"
  424 + id="objs"
  425 + y="344.25024"
  426 + x="139.90613"
  427 + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:30px;line-height:125%;font-family:Roboto;-inkscape-font-specification:Roboto;text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#800000;fill-opacity:1;stroke:none"
  428 + xml:space="preserve"><tspan
  429 + y="344.25024"
  430 + x="139.90613"
  431 + id="tspan3002"
  432 + sodipodi:role="line">Objects</tspan></text>
  433 + <text
  434 + inkscape:label="#text3004"
  435 + xml:space="preserve"
  436 + style="font-size:30px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000080;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  437 + x="479.90613"
  438 + y="36.250248"
  439 + id="rel"
  440 + sodipodi:linespacing="125%"><tspan
  441 + sodipodi:role="line"
  442 + id="tspan3006"
  443 + x="479.90613"
  444 + y="36.250248">Relation(s)</tspan></text>
  445 + <path
  446 + inkscape:label="#path3078"
  447 + inkscape:connector-curvature="0"
  448 + id="arr1"
  449 + d="m 146.42857,65.93361 c 205.71429,-45 205.71429,-7.142857 207.85714,45.71429"
  450 + style="fill:none;stroke:#008080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow1Mend4)" />
  451 + <path
  452 + inkscape:label="#path4292"
  453 + sodipodi:nodetypes="cc"
  454 + inkscape:connector-curvature="0"
  455 + id="arr2"
  456 + d="m 173.57142,85.93361 c 93.57143,-24.285714 358.57143,-65.000001 386.42857,30"
  457 + style="color:#000000;fill:none;stroke:#008080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend4);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  458 + <path
  459 + inkscape:label="#path4333"
  460 + style="color:#000000;fill:none;stroke:#008080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend4);visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
  461 + d="m 201.57142,111.93361 c 110,-31.428568 280.00001,-88.571429 295,4.28571"
  462 + id="arr3"
  463 + inkscape:connector-curvature="0"
  464 + sodipodi:nodetypes="cc" />
  465 + <path
  466 + inkscape:label="#path4335"
  467 + sodipodi:nodetypes="cc"
  468 + inkscape:connector-curvature="0"
  469 + id="arr4"
  470 + d="M 229.57142,133.93361 C 251,121.79075 410.28572,38.219324 425.28571,114.64789"
  471 + style="color:#000000;fill:none;stroke:#008080;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;marker-end:url(#Arrow1Mend4);visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
  472 + <g
  473 + id="optionClass"
  474 + inkscape:label="#g5159"
  475 + transform="translate(0,20)">
  476 + <g
  477 + inkscape:label="#g4337"
  478 + id="g3029"
  479 + transform="translate(100,160)">
  480 + <rect
  481 + style="color:#000000;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:#800000;stroke-width:1px;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"
  482 + id="rect3031"
  483 + width="162.93509"
  484 + height="86.260666"
  485 + x="35"
  486 + y="29.505035" />
  487 + <rect
  488 + style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1px;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"
  489 + id="rect3033"
  490 + width="80.714287"
  491 + height="25.357143"
  492 + x="41.428574"
  493 + y="13.790756" />
  494 + <text
  495 + xml:space="preserve"
  496 + style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  497 + x="81.517784"
  498 + y="35.481583"
  499 + id="text3035"
  500 + sodipodi:linespacing="125%"><tspan
  501 + sodipodi:role="line"
  502 + id="tspan3037"
  503 + x="81.517784"
  504 + y="35.481583">Option</tspan></text>
  505 + <text
  506 + xml:space="preserve"
  507 + style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Roboto;-inkscape-font-specification:Roboto"
  508 + x="58.354218"
  509 + y="69.082764"
  510 + id="text3039"
  511 + sodipodi:linespacing="125%"><tspan